When you are developing ESB solutions, you very often need to perform som sort of dynamic service routing.

In this case we had 10 applications, SharePoint, BizTalk, xRm, .net and custom legacy applications, all calling each other. In total approximatly 160 web services and each application needed a more or less complete list of all services, WCF configurations and their URLs. Deploying was always a real mess.

To simplify this we created a single on-ramp, which then forwards the calls to the actual service. Each application then only needed to know 1 endpoint and this also made it easier to implement a generic logging and security setup to comply with various regulations.

With Neuron ESB, it is acturally quite easy to achieve this setup with very low overhead, but it is not very well documented. The key is to set the adressing property:

context.Data.SetProperty(“Addressing”, “To”, serviceUrl);

I will try to describe a more simplified version of the solution.

 

Simplified solution setup

Topics:
ServiceRouting

Parties:
ServiceRouting.Publisher (publish on ServiceRouting)
ServiceRouting. (subscriber on ServiceRouting)

Processes:
ServiceRouting.RouteRequest (used on ServiceRouting.Publisher OnSend)

Endpoints:
ServiceRouting.OnRamp
ServiceRouting.OffRamp

EnvironmentVariables:
One per service in the format Service.ServiceName.url

The ServiceRouting.RouteRequest is quite simple and only contains a single C# code block:

Service routing c# code step

The best parameter for routing is probably using the SOAP-action and then store the URLs in a corresponding Environment Variable.

In our case, we could not do that and chose to use the namespace of the root element instead. So we do little extra work to exctract the root namespace and then convert it to a nicer format that corresponds to an environment-variable:

So if the namespace of the service is http://our.company.dk/Customer/CustomerGet/v1.0 then we retrieve the URL from the Environment-variable Service.Custom.CustomerGet.v1.0.url and forward the message to that service.

That is it. Fairly simple and it also means that adding a new service is only a matter of adding a new environment-variable with the corresponding URL. In our case we had an entire list and simply batch-imported it into Neuron’s XML-configuration.

Routing to services with different WCF-configurations.

In our case, we could not use a single endpoint to call services, since they used different WCF-configurations and users. Perhaps I will write more on this on a later post and feel free to ask if you have any questions.

They key is to have seperate sub-topics for each endpoint and then determine, which endpoint should be used. We used an XML-file in the repository to store information about which messages should go to which service. And for performance reasons, each XML-lookup was stored in context.State, so we only needed to perform it once.

In addition to setting the Adressing-property, you then also need to set the topic in the RouteRequest-process.

context.Data.Header.Topic = publishTopic;

This ensures that the service receives the request. But when Neuron receives the reply it will be on a different topic than the corresponding request. You therefore need a single process on the receiving party, which sets the topic back to the original

context.Data.Header.Topic = "ServiceRouting";

And thats it. It might seem like a lot of steps, but in our testing on a slow virtual machine we found that it only added 10-20 ms compared to calling the service directly.[/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]