Applications are more and more often being written with a services based architecture. This might range from a very sophisticated enterprise service bus all the way to a simple backend service called directly by the UI. Microsoft has shipped a new service as part of the Microsoft Azure platform AppFabric family called 'Service Bus.' This new service is designed to help you connect any service consumer to any service provider. This Service Bus helps avoid problems of connecting these two parties together that are provided by the complex network environments we tend to work in.
Many times the service consumer might not be internal to the network that is hosting the service. There are likely innumerable proxies, firewalls, and other network hurdles between the consumer and the service. These network challenges make it hard for external applications to connect into your service, resulting in even more network complexity.
What is the Bus?
The Service Bus is simply a way to relay messages to the cloud. Neither the service nor the consumer needs to be running in the cloud. This is an example where you can leverage the power of the cloud to make your application better, without actually running the application in the cloud. In this case we are simply using the cloud to simplify connecting two parties together.
The two parties communicate by relaying messages through the Service Bus in the cloud. This is the same approach that many instant messaging and phone applications (such as MS Messenger and Skype) use so that they can always connect and communicate with other users.
How It Works in the Cloud
Connecting to the Service Bus is easy. You will need a Microsoft Azure account and have installed the Azure platform AppFabric SDK. Both the service and the client will need to be running WCF. To reconfigure them to use the cloud it really only takes changing their WCF bindings to the relay version of what you are already using. For example, if you are using the
netTCP binding, you would change it to the
Both the service and the consumer need to authenticate to the bus before they are allowed to connect. This is a layer of security for your service, but also to make sure that only people you want to can see and use your service. This authentication can be baked into your WCF configuration.
How Do I Connect a Service to the Bus
In this article we aren't going to cover how to build a service with WCF, we will take an existing service and reconfigure it to use the relay binding from the Service Bus. We will start with a fairly normal looking WCF configuration (taken from an app.config of a running service).
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="OnlineCRM.CustomerManagement"> <endpoint address="net.tcp://servername:9000/customersService" binding="netTcpBinding" contract="customerService.Contract.ICustomerManagement"> </endpoint> </service> </services> </system.serviceModel> </configuration>
There are a few things we need to change to connect this service to the bus. We need to change the address, providing it an address on the bus instead of our servers. We also need to change the binding to a binding supported by the bus. These are provided in the Windows Azure platform AppFabric SDK. Lastly, we need to support authenticating to the bus.
You will create a scope within the Service Bus portal to contain your service endpoints that you have published to the bus. This namespace will be unique across all customers using the Service Bus. In my case I am going to create a namespace called
OnlineCRM. The fully qualified name will be
OnlineCRM.servicebus.windows.net once it is provisioned. This fully qualified name represents the root of the address our service will be published to.
We can change the binding to
netTCPRelayBinding. This will tell WCF to connect to and publish this service to the Service Bus. The new <service> tag is displayed below.
<system.serviceModel> <services> <service name="OnlineCRM.CustomerManagement"> <endpoint address= "sb://OnlineCRM.servicebus.windows.net/customersService" behaviorConfiguration="sharedSecretClientCredentials" binding="netTcpRelayBinding" contract="customerService.Contract.ICustomerManagement" /> </service> </services> <behaviors> <endpointBehaviors> <behavior name="sharedSecretClientCredentials"> <transportClientEndpointBehavior credentialType="SharedSecret"> <clientCredentials> <sharedSecret issuerName="owner" issuerSecret="MZuYNde3ZOzUJxKVo62kmWoFSlzEZEaKai5Fktlt3pQ=" /> </clientCredentials> </transportClientEndpointBehavior> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
You can see that we haven't changed our contract attribute; we are still exposing the same service implementation, the same code, as we were doing beforehand. Connecting your service to the bus is very easy, and should have no impact to your code.
We now have to add a new behavior to our configuration to handle authenticating to the Service Bus. We added a
behaviorConfiguration attribute to the <service> tag to do this. The name of our behavior, "
sharedSecretClientCredentials" is declared lower down in the configuration. This behavior basically attaches a user name and password to the requests to the bus, so that the service can authenticate and attach to it. The issuer name of 'owner' is a user that is configured on the Service Bus part of the Microsoft Azure portal. The secret is the key, or password, assigned to the issuer we used. In this way we can create multiple user accounts on the bus, for different people to authenticate with.
After you make these changes in your configuration you can start your service up, and after a moment or two it will authenticate to the Service Bus, and connect to it. Then it can start receiving messages at the address provided in the configuration.
How Do I connect a Client to the Bus
Connecting a client to the Service Bus so it can send messages on the bus (to services that are published there) is equally as easy. A typical client app.config might contain the following configuration for the service they wish to connect to.
<system.serviceModel> <client> <endpoint name="OnlineCRM.CustomerManagement" address="net.tcp://servername:9000/customersService" binding="netTcpBinding" contract="customerService.Contract.ICustomerManagement"> <identity> <userPrincipalName value = "username@servicedomain"/> </identity> </endpoint> </client> </system.serviceModel>
We will need to make the same changes to this configuration, as we did for the service itself. We will need to change the address, the binding, and the identity used to connect with.
<system.serviceModel> <client> <endpoint name="OnlineCRM.CustomerManagement" address="sb://stringreversalinc.servicebus.windows.net/processtring" binding="netTcpRelayBinding" contract="StringReversalLibrary.Contract.IReverseString" behaviorConfiguration="sharedSecretClientCredentials" /> </client> <behaviors> <endpointBehaviors> <behavior name="sharedSecretClientCredentials"> <transportClientEndpointBehavior credentialType="SharedSecret"> <clientCredentials> <sharedSecret issuerName="user1" issuerSecret="QZuDNdw3ZOzUJxVKo62kmWoFSlzEZEaKat5Fktlt3pX=" /> </clientCredentials> </transportClientEndpointBehavior> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
Here we have changed the address to the
sb:// endpoint that we used for the service. We also changed the binding to the relay version of the binding we want to use. We have to remove the <identity> tag and replace it with a behavior in the WCF channel to authenticate to the bus. In this case we created a second issuer (aka User) on the Service Bus.
You do need to pay to use the Service Bus. You will be charged based on the maximum average number of connections to the bus on a daily basis. For example, if you have one service and four consumers connect on a daily basis, you will pay for five connections that month. Connections can either be paid for in an ad-hoc manner as they are used. In that case you pay $3.99 per month per connected service or client. You can also buy packages of connections that reduce the price to about $2.00 per month per connection. This is a small price to pay to completely remove any network issues, and make it easy for your consumers to connect to your services. Spend some time on the Azure.com site and you will find other discounts that might apply.
If you just want to play with the Service Bus then you can either sign up to use the AppFabric labs (check out https://portal.appfabriclabs.com/), or you can activate your MSDN benefits with Azure. With an MSDN subscription you will get a ton of free time and resources in Microsoft Azure, and the related services.
Microsoft has stepped up with a neat way to avoid network and connectivity issues when trying to communicate with a service. With the Service Bus (as part of the Windows Azure platform AppFabric) you can connect to your service from anywhere, without any problems. Changing from a normal WCF binding to using the Service Bus is as easy as making a few small changes to your WCF configuration. Once you are using the bus, you will be able to add on other features that you can't do locally at all.
Some of the common uses for the Service Bus include exposing an internally hosted service to external consumers without having to punch holes through firewalls, or setup reverse proxies. A lot of people are using this to make it easy to separate where they host their service from how people connect to it.