Saving a file after performing a DTL

190 views
Skip to first unread message

Larry

unread,
Apr 25, 2012, 9:52:55 AM4/25/12
to Ensemble-in...@googlegroups.com

I have a Business Service that monitors a directory for a specific file (using EnsLib.RecordMap.Service.FileService).  When this file is found in the directory, a Business Process (using class EnsLib.MsgRouter.RoutingEngine) performs a data transformation on this file, resulting in an xml file.  I am attempting to save this xml file in the Business Operation (using class EnsLib.File.PassThroughOperation), however I receive an error message.

The error is "ERROR <Ens>ErrException: <PROPERTY DOES NOT EXIST>zOnMessage+1^EnsLib.File.PassthroughOperation.1 *Stream,RxHist.Patient -- logged as '18 Apr 2012' number 120 @' Set tFilename=..Adapter.CreateTimestamp(##class(%Library.File).GetFilename(pRequest.Stream.Attributes("Filename")),..Filename)'"

I have investigated this, and think the error may be due to the data not coming across as a StreamContainer, but this is speculation. 

Things I have unsuccessfully tried:
1.  Create a new Business Operation.  In this, I attempted to load test data directly into the pRequest StreamContainer and then call the PutStream function (from adapter EnsLib.File.OutboundAdapter).  I was unsuccessful, however this may be due to the fact that I don't totally understand how to load the object with data.
2.  Create a new Business Process.  Again, I attempted to load test data directly into the pRequest object (the xml was "<Record><MemberNumber>.....</Record>"), however I received an error such as "ERROR <Ens>ErrException: <PROPERTY DOES NOT EXIST>zTransform+5^ProductionInterfaces.RXhistoryDTL.1 *MemberNumber,%Library.GlobalCharacterStream -- logged as '24 Apr 2012' number 1341 @' Set zVALz=source.MemberNumber, zVALz=$S($IsObject(zVALz):zVALz.%ConstructClone(), 1:zVALz)'"

The code I used to load data into the StreamContainer is "Set newrequest = ##class(Ens.StreamContainer).%New(##class(%GlobalCharacterStream).%New("<Record><MemberNumber>...</Record>"))

I am brand new to working with Ensemble and am quite eager to learn and would appreciate any help that can be thrown my way!

Ted Peck

unread,
Apr 25, 2012, 10:16:19 AM4/25/12
to ensemble-in...@googlegroups.com, Larry
This gives me an idea for an interesting enhancement: we could make method EnsLib.File.OutboundAdapter:PutStream() detect whether the supplied object is a Stream or StreamContainer object, or some other kind of XML-enabled object and in this last case automatically stream out the XML representation of the object to the file.

However with the current version you have to convert the object to a stream yourself, probably in the OnMessage() code of your Business Operation. (You need to create your own BusinessOperation that uses the File OutboundAdapter, you can't simply use the File.PassthroughOperation. Something like this:

Class RxHistOperation Extends Ens.BusinessOperation
{
Parameter ADAPTER = "EnsLib.File.OutboundAdapter";

Method OnMessage(pRequest As RxHist.Patient, Output pResponse As %Persistent) As %Status
{
    Set tFilename=..Adapter.CreateTimestamp(##class(%File).GetFilename(pRequest.OriginalFilename),..Filename)
    Set tStream = ##class(%GlobalCharacterStream).%New("")
    Set tSC = pRequest.XMLExportToStream(tStream)  If $$$ISERR(tSC) Quit tSC
    Quit ..Adapter.PutStream(tFilename, tStream)
}
}

Ted
--
You received this message because you are subscribed to the Google Groups "InterSystems: Ensemble in Healthcare Community" group.
To post to this group, send email to Ensemble-in...@googlegroups.com
To unsubscribe from this group, send email to Ensemble-in-Healt...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/Ensemble-in-Healthcare?hl=en

Larry

unread,
Apr 25, 2012, 10:42:19 AM4/25/12
to Ensemble-in...@googlegroups.com
I'm not used to such cryptic error messages.  I guess over time I will get used to these. I implemented the code you specified in the new Business Operation I created.  I receive the following error message:
ERROR <Ens>ErrException: <PROPERTY DOES NOT EXIST>zOnMessage+2^UCHealth.SaveStreamWithFilename.1 *Stream,RxHist.Patient -- logged as '25 Apr 2012' number 1372 @' Set tStream=##class(%Library.GlobalCharacterStream).%New("")'
 
I am happy, as I got through the line of code specifying the Filename, but confused on why I would receive an error on the line that just creates an empty object.  Perhaps this is doing more than I think is happening.  Can you explain what this means?
 
Or, are these errors not exact.  By that, I mean does it mean there is an error occuring around that line.
 
Thanks for helping, Ted.
 
Larry

Dale du Preez

unread,
Apr 25, 2012, 10:44:18 AM4/25/12
to Ensemble-in...@googlegroups.com
Hi Larry,

Ted's suggestion is the way to go, but I do want to point out two small possible gotchas:
    (1) Make sure you have some way of identifying the original filename of the RxHist.Patient message. (I think there ought to be a %Source property if this object was generated by the RecordMapper.) Also not that you might have multiple records from a single file, so you may want to give your naming some thought.
    (2) You may want to use the %XML.Writer class if you need any complex XML namespace handling or specific formatting in the XML you write. (I believe our general recommendation in recent versions is to use %XML.Writer instead of directly using the XMLExport*() methods.)

Your code could then look something like the following (excuse it being way more verbose!):

/// Add a way to specify the filename you want
Property Filename As %String;

/// Make the Filename property visible in the UI
Parameter SETTINGS = "Filename";


Method OnMessage(pRequest As RxHist.Patient, Output pResponse As %Persistent) As %Status
{
    // Sort out filenames and output filename
    Set tOriginalFilename = ##class(%Library.File).GetFilename(pRequest.%Source)
    Set tFilename=..Adapter.CreateTimestamp(tOriginalFilename,..Filename)
    // Write XML to a temporary stream
    Set tStream = ##class(%Stream.TmpCharacter).%New()
    Set tWriter = ##class(%XML.Writer).%New()
    // Modify any properties/options on the %XML.Writer instance here
    Set tSC = tWriter.OutputToStream(tStream)
    If $$$ISERR(tSC) Quit tSC
    Set tSC = tWriter.RootObject(pRequest)
    If $$$ISERR(tSC) Quit tSC
    // You may need to call tStream.Rewind() at this stage
    Quit ..Adapter.PutStream(tFilename,tStream
}

I hope that provides some extra food for thought and doesn't prove confusing.

Dale

Ted Peck

unread,
Apr 25, 2012, 11:10:43 AM4/25/12
to ensemble-in...@googlegroups.com
This error means you are still running your old code; i.e. you forgot to compile!

However the code sample I sent was not perfect; I realized you were going to get errors if you tried it verbatim.

Taking into account Dale's fine suggestions from a few minutes ago here is fresh sample:


Class RxHistOperation Extends Ens.BusinessOperation
{
Parameter ADAPTER = "EnsLib.File.OutboundAdapter";
Property Filename As %String(MAXLEN = 1000, MINLEN = 1) [ InitialExpression = "%f_%Q", Required ];

Parameter SETTINGS = "Filename";

Method OnMessage(pRequest As RxHist.Patient, Output pResponse As %Persistent) As %Status
{
    Set tFilename=..Adapter.CreateTimestamp(##class(%File).GetFilename(pRequest.%Source),..Filename)

    Set tStream = ##class(%Stream.TmpCharacter).%New()
    Set tWriter = ##class(%XML.Writer).%New()
    // Modify any properties/options on tWriter here

    Set tSC = tWriter.OutputToStream(tStream)  If $$$ISERR(tSC) Quit tSC
    Set tSC = tWriter.RootObject(pRequest)  If $$$ISERR(tSC) Quit tSC
    Set tSC = tStream.Rewind()
    Quit ..Adapter.PutStream(tFilename, tStream)
}
}

Remember to compile this time!
Ted

Larry

unread,
Apr 25, 2012, 11:32:11 AM4/25/12
to Ensemble-in...@googlegroups.com
Haha, you are quite the funnyman.  I actually did compile.  That was the first thing I learned. 
 
I decided to run a mix of what the two of you provided.  I do still receive an error, as specified previously.  Does that mean there is an error with the line "Set tStream=##class(%Stream.TmpCharacter).%New()"?  Is that line correct?  Why else would I receive an error on that line?  I'm used to languages such as Visual Basic, which is quite different from this. 

Dale du Preez

unread,
Apr 25, 2012, 11:50:49 AM4/25/12
to Ensemble-in...@googlegroups.com
Hi Larry,

Is the component running? And has it been running while you were working on the code? If you are running a recent version of Ensemble, it includes a feature where currently running code that is in memory won't automatically pick up any changes. Can you try enabling and disabling the operation (or restarting the production) and trying again?

And could you include the error message you are getting. While it may be somewhat cryptic, it can still contain some useful information about the code that is executing and which piece(s) are failing.

As a side note the pieces of your previous error are as follows:

    ERROR <Ens>ErrException: <PROPERTY DOES NOT EXIST>zOnMessage+2^UCHealth.SaveStreamWithFilename.1 *Stream,RxHist.Patient -- logged as '25 Apr 2012' number 1372 @' Set tStream=##class(%Library.GlobalCharacterStream).%New("")'
Error type:    ERROR <Ens>ErrException:
Exception:    <PROPERTY DOES NOT EXIST>
Code location:    zOnMessage+2^UCHealth.SaveStreamWithFilename.1
Variable/property:    *Stream
Object:                    RxHist.Patient

If you would prefer a Basic-like environment, you can also code your classes using our version of Basic.

Dale

Larry

unread,
Apr 25, 2012, 12:08:02 PM4/25/12
to Ensemble-in...@googlegroups.com
So, all this time I have been frustrated because I had to stop and restart the operation.  I don't know if I should be happy or extremely upset :)
 
I'll settle for grateful that I didn't spend any more time doing that.  This time my file saved.  Thanks for all your help, and I'm sure I'll ask for more at a later point.
 
Larry
 
:)

Ted Peck

unread,
Apr 25, 2012, 1:07:22 PM4/25/12
to ensemble-in...@googlegroups.com, Larry
If it's any consolation, in our 2012.2 field test version we have a
warning in the Event Log for the situation where you have recompiled a
class but the old code is still running. Sorry I didn't think to warn
you about this possibility earlier -
Ted
Reply all
Reply to author
Forward
0 new messages