Not all the MSH:9 fields are filled out as most of our downstream systems only use MSH:9.1 and MSH:9.2, so MSH:9.3 is not filled out. Do we need to fill out MSH:9.3?
- Log in to post comments
Not all the MSH:9 fields are filled out as most of our downstream systems only use MSH:9.1 and MSH:9.2, so MSH:9.3 is not filled out. Do we need to fill out MSH:9.3?
Here is what I am seeing....
.png)
But when I look at the trace view...
.png)
So in the router if you are looking at the for the particular docName nothing is found, so in the rule itself you have to specify the MessageType.TriggerEvent that you need to filter off of.
.png)
Thanks the query is very helpful.
You wouldn't happen to have an example of how to create the query as a Stored Procedure within Cache? I know how to do it in MS SQL, I am just looking for an example on how to do it in Cache.
Yes, I was able to create separate roles, and copy the existing Data Lookup pages, locking the users down to only being able to access that particular page for their lookup tables. There are two class files that would need to be created.
1. Filter Dialog if you want to limit the users down to their particular tables.
2. A copy of EnsPortal.LookupSettings - which will limit users ability to get to other places within Ensemble.
I haven't tested this in IRIS just yet as we are in the process of moving to IRIS.
If a Business Router is sending to a file based HL7 operation, I am seeing NULL values being returned. How can I tell the system that if we are sending a message to a File Based HL7 Business Operation that I don't expect a Return and avoid receiving the NULL value back?
Thanks that helped a lot. However I am seeing when I make a call to send the HL7 message to an operation, the callresponse is coming back NULL. Is there a way to send the message but make the process think we don't need a response back?
Can you show me a screen shot of what you mean by
"Routing rules that are called synchronous respond with a "NULL" message when the Response From parameter is empty.
The fix was to set the Response From parameter e.g. to "*" - the first response received will be the one returned"
In reviewing everything within the Business Process, I finally found that in my CALL requests that the response actions were not always filled in. So I am working through those now.
However I am seeing something weird with when a Router sends to the Business Process. Do I need to do something in the Business Process to send a response back to the Router?
1. I would stay away from Modifying the current EnsLib.HL7.SearchTable if at all necessary. Modifying the source code could lead to consequences down the road, especially when you upgrade it might get overwritten. What I did was that I copied the existing code and modified it for our use. That way we can add and remove fields anytime we want.
Class osuwmc.HL7SearchTable Extends (%Persistent, Ens.VDoc.SearchTable) [ ClassType = persistent, CompileAfter = EnsLib.HL7.Message, Inheritance = right, ProcedureBlock, System = 4 ]
{
Parameter DOCCLASS = "EnsLib.HL7.Message";
Parameter EXTENTSIZE = 4000000;
/* Re-declare indices because the superclass is abstract */
Index indexValue On (PropId, PropValue, DocId) [ IdKey, Unique ];
Index indexDocId On (DocId, PropId, PropValue) [ Unique ];
XData SearchSpec [ XMLNamespace = "http://www.intersystems.com/EnsSearchTable" ]
{
<Items>
<Item DocType="" PropName="MSHTypeName" Unselective="true">{1:9.1}_"_"_{1:9.2}</Item>
<Item DocType="" PropName="MSHControlID" PropType='String:CaseSensitive' >{1:10}</Item>
<Item DocType="" PropName="PatientID" >[PID:2.1]</Item>
<Item DocType="" PropName="PatientID" >[PID:3().1]</Item>
<Item DocType="" PropName="PatientID" >[PID:4().1]</Item>
<Item DocType="" PropName="PatientName" >[PID:5()]</Item>
<Item DocType="" PropName="PatientAcct" >[PID:18.1]</Item>
<Item DocType="" PropName="Order#" >[ORC:2.1]</Item>
<Item DocType="" PropName="Order#" >[SCH:26.1]</Item>
<Item DocType="" PropName="Order#" >[ZOR:1]</Item>
<Item DocType="" PropName="Accession#" >[ORC:3.1]</Item>
<Item DocType="" PropName="SIUVisitType">[AIS():3.1]</Item>
<Item DocType="" PropName="SIUProvider#">[AIP():3.1]</Item>
</Items>
}
Storage Default
{
<Data name="HL7SearchTableDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
</Data>
<DataLocation>^osuwmc.HL7SearchTableD</DataLocation>
<DefaultData>HL7SearchTableDefaultData</DefaultData>
<ExtentSize>4000000</ExtentSize>
<IdLocation>^osuwmc.HL7SearchTableD</IdLocation>
<IndexLocation>^osuwmc.HL7SearchTableI</IndexLocation>
<StreamLocation>^osuwmc.HL7SearchTableS</StreamLocation>
<Type>%Library.CacheStorage</Type>
}
}
Yeah tracking down the messages is the hardest part in trying to figure out what is causing it. I am trying to hunt down the problems by using the TimeCreated from EnsLib.HL7.Message and looking for messages around the timeframe of the message in question.
Others have told us that a message always needs to go somewhere, so does that mean if we use a "WHEN" statement within a Router that we should use OTHERWISE too if the message hits the rule but it is not used?
I am not sure I am following what you are trying to do. In my experience with calling stored procs from an external SQL database, I have always returned a RETURN value to tell me if the procedure executed successfully.
I have done a few cases that MS SQL Server assigned a Identity value after the stored procedure executed. In that case I define the output as Output pResponse As EnsLib.SQL.Snapshot within the Method definition, then I will return/loop through the EnsLib.SQL.Snapshot within the Business Process to get the value I need.
Method FetchHospitalEntityKSp(pRequest As osuwmc.CPD.DataStructures.FetchHospitalEntityK, Output pResponse As EnsLib.SQL.Snapshot) As %Status
{
set SPQuery = "{ ?= call CPD.dbo.usp_Interfaces_Fetch_HospitalEntityK_Ens(?) }"
s parm=2
s parm(1,"SqlType")=$$$SQLVARCHAR
s parm(1,"IOTypes")=$$$SQLPARAMOUTPUT
s parm(2)=pRequest.Entity
s parm(2,"SqlType")=$$$SQLVARCHAR
s parm(2,"IOTypes")=$$$SQLPARAMINPUT
set tSC = ..Adapter.ExecuteProcedureParmArray(.FetchEntities,.outputs,SPQuery,"oi",.parm)
if tSC = 1
{
set pResponse = FetchEntities.GetAt(1)
}
quit tSC
}
If the Stored Procedure is just returning a RETURN statement then you should not need to define it in tQuery. So I am imagining that it would look something like this... If you are returning something other than just the RETURN statement from the Stored Procedure it will be a little different.
set arrParam = 2
//for input and output parameter
set arrParam(1,"IOType") = 2
set arrParam(1,"SqlType") = $$$SqlLongVarchar
//for input parameter
set arrParam(2)= Message
set arrParam(2,"SqlType") = $$$SqlLongVarchar
set arrParam(2,"CType") = $$$SqlWChar
set arrParam(2,"IOType") = 1
set arrParam(2,"Prec") = 8000
set arrParam(2,"LOB") = 1
set arrParam(2,"UseLOBLen")= 1
set arrParam(2,"SqlTypeName") = "TEXT"
Set tQuery="{?=call dbo.sp_insertMessage(?) }"
Set tSC = ..Adapter.ExecuteProcedureParmArray(.InsertMessage,.tOutParams,tQuery,"oi",.arrParam)
When I click on "ClassSize query" I am getting a 404 error. Can this link be updated so I can duplicate this?
I am receiving the same error trying to launch Studio from HealthShare Health Connect IRIS 2022.2 from my local PC to connect to the server. So we can't have two versions of Intersystems running on the same PC. I have both HealthShare HealthConnect 2018.1.3 and Health Connect IRIS 2022.2?
It looks like the Private Key is not encrypted as I am not seeing
-----BEGIN ENCRYPTED PRIVATE KEY-----
this is what I am seeing...
-----BEGIN RSA PRIVATE KEY-----
So that is probably my issue. Thanks
I generated the Key and CSR from openssl on the Red Hat server. I sent the CSR to our server folks for them to generate the Cert.
SSL/TLS configuration: %SuperServer
02/28/22-14:48:42:680 (770636) 0 [Generic.Event]
TLS enabled versions, minimum: 16, maximum: 32
02/28/22-14:48:42:680 (770636) 0 [Generic.Event]
Cipher list for TLSv1.2 and below: ALL:!aNULL:!eNULL:!EXP:!SSLv2
02/28/22-14:48:42:680 (770636) 0 [Generic.Event]
Ciphersuites for TLSv1.3: TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256
02/28/22-14:48:42:680 (770636) 0 [Generic.Event]
Certificate file: /etc/pki/tls/certs/ssl_vd01.crt
02/28/22-14:48:42:680 (770636) 0 [Generic.Event]
Private key file: /etc/pki/tls/private/ssl_vd01.key
02/28/22-14:48:42:681 (770636) 0 [Generic.Event]
error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
02/28/22-14:48:42:681 (770636) 0 [Generic.Event]
error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error
02/28/22-14:48:42:681 (770636) 0 [Generic.Event]
error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error
02/28/22-14:48:42:681 (770636) 0 [Generic.Event]
error:0907B00D:PEM routines:PEM_read_bio_PrivateKey:ASN1 lib
02/28/22-14:48:42:681 (770636) 0 [Generic.Event]
error:140B3009:SSL routines:SSL_CTX_use_RSAPrivateKey_file:PEM lib
02/28/22-14:49:02:170 (770555) 0 [Utility.Event] REDEBUG: new netdebugflags FF
02/28/22-18:01:15:093 (759932) 1 [Utility.Event] [SYSTEM MONITOR] DBLatency(/ensemble/DEV/mgr/iristemp/) Warning: DBLatency = 2075.368 ( Warnvalue is 1000).
02/28/22-18:11:45:685 (759932) 0 [Utility.Event] [SYSTEM MONITOR] DBLatency(/ensemble/DEV/
So it sounds like the Key and CSR/Cert wasn't generated correctly.
Right I had formatted it for PEM not pkcs12 which is why I was confused. I can't remember what openssl command I used to create the key but pkcs12 was not involved.
I think it was something like openssl req -newkey x509 rsa:4096 -keyout PRIVATEKEY.key -out MYCSR.csr -config my_config.cnf
When I downloaded the returned certificate file it was in PEM format.
Private key file: /etc/pki/tls/private/ssl_vd01.key
02/28/22-14:48:35:457 (770618) 0 [Generic.Event]
error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
02/28/22-14:48:35:457 (770618) 0 [Generic.Event]
error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error
02/28/22-14:48:35:457 (770618) 0 [Generic.Event]
error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error
02/28/22-14:48:35:457 (770618) 0 [Generic.Event]
error:0907B00D:PEM routines:PEM_read_bio_PrivateKey:ASN1 lib
02/28/22-14:48:35:457 (770618) 0 [Generic.Event]
error:140B3009:SSL routines:SSL_CTX_use_RSAPrivateKey_file:PEM lib
Did I miss something in the documentation that the private key needed to be pkcs12 format? This is the first time I have seen this requirement.
I am also getting SSL/TLS error in SSL_connect(), SSL_ERROR_SYSCALL: I/O error (104) but this time it is in IRIS HealthShare HealthConnect 2021.2 on RedHat using Apache and the Web Gateway. As soon as I turn on the SSL/TLS within the server settings on the Gateway I am getting the error. But as soon as I switch it back to password I am able to get the "Test Server Connection" to work.
I have tried what it suggested but now I am getting the following error and can not start apache...
[root@xxxxxxx conf.modules.d]# apachectl configtest
[Mon Feb 28 11:00:01.370361 2022] [so:warn] [pid 762836:tid 140580690286912] AH01574: module cgid_module is already loaded, skipping
AH00534: httpd: Configuration error: More than one MPM loaded.
[root@int-lxiris-vd01 conf.modules.d]#
I also have noticed as soon as I turned on SSL/TLS on the web gateway I start getting
but as soon as I turn it off it works again. Is it truly secure at that point?
Very minimal since this is a development system and has not been released to my group as of yet. At the most maybe 2 or 3 users as of right now.
We are also seeing a similar issue when the PDF is over 44 mb.
<foreach property='source.{ORCgrp(1).OBRgrp(1).OBXgrp()}' key='k1' >
<if condition='source.{ORCgrp(1).OBRgrp(1).OBXgrp(k1).OBX:ValueType}="ED"' >
<true>
<assign value='"1"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:SetIDOBX}' action='set' />
<assign value='"ED"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ValueType}' action='set' />
<assign value='"7"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationIdentifier.Identifier}' action='set' />
<assign value='"URL"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationIdentifier.Text}' action='set' />
<assign value='"EXTLRR"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationIdentifier.NameofCodingSystem}' action='set' />
<assign value='"1"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationSubID}' action='set' />
<assign value='"PDF"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).Identifier}' action='set' />
<assign value='source.{ORCgrp(1).OBRgrp(1).OBXgrp(k1).OBX:ObservationValue(1).Text}' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).Text}' action='set' />
<assign value='"PDF"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).NameofCodingSystem}' action='set' />
<assign value='"Base64"' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).AlternateIdentifier}' action='set' />
<assign value='##class(%Stream.GlobalCharacter).%New()' property='tStream' action='set' />
<assign value='source.GetFieldStreamRaw(.tStream,"ORCgrp(1).OBRgrp(1).OBXgrp("_k1_").OBX:5.5",.tRemainder)' property='tSC' action='set' />
<assign value='target.StoreFieldStreamRaw(tStream,"ORCgrp(1).OBRgrp(1).OBXgrp("_1_").OBX:5.5",tRemainder)' property='tSC' action='set' />
<assign value='""' property='$P(tRemainder,"|",11)' action='set' disabled='1' />
<assign value='..replace(..ReplaceStr(target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue()}),"VASC^IMAGE/PDF^BASE64^","PDF^^PDF^Base64^")' property='target.{ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue()}' action='set' disabled='1' />
</true>
</if>
</foreach>
Did anyone come up with solution to this issue?
With upgrading to 2021.2 and moving to Red Hat servers we decided to pursue securing the management portal. I have read the documentation but I am still confused on how this should work.
I have installed Apache and a standalone Web Gateway. Does this mean I need to stop the Private Web Gateway that was installed with IRIS? How do I get calls to the Management Portal to go through the standalone Web Gateway? I am having issues trying to connect the parts.
Has anyone installed Apache and the standalone Web Gateway on the same server (Red Hat 8) that IRIS is running on? How did you configure it?
I do have the option of looking in Studio, would I look at the class file for the entire production or do I need to go through all cls files?
Yeah unfortunately I am unable to get Docker Desktop working inside of WSL2. There is some limitation inside of my Virtual Machine that is not letting me install/run it.
Thanks
Scott
How do I install Intersystems IAM manager without using a docker container?
So how do you know which is best to use? Currently we are using EDI to ingest an XML file from WorkDay, but we are running into throughput issues, so I was thinking it might be related to the service. We take the ingested data and put it into a class file, using a BPL and DTL, that is executed using a stored procedure to insert the data into a MS SQL table.
I am confused so bare with me... We currently use EnsLib.EDI.XML.Service.FileService to read the data and send it to a BPL which we just insert the data elements into the parameters for the stored procedure call. Are you saying we need to add another step in between? Is the SAX Parser only part of IRIS? We are still on Healthshare 2018.1.3 for the time being.
The documentation doesn't always give clear views on how it should be setup within the GUI. I tried looking for an example in ENSDEMO but did not see one. Do you have an example?
I believe the bottleneck is in the BPL with the sheer quantity/format of records.
I have done several BPL's that take either flat file data, or HL7 messages and insert them into SQL tables using a JDBC Stored Procedure call.
Looking over the Adapter you mention, how is that different than just inserting the data into a stored procedure to do the insert? It appears that you are creating the "Dynamic" SQL statement in the class file to be sent and executed. In the past I have tried making "Dynamic" SQL statements through a JDBC call and it slows the process down, because the SQL statement will have to be built in SQL before it executes. With Stored Procedures the SQL statement is already on the MS SQL database so it just needs to pass the variables, and doesn't have to add that extra step of validating, and building the SQL query before execution.
I do something similar to what you are trying to do, I Decode the PDF, save the PDF locally, and return a path to the DTL.
Several on the developer community helped me figure this out...
ClassMethod DecodeBase64HL7ToFile(base64 As %Stream.GlobalBinary, Ancillary As %String, FileName As %String) As %String
{
set ArchDir = "/ensemble/data/transfer/AncillaryPDF/"
set ArchAncDir = ArchDir_Ancillary_"/"
set FaxDateDir = ArchAncDir_$PIECE($ZDATE($HOROLOG,7)," ",1)_"-"_$PIECE($ZDATE($HOROLOG,7)," ",2)_"-1/"
if '##class(%Library.File).DirectoryExists(ArchDir)
{
do ##class(%Library.File).CreateDirectory(ArchDir)
}
if '##class(%Library.File).DirectoryExists(ArchAncDir)
{
do ##class(%Library.File).CreateDirectory(ArchAncDir)
}
if '##class(%Library.File).DirectoryExists(FaxDateDir)
{
do ##class(%Library.File).CreateDirectory(FaxDateDir)
}
set Oref = ##class(%FileBinaryStream).%New()
///$$$LOGINFO(FaxDateDir_FileName)
set Oref.Filename = FaxDateDir_FileName
Do base64.Rewind()
While 'base64.AtEnd {
set ln = base64.ReadLine()
set lnDecoded = $system.Encryption.Base64Decode(ln)
do Oref.Write(lnDecoded)
}
Do Oref.%Save()
set PDFFilePath = FaxDateDir_FileName
return PDFFilePath
}