L.S.,
I added this rename behavior to servicemix-ftp. You can now use an
attribute uploadSuffix=".tmp" to get the desired the result. The patch
is attached to JIRA issue SM-889 [1]. If you want, I can also add the
same modifications to the lightweight FTP component. Isn't there a way
to share the message processing code between both components, so
modifications become available to both variants without having to write
the same code twice?
Regards,
Gert
[1] https://issues.apache.org/activemq/browse/SM-889
johper wrote:
Hi Gert!
Ofcourse I will test and try the patch, but for the moment I run the
leightweight variant, not "servicemix-ftp"...
I fixed the FTP rename issue with a few lines of Java-code:
========= Java Code for doing FTP rename after successfull FTP transere, see
"quick and dirty" section ========
/*
* 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.servicemix.components.net;
import java.io.IOException;
import java.io.OutputStream;
import javax.jbi.JBIException;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.NormalizedMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.SocketClient;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.servicemix.components.util.DefaultFileMarshaler;
import org.apache.servicemix.components.util.FileMarshaler;
import org.apache.servicemix.components.util.OutBinding;
/**
* A component which sends a message to a file using FTP via the
* http://jakarta.apache.org/commons/net.html Jakarta Commons Net library
*
* @version $Revision: 486715 $
*/
public class PostmanFTPSender extends OutBinding {
private static final Log log =
LogFactory.getLog(PostmanFTPSender.class);
private FTPClientPool clientPool;
private FileMarshaler marshaler = new DefaultFileMarshaler();
private String uniqueFileName = "ServiceMix";
private boolean overwrite = false;
private String fileRenameSuffix = ".tmp";
// Properties
//-------------------------------------------------------------------------
public void setFileRenameSuffix(String suffix)
{
fileRenameSuffix = suffix;
}
public String getFileRenameSuffix()
{
return fileRenameSuffix;
}
public FTPClientPool getClientPool() {
return clientPool;
}
public void setClientPool(FTPClientPool clientPool) {
this.clientPool = clientPool;
}
public FileMarshaler getMarshaler() {
return marshaler;
}
public void setMarshaler(FileMarshaler marshaler) {
this.marshaler = marshaler;
}
public String getUniqueFileName() {
return uniqueFileName;
}
/**
* Sets the name used to make a unique name if no file name is available
on the message.
*
* @param uniqueFileName the new value of the unique name to use for
generating unique names
*/
public void setUniqueFileName(String uniqueFileName) {
this.uniqueFileName = uniqueFileName;
}
public boolean isOverwrite() {
return overwrite;
}
public void setOverwrite(boolean overwrite) {
this.overwrite = overwrite;
}
// Implementation methods
//-------------------------------------------------------------------------
protected void init() throws JBIException {
if (clientPool == null) {
throw new IllegalArgumentException("You must initialise the
clientPool property");
}
super.init();
}
protected void process(MessageExchange exchange, NormalizedMessage
message) throws Exception {
FTPClient client = null;
OutputStream out = null;
String name = null;
try {
client = (FTPClient) getClientPool().borrowClient();
name = marshaler.getOutputName(exchange, message);
if (name == null) {
if (uniqueFileName != null) {
out = client.storeUniqueFileStream(uniqueFileName);
}
else {
out = client.storeUniqueFileStream();
}
}
else {
out = client.storeFileStream(name);
if (out == null) {
// lets try overwrite the previous file?
if (overwrite) {
client.deleteFile(name);
}
out = client.storeFileStream(name);
}
}
if (out == null) {
throw new IOException("No output stream available for output
name: "
+ name + ". Maybe the file already exists?");
}
marshaler.writeMessage(exchange, message, out, name);
done(exchange);
}
finally {
if (out != null) {
try {
out.close();
}
catch (IOException e) {
log.error("Caught exception while closing stream on
error: " + e, e);
}
}
client.completePendingCommand();
//------- Start QnD FTP (quick and dirty) rename
fix.----------
if(client.rename(name, name.substring(0, name.length() -
4).concat(fileRenameSuffix)) == true){
//"RENAME ON FTP SUCCEEDED"
}else{
//"RENAME ON FTP FAILED"
}
//------- Stop QnD (quick and dirty) FTP rename
fix.-----------
returnClient(client);
}
}
protected void returnClient(SocketClient client) {
if (client != null) {
try {
getClientPool().returnClient(client);
}
catch (Exception e) {
log.error("Failed to return client to pool: " + e, e);
}
}
}
}
===================================================
============ servicemix.xml file with rename suffix setup===========
<!-- Send files over FTP and after that rename with new suffix. -->
<sm:activationSpec componentName="ftpSender" service="foo:ftpSender">
<sm:component>
<bean
class="org.apache.servicemix.components.net.PostmanFTPSender">
<property name="fileRenameSuffix" value=".emm"/>
<property name="clientPool">
<bean id="ftpClientPool"
class="org.apache.servicemix.components.net.FTPClientPool">
<property name="host"
value="localhost"/>
<property name="username"
value="myuserid"/>
<property name="password"
value="mypassword"/>
</bean>
</property>
<property name="marshaler">
<bean
class="org.apache.servicemix.components.util.BinaryFileMarshaler">
<property name="fileName">
<bean
class="org.apache.servicemix.expression.JAXPXPathExpression">
<constructor-arg
value="concat(substring($org.apache.servicemix.file.name, 0,
string-length($org.apache.servicemix.file.name) - 3), '.tmp')" />
</bean>
</property>
</bean>
</property>
</bean>
</sm:component>
</sm:activationSpec>
===================================================
Gert Vanthienen wrote:
L.S.,
As far as I know, ServiceMix does not currently support this feature.
Because I also need it for my own applications, I'm currently working on
a patch to add this behavior to <ftp:sender />. I won't have the time
to do it this week, but I can probably do it next week. Would that be
soon enough for you? Would you be willing to help me test the
modifications?
Regards,
Gert
johper wrote:
Hi,
Doing FTP file transfer from polling directory. In the FTP target
directory
we have to use '.tmp' extension. After successfull transfer, that '.tmp'
file must be renamed. How can this be done with ServiceMix and/or
FTPSender?
tia