Ens.StreamContainer

Hi All,

I am fairly new to Ensemble and I wanted to know I have inbound business service (EnsLib.File.PassthroughService) which is looking for pdf files once it finds a pdf file (within the business process) it needs to find the associated xml file which would be in the same directory. Once both of these files are found they need to be sent to the business operation and deleted from the source (EnsLib.File.PassthroughOperation).  My issue is that when I am looking for the xml file and I want to send it to the business operation I get the error that there is no stream within the streamcontainer.  I am assuming that I need to read the xml file as a streamcontainer object and assign it to a context property, which will then be sent as the request to the business operation but I am unsure how I can achieve this.  Any help or code snippets would be great.

 

Kind Regards,

 

Salma

  • 0
  • 0
  • 717
  • 6
  • 2

Answers

Hi Salma

My first thought is that you could write a custom service class to extend EnsLib.File.PassthroughService and within it override the OnProcessInput method. In here you would perform your IO functionality to read the second file into a stream, set the streams for both files to properties of a custom message that you define (extending Ens.Request), before passing the custom message on to the target process or operation. You would also need to perform matching processing in a custom operation to write both files to the target folder.

But all of this really assumes that you want to do something useful with the file streams along the way. If all you want to do is copy them both as soon as they arrive in an input folder, why not just set up 2 x pass through services, each detecting a different file extension and both targeting the same operation. On re-reading your question, it looks like timing for the two files may be the issue though, in which case I'd stick with the custom service/request/operation classes.

Regards

Duncan

Hi Both,

 

Thank you for the suggestions, the fundamental requirement is that the PDF file needs to reach the target folder before the xml.  Also these files come in pairs so before processing it is important to check that the matching xml actually exists.  What I ended up doing was once the check was complete move the xml file in to a secondary folder which was getting polled by another business service, the xml would only reach the secondary folder once the PDF had been processed and archived this resolved the issue but again I am not sure whether it was the right solution.

 

I will give your suggestion a go too.  Thanks again for your help.

 

Kind Regards,

 

Salma

 

Actually I just noticed the "Semaphore Specification" setting on the EnsLib.File.InboundAdapter which looks to possibly be relevant to your needs. In the help text for this is the following:

"The semaphore sepcification (sic) can be a wildcard filename pairing of target=semaphore filename e.g. ABC*.TXT=ABC*.SEM which means do not process any files found that match ABC*.TXT unless a corresponding ABC*.SEM exists for each one."

May not be relevant but thought I'd pass it on.

Comments

hi

 

I was thinking maybe it can be achieved by opening a file using a filepath or using an inbound file passthrough adapter and giving it a particular filename to process but I don't think that would be the right approach?  Any help would be appreciated.

 

Kind Regards,

 

Salma

Hi ,

 

What I have done is using code I have copied the associated xml file to the target folder. I am not sure whether this is the best approach for doing a task like this.

 

The code snippet used to achieve this is below:

 

  //copy to target directory

  set targetFilePath= "\\serverName\targetPath\" _ context.XMLFileName
 
  set archiveFilePath = "\\serverName\archive\" _ $PIECE(context.XMLFileName,".",1) _$ZDATE($H,8)_".xml"
 
  set res=##class(%Library.File).CopyFile(context.XMLFilePath,targetFilePath)
  //Move file to archive folder with filename
  set res=##class(%Library.File).CopyFile(context.XMLFilePath,archiveFilePath)
 
  //compare that the files are the same and then delete
 
  if (##class(%Library.File).Compare(context.XMLFilePath, targetFilePath))
  {
    //delete from the current filepath
    do ##class(%Library.File).Delete(context.XMLFilePath)
  }

 

Is this the best approach or could you suggest a better approach?

 

Kind Regards,

 

Salma

Hi

 

The issue of having this code within the business process is that there is no transparency in doing a copy over, so I personally don't think that this is the best approach, there must be a better way if someone can recommend the correct way of transferring a file from a business process to a business operation that would be great.

 

Kind Regards,

 

Salma

I had a similar situation and ended up with an Ensemble Service reading in the meta data file (like your xml), and composing an Ensemble message with that information, including a file reference for the data file (your pdf). This meant that the meta data file could be automatically archived by Ensemble, but now I had to archive the data file instead, using calls to the OS like you have done for your xml file above.

In my case this did make some sense, as I wanted to convert the data file using an OS call to an "exe", and at least the messages in Ensemble had all the meta information, file name, etc. But I also think it was a bit clumsy so would be interested in any better ideas.

Regards,

Mike