Martin Staudigel · Dec 15, 2025 go to post

Hello community,

we opened up a WRC call meanwhile and I'll share the gained information in case anyone stumbles into this post.

The information "Web IP Address" is received from the machine (client) which sends messages to the messagebank. It is configured in the client's %SYS Namespace in a global ^SYS in the subscripts ("WebServer","Name") and ("WebServer","Port").

The information NodeId is derived from another client setting stored in every namespace in a global ^Ens.MsgBank("NodeId"). If a message has been sent to the messagebank, a new node with a new NodeId is created, when the given nodeId has not sent any messages before.

In our setup we were able to change the ^SYS("Webserver") to the correct settings and the automatically created nodes were merged with the manually created nodes by the given NodeId and Web IP Address. This enabled us to select messages from the messagebank's message viewer an resend them to the original target without any further action. This also works for messages, which have been sent in the past containing a wrong Web IP Address.

If you want to change a client seemlessly, then make sure to check these globals, especially the NodeId, before any messages will be sent. Hopefully this explanation helps other desperate messagebank users to understand what's going on in the background and not to fall into the same traps we did.

Kind regards,

Martin

Martin Staudigel · Sep 30, 2025 go to post

Hello everybody,

as nobody seems to share the demand for an Orbis HL7 schema definition (or at least nobody seems to have one), I started to create one by myself. If anybody is interested in the schema feel free to write a PM, I'm happy to share my results.

Regards,

Martin

Martin Staudigel · Jan 3, 2025 go to post

Hello everybody,

after some hours of searching it appeared, that I was mislead by the "404 Not Found" error. In the end is was nothing more than an authentication problem, which should have been answered by "403 Forbidden".

Regards and a happy new year,

Martin

Martin Staudigel · Dec 23, 2024 go to post

What solved my problem was to copy the referenced XSD file from schemaLocation="../../tel/error/TelematikError.xsd" to the local folder where the wsdl file was located and then change the reference to schemaLocation="TelematikError.xsd".

After doing this the import of the wsdl file ran through and created all datatype classes, request, resoponse and operation class.

Thanks for your help and time,

regards, Martin

Martin Staudigel · Dec 23, 2024 go to post

Hello Jani,

as far as I understand does the importer resolve imported references. Normally there is no need to separately import the referenced schemas when importing a wsdl file. This worked with some other serviced quite good, it is just two of them, which do not work.

Anyways, I was using the schema reader provided by Luis and the result from importing the VSDService.xsd is a package structure that also contains the elements defined by the file ConnectorContext.xsd. What I still don't have is the soap operation class and the request and response message classes...

Kind regards, Martin

Martin Staudigel · Dec 23, 2024 go to post

Hello Luis,

thanks for taking the time to analyze my problem. I'm not sure if I fully understood what the problem and the suggested solution is. In the end I would like to have a functional SOAP Operation, with request and response classes to use the service.

As I understand your answer, the problem lies in the inclusion of datatypes, which is not supported by the SOAP wizard, so the process has to be done programmatically and the problem lies here:

<types>
  <xs:schema>
    <xs:import schemaLocation="VSDService.xsd" namespace="http://ws.gematik.de/conn/vsds/VSDService/v5.2"/>
    <xs:import schemaLocation="../../tel/error/TelematikError.xsd" namespace="http://ws.gematik.de/tel/error/v2.0"/>
  </xs:schema>
</types>

I would have to Import the referenced schemas using your to create the contained datatypes. I do so by importing the referenced xsd file using the classmethod you provided. After that, I'd guess the original wsdl file has also to be modified in some way to set the referenced datatypes to the formerly imported. Are my assumptions right, and how could I do this?

What I meanwhile tried was to import the two schemas into the currently used namespace using the schema import feature of the management portal. Doing so leads to the creation of some new datatypes:

When I'm then removing the "types" section from the wsdl file, I'm getting another error, which indicates that some other parts are missing.

Could you explain how to enable the import and the class creation of the initial wsdl file after the xsd schema files are imported? I'm sorry, but it seems like there is a missing piece in my understanding.

Thanks and regards,

Martin

Martin Staudigel · Jun 18, 2024 go to post

Hello Nick,

thanks for your help. User rights configuration in Iris Healthconnect is a confusing field, I think. Nevertheless, I have configured a role that contains the functionalities I need, partly by trial and error. From my point of view, the documentation could be a bit more detailed, especially when it comes to the resource level. These days, the topic is too serious and important to simply fall back on %ALL for convenience.

Regards, Martin

Martin Staudigel · Apr 15, 2024 go to post

Thanks for the hint. In the past it was the port of the packaged webserver, that is true. Meanwhile we're using the Apache server that comes with the distribution's package manager in combination with the Intersystems webgateway. We're just using the same port configuration. I hope this at least alleviates the problem described, but unfortunately does not change the problem that all web apps, including the management portal, are addressed via the same port.

Martin Staudigel · Apr 12, 2024 go to post

Thank you for your explanations. The procedure you described sounds somewhat complex, but (as ultimately proven by your report) feasible. Together we are 5 colleagues who deal with the development and administration of interfaces in addition to other topics. We would need external help from our systems department to set up a certificate-based access procedure. I can see the day coming when the certificate has expired or something else has happened and we have locked ourselves out with no way of quickly re-establishing this access on our own. But thanks again for the suggestion, I will definitely look into whether this could be an option for us.

Martin Staudigel · Oct 6, 2023 go to post

Thank you very much for your feedback. After some back and forth and failed attempts, I have now decided on a different approach. The reasons for this are on the one hand that an export of all 133500 records would take something like 12h and in case of an error all preliminary work is gone.
Furthermore, even with 1000 records the transfer to a FHIR bundle again ran into a STORE error. All in all it is more reasonable to split the export into smaller packages. I got a handle on the problem by now initiating export at 500 objects and persistently storing the IDs of the handled records so they can be ignored on the next run.
The process is called on a timed basis every 5 minutes and works in chunks until all resources are exported. This runs since 1h now, and looks good so far.

Regards, Martin

Martin Staudigel · Aug 31, 2023 go to post

Yes, it took a while to find the solution as writing files did not cause problems. It came out, that the port for the lockd process is dynamically negotiated. We configured nfs to use a static port and opend the port in the firewall at the host system and the problems were gone. So you were right with the suggestion to search on OS-level.

Thanks for your help.

Martin Staudigel · Aug 28, 2023 go to post

Thanks to Andreas Schütz and Stephan Mohr - we found out that a blocked firewall port caused the open command to freeze. Timeout settings didn't have any effect, that should not be the case.

Regards,

Martin

Martin Staudigel · Mar 15, 2023 go to post

This is how I translated and simplified your example:

Method OnRequest(pRequest As Ens.Request, Output pResponse As Ens.Response) As%Status
{
	#dim tSc = $$$OK#dim tConvertedStream as Ens.StreamContainer
	#dim tStream as%Library.GlobalBinaryStreamif ( pRequest.%IsA("EnsLib.HTTP.GenericMessage") ){
		set tConvertedStream = ##class(Ens.StreamContainer).%New()
		set tConvertedStream.Stream = ##class(%GlobalCharacterStream).%New()
		set tSc = tConvertedStream.Stream.CopyFrom(pRequest.Stream)
		set tConvertedStream.OriginalFilename = $Piece(pRequest.HTTPHeaders.GetAt("RawParams"),"=",2)
		
		set tStream = ##class(%Library.GlobalBinaryStream).%New()
		set tSc = tStream.Write("<html><head><title>Server Response</title></head><body><h1>This is your response</h1></body></html>")
		set tSc = tStream.%Save()
		
		set pResponse = ##class(EnsLib.HTTP.GenericMessage).%New(tStream,,pRequest.HTTPHeaders)
		do pResponse.HTTPHeaders.SetAt("HTTP/1.1 200 OK","StatusLine")
		do pResponse.%Save()
	}
	
	return tSc
}

It works like expected:

that is exactly what I needed to continue.

Thank you very much for your help,

regards,

Martin

Martin Staudigel · Mar 15, 2023 go to post

Hi Oliver,

thanks a lot for your help. Your assumption is right, but at the moment I'm following the approach to write some COS Code to solve the task.

Class UKEr.BP.FHIR.HttpContsentRequestProcess Extends Ens.BusinessProcess
{

Method OnRequest(pRequest As Ens.Request, Output pResponse As Ens.Response) As%Status
{
	#dim tSc = $$$OK#dim tResponse as%Net.HttpResponse = ##class(%Net.HttpResponse).%New()
	set tResponse.StatusCode = 200// Do something to create a valdid response and assing it to pResponseReturn tSc
}

/// Handle a 'Response'
Method OnResponse(request As%Library.Persistent, ByRef response As%Library.Persistent, callrequest As%Library.Persistent, callresponse As%Library.Persistent, pCompletionKey As%String) As%Status
{
	return$$$OK
}

}

Nevertheless I'll import your example and have a look at the graphical BP as well. At the moment I'd prefer to create a response in code, but I'm quite confident also to be able to translate your example.

Thank you very much, I'll get back here with results (hopefully).

Regards,

Martin

Martin Staudigel · Jan 10, 2023 go to post

Hello David,

thank you very much for your reply. How does this behave in case of using HS.FHIRServer.Interop.Request with HS.FHIRServer.InteropService? The creation of streams is done within the library classes, so it is not directly custom code. Since requests are derived from Ens.Request, they are cleaned up by the mentioned purge task. I can't find any hints in the code of the requests (something like a delete trigger does for persistent object hierarchies) that the quickstreams would be deleted as well. How is this handled in the Intersystems FHIR server?

Edit:

I discovered the globals in the namespace %SYS with "system items" checked in Cachetemp.HS.Stream. In the file system, unlike other stream types, quickstreams have no representation in the form of a file besides the database. As you described, the removal has to be done manually, because the quickstreams of the already purged requests are still present. Alternatively enough memory has to be provided and I wait until the next restart solves the problem by itself. If these assumptions aren't wrong this answers my questions from above.

Regards, Martin

Martin Staudigel · Nov 23, 2022 go to post

Hi Cristiano,

I took your idea and (simplified) added a property and setting 'CheckServerIdentity' which is set to 1 by default to the custom business operation, to make this setting available over settings menu. Works like a charm!

Thanks a lot for your help!

Regards,

Martin

Martin Staudigel · Feb 16, 2022 go to post

Hello community,

I'm trying to break it down to the core problem: why does this function return the following output when trying to create a XML stream - is this a bug?

Class HOME.ms.MsFunctionSet Extends Ens.Rule.FunctionSet
{

ClassMethod FhirToXmlExample() As %Status
  {
    #dim tCapStat as HS.FHIR.DTL.vR4.Model.Resource.CapabilityStatement;
    set tCapStat = ##class(HS.FHIR.DTL.vR4.Model.Resource.CapabilityStatement).%New()
    w tCapStat.ToJSON()
    w tCapStat.ToXML()
  }
}

> do ##class(HOME.ms.MsFunctionSet).FhirToXmlExample()
> 426@%Stream.TmpCharacter
> do ##class(HOME.ms.MsFunctionSet).FhirToXmlExample() - Error <FUNCTION>

Regards,

Martin

Martin Staudigel · Jan 24, 2022 go to post

So, you mean replacing

write tResponse.%ToJSON()

with

do tResponse.%ToJSON()

will do the job, even for big responses? That would be great.

Thank you,

Martin 

Martin Staudigel · Jan 12, 2022 go to post

Hello Marc,

thank's a lot! I had hoped and suspected that it must be a small thing.

Regards,

Martin

Martin Staudigel · Dec 6, 2021 go to post

It seems like the former enterprise client systems configuration had to be modified. 2018.2.1 worked well with the server name. In 2021.1 I had to provide the fqdn at the Web IP Address setting to make the production monitor showing up like expected. I don't know if this was the actual reason, but at least it works now.

Thanks and regards,

Martin

Martin Staudigel · Dec 3, 2021 go to post

Hello Craig,

yes, it is. We're using configured credentials and method "Password" is checked. I also tried a different, newly crated user for testing purposes. Moreover, the access has worked before the upgrade to 2021.1 and we have not changed anything in the configuration. What I find confusing is that even when the "unauthenticated" method is checked at the webapp configuration, the login screen appears.

Regards,

Martin

Martin Staudigel · May 18, 2021 go to post

Finally, Arun's suggestion to write the data objects to the database on the many side using %Save() at the time of creation worked. Regarding performance, this did not result in any significant losses.Thanks to all for the helpful comments and remarks.

Martin Staudigel · May 12, 2021 go to post

Thanks for your reply,

a look into the table of the 'many' data objects confirms that the wrong order is already reflected in the ID of these objects. Since the ID is assigned in ascending order at the time of creation, I don't quite understand why it doesn't reflect the order of the result set.

Anyway, with the hints I can continue the search and make adjustments if necessary to resolve the dependency on implicitly assigning an ascending Object ID.

Regards,
Martin

Martin Staudigel · Apr 14, 2021 go to post

Hello Vic,

yes, our admin users are provided with %ALL privileges, but it seems like I finally managed to get things working. I don't understand in detail why it works, but I noticed that the configuration of the databases on the other hosts is different. 

So I tried out adding the role %HS_DB_%DEFAULT to the user in question. With this additional role it seems to work. 

It would still be interesting to know if there is an unnecessarily large expansion of permissions associated with this role that poses an unintended risk.

Thank you for your help!

Regards, Martin

Martin Staudigel · Apr 14, 2021 go to post

I did, here are the details of the error, which was provoked again after enabling audit log for protect events. By the way - because I didn't mention it earlier - with an admin account the call works.  Does this provide details about the source of the error?

Martin Staudigel · Feb 22, 2021 go to post

Hello Eduard,

thanks for your helpful reply. I assigned the role %DB_CACHESYS to the user, which grants R/W rights to some tables from the INFORMATION_SCHEMA schema. As the user still isn't allowed to login to neither management portal nor studio my basic demands are fullfilled, so I chose not to start an investigation which of the given tables causes the violation. This setting removes the unwanted entries from the auditlog, so the problem is solved from my point of view. Thanks again,

regards,

Martin Staudigel

Martin Staudigel · Jan 29, 2020 go to post

To conclude this topic I would like to present my solution for a runtime configurable SMB access. 
First step was to write a helper class in Java, which provides static methods for all needed functionality. This class encapsulates the dependencies to the Java libraries jcifs-ng-2.1.1.jar, bcprov-jdk15on-1.58.jar and slf4j-1.7.24.jar.

Some of the implemented Methods are:

public static boolean copyFileFromSmbShareToLocal( String smbHost, String smbShare, String smbUser, String smbPass, String smbAuthDomain, String smbFileName, String localDirectory, String localFileName, boolean append, boolean deleteRemote) throws java.io.IOException, InterruptedException { ... }

public static boolean resourceExists(String smbHost, String smbShare, String smbUser, String smbPass, String smbAuthDomain, String smbFileName, boolean checkWriteability) throws jcifs.CIFSException { ... }

 public static String listResources (String smbHost, String smbShare, String smbUser, String smbPass, String smbAuthDomain, String smbFileName, String smbFileFilter) throws jcifs.CIFSException, java.net.MalformedURLException, java.net.UnknownHostException  { ... }

public static String getAttributes(String smbHost, String smbShare, String smbUser, String smbPass, String smbAuthDomain, String smbFileName) throws jcifs.CIFSException, java.net.MalformedURLException, java.net.UnknownHostException { ... }

Next I created a jar file from this class, which could be processed with the Add-In "Java Gateway Wizard" included in Studio and transferred to corresponsing cache wrapper classes.  

This made it possible to create an operation dependending on a Java gateway, by use of the created classes. By using specially created message types, the configuration of the dynamic parameters could be communicated. The operation can be set to any Windows shares by e.g. reading the configuration from a database table and sending the required information to the operation. It is also possible to read files from different sources and copy them to the destinations without having to determine beforehand on which computers the corresponding shares are set up.

If you are interested in further details on how to solve the problem, please send us a PN. Then I will gladly give further information or provide more detailed code components.

Regards,

Martin Staudigel

Martin Staudigel · Feb 12, 2019 go to post

It's Ensemble 2016.2.1.803.0 on SLES 12 SP3

There is the possibility to mount shares into the filesystem, but if this fails, it may go unnoticed because an empty directory remains. I don't know any other way to address a Windows share from an ObjectScript class than via the Java gateway, but that doesn't mean it doesn't exist. Every hint is appreciated.