Question
Julian Matthews · Jul 7, 2020

Extending EnsLib.File.PassthroughOperation to allow the destination to be determined on a per file basis.

Hey everyone.

I have a use case where I need to write files to a handful of locations, and 2-3 subfolders in each location.

My plan was to extend EnsLib.File.PassthroughOperation and then pass  that operation the file and the subfolder details, and then have an operation per destination.

Has anyone done anything similar and can highlight any pitfalls I may be about to make?

0
0 127
Discussion (3)2
Log in or sign up to continue

As Ens.StreamContainer has a OriginalFilename property you can use that in your custom BO by specifying a subfolder ob request (so OriginalFilename  = /subfolderA/name.txt).

I would try to avoid the mixing of:

  • technical issue - outputting file into one of the several subfolders based on a filename
  • business issue - determining which subfolder to output file to based on extracurricular conditions

Operation/adapter should solve only one type of issues, either technical or business.

We have done something similar where we pass the outbound folder to the Operation.   So basically, we have many different Services receiving data (TCP, FTP, FIle) and each Service has OutboundFilePath Property that is passed to only one Operation.  We extended the Ens.StreamContainer to add the OutboundFilePath to the Stream.  The Operation uses the OutboundFilePath Property from the Stream to write the file to the folder.

<OutboundFilePath>D:\FOLDER\SUBFOLDER\SUB</OutboundFilePath>

</StreamContainer>

Operation extends Ens.BusinessOperation

Method OnMessage(pRequest As AIECommon.Stream.StreamContainer, Output pResponse As %Persistent) As %Status
{    
    Quit:'$IsObject(pRequest.Stream) $$$ERROR($$$EnsErrGeneral,"No Stream contained in StreamContainer Request")
    Set tFilename=pRequest.GenerateFileName

    Set tCfgOutboundPath = pRequest.OutboundFilePath

    Set ..Adapter.FilePath = tCfgOutboundPath

    Set tSC=..Adapter.PutStream(tFilename, pRequest.Stream)
    Do pRequest.%Save() ; re-save in case PutStream() optimization changed the Stream filename
    
    Quit tSC
}

The approach I ended up taking was to write a process that uses the source original file name to determine the destination, and it then sends the file to each operation it needs to using a custom request message which includes the stream + other bits of info I want passed to the operation.