1
votes

I have a working application that reads from a directory specified in a properties file and writes to a different directory. Here are the inbound and outbound channel adapters used for reading and writing.

<file:inbound-channel-adapter id="inputFileChannelAdapter" channel="fileIn"    directory="${dir.monitor}"
    auto-startup="false" prevent-duplicates="false" filename-pattern="*.done" >
    <int:poller id="inputFilePoller" time-unit="SECONDS" fixed-delay="1" max-messages-per-poll="100" />
</file:inbound-channel-adapter>


<int:channel id="finishedFileChannel"/>
<file:outbound-channel-adapter id="finishedDataFiles" delete-source-files="true" auto-create-directory="false" 
    directory="${dir.finished}" channel="finishedFileChannel" />

I have a need to allow the directories to be changed while the application is running. I have created a control bus which allowed me to stop the polling service and change the input directory with the code below:

    SourcePollingChannelAdapter adapter = context.getBean("inputFileChannelAdapter", SourcePollingChannelAdapter.class);
    FileReadingMessageSource source = context.getBean("inputFileChannelAdapter.source", FileReadingMessageSource.class);
    File monitorFileDir = new File("C:\newInput");
    source.setDirectory( monitorFileDir );

However, I cannot figure out how to accomplish the same for the outbound channel adapter. I tried getting the reference to out bound channnel adapter and then creating a new EventDivenConsumer and FileWritingMessageHandler and reassign that to the reference, but it didn't work and I feel like I am heading down the wrong path with that solution. Any suggestions would be appreciated.

2

2 Answers

0
votes

For the FileReadingMessageSource you do that correct.

For FileWritingMessageHandler you can't do that, because directory is converted to the private final Expression destinationDirectoryExpression;.

So, it is a tip how we can overcome your change dir a runtime use-case:

<bean id="targetDir" class="java.util.concurrent.atomic.AtomicReference">
    <constructor-arg value="${dir.finished}"/>
</bean>

<file:outbound-channel-adapter directory-expression="@targetDir.get()"/>

Having that you always can retrive at runtime from ApplicationContext that bean and change the value for target dir:

AtomicReference<String> targetDir = (AtomicReference<String>) context.getBean("targetDir", AtomicReference.class);
targetDir.set("/new/target/dir");
0
votes

You can use directory-expression="@someBean.whereTo()" or "@someBean.whereTo(#root)" if you want to base it on the message.

With newer versions of the framework, you can get a reference to the handler with a bean name finishedDataFiles.handler but, as @Artem said, the directory is final.