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 audit an Azure Cosmos DB

In this post, we will talk about how we can audit an Azure Cosmos DB database. Before jumping into the problem let us define the business requirement: As an Administrator I want to be able to audit all changes that were done to specific collection inside my Azure Cosmos DB. The requirement is simple, but can be a little tricky to implement fully. First of all when you are using Azure Cosmos DB or any other storage solution there are 99% odds that you’ll have more than one system that writes data to it. This means that you have or not have control on the systems that are doing any create/update/delete operations. Solution 1: Diagnostic Logs Cosmos DB allows us activate diagnostics logs and stream the output a storage account for achieving to other systems like Event Hub or Log Analytics. This would allow us to have information related to who, when, what, response code and how the access operation to our Cosmos DB was done. Beside this there is a field that specifies what was th...

Can User Technical Profile Influence AI Architecture Decisions?

In the last few days, I ran a small experiment on Devin/Windsurf/Cascade, BMAD, and LLM-based architecture decisions. The initial concern was simple: if an AI coding assistant knows something about the user, for example, that the user is a Java developer or a .NET developer, can this information influence the architecture and technology stack that the AI will propose? This question is important because many companies are starting to use AI tools not only for coding but also for product discovery, architecture, documentation, and technical decision-making. If the AI is influenced by the developer's personal profile, the result may not be fully neutral. It may look like a business or architecture decision, but in reality, it may be partially shaped by the context of the person using the tool. The test was done using BMAD with Devin/Windsurf/Cascade. The scenario was a unified field service operations platform. The task was to let BMAD refine the product, define the architecture and s...

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.51 EF 6.0.2 VS2013 It see...