Contents
The Windows Azure AppFabric Service Bus September 2011 (version
1.5) release introduces enhancements to the Service Bus such as
"brokered" messaging capabilities, through namespace entities
represented by queues,
topics and subscriptions. The Brokered Messaging infrastructure enables to build
an Event-driven distributed Service Oriented Architecture, Distributed
Asynchronous Cloud Notifications and Intra-Application Messaging. Basically, it
can be useful anywhere where a loosely decouple messaging is required such as
Queuing and Publish-Subscribe messaging across both on-promises and cloud
targets.
From the abstraction point of the view, the Azure Service Bus represents a
logical connectivity between the event sources and their consumers using a
loosely decouple model. The consumers need to subscribe their interest to the
Service Bus in prior of receiving a specific event interest. This metadata
(subscriptions) represents a logical connectivity for event interest; they are
stored on the cloud a managed by tools and/or specific client applications.
The following picture shows an Azure Service Bus abstraction:
The above picture shows very high abstractions to hide an AppFabric
infrastructure, entities and etc. to show the basic model of the Azure Service
Bus. Basically, there is a Publisher of the event interest, Subscriber for
receiving this interest and Administrator to assign a logical connectivity
between the Publisher and Subscriber in the secure manner. The Service Bus is
highly available, scalable, multi-tenant service for connecting clients such as
Publishers, Subscribers, Admin, etc. The model of the logical connectivity is
stored in the SQL Azure. Currently, the Azure Service Bus model supports
Namespace entities such as Queue, Topic and Subscription.
The following picture shows a screenshot of the WindowsAzurePlatform
Service Bus Admin Tool:
As you can see, the Subscription-1 account has one Service Bus
Namespace scope named as rk2011
. As I mentioned earlier, the Service Bus is
multi-tenant model, where Namespaces are logical isolated entities, in other
words, Publishers, Subscribers and admin tools are visible each to other based on
the Namespace scope.
The following picture shows next drill-down level of the Service Bus
abstraction:
Basically, the above picture shows service-client architecture. The current release
version of the Azure SDK 1.5 includes many "horse-worker" classes and methods to
simplify access to the Service Bus Service. The Brokered Messaging feature on
the Azure Service Bus is built on the top of the WCF paradigm using full-duplex
connection-oriented sessions between the Sender and Receiver (Listener) with a
bi-directional communication (Microsoft.ServiceBus.Messaging.SBmp
internal classes) From the application (business) layer, the
messaging between Sender and Receiver is One-way supporting unicast and
multicast datagram distribution.
This article is focusing on consuming Azure Service Bus by WCF and WF
Technologies. I will discuss how it can be used in the transparent manner as
part of the Logical Model Connectivity. In the References, you can find more
details about the Service Bus entities and their programming using an API
methods and RESTful from the
Microsoft.ServiceBus.Messaging Namespace. I strong recommend to read
Service Bus Brokered Messaging Performance - Best Practices Guide.
Let's describe the major entities of the Azure Service Bus focusing on the WCF/WF
usage.
Brokered Message
The Brokered Message (BM) is a fundamental entity in the Service Bus
Messaging infrastructure. Its conceptual design is similar to WCF Message.
The BM is holding sys properties such as Label
, TimeToLive
,
CorrelationID
, etc. for message control flow and user
application
specific properties and of course the body (message payload). The
sys
and
user
properties are packaged to the bag under
the name
BrokeredMessageProperty
(BMP) The important thing is
that this BMP bag can flow between the Business-To-Business layers. The following
picture shows a WCF Message for ServiceBus Messaging:
The BrokeredMessageProperty
bag is attached to the WCF Message
via its Properties collection. Having the BMP out of the message body allows us
to use it without serializing/deserializing the business payload by Service Bus
infrastructure. Note, that the name of the key in the collection is
BrokeredMessageProperty
.
Adding BMP into the WCF Message Properties collection is very straight forward
like it is shown in the following code snippet:
using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
{
var bmp = new BrokeredMessageProperty() { Label = "HelloCloud" };
bmp.Properties.Add("abcd", (long)12345);
bmp.Properties.Add("id", Guid.NewGuid());
OperationContext.Current.OutgoingMessageProperties.Add(BrokeredMessageProperty.Name, bmp);
channel.Message(text);
}
The above example is for adding the BMP in an imperatively way using an
OperationContextScope
for channel (proxy). The following picture shows
this process graphically. The point is that the Sender/Publisher is a
producer of the
BrokeredMessage
to the Azure Service Bus. In other
words, the WCF Message + BMP are converted into the
BrokeredMessage
.
This task is implemented by custom channel for
NetMessagingTransport
included in the Azure SDK 1.5.
The behind the above picture is implementation of the
ServiceBusOutputChannel
, where the wcfMessage is converted to
BrokeredMessage and sent it by
SbmpMessageSender
to the Service Bus
channel. The following code snippet from .NetReflector shows this logic in the
Microsoft.ServiceBus.Messaging.Channels.ServiceBusOutputChannel
:
public SendAsyncResult(ServiceBusOutputChannel outputChannel, Message message, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state)
{
this.outputChannel = outputChannel;
outputChannel.AddHeadersTo(message);
outputChannel.TraceSendingMessage(message);
BrokeredMessage message2 = null;
try
{
message2 = outputChannel.ConvertToBrokerMessage(message, out this.bufferToReturn);
IAsyncResult result = outputChannel.MessageSender.BeginSend(
new BrokeredMessage[] { message2 },
timeout,
base.PrepareAsyncCompletion(onSendComplete),
this);
if (base.SyncContinue(result))
{
base.Complete(true);
}
}
catch (MessagingException exception)
{
throw FxTrace.Exception.AsError(exception2);
}
catch (Exception)
{
throw;
}
}
That's great. But do I need to modify my existing WCF Sender/Publisher for
Azure Service Bus Messaging?
Well, it is not necessary, this article gives you a solution for adding a
BrokeredMessageProperty
declaratively using a config file and
custom EndpointBehavior
. The following code snippet shows this
feature in the code:
serviceEndpoint.Behaviors.Add(
new RKiss.Activities.Azure.Messaging.MessagePropertyActionEndpointBehavior()
{
Expression = "SET sys.Label='HelloCloud'; SET abcd=12345; SET id=newid()"
});
As you can see, this custom endpoint behavior implements an Action feature based
on the SqlExpression. The above example will setup a message label (sys property) and
couple user properties such as abcd
and id
with a
new Guid value. Note, that the BMP
is important for
message processing, for example, based on the user properties the message can be
forwarded to the subscriber, etc. More details can be found later in the
usage examples of this article.
Queue Entity
The Queue Entity represents a logical connectivity between the producer and
consumer ends. It's point to point pattern connectivity. The concept is
similar to the on-promises MSMQ Technology. The following picture shows this
basic concept:
The Sender sending a BrokeredMessage
to the specific queue from
where the message can be pulled by its Receiver. There are advanced messaging
features such as schedule time, time to live, session capability, etc.
More details can be found in the References. Basically, this messaging can be
used for migrating NetMsmqBinding
configuration to the
NetMessagingBinding
(Azure Service Bus) in the transparent manner, just
by updating the config file. In some cases, during this migration we can use better
pattern, for example, using
SchedulerEnqueueTimeUtc
property
allows sending a message to the queue in the specific time, which can be
useful for retry mechanisms.
As the above picture shows, there are multiple ReceiverN
for the
same queue. In this scenario, the message will balance between the receivers in round-robin manner, which is perfect use for IIS/WAS/WebRole hosting. Note,
the receiver service on the hosting environment must have Auto-Start enabled.
The following code snippet shows example of receiver configuration on the
queue 'Queue1
':
That's great. As you can see, the above configuration will "plug-in" WCF
Service to receiving a message from the Azure Service Bus Queue. All the magic work
is done in the WCF paradigm using its extension such as
netMessagingBinding
and
transportClientEndpointBehavior
.
This capability allows building a logical connectivity stored in the Repository
and physically deployed to the target based on the deployment model.
Topic Entity
The Topic Entity represents a logical connectivity for event interests in the
specific Namespace. This is a Publish/Subscribe (Pub/Sub
) pattern connectivity,
where sources publish an event interest on the logical channel known as
Topic
and consumers will receive it based on their interest. This connectivity pattern
enables us to build an event-driven distributed architecture where producers and
consumers are loosely decoupled and disconnectable.
The following picture shows the topic-based messaging concept to see a
fundamental difference from the previous, queue-based messaging:
As you can see, the Publisher sends a BrokeredMessage
to the
Namespace/Topic virtual channel without any knowledge of its consumers in the
loosely decouple manner. Publishers can decide on a lifetime of the sent message
such as TimeToLive
, SchedulerEnquueTime
, etc. The
application can mark the message with a source event interest to identify
a specific event. In the loosely decouple manner, there are Subscribers registered
to the Topic which represents a consumers of the event interest. Registration
process is known as subscribing interest on topic.
Subscription Entity
In the Topic Model, this abstraction is represented by Subscription
.
Every Subscriber must have a Subscription. This entity represents a logical
connectivity between the Publisher and Subscriber on the specific Topic channel.
Based on the Subscription, the Subscriber gives an interest for Topic to receive
a message (described by RuleDescription) and some information for message control flow in the case of
exceptions, batch operation, etc.
As I mention earlier, to receive a copy of published message, Subscriber needs
to subscribe its subscription to the specific Topic. The Subscriptions can be
empty, default with one RuleDescription
or with multiple
RuleDescriptions.
The following picture snippet shows this abstraction, where Subscription is a
collection of the RuleDescription
entities:
To obtain the copy of the BrokeredMessage from the Topic channel, the
RuleDescription
within the Subscription must be succeeded. In other words, based on
the Subscription Filter(s), the message copy is delivered to the Subscriber. The
RuleDescription
in the Azure Service Bus Messaging has built-in two features,
such as Filter and Action. Both are based on
SqlExpression and have been implemented with certain limitation to the
BrokeredMessage
entity, for example: scope of the property can be sys
and/or
user
.
From the Topic point of the view, the message is delivered only if we have
valid subscription during the message lifetime. Basically, if we don't have any
valid Subscribers to the Topic, messages will live there based on their
TimeToLive
property. In other hand, the Topic can have many (based on the
Quotas such
as 2000 subscriptions per Topic) empty subscriptions, default subscriptions -
TrueFilter
(one default RuleDescription) or subscription with multiple
RuleDescriptions
.
As I motioned earlier, the Topic channel is loosely decouple model, where
Subscribers and Subscriptions are independed of each other. In other words,
Subscription can be created and registered by Subscriber or any application
component and/or management portal site. The Subscription can be static or
dynamicly created on the fly.
Keep in mind, when Subscription is unregistered (deleted) from the Topic,
its active Subscriber is disconnected, and it will be required to reconnected
in order to renew the subscription. In the case of the dynamic subscription, when
subscriber will create its own subscription, it is not a problem, but for static
subscription needs to be handle it.
Empty Subscription vs. Default Subscription
As we know, the Subscriber needs to subscribe an interest to the specific
Topic. But there is a special case when the subscriber (or management) doesn't
know in advance of this interest. Therefore, it is beneficial to use an Empty
Subscription, which will allow creating the Subscriber for Topic and its Listener
on the Empty Subscription.
When Subscription is created automatically, it is created for one (default)
RuleDescription
. If there is no filter expression (default constructor),
the
TrueFilter
is applied as a Default Subscription. In this case,
every published message delivers its copy to this Subscriber. Keep in
mind this feature when the multicast messaging is required.
By deleting the default RuleDescription
in the Default Subscription, we can
obtain an Empty Subscription
without any glitches on the active
Subscriber. Deleting RuleDescription in the Subscription can be done by its
Subscriber (one time message receiver) or other components.
In the opposite
process, the RuleDescription
can be added into the Subscription. Note, that
each
Filter in the RuleDescription
must match for message (copy)
delivery to its
Subscriber.
RuleDescription
The BrokeredMessage received by Topic channel is flowing via each
Subscription for checking its interest. This interest is declared by the Filter
Entity. The Service Bus Messaging has built-in few filters such as TrueFilter,
FalseFilter, CorrelationFilter and SqlFilter for generic SQL92 Expression. When
the filter match is true, the RuleDescription offers to execute its Action.
The default action is EmtyRuleAction and for custom action, SqlRuleAction can be
used using the SQL92 expression.
The scope of the filter and action is BrokeredMessage entity. The
SqlExpression supports only two scopes of the BrokeredMessage such as its
properties (scope name is sys) and the user scope (default scope) declared in
the BrokeredMessage.Properties collection.
Filter example: "sys.Label='Order" AND TicketID=12345"
Action example: "SET sys.Label='Order'; SET abcd=12345; REMOVE TicketID; SET
flag=TRUE"
Balancing vs. Multicasting (Multiple Subscriptions)
In the Queuing, we saw the by sharing a queue entity we can balance message
between queue receivers in the round-robin manner. We have the same feature
at Subscription, when the Subscribers are using the same Subscription. That's
fine and very useful for load-balancing purposes. But wait a moment, what will
happen when Subscription will have the same Filter expression?
Well, we can get a new pattern connectivity such as multicasting. The
following picture shows these two scenarios:
and their abstraction is shown here:
Basically, we can say, that "sharing" subscriptions is for balancing
and "sharing" filters for message multicasting. Note, that "sharing"
is used for logical explanation. I would be nice to have a Topic Model that supports
referencing entities and sharing them in the Repository, but current release doesn't
support it.
Addressing Queue, Topic and Subscription
The following are examples of addressing Queue, Topic and Subscription in the
connected Namespace:
Addressing can also use a branching structure, for example: /myTopics/myTopic
,
etc. Usage of addressing can be see in the following configuration
example for receiver, publisher and subscriber:
It is a straightforward standard endpoint configuration and the interesting point is
the subscriber endpoint. As you can see, the base address is for addressing Topic
entity and the listenUri
is addressing for its subscription. Each
endpoint must have a behaviorConfiguration
for credentials.
That's great. We can create Namespaces, Topics and Subscriptions in the
Windows Azure Platform for our subscription. From the business model point of the view, we can look
at on the Service Bus like abstraction of the connectivity, where business
entities are logically connected and driven by the metadata. We can consider
Service Bus such as Namespace, Queue,
Topic and Subscriptions (NQTS) as part of this metadata as well. In the logical model, we can declare a logical
subscription without knowledge of the physical topology of the Pub/Sub model.
Basically, the Subscriber interested in the event (message) in the business
model can be decomposited into multiple topics, etc. We can help our business model
by declaring NQTS for public and private scope. However, our logical business model stored in the Repository will need to
be physical
deployed to the target and the deployment model will need a mapping process for
specific physical entities of the target.
To end this thought, the current version of the Azure Service Bus Messaging
doesn't support "wildcard" feature for subscription or publisher for
multiple topics. In the current version, we can consider each subscription as
tightly coupled with a specific one Topic. It is the same Publisher side,
when on event interest is distributed only for specific Topic, not across multiple
topics. It will be nice to have support like subscription for multiple topics -
wildcard subscription, which will simplify our mapping from the business
model.
However, we can build (on top of the fundamental Service Bus Entities) advanced
hierarchy such as "wildcard subscription", publishing over multiple topics,
namespaces, creating public and internal gateways, bridges, etc. The concept is
very simple, subscribing interest to the specific topic and distributing it to
some other one, or multicasting an event interest for multiple topics.
In the following section I will describe this pattern scenario using a WCF
RoutingService, which basically represents a Subscriber/Publisher component
driven by metadata located in the config file (endpoints, routing table,
filters, etc.). Note that this service has a built-in capability to update a
routing table and outbound clients remotely on the fly.
The WCF RoutingService
is a perfect solution for building a
gateway and/or bridges for Service Bus. For this scenario, it can be fully
transparent and declaratively configured. The RoutingService
supports
both contracts for Service Bus such as ISimplexDatagramRouter
and
ISimplexSessionRouter
.
The following picture shows one possible
example, where the event interest from one Namespace/Topic must be delivered to
other Topic channel (bridge pattern) and also some "legacy" producer/consumer
that wants to be part of the Service Bus in the Pub/Sub scenario (gateway pattern).
In the above example, the RoutingService
can be configured for
receiving two kinds of messages such as BrokeredMessage
and
Message
. This is a straightforward configuration, setting an address on
the Topic channel and Listener on Subscription. For "legacy" Publisher, we can
use a standard addressing. That's all for inbound messages. For outbound
messages such as "legacy" Subscribers and Topic channel (2) we can setup a
client endpoint with addressing based on the target (service or Topic).
Now, we need to configure a Routing Table which will be "connect"; - forward
the inbound message to the specific outbound channel. For simple forwarding
messages from Publishers to Subscribers ("legacy" connectivity), we can use
standard built-in message filters (Action, XPath, EndpointName, etc.), but for
BrokeredMessage we need a custom message filter based on BrokeredMessageProperty
with capability to declaratively setup this property
bag for outbound message to the Service Bus. The other option is to forward an
inbound BrokeredMessage without the filtering on BMP bag, for example:
EndpointName, Action, Address. etc.
OK, without any implementation details (it will be described later) the following
configuration allows filtering inbound message from the Service Bus and
generating BMP bag for outbound message to the Service Bus:
The messagePropertyAction
is a custom endpoint behavior
for message inspector to update outgoing message properties for BMP bag. The
other element is a custom MessageFilter to execute
SqlExpression
on the incoming message with a BMP bag.
This is exciting, we can have a generic solution for gateway and bridge
from/to Service Bus which can be very easily deployed on the cloud and used as an Azure
Storage Blob for routing table - see more details about this solution in my
previous article
RoutingService on Azure. This article gives you a solution how we can mediate a message to/from the Service Bus using a WF
Technology.
Note, that the RoutingService has a built in capability for backup message
delivery, which can also be used it in our scenario.
Based on this concept described in the above example, the RoutingService can
be configured for bridging messages across multiple Namespaces and Topics. The
RoutingService can have multiple endpoints configured for different Topics and
Subscriptions. The following picture shows this abstraction:
Another advanced feature of the RoutingService for Service Bus. As we know,
the current release Service Bus
Quotas
limited number of subscription on the Topic. The following picture shows how we
can work around this limitation:
The concept is very simple and straightforward. The RoutingService can be subscribed to the Topic and based on the FilterTable rules can forward
a message
to multiple clients in the multicasting manner.
One more advanced feature of the RoutingService on the Service Bus. The
following picture shows subscribing a RoutingService with Subscription contains
multiple RuleDescriptions. The inbound messages received by this Subscription
(from each Rule) can be forwarded to the proper outbound channel based on the
custom message filter for BrokeredMessageProperty bag driven by Routing (Filter)
Table.
Publisher
Publisher represents a sender (producer) of the event interest. In the
Pub/Sub pattern, the Publisher is loosely decoupled from the consumers, therefore
its publishing is addressed to the virtual channel which in the Azure Service
Bus Messaging is represented by Topic. The Publisher supports only one message
exchange pattern such as One-Way operation (Fire&Forget) without the
SessionMode.Required
, therefore
the Publisher WCF channel can be implemented IOutputChannel
channel
only. The following
example shows a generic (untyped) contract for Publisher:
[ServiceContract]
public interface IGenericOneWayContract
{
[OperationContract(IsOneWay = true, Action="*")]
void Message(System.ServiceModel.Channels.Message msg);
}
Let's look at how we can create a Publisher for Topic. I will demonstrate it
by WF Technology using a declarative way. Basically, in simple case, when the event
interest can be signed statically in the BMP bag, there is no difference for
proxy channel (sender), the BMP bag can be created declaratively like it has
been described earlier, using the custom endpoint behavior (messagePropertyAction
).
When the BMP bag is created dynamically, based on the business
model, we need a mechanism how to add it to the outgoing message properties.
The following example shows adding BMP bag to the untyped message created by
custom activity CreateMessage based on the Contract-First Model and then sending
it
by activity Send:
The above picture shows two custom activities to simplify this message
mediation, the first one can be found in my article
WF4 Custom
activities for message mediation and the other one is part of this article
and it will described in detail later on. So, these two custom activities will
create a complete message for sending by Send Activity, including headers,
properties, body, etc. using a full declaratively way for any element and
entity.
The other way, when we want to use strong type message contract, we can use
the following pattern based on the injecting a BMP bag in the message inspector.
The following picture shows this case:
Again, we need some help with this extension, that's why here is a custom
activity SendScope
which is basically wrapper for Send
Activity.
The Message
mediation for Service Bus such as adding a BMP bag to the message properties is
very simple and straightforward. First step is creating this BMP bag and the
second one is to assign to the Properties in the SendScope activity. This custom
activity is included in this article download.
Note: The WF4 Send Activity didn't allow to add a custom endpoint behavior
declaratively. There is only one way how it can be done such as explicitly setup
the Send.EndpointConfigurationName property by name of the client endpoint from
the config file (e.g. topic). It will be nice to have a capability for injecting
a custom endpoint behavior using a custom wrapper around the Send activity in
the next release WF 4.5.
AssignBMP<T>
AssignBMP<T> is a custom activity for creating an instance of the
BrokeredMessageProperty
object and assigning it to the
System.ServiceModel.Channels.Message.Properties
or
Microsoft.ServiceBus.Messaging.BrokeredMessageProperty
declared variable.
The design and implementation of this custom activity is based on BMP class
type for properties in the sys scope and one collection of the user parameters. This
BMP bag is required by Service Bus infrastructure for a message control flow and
additional user specific data between the producer and the consumers. The custom AssignBMP activity simplifies a message mediation process.
Subscriber
The Subscriber represents a receiver (consumer) end point of the BrokeredMessage. In
the case of no interesting BMP in the service mediation, the Subscriber is a
regular Receiver. In the other case, when the service mediation needs a BMP bag
(additional business data), we need to obtain it from the custom activity OperationContextScope
. This is a Receiver wrapper to inject a value of the
OperationContext.Current to the workflow thread scope, which will get our BMP bag from the IncomingMessageProperties collection.
The Service Bus supports for Subscription and Queue two message
exchange patters such as IInputChannel
and IInputSessionChannel
. Once these
Service Bus entities have been declared for session (required), the Subscriber (Receiver)
needs to implement a session-aware contract. The following is an example of the untyped contract for sessionful pattern:
[ServiceContract(SessionMode = SessionMode.Required)]
public interface IGenericOneWaySessionContract
{
[OperationContract(IsOneWay = true, Action="*")]
void Message(System.ServiceModel.Channels.Message msg);
}
The example of the Subscriber declared by xaml is shown in the following
picture:
This article download contains an AzureMessagingActivityPack solution, with extensions to the BrokeredMessageProperty
and
MessageProperties
classes. The above
GetBrokeredMessageProperty
method is one of them to hide same details.
The Subscriber can be configured in the config file. The above example shows
this service Subscriber2 config section, where its endpoint has an address to the Topic channel
and listener is addressed on the subscription address.
Subscriber and Multiple Publishers
The following scenario shows a mediator where we have one Subscriber and
multiple Publishers. This mediator is an example of the event driven virtual
storage. Mediator (StoragePublisher
) has a responsibility to put a
resource to the virtual storage (for example: Azure Blob Storage), publishing
this event to the Topic channel and triggering a cleaner mechanism sending an
event message to the queue. This message is marked with
ScheduledEnqueueTimeUtc
property which represents a resource TimeToLive. The receiver of this message
will clean-up a specific resource in the Storage.
This is an example of the pattern where consumers will pull-up a
resource from the rental Storage. Instead of multicasting a heavy business
payload (a resource body), the service mediator will send notification (short
message) to the unknown number of consumers via the Topic channel.
The following picture shows a BMP bag:
For event-driven storage demonstration, a custom activity Microsoft.Activities.Azure.Storage.PutBlob
is used. As you can see, the design is very
straightforward using custom activities for putting a resource to Azure
Storage and publishing events to the Azure Service Bus Topic. Note that this
process is not under TransactionScope like we can have on promises environment
SQL/MSMQ and it should be covered by some watchdog mechanism.
All plumbing job is done in the configuration file. The following code
snippet shows this example:
<configuration>
<appSettings>
<add key="AzureStorageConnectionString"
value="DefaultEndpointsProtocol=https;AccountName=MY_ACCOUNT;AccountKey=MY_ACCOUNT_KEY"/>
</appSettings>
<system.serviceModel>
<services>
<service name="Subscriber3">
<endpoint
address="sb://MY_NAMESPACE.servicebus.windows.net/worker"
listenUri="sb://MY_NAMESPACE.servicebus.windows.net/worker/subscriptions/image12"
binding="netMessagingBinding"
contract="IGenericOneWayContract"
behaviorConfiguration="sharedSecretCredentials" />
</service>
</services>
<client>
<endpoint name="TopicPublisher"
address="sb://MY_NAMESPACE.servicebus.windows.net/worker"
binding="netMessagingBinding"
contract="IGenericOneWayContract"
behaviorConfiguration="sharedSecretCredentials" />
<endpoint name="QueuePublisher"
address="sb://MY_NAMESPACE.servicebus.windows.net/search"
binding="netMessagingBinding"
contract="IGenericOneWayContract"
behaviorConfiguration="sharedSecretCredentials" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="MY_ISSUER_NAME" issuerSecret="MY_ISSUER_SECRET" />
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement,
Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement,
Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingElementExtensions>
<bindingExtensions>
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement,
Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
</system.serviceModel>
</configuration>
As you can see, there is an appSettings section for connection string to Azure
Storage and the rest is a configuration for one Subscriber and two Publishers
and of course, we have to put extensions for Service Bus such as transportClientEndpointBehavior
,
netMessagingTransport
and netMessagingBinding
.
That's all for the introduction. I hope you get the picture of the Service Bus
position in the logical connectivity model between producers and consumers based
on the WCF/WF Technology. I didn't describe a Service Bus management tools,
creating Entities such as Queue, Topic, Subscription, etc. More about that,
including their API programming can be found in the
References. Also, I assume that you have a working knowledge of
Windows Azure Platform and WCF/WF Technology.
OK, let's continue, there is lots of stuff to show before we getting into
the usage and the test part.
The AzureMessagingActivityPack is a small package of the custom activities
and class extensions for message mediation from/to Azure Service Bus Messaging. Its
solution with full implementation is included in this article download.
Basically, there are two groups, such as:
1. Endpoint and Class Extensions
This extensions have been created to simplify access and manipulation with
BrokeredMessageProperty
Bag. It can be used imperatively or
declaratively in the xaml or config file.
There are two classes extension such as
MessagePropertiesExtension
and
BrokeredMessagePropertyExtesion
. The following example shows some
of the usage.
var bmp = OperationContext.Current.IncomingMessageProperties.GetBrokeredMessageProperty();
long prop1 = bmp.RequiredItem<long>("prop1");
string prop2 = bmp.RequiredItem("prop2", "Missing {0} in the bag", "prop2");
XElement xbmp = bmp.ToXml();
Trace.WriteLine(bmp.ToXml().ToString());
var bmp1 = message.Properties.GetBrokeredMessageProperty("Missing BMP bag");
string prop3 = message.Properties.GetBrokeredMessageProperty().RequiredItem("prop3");
bmp1.Put(message2.Properties);
MessagePropertyAction
This is a client endpoint behavior extension to inject a BrokeredMessageProperty bag for outgoing message in the config file. Having this
extension, we can "fire event interest" from the "legacy" Publisher to the
Service Bus Topic channel.
public class MessagePropertyActionClientInspector : IClientMessageInspector
{
public string Expression { get; set; }
void IClientMessageInspector.AfterReceiveReply(ref Message reply, object correlationState)
{
}
object IClientMessageInspector.BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (request.Properties.ContainsKey(BrokeredMessageProperty.Name))
{
var bmp = request.Properties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;
var sra = new SqlRuleAction(this.Expression);
sra.Preprocess().Execute(bmp.Message);
}
else
{
var bmp = new BrokeredMessageProperty();
var sra = new SqlRuleAction(this.Expression);
var bm = sra.Preprocess().Execute(bmp.Message);
request.Properties.Add(BrokeredMessageProperty.Name, bmp);
}
return null;
}
}
The core of the above inspector is the execution of the SqlExpression on the
BrokeredMessage object.
The following code snippet shows its usage in the config file:
<behaviors>
<endpointBehaviors>
<behavior name="sharedSecretClientCredentials">
<transportClientEndpointBehavior credentialType="SharedSecret">
<clientCredentials>
<sharedSecret issuerName="MY_ISSUER_NAME"
issuerSecret="MY_ISSUER_SECRET" />
</clientCredentials>
</transportClientEndpointBehavior>
<!-- Set BrokeredMessageProperty Bag -->
<messagePropertyAction enable="true"
expression="SET sys.Label='Router';SET sys.TimeToLive='00:01:00';SET id=newid()"/>
</behavior>
</endpointBehaviors>
</behaviors>
It can be used programmatically, as well:
serviceEndpoint.Behaviors.Add(
new RKiss.Activities.Azure.Messaging.MessagePropertyActionEndpointBehavior()
{
Expression = "SET sys.Label='Router'; SET sys.TimeToLive='00:01:00'; SET id=newid()"
});
BrokeredMessageFilter
The BrokeredMessageFilter has been created for RoutingService to customize a
message filtering on the BrokeredMessageProperty bag. It is a valuable extension
for RoutingService Subscriber to forward a message to the proper outbound
channel.
public class BrokeredMessageFilter : MessageFilter
{
public string Expression { get; set; }
public BrokeredMessageFilter(string expression)
{
this.Expression = expression;
}
public override bool Match(System.ServiceModel.Channels.Message message)
{
if (message.Properties.ContainsKey(BrokeredMessageProperty.Name))
{
var bmp = message.Properties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;
var filter = new SqlFilter(this.Expression);
bool bMatch = filter.Preprocess().Match(bmp.Message);
return bMatch;
}
else
{
return false;
}
}
public override bool Match(System.ServiceModel.Channels.MessageBuffer buffer)
{
throw new NotImplementedException();
}
}
The core of the above filter is executing a SqlFilter on the
BrokeredMessage object. The following code snippet show usage this custom filter in the config file (routing section):
<filters>
<clear />
<filter name="MatchForSubscriber1"
filterType="Custom"
filterData="image=111 AND sys.Label='Hello Cloud'"
customType="RKiss.Activities.Azure.Messaging.BrokeredMessageFilter, RKiss.Activities.Azure.Messaging" />
</filters>
Note, that the above extensions are very helpful for connecting "legacy"
Pub/Sub producer and consumers to the Azure Service Bus via modification of their config files.
2. Custom Activities
AssignBMP<T>
AssignBMP<T> is a custom activity to create a
BrokeredMessageProperty
bag and assign it to the T type which can be accepted only for
System.ServiceModel.Channels.Message
or
Microsoft.ServiceBus.Messaging.BrokeredMessageProperty
types. Its design is
based on the BrokeredMessageProperty class, where Service Bus properties (sys
scope) and application (user) properties in the Parameters collection (user
scope) are found:
Collection of the Parameters can be declared in the pop up dialog. The following picture shows an example of declaring different type of the user properties:
AssignBMP<T> is factorized for the required type T. The following code
snippet shows these templates. It shows some examples of how we can predefine some
common application properties in the collection of the parameters:
public class AssignBMPtoMessage : IActivityTemplateFactory
{
public Activity Create(DependencyObject target)
{
AssignBMP<Message> assign = new AssignBMP<Message>()
{
DisplayName = "AssignBMPtoMessage"
};
assign.Parameters.Add(new KeyValuePair<string,InArgument>("myKey", InArgument<string>.FromValue("12345")));
return assign;
}
}
public class AssignToBMP : IActivityTemplateFactory
{
public Activity Create(DependencyObject target)
{
return new AssignBMP<BrokeredMessageProperty>() { DisplayName = "AssignToBMP" };
}
}
SendScope
SendScope is a generic custom activity for Send Activity to allow
declaratively way create a binding of the Send activity and dynamically
inserting a message headers and properties:
This custom activity will allow adding a BrokeredMessageProperty bag for
typed message contract, when the workflow orchestration is based on the clr
types (DataContract). Note, that for untyped message, the BMP can be assigned
directly to the message properties collection.
Subscribe
This custom activity is to subscribe a subscriber event interest to the Topic
channel. The result of this custom activity is creating a subscription with one RuleDescription (name = $Default) based on the Filter and Action SqlExpression.
Behind the Subscribe activity are API calls to the Service Bus, for checking
existing subscription, then deleting (if Renew is required) and creating a new
one. The current implementation of this custom activity is not full async
process, only creating a subscription is done in the async manner, the others
are sync process.
Note, that Azure SDK 1.5 doesn't support updating existing subscriptions. It
would be nice to have this feature, instead of always deleting and recreating
again and again. This process will impact all active subscribers relayed on this
renewed subscription. To avoid this glitch, I recommend to use Empty
Subscription and use API call for AddRule
to the subscription, in
other words, keeping a subscription alive.
Unsubscribe
This is a custom activity to delete a subscription from the Topic channel in
the async manner. It is very lightweight activity with requirement for Configuration, Namespace, Topic and Subscription names. Note,
by
processing this activity all active subscribers for this subscription are
logically disconnected from the Topic channel.
OperationContextScope
This custom activity is useful for Susbcriber (Receiver) mediator to obtain
operation context of the incoming message, which we need for getting a
BrokeredMessageProperty bag that is sent by the Service Bus. This is a generic custom
activity, originally created in the
WF Security Pack CTP 1
and slightly modified in my package. The concept is very simple and
straightforward such as creating an OperationContext
in the
workflow thread slot within its scope. To obtain a runtime OperationContext, implementation of the built-in message inspector interface such as System.ServiveModel.Activities.IReceiveMessageCallback and
System.ServiveModel.Activities.ISendMessageCallback is used.
That's all for this package. I didn't create a full WF wrapper around the
Service Bus API. The above extensions are focusing on the producer and consumer
sides, which is publishing and consuming an event interest, creating a subscriber and its
subscription. For managing Service Bus, we can use
Windows Azure Platform portal and/or 3rd party explorers, like upcoming new
version
Service Bus Explorer.
OK, let's take a coffee break, because we are going to go through difficult parts such as
Usage and Test
. I am assuming, you have a working knowledge of the
Windows Azure Platform.
First of all, the following are prerequisites:
Let's start with the Windows Azure Service Bus
Step 1. Create your Namespace on the Service Bus
Step 2. Create the following entities such as Queue and Topic in your
Namespace scope
Step 3. Create Container 'box' in your Azure Storage Blob
(this is an option
for one test scenario - Test 3
)
Step 4. Download this article and open it with VS2010SP1.
You should see the following solution:
Basically, the solution is divided into two parts such as
AzureMessagingAcitivtyPack
and Test
. The first one is actually
a package of the
two assemblies to simplify consumption of the Service Bus. The usage of theses
assemblies is shown in the Test package. As you can see, the Test folder
contained different applications (scenarios) driven by WCF and WF Technologies
using imperative and declarative ways to create producers and consumers.
Note, that the solution has been developed and tested on the Windows 7.
Step 5. Compile solution
In this step, you should have successfully built with the provided exe programs such as ConsoleApplications, Management, Publishers and
PubSubRouter. All shortcuts are centralized into the ServiceBusTest
folder, which can be added to the Desktop.
Step 6. Updating config files
Please, replace the following values in all config files located in the Test
folder with your account for Azure Service Bus and Storage:
MY_ISSUER_NAME, MY_ISSUER_SECREET, MY_NAMESPACE, MY_ACCOUNT and
MY_ACCOUNT_KEY
Step 7. Create Subscriptions
Launch the SubscriptionManager
program to create our test
subscriptions:
This program has been created declaratively, using a workflow with a custom
activity Subscribe. See its design in the following picture:
To verify the above subscriptions on the Service Bus, please launch the
console program ManagingSubscriptionRules:
As you can see, we have three subscriptions, where the first one has a simple
test Action expression. Note, that this test program is able to add one
more rule into the subscription image12
, which we will need to demonstrate
later.
OK, now our test environment is ready for testing. But, one more
comment. The Test Package also includes a simple message inspector for logging
messages, including a BrokeredMessageProperty bag on the Console.
Test 1. Send message to the Queue.
This is a very simple test, the Sender will send a message to the Queue
(Search) and the Receiver will retrieve the message from the queue. First (but not
required) launch the Receiver console program:
and then the Sender console program:
You should see that the message has been received by Receiver:
Great, it's working. Now, you can launch one more Receiver and back to the
Sender and press any key to send the message again. You will see that the message
is balancing between the Receivers.
This test has been implemented declaratively within the config file. Please,
visit these config files (Sender and Receiver) for more details. As you can see,
migrating NetMsmqBinding
(MSMQ) to NetMessagingBinding
(Service Bus) can be straightforward and
simple.
The following code snippet shows part of the Sender configuration file. There is messagePropertyAction
element for setting BMP bag in the client
endpoint behavior:
Test 2. Publish message to the Topic
In this test scenario, we are going to fire (publish) an event interest in advance of
the Subscriber, therefore, please launch the Publish console program. The
following screen snippet will show up. You can see the wcf message (yellow
color) and the BMP bag (green color) on the console screen. Note, that the
message has TTL setup for 30 minutes.
Now, launch the Subscriber console program. You should see the following
result on your Subscriber:
That's great, we can see a log message with BMP bag as well as the deserialized
message in the service (white color).
Let's make more advance feature for this Pub/Sub scenario, where Subscriber
subscribed subscription image12
with one $Default Rule such as
image=111 or image=222
, that's why we received only one message.
Now, let's add one more Rule to this subscription. We can do so by using a ManagingSubscriptionRules console program, which has this feature
built-in (hard
coded for test purposes). Please, go back to the ManagingSubscriptionRules
program and press the 'a' key. You should see the same result like it is shown in
the following screen snippet:
Note, that this Rule (name=abcd)
has declared a
RuleAction
for setting a user property
Label
.
Now, we can back to the Publisher console program and send a message to the Service Bus Topic channel
by pressing a key (any key). This is a second message from the Publisher, therefore the counter value is 1. What is
interesting in this test is that fact that the Subscriber received two messages from
this subscription based on the successful expression of its RuleDescription.
You can also see that the second message has the BMP bag different than first one.
There is a result of the RuleAction such as SET Label = 'Hello Roman'
.
That's cool, you can come back later and modify the test code for your RuleDescription, launching more Subscribers (may be on
a different machine), etc.
to see the capability of Pub/Sub on the Azure Service Bus.
This test has been created programmatically, the following code snippet shows
implementation of the Publisher:
try
{
string issuerOwner = ConfigurationManager.AppSettings.Get("sbIssuerName");
string issuerSecret = ConfigurationManager.AppSettings.Get("sbIssuerSecret");
string namespaceAddress = ConfigurationManager.AppSettings.Get("sbNamespaceAddress");
string text = string.Format("[{0}] Hello Service Bus - {1}", counter, DateTime.Now);
EndpointAddress topicAddress = new EndpointAddress(namespaceAddress + "/" + topicName);
var binding = new NetMessagingBinding();
var securityBehavior = new TransportClientEndpointBehavior()
{
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(issuerOwner, issuerSecret),
};
var se = new ServiceEndpoint(ContractDescription.GetContract(typeof(INotify)), binding, topicAddress);
se.Name = "TopicPublisher";
se.Behaviors.Add(securityBehavior);
se.Behaviors.Add(new RKiss.Logger.LoggerAttribute());
factory = new ChannelFactory<INotify>(se);
var channel = factory.CreateChannel();
using (OperationContextScope scope = new OperationContextScope((IContextChannel)channel))
{
var bmp = new BrokeredMessageProperty() { Label = "RKiss", TimeToLive = TimeSpan.FromMinutes(30) };
bmp.Properties.Add("abcd", (long)12345);
bmp.Properties.Add("image", (long)111);
bmp.Properties.Add("id", Guid.NewGuid());
bmp.Properties.Add("counter", (long)counter);
OperationContext.Current.OutgoingMessageProperties.Add(BrokeredMessageProperty.Name, bmp);
channel.Message(text);
}
factory.Close();
Console.WriteLine("Message #{0} has been sent to Topic='{1}'", counter++, topicName);
}
catch (CommunicationException ex)
{
}
catch (Exception ex)
{
}
Console.WriteLine("Press any key to send message");
Console.ReadLine();
Test 3. Event-driven Storage
This test is a scenario where you can see usage of the multiple technologies
such as WCF, WF, Azure Blob Storage, Topic and Queue. The following picture
shows this scenario:
Basically, we have Publisher, Subscriber and Cleaner
components on the promise. On the Azure side we have a Blob Storage and Service Bus with a Queue
and Topic channel. The action is very simple, the Publisher is putting a
resource to the Blob Storage, firing an event to the Topic channel and sending a
scheduled message to the queue to clean-up the resource in the Storage. This
scenario is suitable to avoid a multicast delivering large messages. Instead of
copying a large message for each subscription, the Service Bus will deliver a very
small notification message to the subscriber(s) to pull a resource from the
Storage.
Note, that this test requires an option described in
the prerequisites section such as azure storage account, creating a blob
container and Azure Storage Explorer.
First of all, please launch the AzureStorageExplorer, connect your storage
account and show the container 'box'. The following screen shows that for my
account name (rkstorage):
next, launch the StorageReceiver console program:
Now, we can fire a Publisher, please launch the StoragePublisher program.
Note, that Publisher will automatically perform an action and wait for next
one, therefore please refresh the AzureStorageExplorer to see stored resource in
the container 'box'.
Ok, the next step is to launch the StoragePublisher:
To verify, that our resource is stored in the Azure Blob Storage, please
press the button Refresh on the following Explorer tool. You should see the
following result:
Using this tool, we can also see actual resource in the browser. Note, that the
watchdog time has been setup for 1 minute, after that, the Storage Cleaner
receiver will receive a message from the queue to perform deleting a specific
resource from the Blob Storage.
The following picture is a screen snippet about this action:
I know, the resource TTL time is to short (only 1 minute), however, you
can go back to the StoragePublisher and fire an event again and focus on the
specific action, etc. You can fire publisher multiple times and watch the
Storage container 'box' for its contains.
I like this scenario, its implementation has been straightforward and
readable. The following screen snippet shows a workflow of the StoragePublisher.
There are full sequence of the Put and Notify
activities, it is
simple like 1-2-3.
Test 4. Router
This test is going to show a capability
of the
WCF4 Routing Service on the Service Bus.
To better understand this test scenario, which requires launching more programs for
producing and consuming messages, the following picture will give you a brief
overview of this test
scenario:
As you can see, this test scenario is more complex than previous one.
Therefore, let's discuss it further. The goal of this test is to show the
capability of the WCF RoutingService, which is the Subscriber and
Publisher for Service Bus. The RoutingService can be a
gateway from/to Service Bus. For this case, there is a WinForm program SimulatorPub/Sub to represent a WCF producer and subscriber or web service. It is
a very
simple program that sends or receives a Soap message.
On the other side, we have WCF/WF programs for Pub/Sub message and
one program for receiving message from the queue. The following configuration
snippet shows declaration of the all endpoints such as inbound and outbound
endpoints for Router. Note, that Router subscribed its interest to Topic channel
with subscription image1
:
The logical connectivity between the Router and Service Bus is declared in the routing
section. The following picture shows its filters. As you can see, this routing
table supports three connectivity types (priority 9, 10 and 11). The first one has a
custom message filter for BMP bag (image=111), the second one is based on the
EndpointName
, where any inbound message from the endpointRouter
is
forwarded to the outbound channel TopicPublisher1.
The last one with, the
highest priority 11, is based on the message Action
. If this match is true, the
message is forwarded to the Service Bus Queue.
Please, have a look at the full configuration file PubSubRouter.exe.config
for its contents, specially at the endpoint behavior section.
I hope you understand this config file, especial the routing table, which is
necessary for our next step such as runtime use cases:
Please, close all opened programs and launch the following programs:
PubSubRouter
console program (this is a host process for Routing
Service)
SimulatorPubSub
winform program to simulate Pub/Sub messages
Subscriber
console program for receiving messages from the Service Bus
Topic
Receiver
console program for receiving messages from the Service Bus
Queue
At this moment, you should see on all console programs, a prompt message for
listeners. Our SimulatorPubSub has already predefined a Pub message, so our test
scenario is waiting for an event. We are going to make three use cases, such as the
event is sent by simulator, event from the Topic is received by simulator and one
more case when simulator will send a message to the Queue.
1. Simulator is firing an event_1 message
Please, press the button OneWay on the SimulatorPubSub. You should see the log
messages on the PubSubRouter console program and on the Receiver, so, our
message from the simulator has been sent via Router to the Service Bus Queue and
received by the Receiver console program, see the following screen snippet:
2. Simulator is firing an event_2 message
In this case, simulator will send a different event message. Please, modify
Action for this message, for example, replace Broadcaster
by
BroadcasterXYZ
word and press the button OneWay for sending this message.
You should see on the Subscriber console program the following result:
and on the Simulator Sub message from the subscription image1:
That's great. What happens here? Well, the inbound message from the Pub
Simulator has been routed to the Topic channel and all subscribers (which is
also a Sub Simulator) with subscription image1
received a copy
message from the Service Bus Topic.
Ok, let's make one more case. Please, press button Clear to erase a Sub
message on the Simulator.
3. WorkflowPublisher1 is firing an event message
In this case, we are going to publish a message to the Service Bus Topic. For
this test, we need to launch WorkflowPublisher1 console program. Please, do that
and watch the results on the console programs.
First of all, we can see that the Subscriber received two messages
(different BMP bag but the same message payload). That's correct, this
subscriber subscribed for image12
subscription, which at this
moment has two RuleDescriptions, that's way we received two copies of the
message:
We can see on the other result on the Simulator, where a Sub message has been
received. You can check the message payload for its element id.
That's all for this test. One more note, please have a look at the
PubSubRouter console program. You will see the log messages for inbound and outbound
endpoints including their BMP bag.
If everything is goes well, try to modify the routing table, publishers
and/or subscriber in this scenario to create new use cases in order to see how the WCF
and WF Technologies work with Azure Service Bus Topic/Queue.
Test 4. Subscribers hosted on the IIS/WAS
The Subscriber folder is included in the Test package. This folder contains an
implementation of the three subscribers hosted in the IIS/WAS server. One
subscriber is implemented declaratively using a workflow xaml. The
following code snippet subscriber is created imperatively by the code::
public class Subscriber1 : IGenericOneWayContract
{
public void Message(System.ServiceModel.Channels.Message msg)
{
Trace.WriteLine("*** Subscriber1 ***");
if (msg.Properties.ContainsKey(BrokeredMessageProperty.Name))
{
Trace.WriteLine("BrokeredeMessageProperty:");
var bmp = msg.Properties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;
foreach (var prop in bmp.Properties)
{
Trace.WriteLine(string.Format(" {0} = {1}", prop.Key, prop.Value));
}
}
Trace.WriteLine(msg + "\r\n");
}
}
and the following screen snippet shows Subscriber3 created by WF. You
can see the usage of the OperationContextScope
to obtain a message BMP bag:
The complete plug-in setup to the Service Bus is done in the configuration file.
Please, visit this file to understand each subscriber hosted by IIS/WAS. Note,
that this virtual application must have the Auto-Start feature enabled.
I will leave this test for you and I hope you will see the result of the
subscribers on the trace output such as
DebugView.
You can use the Publisher console program to fire an event to the Topic channel.
Advanced usage
Windows Azure Service Bus Messaging offers advanced features such as
receiving message in the PeekLock
mode, when a message is removed
from the Queue/Subscription after the client will send a request to complete the
message, client batching processing, session-full messaging, etc. These advanced features are not
described in this article. More details can be found in the
Service Bus Brokered Messaging Performance - Best Practices Guide.
In this article, we used access to the Service Bus by .Net API clients
(wrapped by wcf paradigm) implemented in the Azure SDK. The REST API can be used
for .Not application with some limitations. Please, read more about this in
Service Bus REST API Reference.
This article described usage of the Windows Azure Service Bus Messaging by
WCF and WF Technologies. The Azure Service Bus Messaging is built in the multi-tenant
environment and it represents a logical connectivity between its producers and
consumers located on promises and/or Azure environments. The Service Bus is not
a technology, it is a service solution for queuing and Pub/Sub messaging for
event-driven architecture and intra-application message exchange in the
transparent loosely decouple manner. Definitely, the Azure Service Bus plays a
significant role in the business model for mapping a centralized logical
connectivity to the decentralized physical one. I hope you enjoyed this
article.
[1]
Service Bus
[2]
Windows Azure AppFabric Service Bus Brokered Messaging
[3]
Service Bus Brokered Messaging Performance - Best Practices Guide
[4] Service
Bus Topics and Queues – Advanced
[5] The
Windows Azure AppFabric Service Bus: Topics
[6]
Exploring Azure AppFabric Service Bus V2 May CTP: Topics
[7]
Best Practices for Leveraging Windows Azure Service Bus Brokered Messaging API
[8]
How to integrate a BizTalk Server application with Service Bus Queues and Topics
[9] Overview
of Creating a Hosted Service for Windows Azure
[10]
Creating a
Hosted Service for Windows Azure
[11]
Exploring Topics and Queues by Building a Service Bus Explorer Tool–Part 1
[12]
Windows Azure AppFabric Samples
[13]
Azure AppFabric Service Bus Brokered Messaging GA & Rude CTP Diffs
[14]
Exploring Azure AppFabric Service Bus V2 May CTP: Queues
[15]
SqlExpression
[16] Service Bus Samples on
CodePlex
[17]
Using Service Bus Topics and Subscriptions with WCF