Author: pgil
Date: Fri May 18 15:53:35 2018 New Revision: 1831867 URL: http://svn.apache.org/viewvc?rev=1831867&view=rev Log: Implemented : File transfer management with communicationEvent and new contactMech FTP_ADDRESS (OFBIZ-10245) This commit introduce a new way to manage file transfer in OFBiz. Inspired by mailing communication event management, a new communicationEventTypeId is created ('FILE_TRANSFER_COMM'). Such commEvent with classics : partyIdFrom/partyIdTo/contactMechIdTo/entryDate etc. are analysed by a job (like sendEmailDated), to send associated contents to a configured FTP/SFTP/FTPS server. If failure happens, it is catched and stored in communicationEvent, waiting for a new try. For this purpose : A new contactMechTypeId is introduced (FtpAddress), with its corresponding table. This contactMech store needed information for basic user/password authentication (server url and protocol, port, username, password, etc.) A new service sendFileTransferDated that will look for pending file transfer and call following service. A new service sendCommEventAsFtp that take a selected commEvent, check its structure and manage its status after trying the associated content file transfers. A new service sendContentToFtp, that take a content and transfer it to a given FtpAddress. A seca createCommEventFromFtpTransfer on sendContentToFtp to manage plural content file transfer, creating children communicationEvent to follow each content transfer separately (only for several content transfers). A new Interface FtpClientInterface, with the 3 implementations of FTP, FTPS (To Implement), SFTP clients to manage Ftp connection and transfer. A new property file to enable and manage redirection for testing purpose. With this implementation, creating a communicationEvent, with a FtpAddress contactMechIdTo, and sendFileTransferDated job planned, the file is transfered to the ftp : communication event status set to COM_COMPLETE, if error occured the communication event status is set to COM_BOUNCED with error message on communicationEvent note. Thanks Rishi for your feedbacks Added: ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml (with props) ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/ ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java (with props) ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java (with props) ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java (with props) ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java (with props) ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java (with props) ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy (with props) ofbiz/ofbiz-framework/trunk/framework/common/config/ftp.properties (with props) Modified: ofbiz/ofbiz-framework/trunk/applications/content/config/ContentErrorUiLabels.xml ofbiz/ofbiz-framework/trunk/applications/content/ofbiz-component.xml ofbiz/ofbiz-framework/trunk/applications/datamodel/data/seed/PartySeedData.xml ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/party-entitymodel.xml ofbiz/ofbiz-framework/trunk/applications/party/config/PartyEntityLabels.xml ofbiz/ofbiz-framework/trunk/applications/party/config/PartyErrorUiLabels.xml ofbiz/ofbiz-framework/trunk/applications/party/config/PartyUiLabels.xml ofbiz/ofbiz-framework/trunk/applications/party/servicedef/secas.xml ofbiz/ofbiz-framework/trunk/applications/party/servicedef/services.xml ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/communication/CommunicationEventServices.java ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/contact/ContactMechWorker.java ofbiz/ofbiz-framework/trunk/applications/party/template/party/EditContactMech.ftl ofbiz/ofbiz-framework/trunk/applications/party/template/party/profileblocks/Contact.ftl ofbiz/ofbiz-framework/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml ofbiz/ofbiz-framework/trunk/build.gradle Modified: ofbiz/ofbiz-framework/trunk/applications/content/config/ContentErrorUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/config/ContentErrorUiLabels.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/config/ContentErrorUiLabels.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/content/config/ContentErrorUiLabels.xml Fri May 18 15:53:35 2018 @@ -303,6 +303,10 @@ <value xml:lang="zh">没æä¸ä¼ æ件</value> <value xml:lang="zh-TW">æ²æä¸å³æªæ¡</value> </property> + <property key="ftpservices.contact_mech_must_be_ftp"> + <value xml:lang="en">ERROR: Contact mech must be an ftp server</value> + <value xml:lang="fr">ERREUR: La coordonnée destinataire doit être un serveur ftp</value> + </property> <property key="layoutEvents.content_empty"> <value xml:lang="da">indhold er tomt</value> <value xml:lang="de">Inhalt ist leer</value> Modified: ofbiz/ofbiz-framework/trunk/applications/content/ofbiz-component.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/ofbiz-component.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/ofbiz-component.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/content/ofbiz-component.xml Fri May 18 15:53:35 2018 @@ -37,6 +37,7 @@ under the License. <service-resource type="model" loader="main" location="servicedef/services_contenttypes.xml"/> <service-resource type="model" loader="main" location="servicedef/services_data.xml"/> <service-resource type="model" loader="main" location="servicedef/services_document.xml"/> + <service-resource type="model" loader="main" location="servicedef/services_ftp.xml"/> <service-resource type="model" loader="main" location="servicedef/services_output.xml"/> <service-resource type="model" loader="main" location="servicedef/services_survey.xml"/> <service-resource type="model" loader="main" location="servicedef/services_commevent.xml"/> Added: ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml (added) +++ ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml Fri May 18 15:53:35 2018 @@ -0,0 +1,35 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + --> + +<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/services.xsd"> + <description>Content Component Ftp Services</description> + <vendor>OFBiz</vendor> + + <!-- DataResource services --> + <service name="sendContentToFtp" engine="java" + location="org.apache.ofbiz.content.ftp.FtpServices" invoke="sendContentToFtp" auth="true"> + <description>Send content to FtpAddress</description> + <attribute name="contentId" type="String" mode="IN"/> + <attribute name="contactMechId" type="String" mode="IN"/> + <!-- used for parsing and ECAs --> + <attribute name="partyId" type="String" mode="IN" optional="true"/> + <attribute name="communicationEventId" type="String" mode="INOUT" optional="true"/> + </service> +</services> Propchange: ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/content/servicedef/services_ftp.xml ------------------------------------------------------------------------------ svn:mime-type = text/xml Added: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java (added) +++ ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java Fri May 18 15:53:35 2018 @@ -0,0 +1,43 @@ +package org.apache.ofbiz.content.ftp; + +import org.apache.ofbiz.base.util.GeneralException; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public interface FtpClientInterface { + + /** + * Initialization of a file transfer client, and connection to the given server + * + * @param hostname hostname to connect to + * @param username username to login with + * @param password password to login with + * @param port port to connect to the server, optional + * @param timeout timeout for connection process, optional + * @throws IOException + */ + void connect(String hostname, String username, String password, Long port, Long timeout) throws IOException, GeneralException; + + /** + * Copy of the give file to the connected server into the path. + * + * @param path path to copy the file to + * @param fileName name of the copied file + * @param file data to copy + * @throws IOException + */ + void copy(String path, String fileName, InputStream file) throws IOException; + + List<String> list(String path) throws IOException; + + void setBinaryTransfer(boolean isBinary) throws IOException; + + void setPassiveMode(boolean isPassive) throws IOException; + + /** + * Close opened connection + */ + void closeConnection() throws IOException; +} Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpClientInterface.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java (added) +++ ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java Fri May 18 15:53:35 2018 @@ -0,0 +1,204 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.apache.ofbiz.content.ftp; + +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.FileUtil; +import org.apache.ofbiz.base.util.GeneralException; +import org.apache.ofbiz.base.util.UtilMisc; +import org.apache.ofbiz.base.util.UtilProperties; +import org.apache.ofbiz.base.util.UtilValidate; +import org.apache.ofbiz.content.data.DataResourceWorker; +import org.apache.ofbiz.entity.Delegator; +import org.apache.ofbiz.entity.GenericValue; +import org.apache.ofbiz.entity.util.EntityQuery; +import org.apache.ofbiz.entity.util.EntityUtilProperties; +import org.apache.ofbiz.service.DispatchContext; +import org.apache.ofbiz.service.ServiceUtil; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Locale; +import java.util.Map; + + +/** + * FtpServices class + * This class provide Ftp transfer services for content + */ +public class FtpServices { + + public static final String module = FtpServices.class.getName(); + public static final String resource = "ContentUiLabels"; + + private static FtpClientInterface createFtpClient(String serverType) + throws GeneralException { + FtpClientInterface ftpClient = null; + switch (serverType) { + case "ftp": + ftpClient = new SimpleFtpClient(); + break; + case "ftps": + //TODO : to implements + throw new GeneralException("Ftp secured transfer protocol not yet implemented"); + case "sftp": + ftpClient = new SshFtpClient(); + break; + } + return ftpClient; + } + + public static Map<String, Object> sendContentToFtp(DispatchContext dctx, Map<String, Object> context) { + Delegator delegator = dctx.getDelegator(); + Locale locale = (Locale) context.get("locale"); + String contactMechId = (String) context.get("contactMechId"); + String contentId = (String) context.get("contentId"); + String communicationEventId = (String) context.get("communicationEventId"); + boolean forceTransferControlSuccess = EntityUtilProperties.propertyValueEqualsIgnoreCase("ftp", "ftp.force.transfer.control", "Y", delegator); + boolean ftpNotificationEnabled = EntityUtilProperties.propertyValueEqualsIgnoreCase("ftp", "ftp.notifications.enabled", "Y", delegator); + + if (ftpNotificationEnabled) return ServiceUtil.returnSuccess(); + + // for ECA communicationEvent process + Map<String, Object> resultMap = ServiceUtil.returnSuccess(); + resultMap.put("communicationEventId", communicationEventId); + + FtpClientInterface ftpClient = null; + + try { + //Retrieve and check contactMechType + GenericValue contactMech = EntityQuery.use(delegator).from("ContactMech").where("contactMechId", contactMechId).cache().queryOne(); + GenericValue ftpAddress = EntityQuery.use(delegator).from("FtpAddress").where("contactMechId", contactMechId).cache().queryOne(); + if (null == contactMech || null == ftpAddress || !"FTP_ADDRESS".equals(contactMech.getString("contactMechTypeId"))) { + String errMsg = UtilProperties.getMessage("ContentErrorUiLabels", "ftpservices.contact_mech_must_be_ftp", locale); + return ServiceUtil.returnError(errMsg + " " + contactMechId); + } + + //Validate content + GenericValue content = EntityQuery.use(delegator).from("Content").where("contentId", contentId).cache().queryOne(); + if (null == content) { + return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ContentNoContentFound", UtilMisc.toMap("contentId", contentId), locale)); + } + + //ftp redirection + if ("Y".equalsIgnoreCase(UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.enabled"))) { + ftpAddress = delegator.makeValue("FtpAddress"); + ftpAddress.put("defaultTimeout", UtilProperties.getPropertyAsLong("ftp", "ftp.notifications.redirectTo.defaultTimeout", 30000)); + ftpAddress.put("hostname", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.hostname")); + ftpAddress.put("path", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.path")); + ftpAddress.put("port", UtilProperties.getPropertyAsLong("ftp", "ftp.notifications.redirectTo.port", 65535)); + ftpAddress.put("username", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.username")); + ftpAddress.put("password", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.password")); + ftpAddress.put("binaryTransfer", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.binaryTransfer")); + ftpAddress.put("passiveMode", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.passiveMode")); + ftpAddress.put("zipFile", UtilProperties.getPropertyValue("ftp", "ftp.notifications.redirectTo.zipFile")); + } + + String hostname = ftpAddress.getString("hostname"); + if (UtilValidate.isEmpty(hostname)) + return ServiceUtil.returnError("Ftp destination server is null"); + else if (hostname.indexOf("://") == -1) { + return ServiceUtil.returnError("No protocol defined in ftp destination address"); + } + + String serverType = hostname.split("://")[0]; + hostname = hostname.split("://")[1]; + + ftpClient = createFtpClient(serverType); + if (null == ftpClient) { + return ServiceUtil.returnError("Server type : " + serverType + ", not supported for hostname " + hostname); + } + + Long defaultTimeout = ftpAddress.getLong("defaultTimeout"); + Long port = ftpAddress.getLong("port"); + String username = ftpAddress.getString("username"); + String password = ftpAddress.getString("password"); + + if (Debug.infoOn()) + Debug.logInfo("connecting to: " + username + "@" + ftpAddress.getString("hostname") + ":" + port, module); + ftpClient.connect(hostname, username, password, port, defaultTimeout); + boolean binary = "Y".equalsIgnoreCase(ftpAddress.getString("binaryTransfer")); + ftpClient.setBinaryTransfer(binary); + boolean passive = "Y".equalsIgnoreCase(ftpAddress.getString("passiveMode")); + ftpClient.setPassiveMode(passive); + + GenericValue dataResource = delegator.findOne("DataResource", true, "dataResourceId", content.getString("dataResourceId")); + Map<String, Object> resultStream = DataResourceWorker.getDataResourceStream(dataResource, null, null, locale, null, true); + InputStream contentStream = (InputStream) resultStream.get("stream"); + if (contentStream == null) { + return ServiceUtil.returnError("DataResource " + content.getString("dataResourceId") + " return an empty stream"); + } + + String path = ftpAddress.getString("path"); + if (Debug.infoOn()) + Debug.logInfo("storing local file remotely as: " + (UtilValidate.isNotEmpty(path) ? path + "/" : "") + content.getString("contentName"), module); + + String fileName = content.getString("contentName"); + String remoteFileName = fileName; + boolean zipFile = "Y".equalsIgnoreCase(ftpAddress.getString("zipFile")); + if (zipFile) { + //Create zip file from content input stream + ByteArrayInputStream zipStream = FileUtil.zipFileStream(contentStream, fileName); + remoteFileName = fileName + (fileName.endsWith("zip")?"":".zip"); + ftpClient.copy(path, remoteFileName, zipStream); + + zipStream.close(); + } else { + ftpClient.copy(path, remoteFileName, contentStream); + } + contentStream.close(); + + //test if the file is correctly sent + if (forceTransferControlSuccess) { + if (Debug.infoOn()) Debug.logInfo(" Control if service really success the transfer", module); + + //recreate the connection + ftpClient.closeConnection(); + ftpClient = createFtpClient(serverType); + ftpClient.connect(hostname, username, password, port, defaultTimeout); + ftpClient.setBinaryTransfer(binary); + ftpClient.setPassiveMode(passive); + + //check the file name previously copy + List<String> fileNames = ftpClient.list(path); + if (Debug.infoOn()) Debug.logInfo(" For the path " + path + " we found " + fileNames, module); + + if (fileNames == null || !fileNames.contains(remoteFileName)) { + return ServiceUtil.returnError("DataResource " + content.getString("dataResourceId") + " return an empty stream"); + } + if (Debug.infoOn()) + Debug.logInfo(" Ok the file " + content.getString("contentName") + " is present", module); + } + } catch (GeneralException | IOException e) { + return ServiceUtil.returnError(e.getMessage()); + } finally { + try { + if (ftpClient != null) { + ftpClient.closeConnection(); + } + } catch (Exception e) { + Debug.logWarning(e, "[getFile] Problem with FTP disconnect: ", module); + } + } + return resultMap; + } + +} Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/FtpServices.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java (added) +++ ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java Fri May 18 15:53:35 2018 @@ -0,0 +1,43 @@ +package org.apache.ofbiz.content.ftp; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +public class SecureFtpClient implements FtpClientInterface { + + public static final String module = SecureFtpClient.class.getName(); + + /** + * TODO : to implements + */ + @Override + public void connect(String hostname, String username, String password, Long port, Long timeout) throws IOException { + + } + + @Override + public void copy(String path, String fileName, InputStream file) throws IOException { + + } + + @Override + public List<String> list(String path) throws IOException { + return null; + } + + @Override + public void setBinaryTransfer(boolean isBinary) throws IOException { + + } + + @Override + public void setPassiveMode(boolean isPassive) throws IOException { + + } + + @Override + public void closeConnection() { + + } +} Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SecureFtpClient.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java (added) +++ ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java Fri May 18 15:53:35 2018 @@ -0,0 +1,85 @@ +package org.apache.ofbiz.content.ftp; + +import org.apache.commons.net.ftp.FTP; +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPFile; +import org.apache.commons.net.ftp.FTPReply; +import org.apache.ofbiz.base.util.Debug; +import org.apache.ofbiz.base.util.GeneralException; +import org.apache.ofbiz.base.util.UtilProperties; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class SimpleFtpClient implements FtpClientInterface { + + public static final String module = SimpleFtpClient.class.getName(); + private FTPClient client; + + public SimpleFtpClient() { + client = new FTPClient(); + } + + @Override + public void connect(String hostname, String username, String password, Long port, Long timeout) throws IOException, GeneralException { + if (client == null) return; + if (client.isConnected()) return; + if (port != null) { + client.connect(hostname, port.intValue()); + } else { + client.connect(hostname); + } + if (timeout != null) client.setDefaultTimeout(timeout.intValue()); + + if (!FTPReply.isPositiveCompletion(client.getReplyCode())) { + Debug.logError("Server refused connection", module); + throw new GeneralException(UtilProperties.getMessage("CommonUiLabels", "CommonFtpConnectionRefused", Locale.getDefault())); + } + if (!client.login(username, password)) { + Debug.logError("login failed", module); + throw new GeneralException(UtilProperties.getMessage("CommonUiLabels", "CommonFtpLoginFailure", Locale.getDefault())); + } + } + + @Override + public List<String> list(String path) throws IOException { + FTPFile[] files = client.listFiles(path); + List<String> fileNames = new ArrayList<>(); + for (FTPFile file : files) { + fileNames.add(file.getName()); + } + return fileNames; + } + + public void setBinaryTransfer(boolean isBinary) throws IOException { + if (isBinary) { + client.setFileType(FTP.BINARY_FILE_TYPE); + } else { + client.setFileType(FTP.ASCII_FILE_TYPE); + } + } + + public void setPassiveMode(boolean isPassive) { + if (isPassive) { + client.enterLocalPassiveMode(); + } else { + client.enterLocalActiveMode(); + } + } + + @Override + public void copy(String path, String fileName, InputStream file) throws IOException { + client.changeWorkingDirectory(path); + client.storeFile(fileName, file); + } + + @Override + public void closeConnection() throws IOException { + if (client != null && client.isConnected()) { + client.logout(); + } + } +} Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SimpleFtpClient.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java (added) +++ ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java Fri May 18 15:53:35 2018 @@ -0,0 +1,74 @@ +package org.apache.ofbiz.content.ftp; + +import org.apache.commons.io.IOUtils; +import org.apache.sshd.client.SshClient; +import org.apache.sshd.client.session.ClientSession; +import org.apache.sshd.client.subsystem.sftp.SftpClient; +import org.apache.ofbiz.base.util.UtilValidate; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +/** + * Basic client to copy files to an ssh ftp server + */ +public class SshFtpClient implements FtpClientInterface { + + public static final String module = SshFtpClient.class.getName(); + + private SshClient client; + private SftpClient sftp; + + public SshFtpClient() { + client = SshClient.setUpDefaultClient(); + client.start(); + } + + @Override + public void connect(String hostname, String username, String password, Long port, Long timeout) throws IOException { + if (port == null) port = 22l; + if (timeout == null) timeout = 10000l; + + if (sftp != null) return; + ClientSession session = client.connect(username, hostname, port.intValue()).verify(timeout.intValue()).getSession(); + session.addPasswordIdentity(password); + session.auth().verify(timeout.intValue()); + sftp = session.createSftpClient(); + } + + @Override + public void copy(String path, String fileName, InputStream file) throws IOException { + OutputStream os = sftp.write((UtilValidate.isNotEmpty(path) ? path + "/" : "") + fileName); + IOUtils.copy(file, os); + os.close(); + } + + @Override + public List<String> list(String path) throws IOException { + SftpClient.CloseableHandle handle = sftp.openDir((UtilValidate.isNotEmpty(path) ? path + "/" : "")); + List<String> fileNames = new ArrayList<>(); + for (SftpClient.DirEntry dirEntry : sftp.listDir(handle)) { + fileNames.add(dirEntry.getFilename()); + } + return fileNames; + } + + @Override + public void setBinaryTransfer(boolean isBinary) throws IOException { + } + + @Override + public void setPassiveMode(boolean isPassive) throws IOException { + } + + @Override + public void closeConnection() { + if (sftp != null) { + client.stop(); + sftp = null; + } + } +} Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/content/src/main/java/org/apache/ofbiz/content/ftp/SshFtpClient.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: ofbiz/ofbiz-framework/trunk/applications/datamodel/data/seed/PartySeedData.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/datamodel/data/seed/PartySeedData.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/datamodel/data/seed/PartySeedData.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/datamodel/data/seed/PartySeedData.xml Fri May 18 15:53:35 2018 @@ -63,6 +63,7 @@ under the License. <ContactMechType contactMechTypeId="DOMAIN_NAME" description="Internet Domain Name" hasTable="N" parentTypeId="ELECTRONIC_ADDRESS"/> <ContactMechType contactMechTypeId="WEB_ADDRESS" description="Web URL/Address" hasTable="N" parentTypeId="ELECTRONIC_ADDRESS"/> <ContactMechType contactMechTypeId="INTERNAL_PARTYID" description="Internal Note via partyId" hasTable="N" parentTypeId="ELECTRONIC_ADDRESS"/> + <ContactMechType contactMechTypeId="FTP_ADDRESS" description="Ftp server connection" hasTable="Y" parentTypeId="ELECTRONIC_ADDRESS"/> <ContactMechTypePurpose contactMechPurposeTypeId="BILLING_EMAIL" contactMechTypeId="EMAIL_ADDRESS"/> <ContactMechTypePurpose contactMechPurposeTypeId="MARKETING_EMAIL" contactMechTypeId="EMAIL_ADDRESS"/> @@ -117,7 +118,8 @@ under the License. <CommunicationEventType communicationEventTypeId="WEB_SITE_COMMUNICATI" description="Web Site" hasTable="N" contactMechTypeId="WEB_ADDRESS"/> <CommunicationEventType communicationEventTypeId="COMMENT_NOTE" description="Comment/Note" hasTable="N" contactMechTypeId="INTERNAL_PARTYID"/> <CommunicationEventType communicationEventTypeId="AUTO_EMAIL_COMM" description="Auto Email" hasTable="N" contactMechTypeId="EMAIL_ADDRESS"/> - + <CommunicationEventType communicationEventTypeId="FILE_TRANSFER_COMM" description="File transfer" hasTable="N" parentTypeId="" contactMechTypeId="FTP_ADDRESS"/> + <!-- party content types --> <PartyContentType description="Internal Content" partyContentTypeId="INTERNAL"/> <PartyContentType description="User Defined Content" partyContentTypeId="USERDEF"/> Modified: ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/party-entitymodel.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/party-entitymodel.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/party-entitymodel.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/datamodel/entitydef/party-entitymodel.xml Fri May 18 15:53:35 2018 @@ -1304,6 +1304,24 @@ under the License. <index-field name="contactNumber"/> </index> </entity> + <entity entity-name="FtpAddress" + package-name="org.ofbiz.party.contact" + title="Ftp server Entity"> + <field name="contactMechId" type="id"/> + <field name="hostname" type="long-varchar"/> + <field name="port" type="numeric"/> + <field name="username" type="long-varchar"/> + <field name="password" type="long-varchar" encrypt="true"/> + <field name="binaryTransfer" type="indicator"/> + <field name="path" type="long-varchar"/> + <field name="zipFile" type="indicator"/> + <field name="passiveMode" type="indicator"/> + <field name="defaultTimeout" type="numeric"/> + <prim-key field="contactMechId"/> + <relation type="one" fk-name="FTP_SRV_CMECH" rel-entity-name="ContactMech"> + <key-map field-name="contactMechId"/> + </relation> + </entity> <entity entity-name="ValidContactMechRole" package-name="org.apache.ofbiz.party.contact" title="Valid Contact Mechanism Role Entity"> Modified: ofbiz/ofbiz-framework/trunk/applications/party/config/PartyEntityLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/config/PartyEntityLabels.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/config/PartyEntityLabels.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/config/PartyEntityLabels.xml Fri May 18 15:53:35 2018 @@ -1078,6 +1078,11 @@ <value xml:lang="zh">çµåé®ä»¶å°å</value> <value xml:lang="zh-TW">é»åéµä»¶ä½å</value> </property> + <property key="ContactMechType.description.FTP_ADDRESS"> + <value xml:lang="de">Fileserver</value> + <value xml:lang="en">File server</value> + <value xml:lang="fr">Serveur de fichier</value> + </property> <property key="ContactMechType.description.INTERNAL_PARTYID"> <value xml:lang="ar">Ù ÙاØظة طر٠داخÙÙØ©</value> <value xml:lang="cs">Internà poznámka</value> Modified: ofbiz/ofbiz-framework/trunk/applications/party/config/PartyErrorUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/config/PartyErrorUiLabels.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/config/PartyErrorUiLabels.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/config/PartyErrorUiLabels.xml Fri May 18 15:53:35 2018 @@ -52,6 +52,18 @@ <value xml:lang="zh">é误ï¼æ²éäºä»¶ä¸æ¯çµåé®ä»¶æ²éï¼æ以ä¸è½åé®ä»¶ï¼æ²éäºä»¶æ è¯ </value> <value xml:lang="zh-TW">é¯èª¤:éè¨äºä»¶ä¸æ¯é»åéµä»¶éè¨,æ以ä¸è½ç¼éµä»¶,éè¨äºä»¶èå¥ </value> </property> + <property key="commeventservices.communication_event_from_contact_mech_must_be_ftp"> + <value xml:lang="de">FEHLER: Kommunikationsereignis muss ein "Kontaktmechanismus von" besitzen das ein ftp server als Kommunikationereignis ID ist</value> + <value xml:lang="en">ERROR: Communication event must have a from contact mech that is an ftp server for communication event Id</value> + <value xml:lang="es">Error: Los eventos de comunicación deben tener un servidor ftp asociado</value> + <value xml:lang="fr">ERREUR: la réf. d'évènement de communication doit avoir une coordonnée qui soit un serveur ftp pour évènement de communication</value> + </property> + <property key="commeventservices.communication_event_must_be_ftp_for_ftp"> + <value xml:lang="de">FEHLER: Kommunikationsereignis ist keine Ftp Kommunikation und kann nicht als Ftp versendet werden für Kommunikationsereignis ID</value> + <value xml:lang="en">ERROR: Communication event is not an Ftp communication and cannot be transfered for communication event Id </value> + <value xml:lang="es">ERROR: La comunicación no es un transferencia ftp y no puede se enviado</value> + <value xml:lang="fr">ERREUR: l'évènement de communication n'est pas un transfert ftp et ne peut être envoyé comme réf. d'évènement de communication </value> + </property> <property key="commeventservices.communication_event_not_found_failure"> <value xml:lang="de">FEHLER: Kommunikationsereignis nicht gefunden mit der Kommunikationsereignis ID</value> <value xml:lang="en">ERROR: Communication Event not found for communication event ID</value> Modified: ofbiz/ofbiz-framework/trunk/applications/party/config/PartyUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/config/PartyUiLabels.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/config/PartyUiLabels.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/config/PartyUiLabels.xml Fri May 18 15:53:35 2018 @@ -34,6 +34,11 @@ <value xml:lang="zh">å¹´æ¶å ¥</value> <value xml:lang="zh-TW">å¹´æ¶å ¥</value> </property> + <property key="FormFieldTitle_binaryTransfer"> + <value xml:lang="de">Binären transfer</value> + <value xml:lang="en">Binary transfer</value> + <value xml:lang="fr">Transfert binaire</value> + </property> <property key="FormFieldTitle_birthDate"> <value xml:lang="ar">تارÙØ® اÙÙ ÙÙاد</value> <value xml:lang="cs">Datum narozenÃ</value> @@ -339,6 +344,11 @@ <value xml:lang="zh">é»è®¤è´¹ç</value> <value xml:lang="zh-TW">é è¨è²»ç</value> </property> + <property key="FormFieldTitle_defaultTimeout"> + <value xml:lang="de">Voreinstellung timeout</value> + <value xml:lang="en">Default timeout</value> + <value xml:lang="fr">Expiration par défaut</value> + </property> <property key="FormFieldTitle_deleteEmail"> <value xml:lang="ar">Øذ٠اÙبرÙد اÙاÙÙترÙÙÙ</value> <value xml:lang="cs">Smazat e-mail</value> @@ -605,6 +615,11 @@ <value xml:lang="zh">é«åº¦</value> <value xml:lang="zh-TW">身é«</value> </property> + <property key="FormFieldTitle_hostname"> + <value xml:lang="de">Hostname</value> + <value xml:lang="en">Host name</value> + <value xml:lang="fr">Nom d'hôte</value> + </property> <property key="FormFieldTitle_infoString"> <value xml:lang="ar">سÙسÙØ© اÙ٠عÙÙ٠ات</value> <value xml:lang="de">Info String</value> @@ -1392,6 +1407,11 @@ <value xml:lang="zh">ä¼åç±»åæ è¯</value> <value xml:lang="zh-TW">åé«é¡åèå¥</value> </property> + <property key="FormFieldTitle_passiveMode"> + <value xml:lang="de">Passiv modus</value> + <value xml:lang="en">Passive mode</value> + <value xml:lang="fr">Mode passif</value> + </property> <property key="FormFieldTitle_passportExpireDate"> <value xml:lang="ar">تارÙØ® Ø¥ÙتÙاء صÙاØÙØ© جÙاز اÙسÙر</value> <value xml:lang="de">Ablaufdatum Pass</value> @@ -1447,6 +1467,18 @@ <value xml:lang="zh">å¯ç æ示</value> <value xml:lang="zh-TW">å¯ç¢¼æ示</value> </property> + <property key="FormFieldTitle_path"> + <value xml:lang="de">Pfad</value> + <value xml:lang="en">Path</value> + <value xml:lang="fr">Chemin</value> + <value xml:lang="it">Percorso</value> + <value xml:lang="ja">ãã¹</value> + <value xml:lang="pt">Caminho</value> + <value xml:lang="th">Path</value> + <value xml:lang="vi">ÄÆ°á»ng dẫn</value> + <value xml:lang="zh">è·¯å¾</value> + <value xml:lang="zh-TW">è·¯å¾</value> + </property> <property key="FormFieldTitle_percentComplete"> <value xml:lang="ar">Ùسبة اÙإت٠ا٠</value> <value xml:lang="de">Prozent abgeschlossen</value> @@ -1507,6 +1539,11 @@ <value xml:lang="zh">个人å¾ç</value> <value xml:lang="zh-TW">å人åç</value> </property> + <property key="FormFieldTitle_port"> + <value xml:lang="de">Port</value> + <value xml:lang="en">Port</value> + <value xml:lang="fr">Port</value> + </property> <property key="FormFieldTitle_preferredContactMechId"> <value xml:lang="ar">دÙÙÙ ÙسÙÙØ© اÙإتصا٠اÙÙ ÙضÙØ©</value> <value xml:lang="cs">Preferovaný způsob kontaktu</value> @@ -1995,6 +2032,11 @@ <value xml:lang="zh">年为é主</value> <value xml:lang="zh-TW">åéå¹´æ¸</value> </property> + <property key="FormFieldTitle_zipFile"> + <value xml:lang="de">Zipdatei</value> + <value xml:lang="en">File compression</value> + <value xml:lang="fr">Compression de fichier</value> + </property> <property key="NewProspect"> <value xml:lang="ar">ت٠إÙشاء برÙسبÙت جدÙد بÙجاØ.</value> <value xml:lang="de">Neuer Prospect wurde erfolgreich erstellt.</value> @@ -7379,6 +7421,11 @@ <value xml:lang="zh">æ¾ä¸å°å®¶åºçµè¯å·ç ã</value> <value xml:lang="zh-TW">æ²æ家裡é»è©±è碼.</value> </property> + <property key="PartyHostnameMustContainProtocol"> + <value xml:lang="de">Der Hostname muss das Protokoll enthalten</value> + <value xml:lang="en">Hostname must contain the protocol</value> + <value xml:lang="fr">Le nom d'hôte doit contenir le protocole</value> + </property> <property key="PartyImportInvalidCsvFile"> <value xml:lang="ar">ÙÙ Ø· Ù Ù٠اÙCSV غÙر صاÙØ (اÙÙ ÙتاØ, اÙÙÙÙ Ø©, اÙتسÙسÙ)</value> <value xml:lang="de">Ungültiges CSV Format (Schlüssel, Wert, Sequenz)</value> Added: ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy (added) +++ ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy Fri May 18 15:53:35 2018 @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.ofbiz.entity.GenericValue +import org.apache.ofbiz.service.ModelService +import org.apache.ofbiz.service.ServiceUtil + +/** + * Create FtpAddress contact Mech + */ +def createFtpAddress() { + Map contactMech = run service: 'createContactMech', with: [contactMechTypeId: 'FTP_ADDRESS'] + String contactMechId = contactMech.contactMechId + if (contactMechId) { + GenericValue ftpAddress = makeValue('FtpAddress', parameters) + ftpAddress.contactMechId = contactMechId + ftpAddress.create() + } else return error('Error creating contactMech') + + Map resultMap = success() + resultMap.contactMechId = contactMechId + return resultMap +} + +/** + * Update FtpAddress contact Mech + */ +def updateFtpAddressWithHistory() { + Map resultMap = success() + resultMap.oldContactMechId = parameters.contactMechId + resultMap.contactMechId = parameters.contactMechId + Map newContactMechResult + if (resultMap.oldContactMechId) { + newValue = makeValue('FtpAddress', parameters) + if (newValue != from('FtpAddress').where(parameters).queryOne()) { // if there is some modifications in FtpAddress data + newContactMechResult = run service: 'createFtpAddress', with: parameters + } else { //update only contactMech + Map updateContactMechMap = dispatcher.getDispatchContext().makeValidContext('updateContactMech', ModelService.IN_PARAM, parameters) + updateContactMechMap.contactMechTypeId = 'FTP_ADDRESS' + newContactMechResult = run service: 'updateContactMech', with: updateContactMechMap + } + + if (!resultMap.oldContactMechId.equals(newContactMechResult.contactMechId)) { + resultMap.put('contactMechId', newContactMechResult.contactMechId) + } + } + return resultMap +} + +/** + * Create FtpAddress contact Mech and link it with given partyId + * @return + */ +def createPartyFtpAddress() { + Map contactMech = run service: 'createFtpAddress', with: parameters + if (ServiceUtil.isError(contactMech)) return contactMech + String contactMechId = contactMech.contactMechId + + Map createPartyContactMechMap = parameters + createPartyContactMechMap.put('contactMechId', contactMechId) + Map serviceResult = run service: 'createPartyContactMech', with: createPartyContactMechMap + if (ServiceUtil.isError(serviceResult)) return serviceResult + + //TODO: manage purpose + + Map resultMap = success() + resultMap.contactMechId = contactMechId + return resultMap +} + +def updatePartyFtpAddress() { + Map updateFtpResult = run service: 'updateFtpAddressWithHistory', with: parameters + Map result = success() + result.contactMechId = parameters.contactMechId + if (parameters.contactMechId != updateFtpResult.contactMechId) { + Map updatePartyContactMechMap = dispatcher.getDispatchContext().makeValidContext('updatePartyContactMech', ModelService.IN_PARAM, parameters) + updatePartyContactMechMap.newContactMechId = updateFtpResult.contactMechId + updatePartyContactMechMap.contactMechTypeId = 'FTP_ADDRESS' + run service: 'updatePartyContactMech', with: updatePartyContactMechMap + result.contactMechId = updateFtpResult.contactMechId + } + return result +} Propchange: ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/applications/party/groovyScripts/party/ContactMechServices.groovy ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: ofbiz/ofbiz-framework/trunk/applications/party/servicedef/secas.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/servicedef/secas.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/servicedef/secas.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/servicedef/secas.xml Fri May 18 15:53:35 2018 @@ -92,7 +92,16 @@ under the License. <condition field-name="communicationEventId" operator="is-not-empty"/> <action service="updateCommEventAfterEmail" mode="sync" run-as-user="system"/> </eca> - + + <eca service="sendContentToFtp" event="in-validate"> + <condition field-name="communicationEventId" operator="is-empty"/> + <action service="createCommEventFromFtpTransfer" mode="sync" run-as-user="system"/> + </eca> + <eca service="sendContentToFtp" event="commit"> + <condition field-name="communicationEventId" operator="is-not-empty"/> + <action service="setCommEventComplete" mode="sync" run-as-user="system"/> + </eca> + <!-- all these secas are now replaced by a sheduled job (sendEmailDated) which runs every 5 minutes --> <!-- After all the emails have been sent to a contact list, mark it as complete. --> Modified: ofbiz/ofbiz-framework/trunk/applications/party/servicedef/services.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/servicedef/services.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/servicedef/services.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/servicedef/services.xml Fri May 18 15:53:35 2018 @@ -564,7 +564,40 @@ under the License. <attribute name="partyIdFrom" type="String" mode="IN" optional="false"/> <attribute name="partyIdTo" type="String" mode="IN" optional="false"/> </service> - + <service name="createPartyFtpAddress" engine="groovy" + location="component://party/groovyScripts/party/ContactMechServices.groovy" invoke="createPartyFtpAddress" auth="true"> + <description>Create an Ftp Address associated to a party</description> + <permission-service service-name="partyContactMechPermissionCheck" main-action="CREATE"/> + <auto-attributes entity-name="ContactMech" include="nonpk" mode="IN" optional="true"/> + <auto-attributes entity-name="PartyContactMech" mode="IN" optional="true"/> + <auto-attributes entity-name="FtpAddress" mode="IN" optional="true"/> + <attribute name="contactMechPurposeTypeId" type="String" mode="IN" optional="true"/> + <attribute name="contactMechId" type="String" mode="INOUT" optional="true"/> + </service> + <service name="updatePartyFtpAddress" engine="groovy" + location="component://party/groovyScripts/party/ContactMechServices.groovy" invoke="updatePartyFtpAddress" auth="true"> + <description>Update an Ftp Address associated to a party</description> + <permission-service service-name="partyContactMechPermissionCheck" main-action="UPDATE"/> + <auto-attributes entity-name="PartyContactMech" mode="IN" optional="true"/> + <auto-attributes entity-name="FtpAddress" mode="IN" optional="true"/> + <attribute name="contactMechId" type="String" mode="INOUT"/> + </service> + <service name="createFtpAddress" default-entity-name="FtpAddress" engine="groovy" invoke="createFtpAddress" + location="component://party/groovyScripts/party/ContactMechServices.groovy"> + <description>create FtpAddress</description> + <permission-service service-name="partyBasePermissionCheck" main-action="CREATE"/> + <auto-attributes mode="OUT" include="pk"/> + <auto-attributes mode="IN" include="nonpk" optional="true"/> + </service> + <service name="updateFtpAddressWithHistory" default-entity-name="FtpAddress" engine="groovy" invoke="updateFtpAddressWithHistory" + location="component://party/groovyScripts/party/ContactMechServices.groovy"> + <description>update FtpAddress</description> + <permission-service service-name="partyBasePermissionCheck" main-action="UPDATE"/> + <auto-attributes mode="IN" include="pk"/> + <auto-attributes mode="IN" include="nonpk" optional="true"/> + <attribute name="contactMechId" type="String" mode="INOUT"/> <!-- the out paramater is the id of the new address --> + <attribute name="oldContactMechId" type="String" mode="OUT"/> <!-- this is the id of the old address --> + </service> <!-- contact mech attribute services --> <service name="createContactMechAttribute" engine="entity-auto" default-entity-name="ContactMechAttribute" invoke="create" auth="true"> <description>create a contact mech attribute record</description> @@ -886,6 +919,25 @@ under the License. be of type EMAIL_COMMUNICATION. Will look for a contactMechIdTo to send the emails</description> <attribute name="communicationEventId" type="String" mode="IN" optional="false"/> </service> + <!-- ftp communicationEvent services --> + <service name="sendCommEventAsFtp" engine="java" + location="org.apache.ofbiz.party.communication.CommunicationEventServices" invoke="sendCommEventAsFtp" auth="true" + transaction-timeout="7200"> <!-- set transaction time out for 2 hours, since this sometimes may last long during big file transfer --> + <description>Sends communication event associated contents to a ftp server. All parameters come from CommunicationEvent, which must + be of type FILE_TRANSFER_COMM. Will look for a contactMechIdTo to connect to Ftp</description> + <attribute name="communicationEventId" type="String" mode="IN"/> + </service> + <service name="createCommEventFromFtpTransfer" engine="java" + location="org.apache.ofbiz.party.communication.CommunicationEventServices" invoke="createCommEventFromFtpTransfer" auth="true"> + <description>Creates a CommunicationEvent record based on information before + running a sendContentToFtp service (to be used via ECA) + </description> + <attribute name="partyId" type="String" mode="IN" optional="true"/> + <attribute name="contentId" type="String" mode="IN"/> + <attribute name="contactMechId" type="String" mode="IN"/> + <attribute name="communicationEventId" type="String" mode="OUT"/> + </service> + <!-- email to communication event ECA services --> <service name="createCommEventFromEmail" engine="java" Modified: ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/communication/CommunicationEventServices.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/communication/CommunicationEventServices.java?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/communication/CommunicationEventServices.java (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/communication/CommunicationEventServices.java Fri May 18 15:53:35 2018 @@ -270,6 +270,139 @@ public class CommunicationEventServices return result; } + /** + * Service to send all content associated to a FILE_TRANSFER_COMM CommunicationEvent, + * with contactMechIdTo as a FtpAdress contactMech + * + * @param ctx + * @param context + * @return + */ + public static Map<String, Object> sendCommEventAsFtp(DispatchContext ctx, Map<String, ?> context) { + Delegator delegator = ctx.getDelegator(); + LocalDispatcher dispatcher = ctx.getDispatcher(); + Locale locale = (Locale) context.get("locale"); + GenericValue userLogin = (GenericValue) context.get("userLogin"); + + String communicationEventId = (String) context.get("communicationEventId"); + List<String> errorMessages = new ArrayList<>(); + try { + GenericValue communicationEvent = EntityQuery.use(delegator).from("CommunicationEvent").where("communicationEventId", communicationEventId).queryOne(); + if (communicationEvent == null) { + String errMsg = UtilProperties.getMessage(resource, "commeventservices.communication_event_not_found_failure", locale); + return ServiceUtil.returnError(errMsg + " " + communicationEventId); + } + + if ("COM_COMPLETE".equals(communicationEvent.getString("statusId"))) return ServiceUtil.returnSuccess(); + + String communicationEventType = communicationEvent.getString("communicationEventTypeId"); + if (communicationEventType == null || !"FILE_TRANSFER_COMM".equals(communicationEventType)) { + String errMsg = UtilProperties.getMessage(resource, "commeventservices.communication_event_must_be_ftp_for_ftp", locale); + return ServiceUtil.returnError(errMsg + " " + communicationEventId); + } + + String contactMechId = communicationEvent.getString("contactMechIdTo"); + + // Check contactMech type to FTP_ADDRESS + GenericValue contactMech = EntityQuery.use(delegator).from("ContactMech").cache().where("contactMechId",contactMechId).queryOne(); + GenericValue ftpAddress = EntityQuery.use(delegator).from("FtpAddress").cache().where("contactMechId",contactMechId).queryOne(); + if (null == contactMech || null == ftpAddress || !"FTP_ADDRESS".equals(contactMech.getString("contactMechTypeId"))) { + String errMsg = UtilProperties.getMessage(resource, "commeventservices.communication_event_to_contact_mech_must_be_ftp", locale); + return ServiceUtil.returnError(errMsg + " " + communicationEventId); + } + + // Get list of children communication events, to avoid same content multi-send + List<GenericValue> childrenCommunicationEvent = EntityQuery.use(delegator).select("communicationEventId", "statusId") + .from("CommunicationEvent").where("parentCommEventId", communicationEventId).cache().queryList(); + List<String> childrenCommunicationEventIds = EntityUtil.getFieldListFromEntityList(childrenCommunicationEvent, "communicationEventId", true); + // Retrieve all contents to send + List<GenericValue> contents = EntityQuery.use(delegator).from("CommEventContentDataResource").where("communicationEventId", communicationEventId).cache().queryList(); + + if (UtilValidate.isNotEmpty(contents)) { + if (UtilValidate.isEmpty(communicationEvent.getTimestamp("datetimeStarted"))) { + //store the startDate into the communication + Map<String, Object> updateCommEventResult = dispatcher.runSync("updateCommunicationEvent", + UtilMisc.toMap("communicationEventId", communicationEventId, "datetimeStarted", UtilDateTime.nowTimestamp(), "userLogin", userLogin), 600, true); + if (ServiceUtil.isError(updateCommEventResult)) { + errorMessages.add(ServiceUtil.getErrorMessage(updateCommEventResult)); + } + } + + for (GenericValue content : contents) { + Map<String, Object> ftpServiceMap = new HashMap<>(); + //store the child Communication Event, to keep track of errorMessages in note field + String childCommunicationEventId = ""; + ftpServiceMap.put("userLogin", userLogin); + ftpServiceMap.put("contentId", content.getString("contentId")); + ftpServiceMap.put("partyId", communicationEvent.getString("partyIdTo")); + ftpServiceMap.put("contactMechId", contactMechId); + // no need to create a child CommEvent if it is a single content transfer + if (contents.size() == 1) + ftpServiceMap.put("communicationEventId", communicationEvent.get("communicationEventId")); + else { + // check if currentContent is already sent by an existing children communicationEvent + EntityCondition sentCond = EntityCondition.makeCondition(UtilMisc.toList( + EntityCondition.makeCondition("communicationEventId", EntityOperator.IN, childrenCommunicationEventIds), + EntityCondition.makeCondition("contentId", content.getString("contentId")))); + GenericValue alreadySent = EntityQuery.use(delegator).from("CommEventContentAssoc").where(sentCond).cache().queryFirst(); + + if (null != alreadySent) { + GenericValue childCommEvent = EntityUtil.getFirst(EntityUtil.filterByCondition(childrenCommunicationEvent, + EntityCondition.makeCondition("communicationEventId", alreadySent.getString("communicationEventId")))); + // if completely sent, continue to next content + if ("COM_COMPLETE".equals(childCommEvent.getString("statusId"))) continue; + ftpServiceMap.put("communicationEventId", childCommEvent.getString("communicationEventId")); + } + } + + Map<String, Object> resultTmp = dispatcher.runSync("sendContentToFtp", ftpServiceMap, 600, true); + if (ServiceUtil.isError(resultTmp)) { + errorMessages.add(ServiceUtil.getErrorMessage(resultTmp)); + } + + // attach the parent communication event to the new event created when sending the content, and store error if needed + if (UtilValidate.isNotEmpty(resultTmp.get("communicationEventId"))) childCommunicationEventId = (String) resultTmp.get("communicationEventId"); + if (UtilValidate.isNotEmpty(childCommunicationEventId) && !childCommunicationEventId.equals(communicationEventId)) { + GenericValue childCommunicationEvent = EntityQuery.use(delegator).from("CommunicationEvent").where("communicationEventId", childCommunicationEventId).queryOne(); + childCommunicationEvent.set("parentCommEventId", communicationEventId); + if (ServiceUtil.isError(resultTmp)) { + childCommunicationEvent.set("statusId", "COM_BOUNCED"); + childCommunicationEvent.set("note", ServiceUtil.getErrorMessage(resultTmp)); + } + childCommunicationEvent.store(); + } + } + } else { + errorMessages.add(UtilProperties.getMessage(resource, "commeventservices.communication_event_not_without_content", locale)); + } + + if (errorMessages.size() > 0) { + communicationEvent.set("statusId", "COM_BOUNCED"); + communicationEvent.set("note", errorMessages.toString()); + communicationEvent.store(); + } else { + //Update content status + for (GenericValue content : contents) { + Map<String, Object> updateContentResult = dispatcher.runSync("setContentStatus", UtilMisc.<String, Object>toMap("contentId", content.getString("contentId"), "statusId", "CTNT_PUBLISHED", "userLogin", userLogin)); + if (ServiceUtil.isError(updateContentResult)) { + errorMessages.add(ServiceUtil.getErrorMessage(updateContentResult)); + } + } + + Map<String, Object> completeResult = dispatcher.runSync("setCommEventComplete", UtilMisc.<String, Object>toMap("communicationEventId", communicationEventId, "userLogin", userLogin)); + if (ServiceUtil.isError(completeResult)) { + errorMessages.add(ServiceUtil.getErrorMessage(completeResult)); + } + } + } catch (GenericEntityException | GenericServiceException e) { + return ServiceUtil.returnError(e.getMessage()); + } + if (errorMessages.size() > 0) { + return ServiceUtil.returnFailure(errorMessages); + } + return ServiceUtil.returnSuccess(); + } + public static Map<String, Object> sendEmailToContactList(DispatchContext ctx, Map<String, ? extends Object> context) { Delegator delegator = ctx.getDelegator(); LocalDispatcher dispatcher = ctx.getDispatcher(); @@ -514,7 +647,7 @@ public class CommunicationEventServices String partyIdFrom = (String) context.get("partyIdFrom"); try { - GenericValue communicationEvent = delegator.findOne("CommunicationEvent", true, "communicationEventId", communicationEventId); + GenericValue communicationEvent = EntityQuery.use(delegator).from("CommunicationEvent").where("communicationEventId", communicationEventId).cache().queryOne(); if (communicationEvent == null) { return ServiceUtil.returnError(UtilProperties.getMessage("PartyUiLabels", "PartyCommunicationEventNotFound", UtilMisc.toMap("communicationEventId", communicationEventId), (Locale) context.get("locale"))); @@ -536,6 +669,60 @@ public class CommunicationEventServices } /* + * Store an outgoing file transfer as a communication event; + * runs as a pre-invoke ECA on sendContentToFtp service + * - service should run as the 'system' user + */ + public static Map<String, Object> createCommEventFromFtpTransfer(DispatchContext dctx, Map<String, ? extends Object> context) { + LocalDispatcher dispatcher = dctx.getDispatcher(); + + GenericValue userLogin = (GenericValue) context.get("userLogin"); + String contentId = (String) context.get("contentId"); + String contactMechId = (String) context.get("contactMechId"); + String partyId = (String) context.get("partyId"); + String communicationEventId; + + Timestamp now = UtilDateTime.nowTimestamp(); + + Map<String, Object> commEventMap = new HashMap<>(); + commEventMap.put("communicationEventTypeId", "FILE_TRANSFER_COMM"); + commEventMap.put("contactMechTypeId", "FTP_ADDRESS"); + commEventMap.put("contactMechIdTo", contactMechId); + commEventMap.put("statusId", "COM_PENDING"); + commEventMap.put("datetimeStarted", now); + commEventMap.put("entryDate", now); + commEventMap.put("userLogin", userLogin); + if (UtilValidate.isNotEmpty(partyId)) { + commEventMap.put("partyIdTo", partyId); + } + + Map<String, Object> createResult; + try { + createResult = dispatcher.runSync("createCommunicationEvent", commEventMap); + if (ServiceUtil.isError(createResult)) { + return createResult; + } + communicationEventId = (String) createResult.get("communicationEventId"); + + //add content to newly created commEvent + Map createCommEventContentMap = new HashMap<>(); + createCommEventContentMap.put("userLogin", userLogin); + createCommEventContentMap.put("contentId", contentId); + createCommEventContentMap.put("communicationEventId", communicationEventId); + createResult = dispatcher.runSync("createCommEventContentAssoc", createCommEventContentMap); + if (ServiceUtil.isError(createResult)) { + return createResult; + } + } catch (GenericServiceException e) { + Debug.logError(e, module); + return ServiceUtil.returnError(e.getMessage()); + } + Map<String, Object> result = ServiceUtil.returnSuccess(); + result.put("communicationEventId", communicationEventId); + return result; + } + + /* * Store an outgoing email as a communication event; * runs as a pre-invoke ECA on sendMail and sendMultipartMail services * - service should run as the 'system' user Modified: ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/contact/ContactMechWorker.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/contact/ContactMechWorker.java?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/contact/ContactMechWorker.java (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/src/main/java/org/apache/ofbiz/party/contact/ContactMechWorker.java Fri May 18 15:53:35 2018 @@ -123,6 +123,8 @@ public class ContactMechWorker { partyContactMechValueMap.put("postalAddress", contactMech.getRelatedOne("PostalAddress", false)); } else if ("TELECOM_NUMBER".equals(contactMech.getString("contactMechTypeId"))) { partyContactMechValueMap.put("telecomNumber", contactMech.getRelatedOne("TelecomNumber", false)); + } else if ("FTP_ADDRESS".equals(contactMech.getString("contactMechTypeId"))) { + partyContactMechValueMap.put("ftpAddress", contactMech.getRelatedOne("FtpAddress", false)); } } catch (GenericEntityException e) { Debug.logWarning(e, module); @@ -463,6 +465,8 @@ public class ContactMechWorker { requestName = "createTelecomNumber"; } else if ("EMAIL_ADDRESS".equals(contactMechTypeId)) { requestName = "createEmailAddress"; + } else if ("FTP_ADDRESS".equals(contactMechTypeId)) { + requestName = "createFtpAddress"; } else { requestName = "createContactMech"; } @@ -474,6 +478,8 @@ public class ContactMechWorker { requestName = "updateTelecomNumber"; } else if ("EMAIL_ADDRESS".equals(contactMechTypeId)) { requestName = "updateEmailAddress"; + } else if ("FTP_ADDRESS".equals(contactMechTypeId)) { + requestName = "updateFtpAddress"; } else { requestName = "updateContactMech"; } @@ -506,6 +512,19 @@ public class ContactMechWorker { if (telecomNumber != null) { target.put("telecomNumber", telecomNumber); } + } else if ("FTP_ADDRESS".equals(contactMechTypeId)) { + GenericValue ftpAddress = null; + + try { + if (contactMech != null) { + ftpAddress = contactMech.getRelatedOne("FtpAddress", false); + } + } catch (GenericEntityException e) { + Debug.logWarning(e, module); + } + if (ftpAddress != null) { + target.put("ftpAddress", ftpAddress); + } } if ("true".equals(request.getParameter("useValues"))) { Modified: ofbiz/ofbiz-framework/trunk/applications/party/template/party/EditContactMech.ftl URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/template/party/EditContactMech.ftl?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/template/party/EditContactMech.ftl (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/template/party/EditContactMech.ftl Fri May 18 15:53:35 2018 @@ -200,12 +200,86 @@ under the License. <td>[${uiLabelMap.CommonCountryCode}] [${uiLabelMap.PartyAreaCode}] [${uiLabelMap.PartyContactNumber}] [${uiLabelMap.PartyContactExt}]</td> </tr> <#elseif "EMAIL_ADDRESS" = mechMap.contactMechTypeId!> - <tr> - <td class="label">${mechMap.contactMechType.get("description",locale)}</td> - <td> - <input type="text" size="60" maxlength="255" name="emailAddress" value="${(mechMap.contactMech.infoString)?default(request.getParameter('emailAddress')!)}" /> - </td> - </tr> + <tr> + <td class="label">${mechMap.contactMechType.get("description",locale)}</td> + <td> + <input type="text" size="60" maxlength="255" name="emailAddress" value="${(mechMap.contactMech.infoString)?default(request.getParameter('emailAddress')!)}" /> + </td> + </tr> + <#elseif "FTP_ADDRESS" = mechMap.contactMechTypeId!> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_hostname}</td> + <td> + <input type="text" size="60" maxlength="255" name="hostname" value="${(mechMap.ftpAddress.hostname)!request.getParameter('hostname')!}" /> + <span class="tooltip">${uiLabelMap.PartyHostnameMustContainProtocol} (ftp://, sftp://, ftps://...)</span> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_port}</td> + <td> + <input type="text" size="6" maxlength="6" name="port" value="${(mechMap.ftpAddress.port)!request.getParameter('port')!}" /> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.CommonUsername}</td> + <td> + <input type="text" size="60" maxlength="255" name="username" value="${(mechMap.ftpAddress.username)!request.getParameter('username')!''}" /> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.CommonPassword}</td> + <td> + <input type="text" size="60" maxlength="255" name="password" value="${(mechMap.ftpAddress.password)!request.getParameter('password')!''}" /> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_binaryTransfer}</td> + <td> + <select name="binaryTransfer"> + <#if "Y" == (mechMap.ftpAddress.binaryTransfer)!""><option value="Y">${uiLabelMap.CommonY}</option></#if> + <#if "N" == (mechMap.ftpAddress.binaryTransfer)!""><option value="N">${uiLabelMap.CommonN}</option></#if> + <option></option> + <option value="Y">${uiLabelMap.CommonY}</option> + <option value="N">${uiLabelMap.CommonN}</option> + </select> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_path}</td> + <td> + <input type="text" size="60" maxlength="255" name="path" value="${(mechMap.ftpAddress.path)!request.getParameter('path')!''}" /> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_zipFile}</td> + <td> + <select name="zipFile"> + <#if "Y" == (mechMap.ftpAddress.zipFile)!""><option value="Y">${uiLabelMap.CommonY}</option></#if> + <#if "N" == (mechMap.ftpAddress.zipFile)!""><option value="N">${uiLabelMap.CommonN}</option></#if> + <option></option> + <option value="Y">${uiLabelMap.CommonY}</option> + <option value="N">${uiLabelMap.CommonN}</option> + </select> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_passiveMode}</td> + <td> + <select name="passiveMode"> + <#if "Y" == (mechMap.ftpAddress.passiveMode)!""><option value="Y">${uiLabelMap.CommonY}</option></#if> + <#if "N" == (mechMap.ftpAddress.passiveMode)!""><option value="N">${uiLabelMap.CommonN}</option></#if> + <option></option> + <option value="Y">${uiLabelMap.CommonY}</option> + <option value="N">${uiLabelMap.CommonN}</option> + </select> + </td> + </tr> + <tr> + <td class="label">${uiLabelMap.FormFieldTitle_defaultTimeout}</td> + <td> + <input type="text" size="10" maxlength="10" name="defaultTimeout" value="${(mechMap.ftpAddress.defaultTimeout)!request.getParameter('defaultTimeout')!''}" /> + </td> + </tr> <#else> <tr> <td class="label">${mechMap.contactMechType.get("description",locale)}</td> Modified: ofbiz/ofbiz-framework/trunk/applications/party/template/party/profileblocks/Contact.ftl URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/template/party/profileblocks/Contact.ftl?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/template/party/profileblocks/Contact.ftl (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/template/party/profileblocks/Contact.ftl Fri May 18 15:53:35 2018 @@ -95,6 +95,19 @@ under the License. <input name="communicationEventTypeId" value="EMAIL_COMMUNICATION" type="hidden"/> </form><a class="buttontext" href="javascript:document.createEmail${contactMech.infoString?replace('@','')?replace('@','')?replace('.','')}.submit()">${uiLabelMap.CommonSendEmail}</a> </div> + <#elseif "FTP_ADDRESS" = contactMech.contactMechTypeId> + <#if contactMechMap.ftpAddress?has_content> + <#assign ftpAddress = contactMechMap.ftpAddress> + <div> + <b><#if ftpAddress.hostname?has_content>${ftpAddress.hostname!}</#if><#if ftpAddress.port?has_content>:${ftpAddress.port!}</#if><#if ftpAddress.path?has_content>:${ftpAddress.path!}</#if></b> + <br/>${uiLabelMap.CommonUsername} : ${ftpAddress.username!} + <br/>${uiLabelMap.CommonPassword} : ${ftpAddress.password!} + <br/>${uiLabelMap.FormFieldTitle_binaryTransfer} : ${ftpAddress.binaryTransfer!} + <br/>${uiLabelMap.FormFieldTitle_zipFile} : ${ftpAddress.zipFile!} + <br/>${uiLabelMap.FormFieldTitle_passiveMode} : ${ftpAddress.passiveMode!} + <br/>${uiLabelMap.FormFieldTitle_defaultTimeout} : ${ftpAddress.defaultTimeout!} + </div> + </#if> <#elseif "WEB_ADDRESS" = contactMech.contactMechTypeId> <div> ${contactMech.infoString!} Modified: ofbiz/ofbiz-framework/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml (original) +++ ofbiz/ofbiz-framework/trunk/applications/party/webapp/partymgr/WEB-INF/controller.xml Fri May 18 15:53:35 2018 @@ -191,6 +191,19 @@ under the License. <response name="error" type="view" value="editcontactmech"/> </request-map> + <request-map uri="createFtpAddress"> + <security https="true" auth="true"/> + <event type="service" invoke="createPartyFtpAddress"/> + <response name="success" type="view" value="editcontactmech"/> + <response name="error" type="view" value="editcontactmech"/> + </request-map> + <request-map uri="updateFtpAddress"> + <security https="true" auth="true"/> + <event type="service" invoke="updatePartyFtpAddress"/> + <response name="success" type="view" value="editcontactmech"/> + <response name="error" type="view" value="editcontactmech"/> + </request-map> + <request-map uri="createPartyContactMechPurpose"> <security https="true" auth="true"/> <event type="service" invoke="createPartyContactMechPurpose"/> Modified: ofbiz/ofbiz-framework/trunk/build.gradle URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/build.gradle?rev=1831867&r1=1831866&r2=1831867&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/build.gradle (original) +++ ofbiz/ofbiz-framework/trunk/build.gradle Fri May 18 15:53:35 2018 @@ -131,6 +131,7 @@ dependencies { compile 'org.apache.logging.log4j:log4j-api:2.10.0' // the API of log4j 2 compile 'org.apache.poi:poi:3.17' compile 'org.apache.shiro:shiro-core:1.4.0' + compile 'org.apache.sshd:sshd-core:1.7.0' compile 'org.apache.tika:tika-core:1.16' compile 'org.apache.tika:tika-parsers:1.16' compile 'org.apache.tomcat:tomcat-catalina-ha:9.0.7' Added: ofbiz/ofbiz-framework/trunk/framework/common/config/ftp.properties URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/common/config/ftp.properties?rev=1831867&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/common/config/ftp.properties (added) +++ ofbiz/ofbiz-framework/trunk/framework/common/config/ftp.properties Fri May 18 15:53:35 2018 @@ -0,0 +1,35 @@ +############################################################################### +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +############################################################################### + +# -- ftp notifications enabled (Y|N) +ftp.notifications.enabled=N + +# -- redirect all ftp notifications to this server for testing +ftp.notifications.redirectTo.enabled=Y +ftp.notifications.redirectTo.hostname=localhost +ftp.notifications.redirectTo.port=65535 +ftp.notifications.redirectTo.username=admin +ftp.notifications.redirectTo.password=ofbiz +ftp.notifications.redirectTo.binaryTransfer=Y +ftp.notifications.redirectTo.path= +ftp.notifications.redirectTo.passiveMode=Y +ftp.notifications.redirectTo.defaultTimeout= + +# -- if you have some pb with a ftp server, set it to Y to force OFBiz to control the file copy +ftp.force.transfer.control=N \ No newline at end of file |
Free forum by Nabble | Edit this page |