Enrico Parisi · May 16, 2023 go to post

So, if you run the FindNPI() method multiple times you end up with miltiple connections to SQL Server?

I'm curious, what do you get if from terminal you run:

ZWrite %JDBCGateway
Set x=##class(osuwmc.CPD.vProviderNPIEns).FindNPI(123)
ZWrite %JDBCGateway
Set x=##class(osuwmc.CPD.vProviderNPIEns).FindNPI(123)
ZWrite %JDBCGateway
Set x=##class(osuwmc.CPD.vProviderNPIEns).FindNPI(123)
ZWrite %JDBCGateway

How many connection to SQL Server are there before and after these commands?

Enrico

Enrico Parisi · May 16, 2023 go to post

Just tested using "mssql-jdbc-12.2.0.jre8.jar", Java 8 and IRIS:

IRIS for Windows (x86-64) 2022.1 (Build 209U) Tue May 31 2022 12:16:40 EDT

It works fine, the connection is reused correctly. No additional connections are made if I run a query (like your) multiple times from terminal.

I'm using IRIS for Windows, you use same version for RedHat, maybe a platform specific bug?

What jdbc driver & java are you using?

Enrico

Enrico Parisi · May 16, 2023 go to post

It's an issue of the jTDS, using the connection the second time and IRIS try to reuse the connection there is an error:

ERROR #5023: Remote Gateway Error: java.lang.AbstractMethodError
        at net.sourceforge.jtds.jdbc.JtdsConnection.isValid(JtdsConnection.java:2833)
        at com.intersystems.jdbcgateway.JDBCGateway.isValid(JDBCGateway.java:1982)
        at com.intersystems.jdbcgateway.JDBCGatewayHelper.processMessage(JDBCGatewayHelper.java:642)
        at com.intersystems.gateway.JavaGateway.getJDBCGatewayMessage(JavaGateway.java:2015)
        at com.intersystems.gateway.JavaGateway.processMessage(JavaGateway.java:519)
        at com.intersystems.gateway.JavaGateway.run(JavaGateway.java:458)
        at com.intersystems.gateway.JavaGateway.run(JavaGateway.java:421)

My guess is that for IRIS the connection "is not valid" therefore open a new connection.

It's a known issue already reported.

If you search for "jTDS AbstractMethodError isValid()" you will find many entries..

Enrico

Enrico Parisi · May 16, 2023 go to post

Wow how did you pin point that down?

The second time I called the method/query (like your) I looked at the variables and found that %objlasterror was set, then from terminal:

d $system.OBJ.DisplayError()

To get properly formatted error message.

BTW, what is a "Domain Service Account"? From a JDBC authentication I guess it's just a normal domain account with user/password.

Are having the authentication issue with Microsoft JDBC driver only with Domain Service Account or with standard domain user accounts as well?

Enrico

Enrico Parisi · May 16, 2023 go to post

Not if you add in SQL GW Connection config ";trustServerCertificate=true" in the URL, as Jeffrey example

Enrico Parisi · May 16, 2023 go to post

Instead of adding user & password to the url string, can be entered in the SQL GW configuration page and still works. This way the password is masked and not in clear text.

Enrico Parisi · May 19, 2023 go to post

What's the class/type of test.document property?

sendstream.OriginalFilename is replaced/modified by the StreamSet() method

Enrico Parisi · Aug 1, 2023 go to post

What type of messages?

In general, a message is an instance of a persistent class, so "size" is a vague term.

Enrico

Enrico Parisi · Sep 15, 2023 go to post

Ciao Pietro,

I'm afraid you cannot change FailureTimeout "at the first iteration", however, for the specific case you describe, in the Business Operation you can override the method OnFailureTimeout() and there programmatically change the default behavior when the FailureTimeout has been reached. Something like:

/// Override this method to provide custom handling of retry / failure timeout.<p/>/// Set ..Retry=1 to override normal error return and re-evaluate flag properties.<p/>/// Return 0 to skip further (default) FailureTimeout processing, 1 to perform default processing.
Method OnFailureTimeout(pRequest As%Library.Persistent, Output pResponse As%Library.Persistent, ByRef pSC As%Status) As%Boolean
{
	If pRequest.severity = "high" {
		Set..Retry=1Quit0
	} Else {
		Quit1
	}
}

This is just a simple example, you may want to test/check pSC....

Give it a try and let us know.

Ciao,

Enrico

Enrico Parisi · Oct 3, 2023 go to post

When a new task is created in System Management Portal (SMP) there is a field:
"Namespace to run task in"

The task will run in that namespace, to find what database it corresponds to check the namespace definition.

Enrico

Enrico Parisi · Oct 3, 2023 go to post

Converting the Base64 stream to a pdf is trivial, extracting and searching text inside a pdf....can be hard to (almost) impossible.

Enrico

Enrico Parisi · Oct 24, 2023 go to post

For some unknown reason I was convinced he was using version 2018, I probably mixed up with a differente question!

Since it's IRIS version 2020, using the new External Language Server is definitely the way to go, I apologize for my confusion.

Enrico

Enrico Parisi · Nov 2, 2023 go to post

The idea is simple and I'm not sure it can be considered "documentation improvement" or it make sense in the "open exchange".

The idea is: add all the missing documentation for $system.external!!

The problem in not poor documentation, the problem is the MISSING DOCUMENTATION.

And in case you wonder, yes, I have reported this to WRC and sent a feedback to the ISC documentation team.

Nothing has happened.

On the same topic:

Using arrays in $system.external .NET gateway

Enrico

Enrico Parisi · Nov 2, 2023 go to post

Two alternatives comes to my mind:

Use not deprecated HS.FHIR.DTL.vSTU3.* classes, something like:

Set payload=##class(HS.FHIR.DTL.vSTU3.Model.Resource.Bundle).FromJSON(pHttpResponse.Data,"vSTU3")

And then "navigate" the payload instance as a classic IRIS class.

Other option, use FHIRPath

Enrico

Enrico Parisi · Nov 3, 2023 go to post

"we find that the new codes are not visible in the management portal"

Are you sure that your code is from APPCODE database?

Regarding the production settings, replacing the production class only is not sufficient, you need to compile the production class in the final environment. When a production is compiled "some data" is saved in the (APPDATA in your case) database.

Enrico

Enrico Parisi · Nov 3, 2023 go to post

"Do you mean we have to compile those changed codes in the final deployment environment, at customer site?"

Yes, at least only for the production class extending Ens.Production.

Enrico

Enrico Parisi · Nov 6, 2023 go to post

To better understand the requirements, can you post at least one sample source message and a (manually transformed message?

Enrico

Enrico Parisi · Nov 7, 2023 go to post

Sorry, I mixed things up!

Classes in the package HS.FHIR.vSTU3.* are deprecated but HS.FHIR.DTL.vSTU3.* classes are not deprecated. At least to my knowledge. Why do you think they are deprecated?

When I read your post I assumed you referred to the deprecated HS.FHIR.vSTU3.* classes, in fact you mentioned HS.FHIR.DTL.vSTU3.Model.Resource.Bundle, so I got confused.

Using:
Set payload=##class(HS.FHIR.DTL.vSTU3.Model.Resource.Bundle).FromJSON(pHttpResponse.Data,"vSTU3")

You should be able to "convert" (import) the stream bundle to the corresponding classes and then "navigate" the bundle, including the resources within it, as a classic IRIS class.

Enrico

Enrico Parisi · Nov 7, 2023 go to post

Try this:

Class Community.HL7.Laboratorio.ORUToCUPv1 Extends Ens.DataTransformDTL [ ClassType = "", DependsOn = EnsLib.HL7.Message, ProcedureBlock ]
{

Parameter IGNOREMISSINGSOURCE = 0;Parameter REPORTERRORS = 0;Parameter TREATEMPTYREPEATINGFIELDASNULL = 0;
XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='EnsLib.HL7.Message' targetClass='EnsLib.HL7.Message' sourceDocType='2.5:ORU_R01' targetDocType='2.5:ORU_R01' create='new' language='objectscript' >
<assign value='source.{MSH}' property='target.{MSH}' action='set' />
<assign value='source.{PIDgrpgrp().PIDgrp.PID}' property='target.{PIDgrpgrp().PIDgrp.PID}' action='set' />
<assign value='source.{PIDgrpgrp().PIDgrp.PV1grp}' property='target.{PIDgrpgrp().PIDgrp.PV1grp}' action='set' />
<assign value='source.{PIDgrpgrp().PIDgrp.NTE()}' property='target.{PIDgrpgrp().PIDgrp.NTE()}' action='set' />
<assign value='0' property='ORCCounter' action='set' />
<foreach property='source.{PIDgrpgrp(1).ORCgrp()}' key='ORC' >
<assign value='source.{PIDgrpgrp().ORCgrp(ORC).ORC}' property='target.{PIDgrpgrp(1).ORCgrp(ORC).ORC}' action='set' />
<assign value='source.{PIDgrpgrp().ORCgrp(ORC).OBR}' property='target.{PIDgrpgrp(1).ORCgrp(ORC).OBR}' action='set' />
<assign value='source.{PIDgrpgrp(1).ORCgrp(1).TQ1grp(ORC)}' property='target.{PIDgrpgrp(1).ORCgrp(ORC).TQ1grp(ORC)}' action='set' />
<foreach property='source.{PIDgrpgrp(1).ORCgrp(ORC).OBXgrp()}' key='OBX' >
<if condition='1=0' >
<true>
<assign value='source.{PIDgrpgrp(1).ORCgrp(ORC).OBXgrp(OBX)}' property='target.{PIDgrpgrp(1).ORCgrp(OBX).OBXgrp(OBX)}' action='set' />
</true>
<false>
<assign value='ORCCounter+1' property='ORCCounter' action='set' />
<assign value='source.{PIDgrpgrp(1).ORCgrp(ORC).OBR}' property='target.{PIDgrpgrp(1).ORCgrp(ORCCounter).OBR}' action='set' />
<assign value='source.{PIDgrpgrp(1).ORCgrp(ORC).ORC}' property='target.{PIDgrpgrp(1).ORCgrp(ORCCounter).ORC}' action='set' />
<assign value='source.{PIDgrpgrp(1).ORCgrp(ORC).TQ1grp()}' property='target.{PIDgrpgrp(1).ORCgrp(ORCCounter).TQ1grp()}' action='set' />
<assign value='source.{PIDgrpgrp(1).ORCgrp(ORC).OBXgrp(OBX)}' property='target.{PIDgrpgrp(1).ORCgrp(ORCCounter).OBXgrp(OBX)}' action='set' />
</false>
</if>
</foreach>
</foreach>
</transform>
}

}

Ciao,

Enrico

P.S.: I changed the IF condition for testing

Enrico Parisi · Nov 7, 2023 go to post

Hi Dan! I'm please you are listening 😊

"I am listening! $system.external does not replace the old Java Gateway but the old Java and JDBC Gateways should still be available."

I know it's "still there" and works, however all the documentation for the old Java and .NET Gateway has been removed since long time (starting from IRIS?), so implementing it today it's difficult for any developer without previous experience.
In addition, I'm not sure if it would be a good idea to implement today external calls using the old Gateway, I assume that using the new $system.external is preferred.
In fact the documentation contains some info for converting from old gateway to new $system.external:

"...upgrading your code is a simple matter of replacing certain class and method references..."

Assuming that upgrading is "simple matter of replacing certain class and method references", unfortunately for MANY use cases there is no documentation of what to replace with what.

The problem is that now we have no documentation of the (still available) old gateway and "scarce" documentation for the new one.
I don't remember the details of the old gateway documentation, however it offered two GREAT code samples where most (if not all) the functionality was implemented:

%Net.Remote.DotNet.Test
%Net.Remote.Java.Test

Using only documented feature/methods of $system.external is not possible to convert the old samples to use $system.external.

So, my idea was to encourage the implementation of two samples (maybe Phyton as well?) with all the features.

That's the issue at hand.

Ciao,
Enrico

Enrico Parisi · Nov 7, 2023 go to post
do##class(%XML.XPATH.Document).CreateFromStream(pResponse.ContentStream, .tPnRXML)
Set sc=tPnRXML.EvaluateExpression("/XMLMessage/ContentStream/RegistryResponse/RegistryErrorList/RegistryError","@errorCode",.tPnRResult)
Set errorCode=tPnRResult.GetAt(1).Value ; errorCode=XDSRegistryDeprecatedDocumentError

Enrico

Enrico Parisi · Nov 8, 2023 go to post

Sorry, forgot the namespace, try this:

do##class(%XML.XPATH.Document).CreateFromStream(pResponse.ContentStream, .tPnRXML)
Set tPnRXML.PrefixMappings="ns urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0"Set sc=tPnRXML.EvaluateExpression("/XMLMessage/ContentStream/ns:RegistryResponse/ns:RegistryErrorList/ns:RegistryError","@errorCode",.tPnRResult)
Set tPnRResult.GetAt(1).Value ; Value=XDSRegistryDeprecatedDocumentError
Enrico Parisi · Nov 8, 2023 go to post

I was surprised that overriding the OnFailureTimeout() in the custom BO class did not work! According to the description that was definitely the way to go. But it indeed does not work(ed).

I opened a WRC and it turned out that there is a bug "around" the OnFailureTimeout() implementation in Ens.BusinessOperation.

So, if anyone need to implement OnFailureTimeout()  with Set ..Retry=1, first it requires to contact WRC, explain the problem and reference DP-426250 to get the fix.

Enrico

Enrico Parisi · Nov 10, 2023 go to post

If a server installation running Caché wants to migrate to IRIS most likely need to upgrade/move/migrate the Operating System as well.

What IRIS officially supported Server Operating System supports older processor CPU architecture/model? 

Please note that mine is a genuine question, I don't want to open a debate.

Enrico

Enrico Parisi · Nov 10, 2023 go to post

%SYS>s return=1
 
%SYS>do display^GLOBUFF(200,.return)

After the call return() contains the sorted array with same info s displayed.

Enrico