alan
alan

Reputation: 131

Spring Integration DynamicFtpChannelResolver - Unable to autowire service bean

I have implemented the DynamicFtpChannelResolver found in the spring integration samples in order to allow dynamic FTP locations in my integration app.

As part of the outbound adapter I have added an advice chain. The FtpCompleteAdvice requires access to an existing service bean but at runtime this is not injected presumably because the context is dynamically created.

Is there a way for autowiring to work or another way to get access to this service bean?

Here is an extract of the xml:

<int:channel id="toFtpChannel" />

<bean id="ftpClientFactory" class="org.springframework.integration.sftp.session.DefaultSftpSessionFactory">
  <property name="host" value="${host}" />
  <property name="port" value="${port}" />
  <property name="user" value="${user}" />
  <property name="password" value="${password}" />
</bean>

<int-sftp:outbound-channel-adapter id="ftpOutbound" session-factory="ftpClientFactory" channel="toFtpChannel" remote-directory="${remote.directory}" remote-file-separator="/" remote-filename-generator-expression="headers.filename">
  <int-sftp:request-handler-advice-chain>
    <bean class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice">
      <property name="retryTemplate" ref="retryTemplate" />
    </bean>
    <bean class="com.bstonetech.ptms.integration.util.FtpCompleteAdvice">
      <property name="interfaceType" value="OUTBOUND" />
      <property name="interfaceName" value="TEST" />
    </bean>
  </int-sftp:request-handler-advice-chain>
</int-sftp:outbound-channel-adapter>

<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
  <property name="retryPolicy">
    <bean class="org.springframework.retry.policy.SimpleRetryPolicy">
      <property name="maxAttempts" value="3" />
    </bean>
  </property>
  <property name="backOffPolicy">
    <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
      <property name="maxInterval" value="600000" />
      <property name="initialInterval" value="3000" />
      <property name="multiplier" value="2" />
    </bean>
  </property>
</bean>

public class FtpCompleteAdvice extends AbstractRequestHandlerAdvice {

      @Autowired
      private IEmailUtilities emailUtilities;
      @Autowired
      private IFileService fileService;

      private String interfaceType;
      private String interfaceName;

      public void setInterfaceType(String interfaceType) {
         this.interfaceType = interfaceType;
      }

      public void setInterfaceName(String interfaceName) {
         this.interfaceName = interfaceName;
      }

      @Override
      protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws          Exception {

      Object result = callback.execute();
      String filename = (String)message.getHeaders().get("filename");

      //insert ftp row into file_ctl

      fileService.insertFtpFile(filename, interfaceName, interfaceType, new Date());

      //send email to confirm ftp

      emailUtilities.afterFtp(filename, interfaceName);
      return result;
   }
}

Upvotes: 0

Views: 233

Answers (1)

Gary Russell
Gary Russell

Reputation: 174729

You need to make the new context a child of the main context that has those beans. This is discussed in the forum posts referenced in the sample's README, when using a similar technique for inbound endpoints.

Then, any beans in the parent context are available for wiring.

Upvotes: 0

Related Questions