Announcement Announcement Module
Collapse
No announcement yet.
Writing to dynamic directories Using Outbound File Adapter Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Writing to dynamic directories Using Outbound File Adapter

    I'm trying to use the file outbound channel adapter to write to dynamic directories based on message payload. For testing, I've configured the outbound channel adapter to use a base directory of "c:/temp", and am enriching the message with a header of FileHeaders.FILENAME of "2008-04-23/test.txt". It seems that FileWritingMessageHandler doesn't support creating parent directories of a file if it doesn't already exist, so a FileNotFoundException is thrown.

    To work around this, I added a service activator before the outbound file adapter that creates the parent directory in case it doesn't exist:

    Code:
      public Message<?> createParentDirectoriesIfNecessary(Message<?> message)
      {
        Assert.hasText(message.getHeaders().get(FileHeaders.FILENAME, "FileName header must exist!");
        File file = new File(rootDir, (String)message.getHeaders().get(FileHeaders.FILENAME);
    
        //create parent dirs if they don't exist
        if (file.getParentFile() != null && !file.getParentFile().exists())
        {
          file.getParentFile().mkdirs();
        }
        return message;
      }
    I think it'd be a nice enhancement to handle these situations within the FileWritingMessageHandler, allowing for such configuration through the XML namespace.

  • #2
    Good idea, can you create an improvement issue in our issue tracker for this and post a link back here? https://jira.springsource.org/browse/INT

    Comment


    • #3
      Create INT-1798

      Comment


      • #4
        As an FYI we have almost identical request for SFTP https://jira.springsource.org/browse/INT-1756
        So, its coming around

        Comment


        • #5
          Also, please upgrade to 2.0.3.
          Don't ask why , but yes 2.0.3. is out.

          Comment


          • #6
            This was to be fixed in 2.0.4, so I tried but it still doesn't appear to be working for my use case. Here's my config:

            Code:
            <?xml version="1.0" encoding="UTF-8"?>
            <beans:beans xmlns="http://www.springframework.org/schema/integration"
            	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
            	xmlns:int-file="http://www.springframework.org/schema/integration/file"
            	xmlns:beans="http://www.springframework.org/schema/beans"
            	xsi:schemaLocation="http://www.springframework.org/schema/integration
            	http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
            	http://www.springframework.org/schema/integration/file
            	http://www.springframework.org/schema/integration/file/spring-integration-file-2.0.xsd
            	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
            
            
            	<channel id="headerEnricherChannel" />
            	<gateway id="inboundFileWritingGateway" service-interface="org.mycompany.InboundFileWritingGateway"
            		default-request-channel="headerEnricherChannel" />
            
            	<channel id="fileOutboundChannel" />
            	<header-enricher input-channel="headerEnricherChannel"
            		output-channel="fileOutboundChannel">
            		<header name="file_name" value="extra/dir/new.txt" />
            	</header-enricher>
            
            	<int-file:outbound-channel-adapter
            		auto-create-directory="true" directory="c:/temp" channel="fileOutboundChannel" />
            </beans:beans>
            I run my unit test and get a FileNotFoundException:

            Code:
            org.springframework.integration.MessageHandlingException: failed to write Message payload to file
            	at org.springframework.integration.file.FileWritingMessageHandler.handleRequestMessage(FileWritingMessageHandler.java:170)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:98)
            	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
            	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:110)
            	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
            	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
            	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
            	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
            	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
            	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendMessage(AbstractReplyProducingMessageHandler.java:176)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.sendReplyMessage(AbstractReplyProducingMessageHandler.java:160)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.produceReply(AbstractReplyProducingMessageHandler.java:125)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleResult(AbstractReplyProducingMessageHandler.java:119)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:101)
            	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:78)
            	at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:110)
            	at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
            	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:61)
            	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:157)
            	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:128)
            	at org.springframework.integration.core.MessagingTemplate.doSend(MessagingTemplate.java:288)
            	at org.springframework.integration.core.MessagingTemplate.send(MessagingTemplate.java:149)
            	at org.springframework.integration.core.MessagingTemplate.convertAndSend(MessagingTemplate.java:189)
            	at org.springframework.integration.gateway.MessagingGatewaySupport.send(MessagingGatewaySupport.java:183)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:303)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:269)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:260)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
            	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
            	at $Proxy15.process(Unknown Source)
            	at org.mycompany.FileWritingTests.testFileIsWritten(FileWritingTests.java:14)
            	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
            	at java.lang.reflect.Method.invoke(Unknown Source)
            	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
            	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
            	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
            	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
            	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
            	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
            	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
            	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
            	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
            	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
            	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
            	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
            	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
            	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
            	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
            	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
            	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
            	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
            	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
            Caused by: java.io.FileNotFoundException: c:\temp\extra\dir1\new.txtnull (The system cannot find the path specified)
            	at java.io.FileOutputStream.open(Native Method)
            	at java.io.FileOutputStream.<init>(Unknown Source)
            	at java.io.FileOutputStream.<init>(Unknown Source)
            	at org.springframework.integration.file.FileWritingMessageHandler.handleStringMessage(FileWritingMessageHandler.java:225)
            	at org.springframework.integration.file.FileWritingMessageHandler.handleRequestMessage(FileWritingMessageHandler.java:161)
            	... 59 more

            Comment


            • #7
              Writing to dynamic directories Using Outbound File Adapter

              jzcfk9,

              Have you looked at the samples you can clone from git? There's a relevant example there (called file)

              This context file looks relevant:
              [gitpath]/samples/basic/file/src/main/resources/META-INF/spring/integration/fileCopyDemo-text.xml

              Changing this line:
              <file:outbound-channel-adapter id="filesOut" directory="file:${java.io.tmpdir}/spring-integration-samples/output"/>

              to this causes no problems for me:
              <file:outbound-channel-adapter id="filesOut" directory="file:${java.io.tmpdir}/spring-integration-samples/output/f/l/r"/>

              Secondly, noting that it looks like you're on Windows - are you sure the application has permissions to create directories?

              Regards
              David

              Comment

              Working...
              X