6 Replies Latest reply on Jul 12, 2012 10:22 PM by John DeStefano

    Obtaining file name in camel file binding

    John DeStefano Apprentice

      Hi,

       

      I'm using SwitchYard 0.5. I have a camel binding to watch a directory for new files. The files have a common file suffix but the name varies. Using the include property to filter for the required files as follows (regex in bold - .*\.hl7):

       

      <?xml version="1.0" encoding="UTF-8"?>

      <switchyard xmlns="urn:switchyard-config:switchyard:1.0" xmlns:bean="urn:switchyard-component-bean:config:1.0" xmlns:camel="urn:switchyard-component-camel:config:1.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" name="file_to_email" targetNamespace="urn:com.example.switchyard:file_to_email:0.0.1-SNAPSHOT">

        <sca:composite name="file_to_email" targetNamespace="urn:com.example.switchyard:file_to_email:0.0.1-SNAPSHOT">

          <sca:component name="FilePickupServiceBean">

            <bean:implementation.bean class="org.hitect.esb.file_to_email.FilePickupServiceBean"/>

            <sca:service name="FilePickupService">

              <sca:interface.java interface="org.hitect.esb.file_to_email.FilePickupService"/>

            </sca:service>

            <sca:reference name="MailService">

              <sca:interface.java interface="org.hitect.esb.file_to_email.MailService"/>

            </sca:reference>

          </sca:component>

          <sca:service name="FilePickupService" promote="FilePickupServiceBean/FilePickupService">

            <sca:interface.java interface="org.hitect.esb.file_to_email.FilePickupService"/>

            <camel:binding.file>

              <camel:directory>/Users/johndestefano/TestFilePickup</camel:directory>

              <camel:consume>

                <camel:include>%2e*%5c%2ehl7</camel:include>

                <camel:preMove>move/%24%7bdate:now:MMddyyyyhhmmss%7d.hl7</camel:preMove>

                <camel:maxMessagesPerPoll>1</camel:maxMessagesPerPoll>

              </camel:consume>

            </camel:binding.file>

          </sca:service>

          <sca:component name="MailServiceBean">

            <bean:implementation.bean class="org.hitect.esb.file_to_email.MailServiceBean"/>

            <sca:service name="MailService">

              <sca:interface.java interface="org.hitect.esb.file_to_email.MailService"/>

            </sca:service>

          </sca:component>

        </sca:composite>

      </switchyard>

       

      In the FilePickupServiceBean there is a method that processes the file text. During the processing I'd like to know what the real name of the file was as its filtered based on a regex. Is there a way to find that out?

       

      Thanks


        • 1. Re: Obtaining file name in camel file binding
          Keith Babo Master

          In theory, yes.  In practice, let me find out ... ;-)

          • 2. Re: Obtaining file name in camel file binding
            David Ward Master

            According to this page: http://camel.apache.org/file2.html , there are a variety of Camel Headers that are set (like "CamelFileName", "CamelFileNameOnly", "CamelFileAbsolutePath", etc.)  You can see a list of File consumer and File producer headers in the "Message Headers" section.

             

            In SwitchYard, the CamelContextMapper will take those camel message headers and add them as Context properties.  So you should be able to just do exchange.getContext().getPropertyValue("CamelFileNameOnly").  And as of SwitchYard 0.5.0-SNAPSHOT, the Property itself should have a label of "camel_message_header".

            • 3. Re: Obtaining file name in camel file binding
              Keith Babo Master

              Yes, exactly.  I wanted to test this end-to-end just to make sure it worked as advertised.  Unfortunately, there's a bug in the bean component right now that's breaking end-to-end.  Before I get to that, here's what this should look like.

               

              1) As David mentioned, the context mapper will map in all the headers from the file endpoint.

               

              2) The resulting exchange will propagate those headers as context properties.  Using message tracing, I can see that is happening:

               

              ------- Begin Message Trace -------
              Service -> {urn:com.example.switchyard:fileproperty:0.0.1-SNAPSHOT}Hello
              Phase -> IN
              State -> OK
              Exchange Context -> 
                        CamelBatchComplete : true
                        CamelToEndpoint : switchyard://Hello?namespace=urn:com.example.switchyard:fileproperty:0.0.1-SNAPSHOT
                        CamelFileExchangeFile : GenericFile[name.txt]
                        CamelCreatedTimestamp : Tue Jul 03 12:36:17 EDT 2012
                        CamelBatchIndex : 0
                        CamelBatchSize : 1
              Message Context -> 
                        CamelFileParent : target/input
                        org.switchyard.contentType : java:java.lang.String
                        CamelFileLength : 6
                        org.switchyard.messageId : f4223210-b8f1-4fc3-8768-ce4e527f543c
                        CamelFileAbsolute : false
                        org.switchyard.transform.TransformSequence : org.switchyard.transform.TransformSequence@1a2e34bf
                        CamelFileNameOnly : name.txt
                        breadcrumbId : ID-KEITHs-MacBook-Pro-local-53996-1341333376908-1-1
                        CamelFileAbsolutePath : /Users/kbabo/jbds/demo/fileproperty/target/input/name.txt
                        CamelFilePath : target/input/name.txt
                        CamelFileRelativePath : name.txt
                        CamelFileName : name.txt
                        CamelFileLastModified : Tue Jul 03 12:36:12 EDT 2012
              Message Content -> 
              george
              ------ End Message Trace -------
              

               

              3) Inject the context into your bean and query the property, e.g.

               

              @Service(Hello.class)
              public class HelloBean implements Hello {
              
                  @Inject
                  private Context context;
                
               @Override
                        public void hello(String name) {
                                  System.out.println("Hello " + name);
                                  System.out.println("File name is " + context.getProperty("CamelFileExchangeFile"));
                        }
              
              }
              

               

               

              So the wiring is all there and ready to use.  One of those wires is shorting out though:

              https://issues.jboss.org/browse/SWITCHYARD-903

               

              We will get it fixed before 0.5.0.Final releases.

              • 4. Re: Obtaining file name in camel file binding
                Keith Babo Master

                This has been fixed.  I have attached a project which demonstrates the end-to-end.  I left the message trace on so you can see what other properties are available.  Just run the unit test from Eclipse and "mvn test" from the command-line.  Output will look like this:

                 

                Hello george
                File name is target/input/name.txt
                

                 

                hth,

                keith

                • 5. Re: Obtaining file name in camel file binding
                  Keith Babo Master

                  BTW, the fix has already been published to JBoss Nexus, so the unit test will work now.  If you want to deploy to a SY AS7 runtime with the fix, then you'll need to pick up the next nightly build from Hudson.