Enrico Parisi · Mar 23, 2024 go to post

Almost impossible to help without details on the .NET code you are using to connect and call Caché.

I think examples use very old version of Visual Studio

You are using an old version/product too, Caché 2018.1.

Enrico Parisi · Mar 21, 2024 go to post

found no documentation on how to set a VECTOR Datetype on pure object level

Maybe you can have a look to the documentation of $vector, $vectorop, $vectordefined and $isvector intrinsic functions.

Enrico Parisi · Mar 19, 2024 go to post

The prerequisites for the InterSystems HL7 Interface Specialist certification include the training course and "At least 6 months - 1 year designing, building, and performing basic troubleshooting of HL7 interfaces with InterSystems products version 2019.1 or higher."

Actual/real experience will definitely help in passing the certification, theoretical study and some exercise may not be enough to gain the knowledge required.

In the exam description page you can find a list of "Exam Topics and Content". All questions in the exam belong to those topics.

Last but not least, everything is contained in the documentation.

Enrico Parisi · Mar 19, 2024 go to post

It contains the sender of the current request message being processed by the BO.

Enrico Parisi · Mar 19, 2024 go to post

Within your BO method ..%RequestHeader.SourceConfigName contains the name of the "sender" Business Host.

Enrico Parisi · Mar 19, 2024 go to post

Where/when do you want to know it?

Usually you get this information looking at the trace of the session/message.

Or you need to know the sender from within your BO code/method?

Enrico Parisi · Mar 16, 2024 go to post

Parameter runtime computation works fine, you can test it from terminal:

w ##class(ECUH.BPL.ClassMethods.X509CredentialAlias).#VALUELIST

Long story short, you cannot use runtime computed VALUELIST in this context.

I suggest using the proper, officially documented way to implement your requirement, see my first answer above.

Enrico Parisi · Mar 15, 2024 go to post

Using the Curly Braces a parameter is evaluated at compile time:

Parameter VALUELIST = {..GetValueList()};

You need to evaluate it at run time, in that case use COSEXPRESSION:

Parameter VALUELIST As COSEXPRESSION = "..GetValueList()";

The the relevant documentation is:

Defining and Referring to Class Parameters

Enrico Parisi · Mar 15, 2024 go to post

I just realized that with IRIS for Health (and I maybe also HelthShare connect) ZAUTHENTICATE is mapped to HSLIB and you should use/modify HS.Local.ZAUTHENTICATE class in HSCUSTOM namespace.

Enrico Parisi · Mar 15, 2024 go to post

If you are using HealthShare, and I do believe so, please read the following documentation (login required):

Custom Authentication Processing using the Local ZAUTHENTICATE

There you will find:

Important:

The ZAUTHENTICATE provided with HealthShare includes callbacks that allow you to add custom processing at specific entry points. Do not modify the supplied ZAUTHENTICATE. Instead, add your callback processing as class methods in the class HS.Local.ZAUTHENTICATE

Enrico Parisi · Mar 15, 2024 go to post

If it was mapped to HSLIB, then I think you are using HealthShare, if so, you are not supposed to change that mapping, instead you should use/modify HS.Local.ZAUTHENTICATE class in HSCUSTOM namespace.

I believe the mapping will be recreated when updating/upgrading the system.

Enrico Parisi · Mar 15, 2024 go to post

I don't think there is a callback method available.

One option could be to subclass %CSP.REST and use your subclass instead of %CSP.REST.

You subclass can be something like:

Class MyCustomCSP.REST Extends %CSP.REST
{

ClassMethod DispatchRequest(url As %String, method As %String, forwarded As %Boolean = 0, args...) As %Status
{
	Set sc=##super(url,method,forwarded,.args)
	
	; your "onPostDispatch" code here 
	Quit sc
}

}
Enrico Parisi · Mar 13, 2024 go to post

"...the write() function seems to be overlaying the whole stream..."

Of course, that's the way a stream  works as designed. The resulting (target) stream will contains what the Write() method writes to the stream. And only that.

If this is not what you expect, then please provide more details on your goal.

Enrico Parisi · Mar 13, 2024 go to post

Just in case, try adding a "code" action BEFORE your actions with:

  Do source.Stream.Rewind()
  Do target.Stream.Clear()

Enrico Parisi · Mar 13, 2024 go to post

How big (Size) is the stream? If it's larger then the maximum string supported string length (~3.5MB), then you have a problem with your code.

When it does not work, do you get an error?

In the DTL, how do you set the "Create" option/parameter? (copy or new?)

Is there any other reference/set referencing the Stream in the DTL?

Enrico Parisi · Mar 13, 2024 go to post

What product? If it's HealthShare then you should use the class HS.Local.ZAUTHENTICATE in HSCUSTOM namespace.

Enrico Parisi · Mar 13, 2024 go to post

If you use server side editing, you can have as many servers/namespaces as you need in Explorer.

In many environments server side editing in much more convenient.

Enrico Parisi · Mar 13, 2024 go to post

In fact, for simple XML export (no namespace and other amenities) you can just use XMLExport*() methods.

ClassMethod test()
{
	Set message=##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
	Set message.resultado.codigo="06050301"
	Set message.resultado.error=##class(EsquemasDatos.Seguridad.Error).%New()
	Set message.resultado.error.codigo=0
	Set message.resultado.error.descripcion="Proceso realizado correctamente"
	
	Set sc=message.resultado.XMLExportToString(.string)
    ; handle sc error here

	Write string,!!
	
	; convert XML string back to object
    Set reader = ##class(%XML.Reader).%New()
    Set sc=reader.OpenString(string)
    ; handle sc error here
    Do reader.Correlate("resultado","EsquemasDatos.Radiologia.Resultado")
    Do reader.Next(.ReturnObject,.sc)
    ; handle sc error here
    Write "ReturnObject is of type ",ReturnObject.%ClassName(1),!
    do ReturnObject.XMLExport(,",indent")
	
	Quit
}

Result:

Do ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).test()
<resultado><error><codigo>0</codigo><descripcion>Proceso realizado correctamente</descripcion></error><codigo>06050301</codigo></resultado>
 
ReturnObject is of type EsquemasDatos.Radiologia.Resultado
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>
Enrico Parisi · Mar 13, 2024 go to post

OK, you asked XML string to object 😊

ClassMethod test()
{
	Set message=##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
	Set message.resultado.codigo="06050301"
	Set message.resultado.error=##class(EsquemasDatos.Seguridad.Error).%New()
	Set message.resultado.error.codigo=0
	Set message.resultado.error.descripcion="Proceso realizado correctamente"
	
	Set writer=##class(%XML.Writer).%New()
	Set writer.Indent=1

	Set sc=writer.OutputToString()
	; handle sc error here
	Set sc=writer.RootObject(message.resultado)
	; handle sc error here
	Set string=writer.GetXMLString()
	Write string,!
	
	; convert XML string back to object
    Set reader = ##class(%XML.Reader).%New()
    Set sc=reader.OpenString(string)
    ; handle sc error here
    Do reader.Correlate("resultado","EsquemasDatos.Radiologia.Resultado")
    Do reader.Next(.ReturnObject,.sc)
    ; handle sc error here
    Write "ReturnObject is of type ",ReturnObject.%ClassName(1),!
    do ReturnObject.XMLExport(,",indent")
	
	Quit
}

Result:

Do ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).test()
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>
 
ReturnObject is of type EsquemasDatos.Radiologia.Resultado
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>
Enrico Parisi · Mar 13, 2024 go to post

To export a XML enabled class use %XML.Writer class.

ClassMethod test()
{
	Set message=##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).%New()
	Set message.resultado.codigo="06050301"
	Set message.resultado.error=##class(EsquemasDatos.Seguridad.Error).%New()
	Set message.resultado.error.codigo=0
	Set message.resultado.error.descripcion="Proceso realizado correctamente"
	
	Set writer=##class(%XML.Writer).%New()
	Set writer.Indent=1

	Set sc=writer.OutputToString()
	; handle sc error here
	Set sc=writer.RootObject(message.resultado)
	; handle sc error here
	Set string=writer.GetXMLString()
	Write string,!
	Quit $$$OK
}

In your EsquemasDatos.Radiologia.Resultado class add XMLNAME parameter to obtain the correct (lowercase) tag name:

Class EsquemasDatos.Radiologia.Resultado Extends (%SerialObject, %XML.Adaptor)
{

Parameter XMLNAME = "resultado";

Property error As EsquemasDatos.Seguridad.Error;

Property codigo As %String(MAXLEN = "");

Result:

Do ##class(Mensajes.Response.Radiologia.NumeroOrdenAcodigoSERAMResponse).test()
<resultado>
  <error>
    <codigo>0</codigo>
    <descripcion>Proceso realizado correctamente</descripcion>
  </error>
  <codigo>06050301</codigo>
</resultado>
Enrico Parisi · Mar 11, 2024 go to post

Strange. Maybe a permissions issue?

What user starts the IRIS service? The default Local system?
You can check that in Windows Services, look for "InterSystems IRIS Controller for IRIS".

If so, does the SYSTEM account have access to e:\intersystems\iris ?

I'm just guessing.

Enrico Parisi · Mar 7, 2024 go to post

In your OnProcessInput() methods, how do you call the business process (or operation)? SendRequestAsync() or SendRequestSync()?

Enrico Parisi · Mar 6, 2024 go to post

Sure, that's fine, each process commit/rollback it's own transactions.

My message was to @Timo Lindenschmid where he was trying to commit/rollback worker processes from the "main" process. That's not possible.

Enrico Parisi · Mar 5, 2024 go to post

I think that using EnsLib.REST.GenericService and EnsLib.REST.GenericOperation is the way to go.