Scott Roth · Nov 9, 2023 go to post

Since everyone on the team uses the URL that contains the port number of 52773, I was trying to make it possible for them not to have to update their bookmarks they already use. Seamless transition to encrypting the traffic between their web browser and the server.

Scott Roth · Oct 30, 2023 go to post

We have turned off Telnet, and use ssh to connect to our servers, then open a terminal prompt by running...

:>iris session <name space>

There are many different clients out there from Windows Terminal, Cygwin, MobaXTerm, XWin32, even Windows Powershell would work with ssh. It all a matter of preference...

Scott Roth · Oct 26, 2023 go to post

FHIR is still has the reach the level of maturity that 2.3 had. While the technology is nice, it is still more query based than transactional based in my dealings with understanding the flow. How is an application to know a Patient to query if it does not have enough information to begin the query into FHIR.

Scott Roth · Oct 19, 2023 go to post

How do you setup Apache to know the VIP has been moved to one of the other servers? If you include the VIP in the ServerAlias settings in Apache then when a user connects to the VIP, Apache wont know which server to connect to.

Scott Roth · Oct 12, 2023 go to post

How did you configure the web gateway to do this?

Each web gateway is configured to talk to the local Health Connect instance, irrespective of it being primary, secondary or DR at any time.

So, when have to access the primary, we go via the VIP URL -> the request lands on the IIS for the primary instance and that is passed on to the local Health Connect instance.

Scott Roth · Oct 9, 2023 go to post

It is something with the password that is setup during the Install process vs the password that is on the user. I installed IRIS with setting the password as a default, verified that I could get into the Web Gateway Management, but as soon as I changed the password through the Security within the Management portal, I could no longer get into the Web Gateway Management.

So do I have to modify the CSP.ini somehow to tell it to use the LOCAL password, vs the SYSTEM password?

Scott Roth · Oct 6, 2023 go to post

I tracked down the issue to %Service_Login being disabled, as I thought this service was just used for API calls and not internally.

Scott Roth · Oct 6, 2023 go to post

_Ensemble is being called when I try to Enable/Disable/Restart an Object within the namespace,  I don't think it can be changed.

Scott Roth · Oct 6, 2023 go to post

While thinking about this, I am wondering if using an encryption key might be a possible solution as well that way there is limited access to the password, and the key would just have to be regulated to be updated every so often. With using a AD service account, the password still needs to be updated or kept up to date, and still needs to be passed into the shell script for Terminal to open.

I have submitted the following IDEA...

https://ideas.intersystems.com/ideas/DPI-I-466

Scott Roth · Sep 21, 2023 go to post

I have figured out our LDAP configuration to move our users over to use the standard LDAP built in functionality instead of using the ZAUTHENTICATE that I had built.

Scott Roth · Sep 11, 2023 go to post

I rewrote my Response class, however now it is returning that it is successful, but does not display it in the trace viewer. Am I missing something in my Response class?

Class User.REST.Epic.Msg.GetPatientLocationResponse Extends (%Persistent, Ens.Response, %JSON.Adaptor, %XML.Adaptor)

{

Parameter %JSONIGNOREINVALIDFIELD As BOOLEAN = 1;
Parameter XMLNAME = "Patient.GetPatientLocationByVisit2";
Parameter XMLSEQUENCE = 1;
Parameter XMLTYPE = "Patient.GetPatientLocationByVisit2";
Property LastName As %String(%JSONFIELDNAME = "LastName", XMLNAME = "LastName");
Property FirstName As %String(%JSONFIELDNAME = "FirstName", XMLNAME = "FirstName");
Property MiddleName As %String(%JSONFIELDNAME = "MiddleName");
Property Sex As %String(%JSONFIELDNAME = "Sex");
Property DateOfBirth As %String(%JSONFIELDNAME = "DateOfBirth");
Property PatientClass As %String(%JSONFIELDNAME = "PatientClass");
Property EncounterDate As %String(%JSONFIELDNAME = "EncounterDate");
Property ChargeSlipNumber As %String(%JSONFIELDNAME = "ChargeSlipNumber");
Property DepartmentIDs As User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "DepartmentIDs", %JSONINCLUDE = "INPUTONLY");
Property FacilityIDs As User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "FacilityIDs", %JSONINCLUDE = "INPUTONLY");
Property HospitalAccountIDs As User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "HospitalAccountIDs", %JSONINCLUDE = "INPUTONLY");
Property PatientPhoneNumbers As User.REST.Epic.dt.ArrayOfPhone(%JSONFIELDNAME = "PatientPhoneNumbers", %JSONINCLUDE = "INPUTONLY");
Property AttendingPhysician As User.REST.Epic.dt.ArrayOfAttendingPhysician(%JSONINCLUDE = "INPUTONLY");
Property CareTeamPCPs As User.REST.Epic.dt.ArrayOfCareTeamPCP(%JSONINCLUDE = "INPUTONLY");
Property AppointmentSchedules As User.REST.Epic.dt.ArrayOfScheduleProviderReturn(%JSONFIELDNAME = "AppointmentSchedules", %JSONINCLUDE = "INPUTONLY");
Storage Default
{
<Data name="GetPatientLocationResponseDefaultData">
<Subscript>"GetPatientLocationResponse"</Subscript>
<Value name="1">
<Value>LastName</Value>
</Value>
<Value name="2">
<Value>FirstName</Value>
</Value>
<Value name="3">
<Value>MiddleName</Value>
</Value>
<Value name="4">
<Value>Sex</Value>
</Value>
<Value name="5">
<Value>DateOfBirth</Value>
</Value>
<Value name="6">
<Value>PatientClass</Value>
</Value>
<Value name="7">
<Value>EncounterDate</Value>
</Value>
<Value name="8">
<Value>ChargeSlipNumber</Value>
</Value>
<Value name="9">
<Value>DepartmentIDs</Value>
</Value>
<Value name="10">
<Value>FacilityIDs</Value>
</Value>
<Value name="11">
<Value>HospitalAccountIDs</Value>
</Value>
<Value name="12">
<Value>PatientPhoneNumbers</Value>
</Value>
<Value name="13">
<Value>AttendingPhysician</Value>
</Value>
<Value name="14">
<Value>CareTeamPCPs</Value>
</Value>
<Value name="15">
<Value>AppointmentSchedules</Value>
</Value>
</Data>
<DefaultData>GetPatientLocationResponseDefaultData</DefaultData>
<Type>%Storage.Persistent</Type>
}

}
Scott Roth · Sep 11, 2023 go to post

I have been attempting to try to use ZMIRROR (https://docs.intersystems.com/iris20232/csp/docbook/DocBook.UI.Page.cls?KEY=GHA_mirror_set_config#GHA_mirror_set_tunable_params_zmirror_routine) to execute certain scripting when $$NotifyBecomePrimary is kicked off, however it is still a work in progress.

You should be able to call an external script or something to notify you in some fashion that you developed. In our case we have several different notifications available to use via Shell or Perl that could notify us.

Scott Roth · Sep 8, 2023 go to post

I updated my User.REST.Epic.Msg.GetPatientLocationResponse that points to User.REST.Epic.dt.Response with the order in which fields are being returned in the JSON that I saw using postman. However now I am receiving...

ERROR #9404: Unexpected field in input, LastName, using class base mapping.

Method GetPatientLocationVisit2(pRequest As User.REST.Epic.Msg.GetPatientLocationRequest, Output pResponse As User.REST.Epic.Msg.GetPatientLocationResponse) As %Status

{
  #dim tSC As %Status = $$$OK
  set tHTTPRequest = ##class(%Net.HttpRequest).%New()
  set tHTTPRequest.SSLConfiguration = ..Adapter.SSLConfig
  set tHTTPRequest.Https = 1
  set tHTTPRequest.WriteRawMode = 1
  set tHTTPRequest.Port = ..Adapter.HTTPPort
  //Do tHTTPRequest.SetHeader("Authorization",..Adapter.Credentials)
  Do tHTTPRequest.SetHeader("Host",..Adapter.HTTPServer)
  Do tHTTPRequest.SetHeader("Accept-Encoding","application/json")
  Do tHTTPRequest.SetHeader("Content-Type","application/json")
  Do tHTTPRequest.SetHeader("Epic-Client-ID",..EpicClientID)
  Do tHTTPRequest.EntityBody.Write()
  do tHTTPRequest.OutputHeaders()
  set tRequest = ##class(%DynamicObject).%New()
  set tRequest.PatientID = pRequest.PatientID
  set tRequest.PatientIDType = pRequest.PatientIDType
  set tRequest.ContactID = pRequest.ContactID
  set tRequest.ContactIDType = pRequest.ContactIDType
  set tRequest.UserID = pRequest.UserID
  set tRequest.UserIDType = pRequest.UserIDType
  set tPayload = tRequest.%ToJSON()

  set tURL= ..Adapter.URL_"/2014/Access/Patient/GETPATIENTLOCATIONBYVISIT2/Visit/Location2"  //..Adapter.URL
  SET tSC = tHTTPRequest.EntityBody.Write(tPayload)
  set tHTTPResponse = ##class(%Net.HttpResponse).%New()
  set tSC = ..Adapter.SendFormDataArray(.tHTTPResponse,"POST",tHTTPRequest,,,tURL)
  set pResponse = ##class(User.REST.Epic.Msg.GetPatientLocationResponse).%New()
  set tSC = pResponse.%JSONImport(tHTTPResponse.Data)
  quit tSC
}
Class User.REST.Epic.Msg.GetPatientLocationResponse Extends (Ens.Response, %JSON.Adaptor)
{
Property Results As list Of User.REST.Epic.dt.Response;
Storage Default
{
<Data name="GetPatientLocationResponseDefaultData">
<Subscript>"GetPatientLocationResponse"</Subscript>
<Value name="1">
<Value>Results</Value>
</Value>
</Data>
<DefaultData>GetPatientLocationResponseDefaultData</DefaultData>
<Type>%Storage.Persistent</Type>
}
}
Class User.REST.Epic.dt.Response Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{

Parameter %JSONIGNOREINVALIDFIELD As BOOLEAN = 1;
Property LastName As %String(%JSONFIELDNAME = "LastName", MAXLEN = "");
Property FirstName As %String(%JSONFIELDNAME = "FirstName", MAXLEN = "");
Property MiddleName As %String(%JSONFIELDNAME = "MiddleName", MAXLEN = "");
Property Sex As %String(%JSONFIELDNAME = "Sex", MAXLEN = "");
Property DateOfBirth As %String(%JSONFIELDNAME = "DateOfBirth", MAXLEN = "");
Property PatientClass As %String(%JSONFIELDNAME = "PatientClass", MAXLEN = "");
Property EncounterDate As %String(%JSONFIELDNAME = "EncounterDate", MAXLEN = "");
Property HospitalService As %String(%JSONFIELDNAME = "HospitalService", MAXLEN = "");
Property ChargeSlipNumber As list Of %String(%JSONFIELDNAME = "ChargeSlipNumber", MAXLEN = "");
Property DepartmentIDs As list Of User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "DepartmentIDs");
Property FacilityIDs As list Of User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "FacilityIDs");
Property HospitalAccountIDs As list Of User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "HospitalAccountIDs");
Property PatientPhoneNumbers As list Of User.REST.Epic.dt.ArrayOfPhone(%JSONFIELDNAME = "PatientPhoneNumbers");
Property AttendingPhysicians As list Of User.REST.Epic.dt.ArrayOfAttendingPhysician(%JSONFIELDNAME = "AttendingPhysicians");
Property ProviderTeams As list Of User.REST.Epic.dt.ArrayOfProviderTeam(%JSONFIELDNAME = "ProviderTeams");
Property CareTeamPCPs As list Of User.REST.Epic.dt.ArrayOfCareTeamPCP(%JSONFIELDNAME = "CareTeamPCPs");
Property AppointmentSchedules As list Of User.REST.Epic.dt.ArrayOfScheduleProviderReturn(%JSONFIELDNAME = "AppointmentSchedules");
Storage Default
{
<Data name="ResponseState">
<Value name="1">
<Value>LastName</Value>
</Value>
<Value name="2">
<Value>FirstName</Value>
</Value>
<Value name="3">
<Value>MiddleName</Value>
</Value>
<Value name="4">
<Value>Sex</Value>
</Value>
<Value name="5">
<Value>DateOfBirth</Value>
</Value>
<Value name="6">
<Value>PatientClass</Value>
</Value>
<Value name="7">
<Value>EncounterDate</Value>
</Value>
<Value name="8">
<Value>HospitalService</Value>
</Value>
<Value name="9">
<Value>ChargeSlipNumber</Value>
</Value>
<Value name="10">
<Value>DepartmentIDs</Value>
</Value>
<Value name="11">
<Value>FacilityIDs</Value>
</Value>
<Value name="12">
<Value>HospitalAccountIDs</Value>
</Value>
<Value name="13">
<Value>PatientPhoneNumbers</Value>
</Value>
<Value name="14">
<Value>AttendingPhysicians</Value>
</Value>
<Value name="15">
<Value>ProviderTeams</Value>
</Value>
<Value name="16">
<Value>CareTeamPCPs</Value>
</Value>
<Value name="17">
<Value>AppointmentSchedules</Value>
</Value>
</Data>
<State>ResponseState</State>
<StreamLocation>^User.REST.Epic.dt.ResponseS</StreamLocation>
<Type>%Storage.Serial</Type>
}

}
Scott Roth · Sep 8, 2023 go to post

it seems the Test LDAP is failing on... the search for SamAccountName, as search AD user of ensemble.Services is showing authenticated and my Base DN for the user search passed.

Search user ensemble.Services,DC=OSUMC,DC=EDU authenticated
Searching for user roth16, using SamAccountName=roth16
SearchExts error: 1 - Operations error
Test completed

The BaseDN and the Nested Group Search BaseDN is the same that I used in my ZAUTHENTICATE. I shouldn't have to remove the ZAUTHENTICATE for the Test LDAP to run should I?

Scott Roth · Sep 7, 2023 go to post

Is the attributes listed in the documentation the only attributes that can be configured in /etc/iscagent/iscagent.conf? Does turning the logging help with troubleshooting connection issues on the Arbiter?

Scott Roth · Sep 7, 2023 go to post

Well found that my Certificate had expired, so I replaced the certificate with one that I had gotten created for something else I was working on. But it is still not working through the LDAP Test or when I attempt to sign on with my AD account...

Using Test LDAP Authentication I am receiving... SearchExts error: 1 - Operations error

When I attempt to sign into the port with my AD account I am getting the following...

Error message: ERROR #798: Password login failed
ERROR #838: User roth16 does not exist
ERROR #798: LDAP login failed
ERROR #5002: ObjectScript error: <ILLEGAL VALUE>LDAPLogin+47^%SYS.LDAP
Web Application: /csp/sys
$I: |TCP|1972|2013912
$P: |TCP|1972|2013912

Since I moved from Delegated Sign on using ZAUTHENTICATE to LDAP do I need to remove my ZAUTHENTICATE? or does the LDAP functionality know not to use ZAUTHENTICATE?

Scott Roth · Aug 28, 2023 go to post

At the Java Gateway Service, I have specified the following JVM Args

-d64 -XX:+DisableExplicitGC -XX:+AggressiveOpts

At the %JDBCServer level, I have specififed 

-d64 -Xmx1024m -XX:+DisableExplicitGC -Xss512k

I have often asked for Best Practices but have not had much response. You have to play with the settings as you go...

Scott Roth · Aug 28, 2023 go to post

When I attempted that...

ROUTINE ZAUTHENTICATE
ZAUTHENTICATE(ServiceName,Namespace,Username,Password,Credentials,Properties) PUBLIC {

#include %occErrors
  
#include %sySecurity
 
 //Make sure we have an error trap to handle unexpected errors
 s $ZT="Error"
 s Name=$zcvt(Username,"U")
 s Name=$p(Username,"@",1)
 s UserRecord=$g(^USERS(Name))
 i UserRecord="" q $SYSTEM.Status.Error($$$UserDoesNotExist,Username)
 d $System.Security.Users.ImpersonateUser()
 s $ZE="No ZAUTHENTICATE routine found" g Error
 q $SYSTEM.Status.OK()
Error //Handle any COS errors here
 s $zt=""
 q $SYSTEM.Status.Error(5002 /*$$$CacheError*/,$ze)
 }
GetCredentials(ServiceName,Namespace,Username,Password,Credentials) Public {
#include %occErrors
#include %sySecurity
#include %sySite
#include %syLDAP
#include %occErrors    
    
    Quit $SYSTEM.Status.Error($$$GetCredentialsFailed)

}
#include %occErrors
#include %sySecurity
#include %sySite
#include %syLDAP
#include %occErrors
#define LDAPServer $Get(^OSUMCLDAP("Server"))
#define WindowsLDAPServer 1
#define WindowsCacheClient 0
#define UseSecureConnection 1
#define UnixCertificateFile ##class(%Library.File).ManagerDirectory()_"LDAPKeyStore/ProdAll.pem"
#define WindowsBaseDN "dc="_$Get(^OSUMCLDAP("Domain"))_",dc=edu"
#define WindowsFilter "sAMAccountname"
#define WindowsAttributeList $lb("displayName","department","mail")

 w !,"Initializing LDAP connection to "_$$$LDAPServer,!
 Read !,"Username: ",Username
 Read !,"Password: ",Password
 
 //Make sure we have an error trap to handle unexpected errors
 s $zt="Error"
 
 s Status = 0
 i Password="" {
         s Status = $SYSTEM.Status.Error($$$UserInvalidPassword)
        g Error
 }

 i $$$WindowsLDAPServer{
    s AdminDN="CN="_$Get(^OSUMCLDAP("User"))_",OU=Authentication Accounts,DC="_$Get(^OSUMCLDAP("Domain"))_",DC=edu"
    s AdminPW=$Get(^OSUMCLDAP("Pass"))
 }
 
 #;The following line sets up the internal LDAP structures. 
 i $$$ISWINDOWS,$$$UseSecureConnection {
    s LD=##Class(%SYS.LDAP).Init($$$LDAPServer,$$$LDAPPORT)
 } else {
     s LD=##Class(%SYS.LDAP).Init($$$LDAPServer)
 }

 i LD=0 {
    s Status=##Class(%SYS.LDAP).GetLastError()
    s Status="Init error: "_Status_" - "_##Class(%SYS.LDAP).Err2String(Status)
    g Error
 }
 s Status=##Class(%SYS.LDAP).SetOption(LD,$$$LDAPOPTXTLSCACERTFILE,$$$UnixCertificateFile)
 i Status'=$$$LDAPSUCCESS{
     s Status ="ldap_SetOption(Certificate) error: "_Status_" - "_##Class(%SYS.LDAP).Err2String(Status) 
     #;w Status,!
     g Error
 }.....

I am getting the following error when I attempt to use my AD account...

Error message: ERROR #798: Delegated login failed
ERROR #1403: Routine ZAUTHENTICATE requires the following parameters: (ServiceName,Namespace,Username,Password,.Credentials,.Properties)

If I change Quit $SYSTEM.Status as OK instead of ERROR I get a SYSTEM UNAVAILABLE message.

Scott Roth · Aug 23, 2023 go to post

The issue was that I was trying to call GetCredentials within the ZAUTHENTICATE{}, if I move GetCredentials outside of }, the Delegation Authentication no longer works and I get...

Event Data Error message: ERROR #798: Delegated login failed
ERROR #822: Access Denied
Web Application: /csp/sys
$I: |TCP|1972|1659953
$P: |TCP|1972|1659953

its sort of like...

ZAUTHENTICATE(ServiceName,Namespace,Username,Password,Credentials,Properties) PUBLIC {

#include %occErrors
#include %sySecurity
#include %sySite
#include %syLDAP
#include %occErrors....

}

GetCredentials(ServiceName,Namespace,Username,Password,Credentials) Public {

  // For console sessions, authenticate as _SYSTEM.
  If ServiceName="%Service_Console" {
    Set Username="_SYSTEM"
    Set Password="SYS"
    Quit $SYSTEM.Status.OK()
  }

  // For a web application, authenticate as AdminUser.
  If $isobject($get(%request)) { 
    If %request.Application="/csp/samples/" {
      Set Username="AdminUser"
      Set Password="Test"
      Quit $System.Status.OK()
    }

  }

  // For bindings connections, use regular prompting.
  If ServiceName="%Service_Bindings" {
    Quit $SYSTEM.Status.Error($$$GetCredentialsFailed)
  }  // For all other connections, deny access.
  Quit $SYSTEM.Status.Error($$$AccessDenied)
}

When GetCredentials is called I want it to use the code in ZAUTHENTICATE, so what is the proper format or order that this needs to be done to make this happen...

Scott Roth · Aug 21, 2023 go to post

Double check that the JDBC 12.2.0 driver has the appropriate permissions, and is still compatible with SQL 2005. It doesn't look like that driver is compatible anymore with 2005. 

Microsoft JDBC Driver Support Matrix

Might need to use the jTDS driver but it has it own flaws..jTDS Driver

You can try testing the connection via Terminal..https://docs.intersystems.com/iris20232/csp/documatic/%25CSP.Documatic.cls?LIBRARY=%25SYS&CLASSNAME=%25SYSTEM.SQLGateway by getting the connection and using TestConnection() to see if it will give you a more verbose output or errors to variables.

Scott Roth · Aug 10, 2023 go to post

Thanks for the suggestion. 

I was able to find the following error...

ERROR #9404: Unexpected field in input, LastName, using class base mapping.

It shouldn't matter the order in which the Object Class was defined would it?

as my Base class references another Class

class User.REST.Epic.Msg.GetPatientLocationResponse Extends (Ens.Response, %JSON.Adaptor)
{
Property Results As list Of User.REST.Epic.dt.Response;
}
Class User.REST.Epic.dt.Response Extends (%SerialObject, %XML.Adaptor, %JSON.Adaptor)
{
Property AppointmentSchedules As User.REST.Epic.dt.ArrayOfScheduleProviderReturn(%JSONFIELDNAME = "AppointmentSchedules");
Property AttendingPhysicians As User.REST.Epic.dt.ArrayOfAttendingPhysician(%JSONFIELDNAME = "AttendingPhysicians");
Property CareTeamPCPs As User.REST.Epic.dt.ArrayOfCareTeamPCP(%JSONFIELDNAME = "CareTeamPCPs");
Property ChargeSlipNumber As %String(%JSONFIELDNAME = "ChargeSlipNumber", MAXLEN = "");
Property DateOfBirth As %String(%JSONFIELDNAME = "DateOfBirth", MAXLEN = "");
Property DepartmentIDs As User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "DepartmentIDs");
Property EncounterDate As %String(%JSONFIELDNAME = "EncounterDate", MAXLEN = "");
Property FacilityIDs As User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "FacilityIDs");
Property FirstName As %String(%JSONFIELDNAME = "FirstName", MAXLEN = "");
Property HospitalAccountIDs As User.REST.Epic.dt.ArrayOfIDType(%JSONFIELDNAME = "HospitalAccountIDs");
Property HospitalService As %String(%JSONFIELDNAME = "HospitalService", MAXLEN = "");
Property LastName As %String(%JSONFIELDNAME = "LastName", MAXLEN = "");
Property MiddleName As %String(%JSONFIELDNAME = "MiddleName", MAXLEN = "");
Property PatientClass As %String(%JSONFIELDNAME = "PatientClass", MAXLEN = "");
Property PatientPhoneNumbers As User.REST.Epic.dt.ArrayOfPhone(%JSONFIELDNAME = "PatientPhoneNumbers");
Property ProviderTeams As User.REST.Epic.dt.ArrayOfProviderTeam(%JSONFIELDNAME = "ProviderTeams");
Property Sex As %String(%JSONFIELDNAME = "Sex", MAXLEN = "");
}

and in User.REST.Epic.dt.Response definitely does not have LastName listed first, but in the JSON result I am seeing it listed as the first Property.

{"LastName":.......}

Scott Roth · Aug 10, 2023 go to post

@Ashok Kumar T 
So, I tried...

 set tSC = ..Adapter.SendFormDataArray(.tHTTPResposne,"POST",tHTTPRequest,,,tURL)
 set pResponse = ##class(User.REST.Epic.Msg.GetPatientLocationResponse).%New()
 set dynObject = {}.%FromJSON(tHTTPResposne.Data)
 do pResponse.%JSONImport(dynObject)
 
and tried..
set tSC = ..Adapter.SendFormDataArray(.tHTTPResposne,"POST",tHTTPRequest,,,tURL)
set pResponse = ##class(User.REST.Epic.Msg.GetPatientLocationResponse).%New()
do pResponse.%JSONImport(tHTTPResposne.Data)
But within the trace viewer GetPatientLocationResponse comes up blank

Scott Roth · Aug 9, 2023 go to post

Would @Eduard Lebedyuk solution work for an Object Class that contains Dynamic Arrays? My Response from an API call contains Dynamic Arrays and I am looking for a solution to take the JSON Response and copy the data into a Object Class that has Dynamic Arrays.

Scott Roth · Aug 4, 2023 go to post

Not sure I follow... I do all the SetHeader lines, then call  Do tHTTPRequest.EntityBody.Write() is that not writting the headers to tHTTPRequest?

    do tHTTPRequest.EntityBody.Write()
    do tHTTPRequest.OutputHeaders()
    set tURL= "/../../../../"  //..Adapter.URL
    set jsonRequest = {"........."}
    SET tSC = tHTTPRequest.EntityBody.Write(jsonRequest.%ToJSON())
    set tHTTPResposne = ##class(%Net.HttpResponse).%New()
    do tHTTPRequest.OutputParams()
    set tSC = ..Adapter.SendFormDataArray(.tHTTPResposne,"POST",,,tHTTPRequest)
Scott Roth · Aug 3, 2023 go to post

The issue was with the code that I was using in my Business Operation that was not calling the SSL Configuration. I have since reverted my Business Operation code back to the more standard code that is described in the Documentation, however I am still running into issues making sure the correct format of the Header is being sent in the REST API call, and how to interpret the JSON that is being returned by the REST API.

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 31, 2023 go to post

Does the error mean that I can't do just a POST, I need to use SendFormArray?

Here is my Test code...

Scott Roth · Jul 31, 2023 go to post

I enabled DEBUG = 2 on EnsLib.HTTP.OutboundAdapter, but I am still not seeing the entire Request message being sent within the Foreground display that pops up when I execute the Test. 

I was able to $$$LOGINFO(tHTTPRequest.OutputHeaders()) and verified that the header segment is being sent, but it is still throwing a 403 Forbidden error back at me.