Scott Roth · Aug 3, 2023 go to post

According to WRC there is a memory leak with the way the Class Path of the driver is being handled. The reason for this issue was that I had the Class Path defined within the SQL Gateway. I thought this was only due to the jTDS driver we were using, but it is an overall issue with any Java Gateway Service. So I updated the Java Gateway service I was using for the Microsoft JDBC Connection for that Database to now have the Class Path of the driver, and I have not seen issues since.

Scott Roth · Jul 20, 2023 go to post

For others I figured out the issue. Had to use the Base64 formatted Certificate Chain (p7b) from Windows ADCS (Active Directory Certificate Service).

  1. Download Base64 p7b to /etc/pki/ca-trust/source/anchors/ in RedHat
  2. Change ownership group to include irisusr
  3. Change permissions to Read (666)
  4. Convert p7b to pem
  • sudo openssl pkcs7 -in xxxxx.p7b -print_certs -out xxxxx.pem

When I went through testing the request I got the following...

DEVCLIN>set request=##class(%Net.HttpRequest).%New()

DEVCLIN>set request.Server = "xxxxxxxxxxxx"

DEVCLIN>set request.Port=443

DEVCLIN>set request.SSLConfiguration="OSUWMC"

DEVCLIN>set request.Https=1

DEVCLIN>set tSC=request.Get("/",2)
HTTP/1.1 200 OK
ACCEPT-RANGES: bytes
CACHE-CONTROL: private
CONTENT-ENCODING: gzip
CONTENT-LENGTH: 467
CONTENT-TYPE: text/html
DATE: Thu, 20 Jul 2023 20:08:54 GMT
ETAG: "b072b0f23afdd01:0"
LAST-MODIFIED: Fri, 02 Oct 2015 17:51:21 GMT
NTCOENT-LENGTH: 701
SERVER: Microsoft-IIS/8.5
X-POWERED-BY: ASP.NET

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>IIS Windows Server</title>
<style type="text/css">
<!--
body {
        color:#000000;
        background-color:#0072C6;
        margin:0;
}

#container {
        margin-left:auto;
        margin-right:auto;
        text-align:center;
        }

a img {
        border:none;
}

-->
</style>
</head>
<body>
<div id="container">
<a href="http://go.microsoft.com/fwlink/?linkid=66138&amp;clcid=0x409"><img src="iis-85.png" alt="IIS" width="960" height="600" /></a>
</div>
</body>
</html
>

Scott Roth · Apr 20, 2023 go to post

I didn't realize I had posted this same error years ago. The answer was in my other post. In the DTL I was setting the Path = tSC which was being used in other ways.

Scott Roth · Apr 10, 2023 go to post

The problem was from having the Port Authority previously setup using the Namespace before it was recreated. Working with WRC, I had to delete the existing Doc DB IRIS Interoperability from Doc DB Applications, remove the existing job from the task manager, and recreate the Task Scheduler job to have it recreated.

Scott Roth · Dec 22, 2022 go to post

Using Ens.Director EnableConfig Item someone in our team wrote a shell script that runs on cron to start and stop objects. Or run it off the scheduler or task schedule. 

Scott Roth · Aug 11, 2022 go to post

Why not use a view instead of a Temporary table? Since Temporary Tables are just Temporary and created at the time of execution how are you setting privs on the Temporary Table.

Scott Roth · Jul 6, 2022 go to post

I am not sure then, maybe a call to WRC would help further as I have not experienced this issue.

Scott Roth · Jul 6, 2022 go to post

An issue I see with the code is with the value you are specifying with ConvertDateTime. If you are sending YYYY-mm-dd your code needs to account for that "%Y-%m-%d" 

set parms(1) = ##class(Ens.Rule.FunctionSet).ConvertDateTime("2022-01-01","%Y-%m-%d","%q(1)")
set parms(2) = ##class(Ens.Rule.FunctionSet).ConvertDateTime("2022-01-05","%Y-%m-%d","%q(1)")

Scott Roth · Jul 6, 2022 go to post

How is the date columns defined in your Stored Procedure class file? 

For example I have a InsertProviderSp class file that represents all of the Parameters of the stored procedure, and within it I have a Property DOB As %TimeStamp. 

My method within my Outbound adapter looks like this....

If you are "hardcoding" the dates within the EnsLib.SQL.OutboundAdapter, you could be able to call the above ConvertDateTime by adding lines to for ##class(Ens.Rule.FunctionSet).ConvertDateTime....

I have many cases where I am inserting, update, or querying data from external MS SQL sources to pull into Ensemble, so let me know if you still need help.

Scott Roth · Jun 27, 2022 go to post

I am not sure which context you are using to populate the Stored Procedure, but if you are using a DTL, I used ..ConvertDateTime((field),"%Y%m%d","%q(1)")

Scott Roth · Jun 6, 2022 go to post

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?

Scott Roth · Apr 13, 2022 go to post

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.

Scott Roth · Mar 24, 2022 go to post

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" ]

{

<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>

}

Storage Default

{

<Value>%%CLASSNAME</Value>

<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>

}

}

Scott Roth · Oct 4, 2021 go to post

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

}

Scott Roth · Nov 16, 2020 go to post

We have used Length many times in Routing rules to check to see if Admit/Discharge date exists. We haven't quite used HL7.{PV1:45} to get the field, we let the system spell it out for us... so instead of HL7.{PV1:45} we allow the system to put it in the nomenclature that it knows the field as.. in this case HL7.{PV1:AdmitDateTime.Time}

Scott Roth · Nov 12, 2020 go to post

Nicole, I believe your problem is with the repeating fields. You can not leave () blank. You will need to use a counter or loop through OBX to look for the individual fields you are looking for.

Scott

Scott Roth · Apr 15, 2020 go to post

I would believe the only way to put a schema filter in would be within your query and not in the connection string.

Scott Roth · Mar 2, 2020 go to post

I found with create a Inbound BS, you can't really use the Delete query as an update statement. Either you place the update statement within your BPL, or truly make the Delete query a Delete query on your inbound service.

Scott Roth · Jan 29, 2020 go to post

Make sure you are also using EnsLib.RecordMap.Operation.BatchFileOperation as your operation and you define the header in it as well. 

Scott Roth · Oct 30, 2019 go to post

I figured it out on my own. 

It did not like

<assign value='source.GetFieldStreamRaw(.tStream,"ORCgrp(1).OBRgrp(1).OBXgrp(k1).OBX:ObservationValue(1).AlternateText}",tRemainder)' property='tSC' action='set' />
 

I had to change it to 

Scott Roth · Oct 14, 2019 go to post

When we were going through our conversion from egate to Ensemble,  it was suggested not to have anymore that 25 rules within a Business Router. Anymore than that caused us severe performance issues when it came to making sure our downstream systems was receiving the messages in time.

Scott Roth

Scott Roth · Sep 19, 2019 go to post

Not sure if this will answer your question or not, but we had to move to the jTDS JDBC driver in order to pass an AD account through a connection.

jdbc:jtds:sqlserver://(server name/port) ;instance=tp;domain=osumc;useNTLMv2=true;cacheMetaData=true;prepareSQL=2;
 

Scott Roth · Mar 7, 2019 go to post

With a little help I have built the following Method to Decode and save off the Encoded pdf but return me the directory that I saved the PDF under....

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
}

Scott Roth · Feb 13, 2019 go to post

the Syntax for MAXLEN was wrong. Instead of MAXLEN(5000) it should of been MAXLEN = 5000

Scott Roth · Feb 6, 2019 go to post

We are still somewhat old school eGate folks in this sense. We send all of our transactions to flat files, then we can use those files to feed in data into the test system if needed. We did this when we moved from eGate to Ensemble to make sure we were getting the same transactions and counts.

Scott Roth · Dec 20, 2018 go to post

Here is the same code but from the Studio (class view)

<assign value='##class(%Stream.GlobalCharacter).%New()' property='tStream' action='set' />
<assign value='source.GetFieldStreamRaw(.tStream,"ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).AlternateText",.tRemainder)' property='tSC' action='set' />
<if condition='..Length($get(tSC))&gt;0' >
<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='"TMSAUDIO"' 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='target.StoreFieldStreamRaw(tStream,"ORCgrp(1).OBRgrp(1).OBXgrp(1).OBX:ObservationValue(1).AlternateText", tRemainder)' property='tSC' action='set' />
<assign value='""' property='$P(tRemainder,"|",11)' action='set' />
</true>
</if>