2

I want to send an email once an SFTP upload is completed ...

I have an SFTP uploader:

<sftp:outbound-channel-adapter
        id="sftpOutboundAdapter"
        channel="inputFiles"
        charset="UTF-8"
        remote-directory="${directory.remote}"
        session-factory="sftpSessionFactory">
    <sftp:request-handler-advice-chain>
        <bean class="org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice">
            <property name="onSuccessExpression" value="payload.delete()"/>
            <property name="successChannel" ref="successChannel"/>
            <property name="onFailureExpression" value="payload.renameTo(payload.absolutePath + '.error')"/>
            <property name="failureChannel" ref="failChannel"/>
        </bean>
    </sftp:request-handler-advice-chain>
</sftp:outbound-channel-adapter>

Which sends the payload to the successChannel once it's done:

    <int:channel id="successChannel">
        <int:interceptors>
            <int:wire-tap channel="successLogChannel"/>
        </int:interceptors>
    </int:channel>

... which then logs it thanks to a wiretap.

<int:channel id="successLogChannel"/>
    <int:transformer input-channel="successLogChannel" output-channel="logChannel"
                     expression="'Successfully transferred ' + inputMessage.payload.absolutePath + ' [result=' + payload + ']'"/>
<int:logging-channel-adapter id="logChannel" level="INFO"/>

And here is where it's breaking, I don't think properties is the right element to use, I basically need to break out into a java class and be able to pass in parameters including the name of the file I just uploaded.

<int:service-activator input-channel="successChannel" ref="Email" method="sendSuccessMail">
    <property name="to" value="test@gmail.com" />
    <property name="from" value="me@me.com" />
    <property name="filename" ref="'inputMessage.payload.absolutePath'" />
</int:service-activator>

Java Class:

@Component(value = "Email")
public class Email extends AbstractMessaging<EmailRequest, EmailResponse> {

    ....

    public void sendSuccessMail(String to, String from, String filename){

        log.info("--------------------------------------------");
        log.info("Success Mail will be sent here to" + to + ", from " + from + " for " + filename);
        log.info("--------------------------------------------");

    }

}

FactoryBean threw exception on object creation; nested exception is java.lang.IllegalArgumentException: Target object of type [class ... .email.Email] has no eligible methods for handling Messages.

Is it possible to pass params or just the payload if I can't params to my method sendSuccessMail?

Jan Vladimir Mostert
  • 12,380
  • 15
  • 80
  • 137

1 Answers1

1

Use a <header-enricher/> to create the values you need in headers; then...

public void sendSuccessMail(@Header("to") String to, @Header("from") String from, @Payload String filename){
    ...
}

<int:chain ...>
    <int:header-enricher>
        <int:header name="to" value="test@gmail.com">
        ...
        <int:header name="inputMessage" expression="inputMessage">
    </int:header-enricher>
    <int:transformer expression="headers['inputMessage'].payload.absolutePath">
    <int:service-activator ... />
</int:chain>
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • That works, except that my payload is the physical string `inputMessage.payload.absolutePath`, if I remove the quotes, things break, I get a success log, `....LoggingHandler - Successfully transferred /tmp/lala.dat [result=true] `, then followed by a fail message and a stacktrace: `ERROR ....LoggingHandler - org.springframework.integration.transformer.MessageTransformationException: org.springframework.integration.MessageHandlingException: Expression evaluation failed: inputMessage.payload.absolutePath`. So inputMessage.payload is available for logging, but not in the chain. – Jan Vladimir Mostert May 25 '15 at 14:24
  • Sorry - I copied it from your question without noticing the errant `' '`. Remove them. Also, yes, the header enricher will cause the `payload.inputMessage` to be lost - I edited the answer; sorry about that. Bottom line is you have to save the `inputMessage` in another header. – Gary Russell May 25 '15 at 16:51
  • Thanks Gary! I was wondering how to transfer payload.inputMessage, your example explains it perfectly :-) – Jan Vladimir Mostert May 25 '15 at 18:12