Hi Antoine,
you are right regarding inheriting from %Persistent and Ens.Request/Response, it does makes sense in many cases!
I've edited my message to refer to your comment
- Log in to post comments
Hi Antoine,
you are right regarding inheriting from %Persistent and Ens.Request/Response, it does makes sense in many cases!
I've edited my message to refer to your comment
Suppose you have your JSON in a stream StreamFHIR, then:
Set BundleObject=##class(HS.FHIR.DTL.vR4.Model.Resource.Bundle).FromJSON(StreamFHIR,"vR4")
If you want ONLY the first entry, then:
Set FirstEntry=BundleObject.entry.GetAt(1)
First I'd suggest not to use a persistent class "linked" to a message (Ens.Response in this case), Supplier is linked by your message class in this case.
If you do it, you will definitely create "orphaned" persistent objects when you purge, unless you add some logic (like triggers and callbacks) to delete the "linked" persistent objects when a message is purged.
To avoid this (when possible) a serial class is preferred.
So, the Supplier class would be:
Class Community.App.Msg.Supplier Extends (%SerialObject, %XML.Adaptor)
{
Property row As%Integer;
}As for the message class:
Class Community.App.Msg.Suppliers Extends Ens.Response
{
Property Supplier As list Of Community.App.Msg.Supplier(XMLPROJECTION = "ELEMENT");ClassMethod test() As%Status
{
set XmlString="<Suppliers><Supplier><row>1</row></Supplier><Supplier><row>2</row></Supplier></Suppliers>"set reader = ##class(%XML.Reader).%New()
$$$ThrowOnError(reader.OpenString(XmlString))
do reader.CorrelateRoot("Community.App.Msg.Suppliers")
do reader.Next(.Suppliers, .tSC)
do Suppliers.XMLExport(,",indent")
quit tSC
}
}For simplicity I modified the sample to be a classmethod.
When the test() method is run the output is:
EPTEST>d ##class(Community.App.Msg.Suppliers).test()
<Suppliers>
<Supplier>
<row>1</row>
</Supplier>
<Supplier>
<row>2</row>
</Supplier>
</Suppliers>The relevant documentation is "Controlling the Form of the Projection for Collection Properties" here.
Let me add a few notes.
If a class extend Ens.Response or Ens.Request is not necessary to extend %Persistent because is already inherited by Ens.Request/Ens.Response.
Edit: please see Antoine commnet below
If the desired XML tag correspond to the class name (without package), it is not necessary to add the XMLNAME parameter, like you did in App.Objects.Suppliers class.
Same goes for XMLNAME property parameter XMLNAME = "row" is not necessary because the property name correspond to the desired XML tag name.
Did you specified in the classpath the path to ALL required (IRIS and yours) jars?
Multiple path are separated by semicolon, looking at your post, in your case should be something like:
/usr/iris/dev/java/lib/JDK18/;<something>/tomcat/webapps/GAPP/WEB-INF/lib/notificationEngine/slf4j-simple-1.7.36.jar
As you did in the wizard, you need to add/specify the classpath to "your" jars, this can be done in the java gw definition (and seems you didn't) or in your code when you connect to the java gw.
The fact that it works after using the wizard (that add the javapath) suggest this may be the issue.
Did you add the classpath to the java gateway definition (not the import wizard) or added before you connect to the java gw?
Difficult to tell with the little info given.
Can you please provide some more detail, ideally the code you use when you say "on trying to connect"?
Did you include the classpath?
Did you start the Java Gateway?
Please check "Enabling Tracing" documentation here.
Optionally, instead of using IgnoreNull property of the reader, add to your M.PAT class:
Parameter XMLIGNORENULL = 1;
Please check the documentation here regarding the IgnoreNull property of the reader.
- Use a Utility Method: Develop a utility method within a class that inherits from Ens.Util.FunctionSet. This method would read the source config name from the first message header in the session. You can then use this method in your router logic as it will be automagically included.
Custom utility functions used in DTL and Rules are defined in a class extending/inherits from Ens.Rule.FunctionSet, not Ens.Util.FunctionSet.
As documented here.
OK, I think I understand the question! 😊
Suppose you want to put the "source" HL7 Message SourceConfigName in MSH:Security:
<assign value='##class(Ens.MessageHeader).%OpenId($$$JobCurrentHeaderId).SourceConfigName' property='target.{MSH:Security}' action='set' />
In case you what to get the first message source config name:
<assign value='##class(Ens.MessageHeader).%OpenId($$$JobSessionId).SourceConfigName' property='target.{MSH:Security}' action='set' />
With "Message Header" you refer to MSH segment or Ens.MessageHeader?
Ens.MessageHeader properties cannot should not be modified.
The double-double quotes after .log?
d $ZF(-100,"/SHELL /LOGCMD /STDOUT=/archive/logs/failover-intengtest-vip.log""",cmd)
I had the same issue in in one system and opened a WRC case.
This is a spurious message (benign, simply should not be there) and can be ignored, nevertheless make messages.log analysis...complicated.
You may want to contact WRC and mention MAK5798 and DP-412382.
Please note that this was "First fixed in IRIS 2022.2.0", so upgrading can be another option.
To "capture" output I'd use a pipe instead of $ZF(-100), here a code sample:
Class Community.ExecOS [ Abstract ]
{
/// run an operating system commandClassMethod ExecOS(cmd As%String, Output LinesOut As%String)
{
set oldzeof=$SYSTEM.Process.SetZEOF(0)
set io=$IO,LinesOut=0try {
if cmd=""Quitopen cmd:"Q"use cmd
for LinesOut=1:1 {
read LinesOut(LinesOut)
}
} catch CatchError {
If CatchError.Name'="<ENDOFFILE>" {
set LinesOut=CatchError.Name
}
}
close cmd
Do$SYSTEM.Process.SetZEOF(oldzeof)
Use io
quit
}
}EPTEST>d ##class(Community.ExecOS).ExecOS("dir",.out)
EPTEST>zw
out=13
out(1)=" Volume in drive C has no label."
out(2)=" Volume Serial Number is 3E11-87B5"
out(3)=""
out(4)=" Directory of c:\intersystems\irishealth\mgr\eptest"
out(5)=""
out(6)="02.01.2024 12:14 <DIR> ."
out(7)="02.01.2024 12:14 <DIR> .."
out(8)="11.01.2024 19:04 429'916'160 IRIS.DAT"
out(9)="05.01.2024 14:26 42 iris.lck"
out(10)="24.11.2023 00:34 <DIR> stream"
out(11)=" 2 File(s) 429'916'202 bytes"
out(12)=" 3 Dir(s) 63'936'786'432 bytes free"
EPTEST>Instantiated classes can be compiled with no error since....long time, I think at least Cachè 2017 but I might be wrong.
This is also documented here:
If the compiler is called while an instance of the class being compiled is open, there is no error. The already open instance continues to use its existing code. If another instance is opened after compilation, it uses the newly compiled code.
However, the code to scan all processes variables is good to know/useful!
Check ##class(HS.Util.Installer.Foundation).Install()
It's a bug, I've created an issue in github with a possible fix.
Thank you for ll the info, I was able to install git-source-control and I'm....fighting testing it.
I think that the main problem with OEX software is the lack of information/details/documentation on how to install, configure and the use them.
Even ZPM itself suffer this problem, I found nowhere that a ZPM package can be downloaded as tarball and installed using the load command.
Where is the url for downloading the the tarballs for the ZMP packages reported/documented?
The git-source-control has very (very, very....) limited documentation/information on any aspect, from configuration to usage. Often it's a reverse engineering activity to figure out how it (should) work.
The feeling is that is a half backed software that has been abandoned.
Nevertheless I keeping fighting testing it.
At the moment IRIS does not support OpenAPI 3.0, the project OpenAPI-Suite in Open Exchange ("Set of tools for ObjectScript code generation from Swagger 3.0") support it.
I found the problem.
The issue does not happen if the service user is changed using:
IRISinstall.exe setserviceusername <instance-name> <username> <password>
When that command is issued two groups are created:
IRISServices
IRIS_Instance_<InstanceNme>
and the service user is added as member of there two groups.
The reason that it works using this way is that to the IRISServices group, in Local Security Policy is assigned the "Replace a process level token" user right.
In other words, the user that stars IRIS need the "Replace a process level token" right assigned via Local Security Policy (or GPO in an AD Domain).
Lesson learned:
- Use IRISinstall.exe to change the user for the IRIS service
or
- Assign "Replace a process level token" right to the user of IRIS service
That's EXACTLY what a Schedule setting does in any Item/Business Host (Business Service in your case).
.png)
Enrico
Well...installing a ZPM registry require ZPM itself and internet connection.
Additionally, in environments with no internet connection adding a new server (or docker) with internet connection just to install a source control software does not sound like "a solution".
I understand that ZPM is simple and handy, but why not releasing a stand alone installer that can be downloaded and installed without ZPM?
Enrico
Is internet connection a requirement?
It seems is not possible to download and install it without using ZPM that require internet connection.
Not every server has internet connection.
Enrico
"Unfortunately the Schedule Option isn't suitable where we need the job to run only once at a set time per day"
Why not? It is definitely possible to schedule to start every day at 8:00 for example using this schedule string:
START:*-*-*T08:00:00,STOP:*-*-*T08:10:00
You start a Business Service at 8:00 and stop it at 8:10 (for example).
All you need to take care is that the BS only make one call when started.
Enrico
have a look to this article:
"here has to be a way to do this. No?"
well...no!