Results 1 to 7 of 7

Thread: Writing to dynamic directories Using Outbound File Adapter

  1. #1
    Join Date
    Jul 2010
    Posts
    139

    Default 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. #2
    Join Date
    May 2007
    Location
    Netherlands
    Posts
    614

    Default

    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

  3. #3
    Join Date
    Jul 2010
    Posts
    139

    Default

    Create INT-1798

  4. #4
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

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

  5. #5
    Join Date
    Jan 2008
    Location
    Mohnton, PA USA (that's near Philadelphia)
    Posts
    2,148

    Default

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

  6. #6
    Join Date
    Jul 2010
    Posts
    139

    Default

    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

  7. #7
    Join Date
    Jun 2011
    Posts
    25

    Default 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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •