Tag Archives: UDDI

How to dynamically route a message in the ESB to a static port

5
Filed under BPI
Tagged as , ,

What is the problem? Consider the next Itinerary:

image

A message is received on the on-ramp, it is transformed to our HL7 message and after that send to an Orchestration. In the Orchestration the message parts MSHSegment (Header information) and ZSegments are added as part in a multipart message. This Orchestration is a generic process (service as you wish) for extending HL7 messages. After that the multipart messages must be routed to the off-ramp, which must be connected to the MLLP Adapter (from the Microsoft BizTalk Server HL7 Accelerator).

But, the MLLP Adapter is a static adapter and not dynamic. This means that no property schema is available for the MLLP transport settings (and if it was, the MLLP send adapter is not programmed that way). This means that no custom ESB adapter provider can be created and this means that you can’t use the MLLP Adapter in an ESB solution. You can’t use the MLLP Adapter in the Itinerary, because you can only use dynamic ports, and the MLLP Adapter has no possibilities to configure it dynamically (setting context properties for the transport).

I would like to see that Microsoft add some new features to the HL7 Accelerator: use it in a dynamic solution. But till that time, I’ve to use another way to get the benefits of the ESB Toolkit and thus my Itinerary (which can be successfully validated). Below I will describe my solution.

Because the MLLP Adapter can only be used in a static scenario, I created a static send port. For this solution I used an one-way port, and I don’t care for the ACK and NACK right now (will be a next blog). Because I want to use the power of the ESB Toolkit, I added a filter to my port:

image

I’m using my custom send pipeline with the ESB Dispatcher component, HTAHL7 2.x Assembler component (TrailingDelimiterAllowed on True!) and the ESB Itinerary Cache component:

image

As I mentioned above, you can only use dynamic ports in the off-ramp. So I created a dummy send port (or use an existing one). This dummy port I’m using in my itinerary:

image

Because my off-ramp has now the wrong values for Service Name, Service State and Service Type, I’ve to overwrite them so the filter is working correctly. Because I want to change my routing easily I define those settings in UDDI. I created a service ‘sendfilterformedicalsystemx’ and a binding ‘MyMLLPBackendSystem’:

image

Notice that I only added one instance info. I gave the binding a meaningful name so I can use it in the Itinerary:

image

Don’t forget to add a Category to this binding, else you will receive an exception during testing (see a blog from my earlier this month). It really doesn’t matter now what is in here so I added the transporttype:

image

And as latest in UDDI I add only one Instance Info: microsoft-com:esb:runtimeresolution:endpointconfig . This property has the next values:

image

As you can see, this property contains my filter keys and values for my send port. Now my UDDI service is registered (only for filter properties) I can finish my Itinerary. I can fill in the binding key in my UDDIResolver: uddi:esb:systemx

image

To continue the Itinerary in the ESB the right properties must be set in the Orchestration (note: Itinerary processing takes plance in receive- and send pipelines and Orchestrations). Some are basic and described on the site of Microsoft.

First I execute the next statements to retrieve the Itinerary and the current step:

itinerary = new Microsoft.Practices.ESB.Itinerary.SerializableItineraryWrapper();
itineraryStep = new Microsoft.Practices.ESB.Itinerary.SerializableItineraryStepWrapper();

itinerary.Itinerary = Microsoft.Practices.ESB.Itinerary.ItineraryOMFactory.Create(InboundMsg);
itineraryStep.ItineraryStep = itinerary.Itinerary.GetItineraryStep(InboundMsg);

Because the next service in the Itinerary can be used, the next step must be retrieved:

itinerary.Itinerary.Advance(msgPharma, itineraryStep.ItineraryStep);
//itinerary.Itinerary.Write(msgPharma);

For my scenario the Write is not necessary. From the current service (my UDDI Resolver) I can retrieve my endpoint settings from UDDI and put them on the context of my message, so it will be published to my static send MLLP send port:

resolverDict = Microsoft.Practices.ESB.Resolver.ResolverMgr.Resolve(InboundMsg, itineraryStep.ItineraryStep.ResolverCollection[0]);
filterKeys = resolverDict.Item("Resolver.EndpointConfig");

ServiceName = OrchestrationHelper.GetConfigItem(filterKeys, "ServiceName");
ServiceState = OrchestrationHelper.GetConfigItem(filterKeys, "ServiceState");
ServiceType = OrchestrationHelper.GetConfigItem(filterKeys, "ServiceType");

msgPharma(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceName) = ServiceName;
msgPharma(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceState) = ServiceState;
msgPharma(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceType) = ServiceType;

ResolverMgr.Resolve will resolve my UDDI Service and retrieve all the information I defined. The resolver dictionary will contain my EndPointConfig. Now it is just a matter of getting the right values (split a string) and place them on the context.

As you can see it isn’t that difficult, but I’m still not quiet happy with this solution (dynamic MLLP Adapter is preferable). I hope it gave you an idea how to use UDDI, Itineraries and Static Ports. The next challenge will be to send a message to a MLLP system, receive an ACK/NACK (or nothing), and return this information to the calling system: all of course defined in an Itinerary. I hope to blog about this very soon.

If you have questions, remarks or other ideas please contact me. Thanks for reading.

  • Share/Bookmark

UDDI ArgumentNullException: Value cannot be null

0
Filed under BPI
Tagged as ,

I received the message in the EventLog: Value cannot be null. Parameter name: binding

xlang/s engine event log entry: Uncaught exception (see the ‘inner exception’ below) has suspended an instance of service ‘project.orchestration(782dca1d-7bf7-acae-1545-cb3861ca1a3b)’.
The service instance will remain suspended until administratively resumed or terminated.
If resumed the instance will continue from its last persisted state and may re-throw the same unexpected exception.
InstanceId: 3404f012-f181-4e83-8d45-d9537f40a712
Shape name: ConstructMessage_1
ShapeId: 52a16d91-9de3-494b-8f43-a9a8f0459371
Exception thrown from: segment 1, progress 25
Inner exception: Value cannot be null.
Parameter name: binding
Exception type: ArgumentNullException
Source: Microsoft.Practices.ESB.Resolver.UDDI3
Target Site: Void ExtractBindingCategoryInfo(Microsoft.Practices.ESB.UDDI3.categoryBag, System.String, System.Collections.Generic.Dictionary`2[System.String,System.String])
The following is a stack trace that identifies the location where the exception occured

   at Microsoft.Practices.ESB.Resolver.UDDI3.ResolveProvider.ExtractBindingCategoryInfo(categoryBag categoryBag, String keyPrefix, Dictionary`2 uddiValues)
   at Microsoft.Practices.ESB.Resolver.UDDI3.ResolveProvider.ResolveUddi(String config, String resolver, String keyPrefix, Dictionary`2 resolutionOrig)
   at Microsoft.Practices.ESB.Resolver.UDDI3.ResolveProvider.Resolve(ResolverInfo resolverInfo, XLANGMessage message)
   at Microsoft.Practices.ESB.Resolver.ResolverMgr.Resolve(ResolverInfo info, XLANGMessage message)
   at Microsoft.Practices.ESB.Resolver.ResolverMgr.Resolve(XLANGMessage message, String config)
   at Microsoft.Practices.ESB.Itinerary.OM.V1.ItineraryV1.Advance(XLANGMessage message, IItineraryStep step)
   at BTAHL7Schemas.ChangeHL7.segment1(StopConditions stopOn)
   at Microsoft.XLANGs.Core.SegmentScheduler.RunASegment(Segment s, StopConditions stopCond, Exception& exp)

For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

image

I ran into this problem earlier, see one of my old posts about manually configuring UDDI. In my case I forgot to enter the Category information for the UDDI service in the tab Categories:

image

  • Share/Bookmark

UDDI Configuration – an easier way

0
Filed under BPI
Tagged as , ,

Yesterday I blogged about my second scenario and how to configure a service in UDDI. Because my send ports are dynamic I couldn’t register it in the ESB Management Portal as a service, so I did it the hard way :-) . Another possibility and an easier way is to create a temporarily send port in the BizTalk Administration Console and configure it for your needs (WCF, FILE, etc):

image 

After that you can register this port in UDDI via the ESB Management Portal. Click on Registry and New Registry Entry. Select your application. Find your temporarily port and click publish:

image

On the next screen you can change the settings for your need. When you are finished, then click publish:

image

Open the UDDI portal and navigate to publish:

image

As you can see your service is now available in UDDI and all settings are made for you. If you want you can clean up the categories of your binding (but always leave one in place, doesn’t matter which one). In the BizTalk Administration Console you can delete the port physically. Change your itinerary to use the new UDDI service. Note: the name of the send port is used as binding key, so choose your name wisely ;-)

image

  • Share/Bookmark