Question
· Jun 2

EnsLib.SOAP.OutboundAdapter - Bind to Address?

We are attempting to setup an EnsLib.SOAP.OutboundAdapter to send an HL7 message to a vendor hosted AWS site. We have the Certificate from the vendor and defined the TLS setting. However, when we are sending the message we are receiving...

Unable to open TCP/IP socket to server hcis-staging.cbord.com:443

So, we figured it might be a firewall issue. With the TCP Outbound Adapter, we could specify which "Local Interface" to use so that our firewall knew to use the VIP that had has been NAT'd. I don't see this option with the EnsLib.SOAP.OutboundAdapter, so is this possible to do? How can I ensure that when the connection is being made that it is using the VIP address within the message header?

looking at netstat I am not seeing a connection ever being attempted via udp to the URL

How do I ensure that the SOAP request is being bound to the VIP address instead of the local IP Address?

$ZV: IRIS for UNIX (Red Hat Enterprise Linux 8 for x86-64) 2024.1 (Build 267_2U) Tue Apr 30 2024 16:06:39 EDT [HealthConnect:3.5.0-1.m1]
Discussion (7)2
Log in or sign up to continue

You can extend EnsLib.SOAP.OutboundAdapter and add support for LocalInterface and use the "new" adapter in your BO.

With "inspiration" 😁 from EnsLib.HTTP.OutboundAdapter, something like:

Class Community.adapter.SoapOutbound Extends EnsLib.SOAP.OutboundAdapter
{

/// In a multi-homed system, specify which network interface the TCP connection should go through.  An empty value means to use any interface. <br/>
/// To be able to bind to IPv6 interfaces you may need to enable IPv6 in your instance.  This is done in the System Management Portal under 
/// System Administration > Configuration > Additional Settings > Startup, by editing the IPv6 setting.
Property LocalInterface As %String(MAXLEN = 250);
Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}";
Method OnInit() As %Status
{
	Set ..%Client.HttpRequest=##class(%Net.HttpRequest).%New()
	Set ..%Client.HttpRequest.LocalInterface=$ZStrip($P(..LocalInterface,"("),"*W")
	Return ##super()
}

}

I did not tested it, try it and let us know.

Nete, if for any reason you reinstantiate ..%Client.HttpRequest, then you need to set the LocalInterface  property.

Having LocalInterface support in EnsLib.SOAP.OutboundAdapter "out of the box" can be worth an entry in the ideas portal.

I ended up doing..

Class osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port Extends (Ens.BusinessOperation, EnsLib.SOAP.GenericOperation) [ ProcedureBlock ]
{

Parameter ADAPTER = "EnsLib.SOAP.OutboundAdapter";

Property LocalInterface As %String(MAXLEN = 255);

Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}";

Method OnInit() As %Status
{
	set interface = $ZStrip($P(..LocalInterface,"("),"*W")
	set HttpRequest = ##class(%Net.HttpRequest).%New()
	set HttpRequest.LocalInterface = interface
	$$$LOGINFO("CBORDHL7Port OnInit: LocalInterface="_interface)
	QUIT $$$OK
}

The $$$LOGINFO is showing the correct address, but I am still having issues connecting. But thanks

That won't work, you are just setting a %Net.HttpRequest object in a (private) variable called HttpRequest that is destroyed when the method ends.

You need to set/change the %Net.HttpRequest instance contained in the ..%Client property of the adapted AFTER the web service client class is set/instantiated in ..%Client.

Did you had a chance to test the modified adapter I've posted? Maybe tomorrow I'll have time to test it.

Class osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port Extends (Ens.BusinessOperation, EnsLib.SOAP.GenericOperation) [ ProcedureBlock ]
{

Parameter ADAPTER = "EnsLib.SOAP.OutboundAdapter";

Property LocalInterface As %String(MAXLEN = 255);

Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}";

Method OnInit() As %Status
{
	set interface = $ZStrip($P(..LocalInterface,"("),"*W")
    Set ..%Client.HttpRequest=##class(%Net.HttpRequest).%New()
	set ..%Client.HttpRequest.LocalInterface = interface
	QUIT $$$OK
}

I tried using ..%Client but got..

ERROR: osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port.cls

ERROR:  osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port.1(4) : MPP5376 : Method or Property '%Client' does not exist in this class.

 TEXT:   Set ..%Client.HttpRequest=##class(%Net.HttpRequest).%New()

ERROR:  osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port.1(5) : MPP5376 : Method or Property '%Client' does not exist in this class.

 TEXT:  set ..%Client.HttpRequest.LocalInterface = interface

When I tried to compile.

Another option, in your BO add:

Property LocalInterface As %String(MAXLEN = 255);
Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}";

Then before calling the service (..Adaper.Invoke*()) add this:

	If 'IsObject(..Adapter.%Client.HttpRequest) {
		Set ..Adapter.%Client.HttpRequest=##class(%Net.HttpRequest).%New()
	}
	Set ..Adapter.%Client.HttpRequest.LocalInterface=$ZStrip($P(..LocalInterface,"("),"*W")
	

Edit to add: Why are you extending EnsLib.SOAP.GenericOperation?

For a SOAP BO using EnsLib.SOAP.OutboundAdapter the class signature is supposed to be:

Class osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port Extends Ens.BusinessOperation
 

Still not working right..

Class osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port Extends Ens.BusinessOperation [ ProcedureBlock ]
{

Parameter ADAPTER = "EnsLib.SOAP.OutboundAdapter";

Property LocalInterface As %String(MAXLEN = 255);

Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}";

Method OnInit() As %Status
{
	If 'IsObject(..Adapter.%Client.HttpRequest) {
		Set ..Adapter.%Client.HttpRequest=##class(%Net.HttpRequest).%New()
	}
	Set ..Adapter.%Client.HttpRequest.LocalInterface=$ZStrip($P(..LocalInterface,"("),"*W")
}

Terminating Job 819984 / 'NutritionCBOARDNetMenuSOAP' with Status = ERROR <Ens>ErrException: <SUBSCRIPT>OnInit+1^osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port.1 *IsObject("") -- logged as '-' number - @' If 'IsObject(..Adapter.%Client.HttpRequest) {', %QuitTask=