Written by

Question MarkLee · Apr 22

Business rule condition based on variable file name and count

I have a daily service that consumes x number of files, each file name chronologically suffixed sequentially by _1, _2, etc. I only want to process the latest file.

How do I build a business rule so it will only process the last file?

Product version: HealthShare Health Connect 2025.3

Comments

Eduard Lebedyuk · Apr 23

Are the files in a local folder? 

I think the simplest would be customizing EnsLib.File.PassthroughService to drop all files except for the last.

Or writing  a new adapter/BS which does it for you.

0
MarkLee  May 11 to Eduard Lebedyuk

I have a class that tries to get the latest file, but I can't test it because I am getting METHOD DOES NOT EXIST.

This is the error my logger outputs.

***************************

tLatestFile: 0 o<METHOD DOES NOT EXIST>GetLatestFile+7 ^UHNuEPICPKG.UHNEpicProduction.Epic.X12WSIBClm.UHN.EpicX12wsibclmUhnService.1 *NameList,EnsLib.File.InboundAdapterÆ
UHN_EPIC·a ^GetLatestFile+7^UHNuEPICPKG.UHNEpicProduction.Epic.X12WSIBClm.UHN.EpicX12wsibclmUhnService.1 ^1ce^OnProcessInput+7 ^UHNuEPICPKG.UHNEpicProduction.Epic.X12WSIBClm.UHN.EpicX12wsibclmUhnService.1 ^1+e^ProcessInput+12 ^Ens.BusinessService.1 ^12e^processFile+127 ^EnsLib.File.InboundAdapter.1 ^1-e^OnTask+107^EnsLib.File.InboundAdapter.1 ^1%e^OnTask+29^Ens.BusinessService.1 ^1e^Start+62^Ens.Job.1 ^2$d^StartEnsembleJob+8 ^|"%SYS"|STU^1d^ ^^0
**************************

code

*************************

/// Accepts ONLY THE LATEST MODIFIED FILE from the File Inbound Adapter, encapsulates each one as a Stream object within a StreamContainer object and forwards the container object to the configured target configuration item or items.
Class My.Package.NewService Extends EnsLib.File.PassthroughService
{

/// Property to store the file path directory
Property FilePath As %String;

/// Property to store the file wildcard pattern
Property FilePattern As %String(MAXLEN = 255) [ InitialExpression = "*" ];

Method OnProcessInput(pInput As %Stream.Object, pOutput As %RegisteredObject) As %Status
{
       Set tSC = $$$OK
       Set tSource = pInput.Attributes("Filename")

      
       Try {
           // Get the directory from the input stream filename
           Set tDirectory = ##class(%File).GetDirectory(tSource)
          
           // Get all files matching the pattern
           Set tLatestFile = ..GetLatestFile(tDirectory)
           $$$LOGINFO("tSource: "_tSource)
           $$$LOGINFO("tDirectory: "_tDirectory)
           $$$LOGINFO("tLatestFile: "_tLatestFile)

           /*If $$$ISERR(tSC) {
               $$$LOGERROR("Error retrieving file list: "_$ZERROR)
               Return tSC
           }*/
          
           // If we found a latest file and it matches our current input, process it
           If tLatestFile = tSource {
               // Wrap the stream in a container and send it
               Set pInput = ##class(Ens.StreamContainer).%New(pInput)
              
               Set tWorkArchive = (""'=..Adapter.ArchivePath) &&
                   (..Adapter.ArchivePath = ..Adapter.WorkPath ||
                    (""=..Adapter.WorkPath &&
                     (..Adapter.ArchivePath=..Adapter.FilePath)))
              
               For iTarget = 1:1:$Length(..TargetConfigNames, ",") {
                   Set tOneTarget = $ZStrip($Piece(..TargetConfigNames, ",", iTarget), "<>W")
                   Continue:""=tOneTarget
                  
                   If tWorkArchive {
                       Set tSC1 = ..SendRequestAsync(tOneTarget, pInput)
                       Set:$$$ISERR(tSC1) tSC = $$$ADDSC(tSC, tSC1)
                   } Else {
                       Set tSC1 = ..SendRequestSync(tOneTarget, pInput)
                       Set:$$$ISERR(tSC1) tSC = $$$ADDSC(tSC, tSC1)
                   }
               }
           } Else {
               $$$LOGINFO("Skipping file: "_tSource_" (not the latest file)")
           }
       }
       Catch ex {
           Set tSC = ex.AsStatus()
           $$$LOGERROR("Exception in OnProcessInput: "_$ZERROR)
       }
      
       Return tSC
}


/// Method to get the latest file from a directory
Method GetLatestFile(pDirectory As %String, Output pLatestFile As %String) As %Status
{
       Set tSC = $$$OK
       Set pLatestFile = ""
       Set tLatestTimestamp = 0
       Set tLatestFullPath = ""
      
       Try {
           // Use the Adapter's NameList method to get all files
           Set tSC = ..Adapter.NameList(.tFileList, ..FilePattern)
           If $$$ISERR(tSC) {
               Return tSC
           }
          
           // Iterate through the file list
           Set tIterator = tFileList.%GetIterator()
           While tIterator.%GetNext(.key, .tFileEntry) {
               // Parse the file entry: Filename;Type;Size;DateCreated;DateModified;FullPathName

               $$$LOGINFO("File Entry: "_tFileEntry)

               
               Set tFilename = $Piece(tFileEntry, ";", 1)
               Set tType = $Piece(tFileEntry, ";", 2)
               Set tDateModified = $Piece(tFileEntry, ";", 5)
               Set tFullPath = $Piece(tFileEntry, ";", 6)
              
               // Skip directories
               If tType = "D" {
                   Continue
               }
              
               // Compare timestamps to find the latest file
               If tDateModified > tLatestTimestamp {
                   Set tLatestTimestamp = tDateModified
                   Set tLatestFullPath = tFullPath
                   Set pLatestFile = tFilename
               }
           }
          
           If tLatestFullPath = "" {
               $$$LOGWARNING("No files found in directory: "_pDirectory)
           } Else {
               $$$LOGINFO("Latest file identified: "_pLatestFile_" (modified: "_tLatestTimestamp_")")
           }
       }
       Catch ex {
           Set tSC = ex.AsStatus()
       }
      
       Return tSC
}

}
 

0
Julian Matthews  14 hr ago to MarkLee

The method that seemingly doesn't exist is "NameList" which you are attempting to call from your method "GetLastMethod".

You can demonstrate this by adding a trace before and after the following line and seeing that it never hits the second trace:

Set tSC = ..Adapter.NameList(.tFileList, ..FilePattern)

The adapter for the file passthrough service is EnsLib.File.InboundAdapter, and this does not contain a method called NameList.

0