go to post Michael Davidovich · Dec 7, 2022 @Colin Brough I have found generally the message header and body data is a bit putzy to access, but not impossible. I'm fairly new at all of this but in the spirit of trying to be helpful: I think a business process in-between that holds on to the metadata for the message in a context object and then pass that all to a custom business operation that uses the data to generate the file name. I am thinking though that if you are using a message router you can't send the context over, but I think if you use a call operation in the BPL you can pass in the context to the custom operation that you are calling. You could define a rule then that picks the correct operation to route to and use indirection to call that in the BPL while passing the context. Someone more experienced will have to fact check me there.
go to post Michael Davidovich · Nov 28, 2022 @Tony Alexander, @Jeffrey Drumm I came across your replies here and wanted to confirm I am having the same issue, but I am using the DTL editor and not so much code. My base ADT is version 2.3.1 and I am transforming to 2.4. In the DTL it seems that's there's no problem bridging the two messages, however, when the message is ultimately routed out of Ensemble, the message body says the DocType is 2.3.1 but the TypeVersion is 2.4, but also the DocTypeCategory is 2.3.1. I suppose I would expect that after the transformation the message body would reflect the correct metadata but maybe I misundersand what it's supposed to represent in the context of the whole process? In the DTL, I select "existing" as the Create action thinking that this will overwrite the data on the base object. Would be interested in your understanding of all of this.
go to post Michael Davidovich · Nov 28, 2022 I have always over-used parentheses for this reason. It's also very important when using logical operators: 1=0&&1=0 -> 0&&0=0 -> 1=0 -> 0 (1=0)&&(1=0) -> 0&&0 -> 1
go to post Michael Davidovich · Nov 15, 2022 /// This method is for File and FTP Operations: per-message batch output with no reply. TCP and HTTP Operations/// receive reply messages and only support entire batch output. Why?
go to post Michael Davidovich · Nov 15, 2022 Looks like the superclass for EnsLib.HL7.Operation.FileOperation wants to return an HL7.Message so I believe I'm on the right track.
go to post Michael Davidovich · Nov 15, 2022 I re-read the documentation and implemented very carefully the steps using the adaptor-less method and was able to remove the need for a custom adatptor.
go to post Michael Davidovich · Nov 15, 2022 The <call> was on sync, so I put it on async to wait for a response. The order is better now, but still a new response from the outbound file service.
go to post Michael Davidovich · Nov 15, 2022 I have found https://docs.intersystems.com/healthconnect20212/csp/docbook/DocBook.UI.... Evidently what I'm doing is a 'less common task.' How do others setup business operations when the 'incoming' data isn't an external application, rather IRIS itself?
go to post Michael Davidovich · Nov 14, 2022 @Eduard Lebedyuk if it helps, I just ran into the same issue and solved it as @Ronald Peña did. I found it odd that the name of the business service can't defer from the class name (and you can't rename them it seems, at least not in the management portal). Is this a bug?
go to post Michael Davidovich · Nov 9, 2022 I did get my code to work as expected but there's still some unknowns. I used the example as shown above but also added another block of code to capture the properties that changed into a log. I also did a KILL on the ^test array before the lines of code were generated. I either the KILL on the array and/or the number of saves and background calls happening in our system had something to do with my initial issues. My most apparent issue however, was I wasn't using %code.WriteLine to produce the generated code. At the end of the day this will probably go into a local array and not a global so all the update operations don't compete.
go to post Michael Davidovich · Nov 8, 2022 I did set some debug targets in the INT code and just opened an object, set a property and %Save(). The ^test array did show a true for the property I changed. So it worked command on the command line, but something is breaking down when using CSP.
go to post Michael Davidovich · Nov 8, 2022 Hi @Pravin Barton, I was looking for this exact advice however, I am having trouble debugging. I have looked at the generated INT code and I'm a bit stumped. All our %Persistent objects are updated via object access in CSP pages calling class methods. I utilzed the example you have below but I used set tableName = %compiledclass.NameGet() to get the tableName. The properties wrote to ^test no problem, so that's not an issue. The issue is after updating objects using the CSP pages (i.e. the front end), all the checks for {property*C} are false (0). I see expected operations being passed into the zFunctions with the pChanged array being setup. All our inserts and updates are accomplished by %Save(). We never %Delete(). I also included Time=After as a parameter in the trigger generator. So according to the doc, the trigger should happen similar to then %OnAfterSave() method. Any thoughts on what I may have missed or why this isn't working in my setup?
go to post Michael Davidovich · Nov 3, 2022 I suppose another way of stating the issue. The doc says you might want to use sessions to: Preserve data across REST calls — in some cases, preserving data across REST calls may be necessary to efficiently meet your business requirements. Well, I'm not finding an easy way to do this using spec first dev because the %session variable is undefined in the generated impl.cls. Even when I extend impl.cls to use %CSP.REST. @Eduard Lebedyuk I did catch one article you wrote that said sessions are basically only good for authentication (I assume you just meeting keep one logged into the IRIS server over the session), however since the doc does mention preserving data, I would like to see if I can utilize that feature. For now I've reverted to the manual creation of rest services which now allows me the %session variable to use.
go to post Michael Davidovich · Nov 1, 2022 Thanks, @Eduard Lebedyuk. See above that I did set UseSession=1. That's all the doc really explains. What next though? How to utilize the session (%session) in impl.cls? When I do this I get a undefined error: "error":"ERROR #5002: ObjectScript error: <UNDEFINED>zgetQuotes+1^API.QuoteLibrary.impl.1 *.Data(\"session\",1)"
go to post Michael Davidovich · Oct 25, 2022 Welp, this was total user error. I was trying to read class property that didn't exist. Also there's some good debugging advice here: Debugging Web | InterSystems Developer Community | CSP|Debugging|Frontend @Rich Taylor maybe you can help me? I am passing in a very simple structure in the body of a post request and I'm getting an error returned in Postman saying that the Dynamic Object I'm trying to create from the stream has a property that doesn't exist. HTTP/1.1 500 Internal Server ErrorContent-Type: application/json; charset=utf-8{ "errors":[ { "code":5002, "domain":"%ObjectErrors", "error":"ERROR #5002: ObjectScript error: <PROPERTY DOES NOT EXIST>... Sample data: {"quote_id":2000} ClassMethod deleteQuote(quote As %Stream.Object) As %DynamicObject { s quoteObj={}.%FromJSON(quote) s quoteId=quoteObj."quote_id" ..... So a few problems: 1) I can't debug this easily . . . I can't pass in a %Stream.Object in VS Code using the debugger and on the command line I can't seem to create a %New() %Stream.Object (my guess is because it's an interface). Any tips on debugging when you're passing in a stream? 2) The one thing I did do was set my stream data to a global and I'm getting some hints as to what's wrong but I'm not understanding. A ZW of the global shows me "9430@%Library.DynamicObject" after I have done the %FromJSON() method (I'm pretty sure a global can't store an object so no wonder it's quoted but there's more). If I just save the Read() of the stream to the global then go to the command line and set the string to a variable and then do the {}.%FromJSON(data) method I get the expected data=<OBJECT REFERENCE>[3304@%Library.DynamicObject] and can access the property. I did notice when using postman, if you 'beautify' the JSON string you get lots of white space and other characters that need to be stripped, so I'm aware that could be a problem, but right now I have the data as a single line with no extra characters. It's working on the command line when I break it down, but I can't see what the issue is when running the actual POST request. Any experience with these kinds of issues?
go to post Michael Davidovich · Oct 21, 2022 Can this be used to temporarily set a dynamic entity to a DocDB so one could run a query on it and return a result set object? I'm trying to find a solution for returning a result set object to a CSP page when I have a dynamic entity or JSON object. It's basically a complex, ad hoc query that's easier (for me) to write in ObjectScript rather than write a SQL query and aggregate and transform all kinds of data. I really need something in memory just to run the report, nothing saved to disk, but it seems creating a database using %DocDB will create a new class def weather I like it or not.
go to post Michael Davidovich · Oct 20, 2022 Can you go the opposite way? Bind a JSON object to a %Library.ResultSet?
go to post Michael Davidovich · Oct 17, 2022 I'm just poking around here to gain some knowledge. When you say routine to you mean a compiled MAC file? I'm curious to know how ZR would work if you've compiled the routine and, as Robert said, it's not on the stack. Any time I've run a routine from the CLI and do a zprint, there's nothing there, so I'm not sure what ZR would remove it ZP isn't showing in the buffer. When you call an entry point and there's a quit, isn't there an inherent ZR to get the routine out of the buffer? I guess I'm simply asking: did ZR solve your issue?
go to post Michael Davidovich · Sep 16, 2022 Well we are in IRIS 2021 and that's the documentation I was looking in. So I'm not sure what's going on. Here's where I landed: Given a %Stream.FileBinary I calculate the size to read as such s readSize=($J((stream.SizeGet()/12000),"",0)+1)*12000 And then 'cast' my stream to a %xsd.base64Binary datatype (ODBC type VARBINARY) as such s base64string=##class(%xsd.base64Binary).LogicalToJSON(stream.Read(readSize,.sc)) In my command line testing I'm able to decode this base64string, write it to a file stream and save and I have a very much in tact PDF. This is new to me however, so I hope I'm not tricking myself into thinking this is working correctly. When I run w ##class(%xsd.base64Binary).IsValid(myVarBinaryData) I get 1 so I think it's working correctly! Wondering however about the reading of 12,000 at a time. Just as long as the read len is divisible by four it should work?
go to post Michael Davidovich · Sep 14, 2022 I would be interested in a method that would simple encode a stream object into a base64 string but I don't see this method in the doc e.g.