Category Archives: BizTalk

HL7 FHIR JSON decoding in BizTalk

HL7 FHIR represents the next generation healthcare interoperability standard and tries to combine the good stuff from older standards yet leveraging (somewhat) modern things like JSON, XML, HTTP and REST.

With BizTalk you can use the XML-schemas found on the main FHIR site. As BizTalk is all about XML it’s a perfect match.

A side note is that FHIR does not use any versioning in its namespace which will lead to problems if you need more than one version deployed. As usual this can be solved by modifying the namespace in and out of BizTalk using a namespace altering pipeline component.

FHIR JSON

While FHIR resources can be represented in XML they also can come dressed in JSON. Lets have a look at how we can handle that in BizTalk.

If we try to use the out-of-the-box pipeline components in BizTalk 2013 R2 for JSON –> XML conversion (or any other non-FHIR aware json decoder) the generated XML will not conform with the the FHIR-schemas and specification. The differences are highlighted here http://hl7.org/fhir/json.html#xml but two key ones are:

  • How FHIR resource type are defined.
    • In XML its the actual root-node name
    • In JSON its the ‘resourceType’ field.
  • Values are normally placed in a xml attribute instead of in the elements.

Lets look at a simplified example with a FHIR “Encounter” in JSON and HTTP POST it to a BizTalk (WCF-WebHttp) ReceiveLocation using a pipeline with the new and out-of-the-box BizTalk 2013R2 JSON Decoder.

The source json document used

The source json document used

After the pipeline the XML looks like this:

Several problems. The ResourceType element should not exist and the values should be placed inside value xml attributes.

Several problems. The ResourceType element should not exist and the values should be placed inside value xml attributes.

This does NOT match the FHIR schema.

Solution

To solve this we need a “FHIR aware” JSON to XML Decoder. Luckily there is a great open source one for .NET called .NET API for HL7 FHIR. It´s a really feature rich API that can do a lot more than just FHIR JSON and XML conversion!

Lets create a BizTalk pipeline component using .NET API for HL7 FHIR.

As there is a 1:1 correlation between the FHIR ResourceType and xml root node name there is no need to have a configuration parameter for root node name/namespace as we have in the standard JSON decode component. Surely we could have some parameters controlling some aspects of the .NET API for HL7 FHIR but not for this simple proof-of-concept.

Lets see how the XML now looks after a HTTP POST of the source FHIR JSON to the same ReceiveLocation with a pipeline using our new pipeline component.

This looks much better and matches the FHIR XML schemas.

This looks much better and matches the FHIR XML schemas.

Great, we now have a correct FHIR XML instance and we can use it in a BizTalk integration process.

To return/send an instance of a FHIR message we just need to reverse the process by creating a FHIR JSON to FHIR XML BizTalk pipeline component and use that in a send pipeline.

Connecting BizTalk with a mobile app using Azure Appfabric ServiceBus Queues, REST and WCF

The Azure Appfabric Service Bus 1.5 released in September had a feature I really have been looking forward to, durable queues and topics (pub/sub). A cloud based MSMQ ‘like’ queue can help both enterprise-enterprise scenarios as well as in connecting mobile applications with on-premise or cloud-hosted services in a reliable way.

Appfabric Service Bus queues and topics support three programming models:

 

  • .NET API
  • REST API
  • WCF Bindings

While the.NET API offers great control and simplicity, the REST API is supported on almost all platforms. Finally the WCF binding allows .NET programmers not having to learn yet another programming model.

In BizTalk the easiest way to utilize queues and topics are by the WCF binding NetMessagingBinding. Although we surely could use the REST API, just getting the security token out-of-band and keeping it updated, in the WCF-pipeline or elsewhere, would make it a bit cumbersome. NetMessagingBinding will automatically do the token acquisition before accessing the queue/topic.

If both sender and receiver use WCF things are pretty straight forward but if different programming models are used there are some things that need to be addressed.

Scenario

This scenario consists of an Android device which will use REST to send messages to a Service Bus queue then picked up by BizTalk using WCF.

I want the the client to be able to send any data (XML, text or binary) to the same Receive Location in BizTalk.

The Service Bus authorization is claims-based and the Azure Appfabric ACS (Access Control Service) is automatically configured when the Service Bus namespace is created. For simplicity I use ACS Service identities for both BizTalk and Android. In real world, the Android application would probably use something else such as an external IdP together with ACS. More on that in a later post!

Setup

Appfabric 1.5 SDK does not add entries to the machine.config as the previous versions did and we need those in BizTalk. I copy/pasted the necessary lines from http://msdn.microsoft.com/en-us/library/windowsazure/hh148155.aspx. Make sure to add them both to 32 & 64 bit machine.config!

Create a new one-way Receive Location hosted ‘in-process’ using the WCF-Custom adapter.

To be able to receive anything the client sends in the body of the HTTP POST we have to use CustomBinding instead of the pre-configured NetMessagingBinding. This allows us to replace the default TextMessageEncoding binding element with a WebMessageEncodingElement instead. Remember to move it above the NetMessagingTransport element after it is added.

WebMessageEncoding can output XML, JSON or binary data and it defaults to binary. It is possible to control this behavior using a custom WebContentTypeMapper but in this scenario it works fine with the default.

On the general tab enter the address of the already existing queue using the following format :  “sb://{servicebusnamespace}.servicebus.windows.net/{Queue}”.

Authentication and authorization

To receive messages from the queue the authorization will require a claim of type ‘net.windows.servicebus.action’ with value ‘Listen’.

The pre-configured ACS Service Identity ‘owner’ has this claim but it is considered more secure to create a separate identity with a shared symmetric key or an X509 certificate as identification. If you use something different than ‘owner’ do not forget to update the Rule Group to create the claim.

To specify how to authenticate against Service Bus add a TransportClient Endpoint Behavior and specify the identity and shared key to use.

Addressing

By default the NetMessageTransport assumes WCF and that WS-Addressing “To” is present in the message. So if you make a HTTP POST with a non-SOAP body to the queue the WCF trace will show that the adapter throws this exception:

The message with To ” cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver’s EndpointAddresses agree.

To fix this we need to insert the more forgiving Address Filter such as “System.ServiceModel.Dispatcher.MatchAllMessageFilter”. This must be done in a custom behavior extension.

Add this BehaviorExtensionElement to machine.config (32 & 64-bit) in the behaviorExtensions section.

Go to the Receive Location and add this in the EndpointBehaviors.

BizTalk message source

If you would make a REST HTTP POST to the queue now BizTalk would publish the message from WebMessageEncoding and it would look something like this:

<Binary>Qk3WAAAAAAAAADYAAAAoAAAA==</Binary>

This is Base64 encoded data and to fix that we just need to change what BizTalk publishes to the message box.

Go to the Messages tab and enter /*[local-name()=’Binary’] as the Body path expression and Base64 as Node encoding.

Now the WCF adapter will decode and publish everything inside <Binary> to the messagebox where a subscribing orchestration or send port can use the message.

Client

To test it I would use a REST capable test-client such Fiddler, SoapUI or the test client in WCF WEB API

Make a HTTP POST to “https://{servicebusnamespace}.servicebus.windows.net/{QueueName}/Messaging” with the token received from ACS in the authorization http header.

To test the mobile scenario i made a heavily simplified Android application that can send an image from the phones image gallery to the Azure Appfabric Service Bus Queue.

Code handling image-resize and some basic Android stuff are not shown above.

In BizTalk we now get the binary representation of the image published to the messagebox and a simple FILE Sendport makes the image viewable. In a real world scenario, metadata about the image could go as custom http headers or similar.

The takeaway here is that we can use the same queue and BizTalk Receive Location no matter what client or Service Bus API (WCF, REST or .NET) is used on the other side!

BizTalk, Claims and Windows Identity Foundation

Being a fan of Microsoft’s Windows Identity Foundation and its claims and federation based approach to identity i have been interested in how well it fits into BizTalk. Even though BizTalk does not provide any built-in support for the Windows Identity Foundation classes its support for WCF-bindings such as WS2007FederationHttpBinding gives support for WS-Trust and SAML tokens issued by external Security Token Services (STS).

I this scenario a Security Token Service (STS) are used to issue tokens to clients who are using the WS-Trust protocol and the WS2007FederationHttpBinding. The token is passed on to the service hosted in BizTalk. I use an test-STS based on Windows Identity Foundation but any STS supporting the WS-Trust protocol will do.

Claims-based authorization

With BizTalk hosting the service, as in any WCF service hosting scenario, authentication and authorization of the caller are best made in the WCF-channel. As the WIF-based extension ClaimsAuthorizationManager is not an option, i can use the standard WCF ServiceAuthorizationManager to determine access as i do in the simplified example below. In this scenario only persons of 18 years or older, based on a date-of-birth claim inside the received token, will be allowed access.

 

You specify the ServiceAuthorizationManager by adding a ServiceAuthorization behavior and specify the class in the serviceAuthorizationManagerType property as seen below.

Claims inside BizTalk

One obvious thing missing with BizTalk is that the WCF-adapters does not flow the claims received into the BizTalk message-context where it could be used for routing, business-logic or similar. As a comparison, in ASP.NET or WCF an IClaimsPrincipal provided by WIF will contain the claims but in BizTalk they are lost when the message hits the BizTalk messagebox.

In scenarios where access to the claims inside BizTalk are needed one solution is to copy them to the message-context with the help of a custom WCF MessageInspector. This will place the claims into the message header that later, by the use of a brilliant built-in WCF-adapter feature, will automatically get transferred to the message-context. The code below is a simplified example on how this can be done with token claims.

 

I can choose if the values simply should be written to the message context or if they also should be promoted by selecting one of two namespaces when writing the request (see code sample above). Note that if they are to be promoted, which is necessary to do routing, a property-schema must be deployed and the value must not exceed 256 characters.

As with any WCF MessageInspector i also need an EndpointBehavior and BehaviorExtensionElement to place it into the WCF-channel.

To activate it should be registed in the <behaviorExtensions> section in machine.config. Note that if you are running on 64-bit host do this in both 32 & 64 -bit machine.config as the MMC-based BizTalk Server Administration Console always runs in 32-bit. After registration and restarting Administration Console i can add the EndpointBehavior on my ReceiveLocation.

 

Now when a request is received and the message is published in BizTalk messagebox the claims are available in the message context.

They can now be used in orchestrations, pipeline components or for routing purposes.