Skip to main content

Service Bus Topics - Using with WCF services

If in my last post I talked a little about the limitations of Service Bus Topics, I think that this is the moment to see one of the greatest features of this service. Service Bus Topics has a lot in common with Service Bus Queues. In one of my posts I describe how we can integrate WCF with Service Bus Queues, but this can be done with Service Bus Topics as well.
In a large system, we have a lot of services that communicate between them and there are cases when a WCF service do more than one thing because the endpoint of that WCF service is the entry point and this is the only way how we can ensure that a couple of actions are executed when the services is called by a specific client. Because of this is not very easy to add, remove some behaviors to an endpoint and also the load balancing in this case can be nightmare.
Using WCF services exposed using Service Bus Topics can be our solution. Very easily a client can call a service that is only a fa├žade to more than one service. Based on subscribers’ filters we can specify what messages to be received by our service.
The step that needs to be done to integrate Service Bus Topics in our WCF services is very simple. Basically we need to change only the configuration files. I will start from scratch, creating the WCF service also.
The first step is to create the Service Bus namespace from Windows Azure portal, if we don’t have already a namespace created. Topics can create in different way using Windows Azure portal (we cannot add filters to subscriber, from configuration files and from code.
var namespaceManager =
NamespaceManager
.CreateFromConnectionString(CloudConfigurationManager.GetSetting("ServiceBusConnectionString"));

if (!namespaceManager.TopicExists("myFooTopic"))
{
namespaceManager.CreateTopic("myFooTopic");
}

namespaceManager.CreateSubscription(
"myFooTopic1",
"retriveAllMessagesSubscriber");
namespaceManager.CreateSubscription(
"myFooTopic2",
"valueIs10Subscriber",
new SqlFilter("Id > 2000"));
We create a topic named “myFooTopic” and two subscribers “myFooTopic1” and “myFooTopic2”. The second one has a filter. Next we defined the service contract, data contract and the implementation of our WCF service.
[ ServiceContract ]
public interface ICarService
{
[ OperationContract ( IsOneWay = true ) ]
void Open(Car car);
void Close(Car car)
}

[ DataContract ]
public class Car
{
[ DataMember ]
public int Id { get; set; }

[ DataMember ]
public string Number { get; set; }
}
public class CarService : ICarService
{
public void Open(Car car)
{
...
}

public void Close(Car car)
{
...
}
}
We have two services, because of this I will write a second implementation of our service. The two services don’t need to be hosted on the same server or to know one each other. All the magic is made by the Service Bus Topics from the configuration file.
public class CarService2 : ICarService
{
public void Open(Car car)
{
...
}

public void Close(Car car)
{
...
}
}
In the configuration file of our services we need to add a new binding extension named “netMessagingBinding”. This binding will be used when we specify the endpoint, where we will need to specify the address of our topic and the subscription address.
Both address are simple and have the following format:
  • sb://[serviceBusNamespace].servicebus.windows.net/[topicName] – topic address
  • sb:// [serviceBusNamespace].servicebus.windows.net/[topicName]/subscriptions/[subscriptionName] – subscription address
The endpoint configuration will contain our secret key that I used for authentication. The configuration file for our first service would look something like this:
 <system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus"/>
</bindingElementExtensions>
<bindingExtensions>
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus"/>
</bindingExtensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus"/>
</behaviorExtensions>
</extensions>
<behaviors>
<endpointBehaviors>
<behavior name="myBehavior">
<transportClientEndpointBehavior>
<tokenProvider>
<sharedSecret issuerName="[accountOwner]" issuerSecret="[secretKey]" />
</tokenProvider>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netMessagingBinding>
<binding name="queueBinding" closeTimeout="00:10:00" openTimeout="00:10:00"
receiveTimeout="00:10:00" sendTimeout="00:10:00" sessionIdleTimeout="00:01:00"
prefetchCount="-1">
<transportSettings batchFlushInterval="00:00:05" />
</binding>
</netMessagingBinding>
</bindings>
<services>
<service name="Demo.CarService">
<endpoint name="CarService"
address="sb://myNamespace.servicebus.windows.net/myFooTopic"
listenUri="sb://myNamespace.servicebus.windows.net/myFooTopic/subscriptions/retriveAllMessagesSubscriber"
binding="netMessagingBinding"
bindingConfiguration=" queueBinding "
contract="Demo.ICarService"
behaviorConfiguration="myBehavior" />
</service>
</services>
</system.serviceModel>
As you can see it is almost identical with the configuration that we done to our WCF service that was integrated with Service Bus Queue. We only need to specify the subscription address in our configuration. The good part of all this is that we don’t need to change the code at all. Because of this any WCF service can be upgraded to Service Bus Topics.
When we specify the client we will do the same thing. The difference is in the client node of the configuration. When we need to specify the endpoint we will need to specify the address of the topic. In comparison with the service configuration we don’t have to specify the listenUri, because the message added to the topic will be send to all subscribers.
In the end what we should remember when we need to change a WCF service to use Service Bus Topics:
  • The client point to the topic address (URL)
  • The server contains not only the topic address but also the subscription address
  • The differences two different services that point to the same topic is the subscription
  • The properties of data contract can be accessed from subscription filters as a BrokeredMessage property
The service can have as many endpoints we want
In conclusion Service Bus Topics can be very easy integrated to our WCF service without changing our code. It is a powerful feature that can help us in large applications.

Comments

Popular posts from this blog

How to check in AngularJS if a service was register or not

There are cases when you need to check in a service or a controller was register in AngularJS.
For example a valid use case is when you have the same implementation running on multiple application. In this case, you may want to intercept the HTTP provider and add a custom step there. This step don’t needs to run on all the application, only in the one where the service exist and register.
A solution for this case would be to have a flag in the configuration that specify this. In the core you would have an IF that would check the value of this flag.
Another solution is to check if a specific service was register in AngularJS or not. If the service was register that you would execute your own logic.
To check if a service was register or not in AngularJS container you need to call the ‘has’ method of ‘inhector’. It will return TRUE if the service was register.
if ($injector.has('httpInterceptorService')) { $httpProvider.interceptors.push('httpInterceptorService&#…

ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded

Today blog post will be started with the following error when running DB tests on the CI machine:
threw exception: System.InvalidOperationException: The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer' registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information. at System.Data.Entity.Infrastructure.DependencyResolution.ProviderServicesFactory.GetInstance(String providerTypeName, String providerInvariantName) This error happened only on the Continuous Integration machine. On the devs machines, everything has fine. The classic problem – on my machine it’s working. The CI has the following configuration:

TeamCity.NET 4.51EF 6.0.2VS2013
It seems that there …

Run native .NET application in Docker (.NET Framework 4.6.2)

Scope
The main scope of this post is to see how we can run a legacy application written in .NET Framework in Docker.

Context
First of all, let’s define what is a legacy application in our context. By a legacy application we understand an application that runs .NET Framework 3.5 or higher in a production environment where we don’t have any more the people or documentation that would help us to understand what is happening behind the scene.
In this scenarios, you might want to migrate the current solution from a standard environment to Docker. There are many advantages for such a migration, like:

Continuous DeploymentTestingIsolationSecurity at container levelVersioning ControlEnvironment Standardization
Until now, we didn’t had the possibility to run a .NET application in Docker. With .NET Core, there was support for .NET Core in Docker, but migration from a full .NET framework to .NET Core can be costly and even impossible. Not only because of lack of features, but also because once you…