Hi Pietro,

Not sure if this will help you but I written a retry mechanisme in the BO with 2 additional settings MaxRetries and RetryWaitSeconds. 

See code below:

Class BO.Rest.PostBodyHeaderAuth Extends EnsLib.REST.Operation
{

Parameter ADAPTER = "EnsLib.HTTP.OutboundAdapter";

Parameter INVOCATION = "Queue";

Property HeaderName As %String(MAXLEN = 1000) [ InitialExpression = "Authorization", Required ];

Property HeaderValue As %String(MAXLEN = 10000) [ InitialExpression = "Bearer", Required ];

Property UseSSL As %Integer [ InitialExpression = 1, Required ];

Property MaxRetries As %Integer [ InitialExpression = 3, Required ];

Property RetryWaitSeconds As %Integer [ InitialExpression = 300, Required ];

Property ContentType As %String(MAXLEN = 300) [ InitialExpression = "application/json; charset=utf-8", Required ];

Parameter SETTINGS = "HeaderName:Auth,HeaderValue:Auth,MaxRetries:Retry,RetryWaitSeconds:Retry,UseSSL:Connection,ContentType:ContentType";

Method PostBodyData(pRequest As BO.Rest.PostBodyHeaderAuth.PostBodyHeaderAuthReq, Output pResponse As BO.Rest.PostBodyHeaderAuth.PostBodyHeaderAuthResp) As %Status
{
      Set tSc	= $$$OK
      
      Set tCounter = 0
      
      While (tCounter <= ..MaxRetries)
      {
        //Create a new %Net.HttpRequest
        Set tHttpRequest	= ##class(%Net.HttpRequest).%New()
            
        //Get the serversetting from the Adapter
        Set tHttpRequest.Server	= ..Adapter.HTTPServer
        Set tHttpRequest.Port		= ..Adapter.HTTPPort
            
        //Set Content-Type
        Set tHttpRequest.ContentType = ..ContentType
      
        //Set Body from Request Object
        Do tHttpRequest.EntityBody.Write(pRequest.Body)
        
        // Set Https Flag
        If (..UseSSL = 1) {
            Set tHttpRequest.Https	= 1
            Set tHttpRequest.SSLConfiguration	= ..Adapter.SSLConfig
        } Else {
            Set tHttpRequest.Https	= 0
        }
          
        //Set the Header value for Authentication
        If ($LENGTH(pRequest.HeaderValue) > 0) {
            Set tSc = tHttpRequest.SetHeader(..HeaderName, pRequest.HeaderValue)
        } Else {
            Set tSc = tHttpRequest.SetHeader(..HeaderName, ..HeaderValue)  
        }
        
        //Set Custom Timeouts from Adapter
        Set tHttpRequest.WriteTimeout = ..Adapter.WriteTimeout
        Set tHttpRequest.Timeout = ..Adapter.ResponseTimeout
        Set tHttpRequest.OpenTimeout  = ..Adapter.ConnectTimeout
            
        If ($LENGTH(pRequest.Url) > 0) { 
            Set tUrl = pRequest.Url
        } Else {
            Set tUrl = ..Adapter.URL
        }
      
        //Create a trace with the complete url
        $$$TRACE(..Adapter.HTTPServer_"/"_tUrl)
            
        //Do the post call
        Set tSc = tHttpRequest.Post(tUrl)
    
        //Create the tHttpResponse object
        #dim tHttpResponse As %Net.HttpResponse
          
        //Set the response object	
        Set tHttpResponse = tHttpRequest.HttpResponse
                  
        //If an technical error has occured
        If ($$$ISERR(tSc)) 
        { 
            $$$TRACE("Error:"_$System.Status.GetErrorText(tSc))
            
        } ElseIf ('$IsObject(tHttpResponse)) 
        {
            $$$TRACE("Invalid HTTP Response Object")
            Set tSc=$$$ERROR($$$EnsErrGeneral, "Invalid HTTP Response Object.")
        } 
        Else 
        {
          ;Build Operation Response
          Set pResponse = ##class(BO.Rest.PostBodyHeaderAuth.PostBodyHeaderAuthResp).%New()
          Set pResponse.HTTPStatusCode = tHttpResponse.StatusCode
          Set pResponse.HTTPStatusLine = tHttpResponse.StatusLine
          
          ;Check the HTTPStatusCode
          Set tSuccess = ##class(Util.Functions).IsSuccess(tHttpResponse.StatusCode)
          
          If (tSuccess) {
            Set tCounter = ..MaxRetries + 1
              Do tHttpResponse.Data.Rewind()
              Set pResponse.HTTPResponseData = tHttpResponse.Data
          } Else {
            $$$TRACE("An error HTTP code has been received. HTTPSCode="_tHttpResponse.StatusCode)  
            Try {
                Do tHttpResponse.Data.Rewind()
                Set pResponse.HTTPResponseData = tHttpResponse.Data
            } Catch exception {}
          }
        }
        
        Set tCounter = tCounter+1
        If (tCounter <= ..MaxRetries) {
            $$$TRACE("Retry: "_tCounter_". Wait for "_..RetryWaitSeconds_" seconds")
            HANG ..RetryWaitSeconds	
        }	  
      }
     return tSc
}
}

Hi All,

The  problem is in HS.FHIRServer.RestHandler

 Class HS.FHIRServer.HC.FHIRInteropAdapter Extends HS.FHIRServer.RestHandler
{ Parameter isInteropAdapter As %Boolean = 1; Parameter ServiceConfigName As %String = "InteropService"; }

For some reason its not allowed to send the bearer token with the unauthenticated application:

 // Access token present on unsecure CSP request is invalid. Otherwise, if access
// token found on secure CSP request then add to FHIR request AdditionalInfo for
// later evaluation by the FHIR service.
If '%request.Secure {
If ($ZConvert($Piece(%request.GetCgiEnv("HTTP_AUTHORIZATION")," ",1),"U") = "BEARER") || ($Get(%request.Data("access_token",1)) '= "") {
Set %response.Status = ..#HTTP401UNAUTHORIZED
Return $$$OK
}
Set accessToken = ""
Else {
// InterSystems FHIRServer policy is to NOT allow passing access token in the
// request URL or form encoded body (either can be found in %request.Data).
If $Get(%request.Data("access_token",1)) '= "" {
Set %response.Status = ..#HTTP401UNAUTHORIZED
Return $$$OK
}
Set accessToken = ##class(%SYS.OAuth2.AccessToken).GetAccessTokenFromRequest(.tSC)
$$$ThrowOnError(tSC)
If accessToken '= "" {
Do tRequest.AdditionalInfo.SetAt(accessToken, "USER:OAuthToken")
Do tRequest.AdditionalInfo.SetAt(hsrestconfig.OAuthClientName, "USER:OAuthClient")
}
}

We're gonna discuss the issue with intersystems but it looks like we need custom programming to make this situation work in the new HC version.

Thank you @Alister Pino and @Julius Kavay for your help.

In this scenario see the final solution below:

ClassMethod MergeDynamicObjects(ObjComplete As %Library.DynamicObject, ObjAddendum As %Library.DynamicObject) [ Final ]
{
  Set obj1 = ObjComplete.%Get("OptOuts")
  Set obj2 = ObjAddendum.%Get("OptOuts")     
  Set OptOuts2Iter = obj2.%GetIterator()
  While OptOuts2Iter.%GetNext(.key , .value ) {
    Do obj1.%Push(value)
  }
  return ObjComplete
}