Warning: A non-numeric value encountered in /home/ricston2/public_html/blogarchive/wp-content/themes/Divi/functions.php on line 5766

Mule has a file transport that lets it read and write files to the underlying file system.  This is especially convenient when you need to integrate with some older application that can produce files (more modern programs would use JMS or web services). One common problem that Mule developers encounter (and you can see this on the user list from time to time) relates to files that are still being created by the other application

In such a situation, Mule tries to read the file but cannot move it (using the moveToDirectory attribute) or delete it (if the autoDelete attribtue is set to true) as the file is still locked and being used.

The answer is to use the fileAge attribute.  This setting configures the file connector to ignore files unless they are x milliseconds old.  If your external application takes 5 seconds to write files out, you can set this to, say, 10000 and read in new files provided that they are 10 seconds old.

I built a simple test case to demonstrate this.  First, let’s take a look at the file connector:


I’ve configured Mule to read in files that are 7 seconds old and to avoid streaming these files in.  I then configured a service that will pass on these files to a VM endpoint:


  
    
  
  
    
      
    
  

The transformer is the file to string transformer that is provided in Mule. The VM transport is configured to be asynchronous.  Once a file is read, it is converted into a string and passed on to the VM queue.  In my test case, I do the following:

MuleClient myClient;
MuleMessage reply = null, replyTwo = null;
try {
  myClient = new MuleClient();

  do
  {
    reply = myClient.request("vm://processedFile", 2000);
  } while (reply != null);

  myClient.dispatch ("file://toProcess", "Any old text", null);
  Thread.sleep(10000);
  myClient.dispatch ("file://toProcess", "A newer chunk of text",
      null);

In this section of code, I empty the queue before doing anything else. I did this as otherwise I’ll end up with the Poison Message pattern. I then write out a file, wait for 10 seconds and write out another one.

  reply = myClient.request("vm://processedFile", 1000);
  replyTwo = myClient.request("vm://processedFile", 1000);

  } catch (MuleException e) {
    fail (e.getDetailedMessage());
  } catch (InterruptedException e) {
    fail (e.getLocalizedMessage());
  }

assertNotNull (reply);
assertNotNull (reply.getPayload());
assertTrue (((String)reply.getPayload()).
    equalsIgnoreCase("Any old text"));

assertNull (replyTwo);
}

After requesting two messages off the queue, I can assert that the first message is what it should be and that the second message is empty as expected.