ESB http://rickgaribay.net/category/22.aspx ESB en-US Rick G. Garibay rickgaribay@hotmail.com Subtext Version 1.9.5.176 Introducing the Neuron Azure Service Bus Adapter for Neuron 3.0 http://rickgaribay.net/archive/2013/02/26/introducing-the-neuron-azure-service-bus-adapter-for-neuron-3.0.aspx <p>Anyone who knows me knows that I’m a messaging nerd. I love messaging so much, that I all but gave up web development years ago to focus exclusively in the completely unglamorous spa<a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/Neuron_Logo_3_Gray_and_Blue_PNG_6.png"><img style="background-image: none; border-right-width: 0px; margin: 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="Neuron_Logo_3_Gray_and_Blue_PNG" border="0" alt="Neuron_Logo_3_Gray_and_Blue_PNG" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/Neuron_Logo_3_Gray_and_Blue_PNG_thumb_2.png" width="240" height="60" /></a>ce of messaging, integration and middleware. What drives me to this space? Why not spend my time and focus my career on building sexy Web or device apps that are much more fashionable and that will allow people to actually see something tangible, that they can see, touch and feel?</p> <p>These are questions I ponder often, but every time I do, an opportunity presents itself to apply my passion for messaging and integration in new and interesting ways that have a pretty major impact for my clients and the industry as a whole. Some recent examples of projects I led and coded on include the Intelligent Transportation and Gaming space including developing <a href="http://www.prepass.com/services/PrePassGates/Pages/WhatIsPrePassGates.aspx" target="_blank">an automated gate management solution</a> to better secure commercial vehicles for major carriers when they’re off the road; integrating slot machines for a major casino on the Vegas strip with other amenities on property to create an ambient customer experience and <a href="http://www.microsoft.com/casestudies/Case_Study_Detail.aspx?CaseStudyID=710000000945" target="_blank">increasing the safety of our highways by reading license plates and pushing messages to and from the cloud</a>. These are just a few recent examples of the ways in which messaging plays an integral role in building highly compelling and interesting solutions that otherwise wouldn’t be possible. Every day, my amazing team at Neudesic is involved in designing and developing solutions on the Microsoft integration platform that have truly game changing business impacts for our clients.</p> <p>As hybrid cloud continues to prove itself as the most pragmatic approach for taking advantage of the scale and performance of cloud computing, the need for messaging and integration becomes only more important. Two technologies that fit particularly well in this space are Neuron and Azure Service Bus. I won’t take too much time providing an overview of each here as there are plenty of good write ups out there that do a fine job, but I do want to share some exciting news that I hope you will find interesting if you are building hybrid solutions today and/or working with Azure Service Bus or Neuron.</p> <p>Over the last year, the Neuron team at Neudesic has been hard at work cranking out what I think is the most significant release since version 1.0 which I started working with back in 2007 and <a href="http://products.neudesic.com/latest" target="_blank">I’m thrilled to share that as of today, Neuron 3.0 is live!</a></p> <p>Building on top of an already super solid WCF 4.0 foundation, <a href="http://products.neudesic.com/Help3/Neuron.htm" target="_blank">Neuron 3.0</a> is a huge release for both Neudesic and our clients, introducing a ton of new features including:</p> <table border="0" cellspacing="0" cellpadding="2" width="1550"><tbody> <tr> <td valign="top" width="469"> <p> </p> <ul> <li><font size="3">Full Platform support for Microsoft .NET 4/LINQ, Visual Studio 2010/2012 </font></li> <li><font size="3">New features in <strong>Management and Administration</strong> including </font> <ul> <li><font size="3">New User Interface Experience </font></li> <li><font size="3">Queue Management </font></li> <li><font size="3">Server and Instance Management </font></li> <li><font size="3">Dependency Viewers </font></li> </ul> </li> <li><font size="3">New features in <strong>Deployment and Configuration</strong> <strong>Management</strong> including </font> <ul> <li><font size="3">New Neuron ESB Configuration storage </font></li> <li><font size="3">Multi Developer support </font></li> <li><font size="3">Incremental Deployment </font></li> <li><font size="3">Command line Deployment </font></li> </ul> </li> <li><font size="3">New features in <strong>Business Process Designer</strong> including </font></li> <ul> <li><font size="3">Referencing External Assemblies </font></li> <li><font size="3">Zoom, Cut, Copy and Paste </font></li> <li><font size="3">New Process Steps </font></li> <ul> <li><font size="3">Duplicate Message Detection </font></li> <li><font size="3">For Each loop </font></li> <li><font size="3">ODBC</font></li> </ul> </ul> <li><font size="3">New <strong>Custom Process Steps</strong> including </font></li> <ul> <li><font size="3">Interface for Controlling UI Properties </font></li> <li><font size="3">Folder hierarchy for UI display </font></li> </ul> <!--EndFragment--></ul> </td> <td valign="top" width="383"> <p><font size="3"></font></p> <ul> <li><font size="3">New features in <strong>Neuron Auditing</strong> including </font> <ul> <li><font size="3">Microsoft SQL Azure </font></li> <li><font size="3">Excluding Body and Custom Properties </font></li> <li><font size="3">Failed Message Monitoring </font></li> </ul> </li> <li><font size="3">New <strong>Messaging features</strong> including </font> <ul> <li><font size="3">AMQP Powered Topics with Rabbit MQ </font></li> <li><font size="3">Improved MSMQ Topic Support </font></li> <li><font size="3">Adapters </font> <ul> <li><font size="3">POP3 and Microsoft Exchange Adapters </font></li> <li><font size="3">ODBC Adapter enhancements </font></li> <li><font size="3"><strong>Azure Service Bus Adapter</strong> </font></li> </ul> </li> </ul> </li> <li><font size="3">New in <strong>Service Broker</strong> including </font></li> <ul> <li><font size="3">REST enhancements </font></li> <li><font size="3">REST support for Service Policies </font></li> <li><font size="3">WSDL support for hosted SOAP services </font></li> </ul> <li><font size="3">Many enhancements to UI, bug fixes and improvements to overall user experience.</font></li> </ul> </td> <td width="696" align="center"><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_20.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_thumb_6.png" width="547" height="464" /></a></td> </tr> </tbody></table> <p>In version 2.6, I worked with the team to bring Azure Service Bus Relay Messaging in as a first-class capability. Since Neuron is built on .NET and WCF, and the relay service is exposed very nicely using the WCF programming model, adding the relay bindings to Neuron’s Service Endpoint feature was a no-brainer. This immediately provided the ability to bridge or extend the on-premise pub-sub messaging, transformation, mediation, enrichment and security capabilities with Azure Service Bus Relay, enabling new, highly innovative hybrid solutions <a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_5.png"><img style="background-image: none; border-right-width: 0px; margin: 10px 5px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_thumb_1.png" width="538" height="354" /></a>for my team and our customers.</p> <p>Between then and this new release, Microsoft released support for queues and topics also known as <a href="http://msdn.microsoft.com/en-us/library/ee732537.aspx" target="_blank">Brokered Messaging</a>. These capabilities introduced the ability to model durable, pull-based pub-sub messaging in scenarios where such a brokered mechanism makes sense. To be clear, Brokered Messaging is not a replacement for Relay- in fact we’ve worked on a number of solutions where both the firewall friendly push messaging capabilities of relay fit  and even compliment certain scenarios (notification first pull-based pub-sub is a very handy dandy messaging pattern where both are used and perhaps I’ll write that up some day). Think of each being tools in your hybrid cloud messaging tool box. </p> <p>It didn’t take long to see the potential of these additions to Azure Service Bus and I started having discussions with the Neuron team at Neudesic and the Azure Service Bus team at Microsoft about building an adapter that like Relay, would bring Brokered Messaging capabilities to Neuron, enabling a complete, rich spectrum of hybrid messaging capabilities.</p> <p>Luckily, both teams agreed it was a good idea and Neudesic was nice enough to let me write the adapter. </p> <p>Obviously, as a messaging nerd, this was an incredibly fun project to work on and after just a couple of hours, I had my first spike up and running on a very early build of Neuron 3.0 which demonstrated pushing a message that was published to Neuron and re-published on an Azure Service Bus topic. 7 major milestones later, a number of internal demos, walkthroughs with the Service Bus Team and a ton of load and performance testing I completed what is now the initial release of the Neuron Azure Service Bus Adapter which ships with Neuron 3.0!</p> <p>What follows is a lap around the core functionality of the adapter largely taken from the product documentation that ships with Neuron 3.0. I hope you will find the adapter interesting enough to take a closer look and even if hybrid cloud is not on your mind, there are literally hundreds of reasons to consider Neuron ESB for your messaging needs. </p> <h2><a name="_Toc347777630"><font color="#000000">Overview</font></a></h2> <p>Windows Azure Service Bus is a Platform as a Service (PaaS) capability provided by Microsoft that provides a highly robust messaging fabric hosted by Microsoft Windows Azure. </p> <p>Azure Service Bus extends on-premise messaging fabrics such as Neuron ESB by providing pub-sub messaging capable of traversing firewalls, a taxonomy for projecting entities and very simple orchestration capabilities via rules and actions.</p> <p>As shown below, Azure Service Bus bridges on-premise messaging capabilities enabling the ability to develop hybrid cloud applications that integrate with external services and service providers that are located behind the firewall allowing a new, modern breed of compositions to transcend traditional network, security and business boundaries.</p> <p><a href="http://www.code-magazine.com/ShowLargeArticleImage.aspx?QuickID=1112041&amp;Image=Garibay%20Figure%201.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image002_8b14d496-1968-495a-9002-9e285eb97cec.jpg" width="575" height="350" /></a></p> <p><b><i>Bridging ESBs in Hybrid Clouds </i></b><i>– Azure Service Bus extends on-premise messaging fabrics such as Neuron ESB enabling a next generation of hybrid cloud applications that transcend traditional network, security and business boundaries.</i></p> <p>There are two services supported by Azure Service Bus: </p> <ul> <li><b>Azure Service Bus Relay:</b> Serves as a push-based relay between two (or more) endpoints. A client and service (or services) establish an outbound, bi-directional socket connection over either TCP or HTTP on the relay and thus, messages from the client tunnel their way through the relay to the service. In this way, both the client and service are really peers on the same messaging fabric. </li> </ul> <p> </p> <ul> <li><b>Azure Service Bus Brokered Messaging: </b>Provides a pull-based durable message broker that supports queues, topics and subscriptions. A party wishing to send messages to Azure Service Bus establishes a TCP or HTTP connection to a queue or topic and pushes messages to the entity. A party wishing to receive messages from Azure Service Bus establishes a TCP or HTP connection and pulls messages from a queue or subscription. </li> </ul> <p>Neuron ESB 3.0 supports both Azure Service Bus services and this topic focuses on support of <a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee732537.aspx">Azure Service Bus Brokered Messaging</a> via the Neuron Azure Service Bus Adapter.</p> <p>For more information on support for Azure Service Bus Relay support, please see “Azure Service Bus Integration” in the “Service Endpoints” topic in the Neuron ESB 3.0 product documentation.</p> <h2><a name="_Toc347777631"><font color="#000000">About the Neuron Azure Service Bus Adapter</font></a></h2> <p>The Neuron Azure Service Bus Adapter provides full support for the latest capabilities provided by the Windows Azure SDK version 1.7. </p> <p>Once the Neuron Azure Service Bus adapter is registered and an Adapter Endpoint is created, all configuration is managed through the property grid of the Adapter located on the properties tab of the Adapter Endpoint’s Details Pane:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image004_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image004_thumb.jpg" width="781" height="285" /></a></p> <p><b><i>Neuron Azure Service Bus Adapter – Property Grid </i></b><i>– All configurations for adapter is managed through the property grid. Properties are divided into 3 sections, General, Publish Mode Properties, and Subscribe Mode Properties.</i></p> <p>Please note that in order to connect to an Azure Service Bus entity with the Neuron Azure Service Bus adapter, you need to sign up for an Azure account and create an Azure Service Bus namespace with the required entities and ACS configuration. For more information, visit <a href="http://azure.com">http://azure.com</a></p> <h4><a name="_Toc347777632"><font color="#000000">Features</font></a></h4> <p>The Neuron Azure Service Bus adapter supports the following Azure Service Bus Brokered Messaging features:</p> <ul> <li>Send to Azure Service Bus Queue </li> <li>Send to Azure Service Bus Topic </li> <li>Receive from Azure Service Bus Queue </li> <li>Receive from Azure Service Bus Subscription </li> </ul> <p>In addition, the Neuron Azure Service Bus adapter simplifies the development experience by providing additional capabilities typical in production scenarios without the need to write custom code including:</p> <ul> <li>Smart Polling </li> <li>Eventual Consistency </li> <li>Transient Error Detection and Retry </li> </ul> <p>The Neuron Azure Service Bus adapter is installed as part of the core Neuron ESB installation. The adapter is packaged into a single assembly located within the <b>\Adapters</b> folder under the root of the default Neuron ESB installation directory:</p> <p>· Neuron.Esb.Adapters.AzureServiceBusAdapter.dll </p> <p>In addition, the following assembly is required and automatically installed in the root of the folder created for the service instance name:</p> <p>· Microsoft.ServiceBus.dll (Azure SDK version 1.7)</p> <p>To use the adapter, it must first be registered within the <i>Neuron ESB Explorer Adapter Registration Window</i>. Within the Adapter Registration Window, the adapter will appear with the name “<b>Azure Service Bus Adapter</b>”. Once registered, a new Adapter Endpoint can be created and configured with an instance name of your choice:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image006_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image006_thumb.jpg" width="780" height="509" /></a></p> <p><b><i>Neuron ESB Explorer Adapter Registration Window</i> -<i> Property Grid </i></b><i>– Before configuring the adapter instance for Publish or Subscribe mode, the adapter must first be registered.</i></p> <h4><a name="_Toc347777633"><font color="#000000">Supported Modes</font></a></h4> <p><font color="#000000">Once the initial registration is complete, the Neuron Azure Service Bus adapter can be configured in one of 2 modes: Publish and Subscribe. </font></p> <h4><a name="_Toc347777634"><font color="#000000">Publish</font></a></h4> <p>Publish mode allows Neuron ESB to monitor an Azure Service Bus Queue or Subscription by regularly polling, de-queuing all the messages, and publishing those messages to a Neuron ESB Topic. Messages are read synchronously via a one-way MEP.</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image008_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image008_thumb.jpg" width="779" height="85" /></a></p> <p><b><i>Receiving Messages from Azure Service Bus </i></b><i>– When in Publish mode, the adapter supports receiving messages from an Azure Service Bus entity and publishing the messages on Neuron ESB.</i></p> <h6><font size="2">Configuration</font></h6> <p>Configuring the Publish mode of the Neuron Azure Service Bus adapter requires that minimally, the following properties are set:</p> <h6><font color="#000000" size="2">General Properties</font></h6> <ul> <li>Azure Service Bus Namespace Name - A registered namespace on Azure Service Bus. For example 'neudesic' would be the namespace for: sb://neudesic.servicebus.windows.net (for information on how to provision, configure and manage Azure Service Bus namespaces, please see the Azure Service Bus topic on <a href="http://azure.com">http://azure.com</a>). </li> <li>Azure ACS Issuer Name – The account/claim name for authenticating to the Windows Azure Access Control Service (ACS - For information on how to provision, configure and manage Azure Access Control namespaces, please see the Azure Access Control topic on <a href="http://azure.com">http://azure.com</a>). </li> <li>Azure ACS Key – The shared key used in conjunction with Azure ACS Issuer Name. </li> <li>Azure Entity Type - Queue or Subscription </li> <li>Azure Channel Type – Default, if outbound TCP port 9354 is open or HTTP to force communication over HTTP port 80/443 (In Default mode, the Neuron Azure Service Bus Adapter will try to connect via TCP. If outbound TCP port 9354 is not open, choose HTTP). </li> <li>Retry Count - The number of Service Bus operations retries to attempt in the event of a transient error (for more information on this setting, see the “Understanding Transient Error Detection and Retry” topic). </li> <li>Minimum Back-Off - The minimum number of seconds to wait before automatically retrying a Service Bus operation in the event that a transient error is encountered (for more information on this setting, see the “Understanding Transient Error Detection and Retry” topic). </li> <li>Maximum Back-Off - The maximum number of seconds to wait before automatically retrying a Service Bus operation in the event that a transient error is encountered (for more information on this setting, see the “Understanding Transient Error Detection and Retry” topic). </li> </ul> <h6><font size="2">Publish Properties</font></h6> <ul> <li>Azure Queue Name- The name of the queue that you want to receive messages from (this option appears when you choose “Queue” as the Azure Entity Type in General Properties). </li> <li>Azure Topic Name – The name of the topic that the subscription you want to receive messages from is associated with (this option appears when you choose “Topic” as the Azure Entity Type in General Properties). </li> <li>Azure Subscription Name - The name of the subscription you want to receive messages from (this option appears when you choose “Topic” as the Azure Entity Type in General Properties). </li> <li>Delete After Receive – False by default. If set to True, deletes the message from the queue or topic after it is received regardless of whether it is published to Neuron successfully (for more information on this setting, see the “Understanding Eventual Consistency” topic). </li> <li>Wait Duration - Duration (in seconds) to wait for a message on the queue or subscription to arrive before completing the poll request (for more information on this setting, see the “Understanding Smart Polling” topic). </li> <li>Neuron Publish Topic - The Neuron topic that messages will be published to. Required for Publish mode. </li> <li>Error Reporting – Determines how all errors are reported in the Windows Event Log and Neuron Logs. Either as Errors, Warnings or Information. </li> <li>Error on Polling – Register failed message and exception with Neuron Audit database. Please note that a valid SQL Server database must be configured and enabled. </li> <li>Audit Message on Failure - Determines if polling of data source continues on error and if consecutive errors are reported. </li> </ul> <p>The following shows the General configuration for an instance of the Neuron Azure Service Bus adapter called “Azure - Receive” in Publish mode:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image010_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image010_thumb.jpg" width="780" height="178" /></a></p> <p><b><i>Publish Mode General Configuration</i></b><i>– When in Publish mode, the adapter supports receiving messages from an Azure Service Bus entity and publishing the messages on Neuron ESB.</i></p> <p>The following shows the Properties configuration for a fully configured instance of the Neuron Azure Service Bus adapter in Publish mode:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image012_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image012_thumb.jpg" width="780" height="201" /></a></p> <p><b><i>Publish Mode Properties Configuration</i></b><i>– When in Publish mode, the adapter supports receiving messages from an Azure Service Bus entity and publishing the messages on Neuron ESB.</i></p> <h4><a name="_Toc347777635"><font color="#000000">Subscribe</font></a></h4> <p>Subscribe mode allows Neuron ESB to write messages that are published to Neuron ESB to an Azure Service Bus queue or topic. In this manner, Neuron ESB supports the ability to bridge an Azure Service Bus entity, allowing for on-premise parties to seamlessly communicate with Azure Service Bus. Once Neuron ESB receives a message, it sends the message to an Azure Service Bus Queue or Topic.</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image014_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image014_thumb.jpg" width="779" height="85" /></a></p> <p><b><i>Sending Messages to Azure Service Bus </i></b><i>– When in Subscribe mode, the adapter supports sending messages published on Neuron ESB to an Azure Service Bus entity.</i></p> <h6><font size="2">Configuration</font></h6> <p>In addition to the General Properties covered under the Publish mode documentation, configuring the Subscribe mode of the Neuron Azure Service Bus adapter requires that minimally, the following properties are set:</p> <h6><font size="2">Subscribe Properties</font></h6> <ul> <li>Adapter Send Mode - Choose Asynchronous for maximum throughput or Synchronous for maximum reliability (for more information on this setting, see the “Choosing Synchronous vs. Asynchronous” topic). </li> <li>Adapter Queue Name - The name of the queue you want to send messages to (this option appears when you choose “Queue” as the Azure Entity Type in General Properties). </li> <li>Adapter Topic Name - The name of the topic you want to send messages to (this option appears when you choose “Topic” as the Azure Entity Type in General Properties). </li> </ul> <p>The following shows the General configuration for an instance of the Neuron Azure Service Bus adapter called “Azure - Send” in Subscribe mode:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image016_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image016_thumb.jpg" width="780" height="170" /></a></p> <p><b>S<em>ubscribe Mode General Configuration</em></b><em>– When in Subscribe mode, the adapter supports sending messages from Neuron ESB to an Azure Service Bus entity.</em></p> <p>The following shows the Properties configuration for a fully configured instance of the Neuron Azure Service Bus adapter in Subscribe mode:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image018_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image018_thumb.jpg" width="780" height="158" /></a></p> <p><b><i>Subscribe Mode General Configuration</i></b><i>– When in Subscribe mode, the adapter supports sending messages from Neuron ESB to an Azure Service Bus entity.</i></p> <h2><a name="_Toc347777636"><font color="#000000">Understanding Transient Error Detection and Retry</font></a></h2> <p><font color="#000000">When working with services in general and multi-tenant PaaS services in particular, it is important to understand that in order to scale to virtually hundreds of thousands of users/applications, most services like Azure Service Bus, SQL Azure,</font> etc. implement a throttling mechanism to ensure that the service remains available.</p> <p>This is particularly important when you have a process or application that is sending or receiving a high volume of messages because in these cases, there is a high likelihood that Azure Service Bus will throttle one or several requests. When this happens, a fault/HTTP error code is returned and it is important for your application to be able to detect this fault and attempt to remediate accordingly.</p> <p>Unfortunately, throttle faults are not the only errors that can occur. As with any service, security, connection and other unforeseen errors (exceptions) can and will occur, so the challenge becomes not only being able to identify the type of fault, but in addition, know what steps should be attempted to remediate. </p> <p>Per the guidance provided by the Azure Customer Advisory Team (<a href="http://windowsazurecat.com/2010/10/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications/">http://windowsazurecat.com/2010/10/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications/</a>), the Neuron Azure Service Bus adapter uses an exponential back-off based on the values provided for the Retry Count, Minimum Back-Off and Maximum Back-Off properties within the Properties tab for both Publish and Subscribe mode.</p> <p>Given a value of 3 retries, two seconds and ten seconds respectively, the adapter will automatically determine a value between two and ten and back off exponentially one time for each retry configured:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image020_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image020_thumb.jpg" width="780" height="158" /></a></p> <p><b><i>Exponential Back-Off Configuration</i></b><i>– The adapter will automatically detect transient exceptions/faults and retry by implementing an exponential back-off algorithm given a retry count, initial a<a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image022_4.jpg"><img style="background-image: none; border-right-width: 0px; margin: 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image022" border="0" alt="clip_image022" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image022_thumb_1.jpg" width="111" height="293" /></a>nd max back-off configuration.</i></p> <p>Taking this example, as shown in the figure on the right, if the adapter chose an initial back-off of two seconds, in the event of a transient fault being detected (i.e. throttle, timeout, etc.) the adapter would wait two seconds before trying the operation again (i.e. sending or receiving a message) and exponentially increment the starting value until either the transient error disappears or the retry count is exceeded.</p> <p>In the event that the retry count is exceeded, the Neuron Azure Service Bus adapter will automatically persist a copy of the message in the audit database to ensure that no messages are lost (provided a SQL Server database has been configured).</p> <h2><a name="_Toc347777637"><font color="#000000">Understanding Smart Polling</font></a></h2> <p><font color="#000000">When <a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_7.png"><img style="background-image: none; border-right-width: 0px; margin: 10px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_thumb.png" width="161" height="240" /></a>configuring the Neuron Azure Service Bus Adapter in Publish mode, the adapter can take advantage of a Neuron ESB feature known as Smart Polling. </font></p> <p><font color="#000000">With Smart Polling, the adapter will connect to an Azure Service Bus queue or subscription and check for messages. If one or message is available, all messages will be immediately delivered (see “Understanding Eventual Consistency” for more information on supported read behaviors). </font></p> <p><font color="#000000">However, if no messages are available, the adapter will open a connection to the Azure Service Bus entity and wait for a specified timeout before attempting to initiate another poll request (essentially resulting in a long-polling behavior). In this manner, Azure Service Bus quotas are honored while ensuring that the adapter issues a receive request only when the configured timeout occurs as opposed to repeatedly polling the Azure Service Bus entity.</font></p> <h2><a name="_Toc347777638"><font color="#000000">Understanding Eventual Consistency</font></a></h2> <p><font color="#000000">When working with Azure Service Bus, it is important to note that the model for achieving consistency is different than traditional distributed transaction models. For example, when working with modern relational databases or spanning multiple services that are</font> composed into a logical unit of work (using WS-Atomic Transactions for example), it is a common expectation that work will either be performed completely or not at all. These types of transactions have the characteristics of being atomic, consistent, independent and durable (ACID). However, to achieve this level of consistency, a resource manager is required to coordinate the work being carried out by each service/database that participates in a logical transaction.</p> <p>Unfortunately, given the virtually unlimited scale of the web and cloud computing, it is impossible to deploy enough resource managers to account for the hundreds of thousands if not millions of resources required to achieve this level of consistency. Even if this were possible, the implications on achieving the scale and performance demanded by modern cloud-scale applications would be physically impossible.</p> <p>Of course, consistency is still as important for applications that participate in logical transactions across or consume cloud services. An alternative approach is to leverage an eventually consistent, or basically available, soft state, eventually consistent (BASE) approach to transactions. </p> <h6><font size="2">Ensuring Eventual Consistency in Publish Mode<a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_10.png"><img style="background-image: none; border-right-width: 0px; margin: 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/image_thumb_2.png" width="240" height="104" /></a></font></h6> <p>Azure Service Bus supports this model for scenarios that require consistency and the Neuron Azure Serviced Bus adapter makes taking advantage of this capability simply a matter of setting the “Delete After Receive” property (available in the Publish Mode Settings) to False, which is the default. </p> <p>When set to False, when receiving a message, the adapter will ensure that the message is not discarded from the Azure Service Bus entity until the message has been successfully published to Neuron ESB. In the event that an error occurs when attempting to publish a message, the message will be restored on the Azure Service Bus entity ensuring that it remains available for a subsequent attempt to receive the message (Please note that lock durations configured on the entity will affect the behavior of this feature. For more information, please refer to the Azure Service Bus documentation on MSDN: <a href="http://msdn.microsoft.com/en-us/library/ee732537.aspx">http://msdn.microsoft.com/en-us/library/ee732537.aspx</a>).</p> <h2><a name="_Toc347777639"><font color="#000000">Choosing Synchronous versus Asynchronous Receive</font></a></h2> <p><font color="#000000">When the Neuron Azure Service Bus adapter is configured in Subscribe mode, you can choose to send messages to an Azure Service Bus queue or topic in either synchronous or asynchronous mode by setting the <b><i>Adapter Send Mode </i></b>property to either “Asynchronous” or “Synchronous</font>” in the Subscribe Mode Property group. </p> <p>If reliability is a top priority such that the possibility of message loss cannot be tolerated, it is recommended that you choose Synchronous. In this mode, the adapter will transmit messages to an Azure Service Bus queue or topic at rate of about 4 or 5 per second. While it is possible to increase this throughput by adding additional adapters in subscribe mode, as a general rule, use this mode when choosing reliability at the expense of performance/throughput.</p> <p>To contrast, if performance/low-latency/throughput is a top priority, configuring the adapter to send asynchronously will result in significantly higher throughput (by several orders of magnitude). While the send performance in this mode is much higher, in the event of a catastrophic failure (server crash, out of memory exception) it is possible for messages that have left the Neuron ESB process but have not yet been transmitted to the Azure Service Bus (i.e. are in memory) the possibility for message loss is much higher than when in synchronous mode because of the significantly higher density of messages being transmitted. </p> <p><b></b></p> <h2><a name="_Toc347777640"><font color="#000000">Other Scenarios</font></a></h2> <h4><a name="_Toc347777641"><font color="#000000">Temporal Decoupling</font></a></h4> <p><font color="#000000"><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image024_2.jpg"><img style="background-image: none; border-right-width: 0px; margin: 10px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image024" border="0" alt="clip_image024" align="left" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image024_thumb.jpg" width="133" height="157" /></a>One of the benefits of any queue-based messaging pattern is that the publisher/producer is decoupled from the subscribers/consumers. As a result, parties interested in a given message can be added and removed without any knowledge of the publisher/producer.</font></p> <p><font color="#000000">By persisting the message until</font> an interested party receives the message, the sending party is further decoupled from the receiving party because the receiving party need not be available at the time the message was written to persistence store. Azure Service Bus supports temporal decoupling with both queues and topics because they are durable entities.<a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image026_2.jpg"><img style="background-image: none; border-right-width: 0px; margin: 10px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image026" border="0" alt="clip_image026" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image026_thumb.jpg" width="117" height="240" /></a></p> <p>As a result, a party that writes new order messages to an Azure Service Bus queue can do so uninhibitedly as shown below: </p> <p>When you configure an instance of the Neuron Azure Service Bus adapter in Publish mode, you can disable the adapter by unchecking the “Enabled” box. Any new messages written to the Azure Service Bus queue or subscription will persist until the adapter is enabled once again. </p> <p><b></b></p> <h4><a name="_Toc347777642"><font color="#000000">Competing Consumers</font></a></h4> <p><font color="#000000">Another messaging pattern that allows you to take advantage of the benefits of pull-based pub-sub model from a performance and scalability perspective is to adjust the number of consumers supported by the resources available to you</font> and keep adding consumers until throughput requirements are met.</p> <p>To take advantage of this pattern with the Neuron Azure Service Bus adapter and Azure Service Bus, simply add additional instances of the Publishing adapter as needed:</p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image028_2.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image028" border="0" alt="clip_image028" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/848795df03a9_13251/clip_image028_thumb.jpg" width="568" height="277" /></a></p> <p><b><i>Competing Consumers </i></b><i>–Adding additional consumers with Neuron Azure Service Bus is simply a matter of adding additional instances of the Publishing adapter. </i></p> <h2><a name="_Toc347777643"><font color="#000000">Property Table</font></a></h2> <p> </p> <p>The following table provides details for each property exposed through the Neuron Explorer UI:</p> <table border="1" cellspacing="0" cellpadding="0"><tbody> <tr> <td valign="top" width="18%"> <p><b>Section Name</b></p> </td> <td valign="top" width="19%"> <p><b>Property Name</b></p> </td> <td valign="top" width="10%"> <p><b>Required</b></p> </td> <td valign="top" width="50%"> <p><b>Description</b></p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i>General</i></p> </td> <td valign="top" width="19%"> </td> <td valign="top" width="10%"> </td> <td valign="top" width="50%"> <p><i>These properties are used for all modes of the adapter</i></p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Azure Service Bus Namespace Name </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p>A registered namespace on Azure Service Bus. For example 'neudesic' would be the namespace for: sb://neudesic.servicebus.windows.net </p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Azure ACS Issuer Name </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p>The account/claim name for authenticating to the Windows Azure Access Control Service (ACS) </p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Azure ACS Key</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p>The shared key used in conjunction with Azure ACS Issuer Name.</p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Azure Entity Type </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p><b>Default Queue. </b>Queue or Topic</p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Azure Channel Type</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p><b>Default is Default.</b> Default, if outbound TCP port 9354 is open or HTTP to force communication over HTTP port 80/443 </p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Retry Count </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p><b>Default 5. </b>The number of Service Bus operations retries to attempt in the event of a transient error (for more information on this setting, see the “Understanding Transient Error Detection and Retry” topic). </p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Minimum Back Off</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p><b>Default 3. </b>The minimum number of seconds to wait before automatically retrying a Service Bus operation in the event that a transient error is encountered (for more information on this setting, see the “Understanding Transient Error Detection and Retry” topic).</p> </td> </tr> <tr> <td valign="top" width="18%"> </td> <td valign="top" width="19%"> <p>Maximum Back Off</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p><b>Default 3.</b> The maximum number of seconds to wait before automatically retrying a Service Bus operation in the event that a transient error is encountered (for more information on this setting, see the “Understanding Transient Error Detection and Retry” topic).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i>Publish Properties</i></p> </td> <td valign="top" width="19%"> </td> <td valign="top" width="10%"> </td> <td valign="top" width="50%"> <p><i>These properties are only used when the adapter is in either Request/Response or Publish mode.</i></p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Azure Queue Name</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p>The name of the queue that you want to receive messages from (this option appears when you choose “Queue” as the Azure Entity Type in General Properties).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Azure Topic Name </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p>The name of the topic that the subscription you want to receive messages from is associated with (this option appears when you choose “Topic” as the Azure Entity Type in General Properties).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Azure Subscription Name </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p>The name of the subscription you want to receive messages from (this option appears when you choose “Topic” as the Azure Entity Type in General Properties).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Delete After Receive</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p><b>Default False</b>. If set to True, deletes the message from the queue or topic after it is received regardless of whether it is published to Neuron successfully (for more information on this setting, see the “Understanding Eventual </p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Wait Duration </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p><b>Default 5.</b> Duration (in seconds) to wait for a message on the queue or subscription to arrive before completing the poll request (for more information on this setting, see the “Understanding Smart Polling” topic).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Neuron Publish Topic </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p>The Neuron topic that messages will be published to. Required for Publish mode.</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Error Reporting </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p><b>Default Error. </b>Determines how all errors are reported in the Windows Event Log and Neuron Logs. Either as Errors, Warnings or Information.</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Error on Polling</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p><b>Default Stop Polling On Error. </b>Register failed message and exception with Neuron Audit database. Please note that a valid SQL Server database must be configured and enabled.</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="bottom" width="19%"> <p>Audit Message on Failure </p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="bottom" width="50%"> <p><b>Default False. </b>Determines if polling of data source continues on error and if consecutive errors are reported.</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i>Subscribe Properties</i></p> </td> <td valign="top" width="19%"> </td> <td valign="top" width="10%"> </td> <td valign="top" width="50%"> <p><i>These properties are only used when the adapter is in either Solicit/Response or Request/Response mode.</i></p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="top" width="19%"> <p>Adapter Send Mode</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p><b>Default Asynchronous. </b>Choose Asynchronous for maximum throughput or Synchronous for maximum reliability (for more information on this setting, see the “Choosing Synchronous vs. Asynchronous” topic).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="top" width="19%"> <p>Adapter Queue Name</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p>The name of the queue you want to send messages to (this option appears when you choose “Queue” as the Azure Entity Type in General Properties).</p> </td> </tr> <tr> <td valign="top" width="18%"> <p><i></i></p> </td> <td valign="top" width="19%"> <p>Adapter Topic Name</p> </td> <td valign="top" width="10%"> <p>Yes</p> </td> <td valign="top" width="50%"> <p>The name of the topic you want to send messages to (this option appears when you choose “Topic” as the Azure Entity Type in General Properties).</p> </td> </tr> </tbody></table> <h2><a name="_Toc347777644"><font color="#000000">Message Format</font></a></h2> <p><font color="#000000">Azure Service Bus uses a proprietary message envelope called a </font><a href="http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.servicebus.messaging.brokeredmessage.aspx"><font color="#000000">Brokered Message</font></a><font color="#000000"> as the unit of communication between all messaging entities including queues, topics and subscriptions.</font></p> <h4><a name="_Toc347777645"><font color="#000000">Publish Mode</font></a></h4> <p><font color="#000000">In Publish mode, the</font> Neuron Azure Service Bus Adapter will automatically map the body of the incoming Brokered Message to the Body property of the Neuron ESBMessage serializing the payload based on the detected encoding type as follows: </p> <p> </p> <p> </p><table border="1" cellspacing="0" cellpadding="0"><tbody> <tr> <td valign="top" width="282"> <p><b>BrokeredMessage.ContentType</b></p> </td> <td valign="top" width="254"> <p><b>ESBMessage.Header.BodyType</b></p> </td> </tr> <tr> <td valign="top" width="282"> <p>text/plain</p> </td> <td valign="top" width="254"> <p>text/plain</p> </td> </tr> <tr> <td valign="top" width="282"> <p>text/xml</p> </td> <td valign="top" width="254"> <p>text/xml</p> </td> </tr> <tr> <td valign="top" width="282"> <p>application/msbin-1</p> </td> <td valign="top" width="254"> <p>application/msbin-1</p> </td> </tr> <tr> <td valign="top" width="282"> <p>binary/bytes</p> </td> <td valign="top" width="254"> <p>binary/bytes</p> </td> </tr> <tr> <td valign="top" width="282"> <p>Other</p> </td> <td valign="top" width="254"> <p>text/xml</p> </td> </tr> </tbody></table> <p>Note per the table above that unless otherwise specified, the Neuron Azure Service Bus adapter will assume that the incoming message payload is text/xml. </p> <p>In addition, any properties stored in the Property property bag of the BrokeredMessage will be automatically mapped to the ESBMessage property bag provided the “Include Metadata” option is checked on the General tab in the Adapter Endpoints configuration. An exception to this rule is that the adapter will always map the BrokeredMessage.LockToken to the ESBMessage property bag with the same name regardless of whether “Include Metadata” is checked. </p> <h4><a name="_Toc347777646"><font color="#000000">Subscribe Mode</font></a></h4> <p>In Subscribe mode, the Neuron Azure Service Bus Adapter will automatically create a new Brokered Message for each transmission and map the body of an outgoing ESBMessage to the new message body as follows: </p> <p> </p> <p> </p><table border="1" cellspacing="0" cellpadding="0"><tbody> <tr> <td valign="top" width="282"> <p><b>ESBMessage.Header.BodyType</b></p> </td> <td valign="top" width="258"> <p><b>BrokeredMessage.ContentType</b></p> </td> </tr> <tr> <td valign="top" width="282"> <p>text/plain</p> </td> <td valign="top" width="258"> <p>text/plain</p> </td> </tr> <tr> <td valign="top" width="282"> <p>text/xml</p> </td> <td valign="top" width="258"> <p>text/xml</p> </td> </tr> <tr> <td valign="top" width="282"> <p>application/msbin-1</p> </td> <td valign="top" width="258"> <p>application/msbin-1</p> </td> </tr> <tr> <td valign="top" width="282"> <p>binary/bytes</p> </td> <td valign="top" width="258"> <p>binary/bytes</p> </td> </tr> <tr> <td valign="top" width="282"> <p>Other</p> </td> <td valign="top" width="258"> <p>text/xml</p> </td> </tr> </tbody></table> <p>In addition, any properties stored in the Property property bag of the ESBMessage will be automatically mapped to the BrokeredMessage property bag provided the “Include Metadata” option is checked on the General tab in the Adapter Endpoints configuration. </p> <h2><a name="_Toc347777647"><font color="#000000">Brokered Message Limitations</font></a></h2> <p>Note that the total payload size for Azure Service Bus messages is 256KB. The Neuron Azure Service Bus adapter will throw a runtime exception if a message greater than or equal to 256KB is sent and will save the message to the failed audit table. </p> <h2>Wrapping Up</h2> <p>Thanks for your interest and please don’t hesitate to hit me with questions, comments and feedback. If you see something missing, I’d love to hear from you as we are already starting to think about features for v.Next.</p> <p>I had a ton of fun writing this adapter and would like to that the Neuron product team for allowing me to make this small contribution to this incredible release.</p> <p>This adapter is just a small part of this major release and I hope this post has peeked your interest in <a href="http://products.neudesic.com/latest" target="_blank">checking out Neuron ESB</a>. Getting up and running is super simple and you can download the trial bits here: <a title="http://products.neudesic.com/" href="http://products.neudesic.com/">http://products.neudesic.com/</a></p><img src="http://rickgaribay.net/aggbug/355.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2013/02/26/introducing-the-neuron-azure-service-bus-adapter-for-neuron-3.0.aspx Tue, 26 Feb 2013 17:47:44 GMT http://rickgaribay.net/archive/2013/02/26/introducing-the-neuron-azure-service-bus-adapter-for-neuron-3.0.aspx#feedback 1 http://rickgaribay.net/comments/commentRss/355.aspx http://rickgaribay.net/services/trackbacks/355.aspx DCC 2011.2 Lap Around Azure Service Bus: The Goods http://rickgaribay.net/archive/2011/11/05/dcc-2011.2-lap-around-azure-service-bus-the-goods.aspx <p>Thanks to all that came out to my “<a href="http://nov2011.desertcodecamp.com/session/430" target="_blank">Lap Around Azure Service Bus Brokered Messaging</a>” talk at Desert Code Camp today. </p> <p>We covered a ton of content including things a few folks didn’t know about relay messaging capabilities in Azure Service Bus and demonstrated how simple it is to expose a REST or SOAP endpoint from behind the firewall. I also demonstrated the brand new load balancing capabilities that were just released last week. </p> <p>From there, we dove deep into the .NET API to walk through how to provision queues and topics from code and start messaging within minutes by simply grabbing the Azure Service Bus NuGet package and writing a few lines of code.<iframe height="327" src="http://r.office.microsoft.com/r/rlidPowerPointEmbed?p1=1&amp;p2=1&amp;p3=SDDF930EE6F91132FD!422&amp;p4=&amp;kip=1" frameborder="0" width="402" scrolling="no" align="right"></iframe></p> <p>Next, we explored the REST API, and how simple it is for any HTTP client, regardless of platform to take advantage of the robust messaging capabilities that Azure Service Bus queues and topics have to offer.</p> <p>Last but not least, we wrapped up with a quick walkthrough of the NeMessagingBinding and how simple it is to send and receive messages over a queue using the familiar WCF programming model.</p> <p>I hope that each of you will unlock new possibilities with the power that these hybrid messaging capabilities have to offer. </p> <p>I’d also like to thank <a href="http://www.pluralsight-training.net/microsoft/" target="_blank">Pluralsight</a> for sponsoring my session. The <a href="http://twitter.com/#!/search/realtime/%23dcc11%20%23Azure%20%23ServiceBus%20%23Q1" target="_blank">quiz is now up</a> for the first 5 smartest attendees. </p> <p>Search for hashtags <a href="http://twitter.com/#!/search/realtime/%23dcc11%20%23Azure%20%23ServiceBus%20%23Q2" target="_blank">#dcc11 #Azure #ServiceBus #Q1 to #Q5.</a></p> <p>Good Luck! </p> <p> </p> <table border="0" cellspacing="0" cellpadding="2" width="229"><tbody> <tr> <td valign="middle" width="91"><strong>Code Demos</strong></td> <td valign="middle" width="136"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="https://skydrive.live.com/embedicon.aspx/Public/Talks/DCC%202011.2?cid=df930ee6f91132fd&amp;sc=documents" frameborder="0" marginwidth="0" scrolling="no" align="right"></iframe></td> </tr> </tbody></table> <p> </p> <p>Happy Messaging!</p><img src="http://rickgaribay.net/aggbug/323.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2011/11/05/dcc-2011.2-lap-around-azure-service-bus-the-goods.aspx Sat, 05 Nov 2011 21:33:25 GMT http://rickgaribay.net/archive/2011/11/05/dcc-2011.2-lap-around-azure-service-bus-the-goods.aspx#feedback http://rickgaribay.net/comments/commentRss/323.aspx http://rickgaribay.net/services/trackbacks/323.aspx Exploring AppFabric Service Bus V2 May CTP: Topics http://rickgaribay.net/archive/2011/05/31/exploring-appfabric-service-bus-v2-may-ctp-topics.aspx <p>In my previous <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">post</a>, I discussed Azure <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">AppFabric Service Bus Queues</a>, a key new capability in the first CTP of the Azure AppFabric Service Bus V2 release that was <a href="http://blogs.msdn.com/b/appfabric/archive/2011/05/14/announcing-the-windows-azure-appfabric-ctp-may-and-june-releases.aspx">announced</a> on May 17th.</p> <p>Queues are an important addition to Azure AppFabric Service Bus capabilities because they provide a solid foundation on which to build loosely coupled distributed messaging solutions. The natural decoupling of queues introduces a number of natural side effects that can further benefit non-functional quality attributes of your solution such as performance, scalability and availability. </p> <p>The graphic on the right is taken from my recent whitepaper <a href="http://www.microsoft.com/en-us/cloud/developer/resource.aspx?resourceId=developing-and-extending-apps&amp;fbid=JznnsphSt83">“Developing and Extending Apps for Windows Azure with Visual Studio”</a><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_2.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb.png" width="240" height="166" /></a> and shows the perpetual mismatch of supply and demand of IT capacities. If we think of this mismatch as load on the Y axis being introduced over time, the result is either failure to deliver a service or spending too much on hardware. <a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_4.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb_1.png" width="240" height="175" /></a>The goal, then is to align the demand with capacity. </p> <p>Queues allow us to get closer to the drawing on the left because capacity can be tuned to scale as needed and at its own pace. This is effective because with queues, a consumer/worker can be throttled to only consume what it can handle. If the consumer/worker is offline, items in the queue will queue up, providing classic “store and forward” capabilities. If the consumer/worker is very busy, it will only consume the messages it is able to reliably pull from the queue. If we add more consumers/workers, each consumer/worker will consume messages at its optimal rate (determined by processing capacity, tuning, etc.), resulting in a natural distribution of work. Of course, stronger, more capable consumers/workers may consume more messages, but as long as there are messages in the queue, there is work to be done and the capacity can be allocated accordingly.</p> <p>As you can see, queues are a great pattern for building loosely coupled distributed solutions, and the ability to add consumers/workers to a process or message exchange in a manner that is transparent from the client/producer perspective makes queues even more useful. </p> <p>This is the idea behind topics. Before I dive into topics though, let’s talk about the problem that topics are trying to solve.<a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_8.png"><img style="background-image: none; border-right-width: 0px; margin: 5px 2px 2px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb_3.png" width="123" height="192" /></a></p> <p><a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_6.png"><img style="background-image: none; border-right-width: 0px; margin: 2px 5px 2px 2px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb_2.png" width="123" height="179" /></a>In distributed systems, it is useful to design message exchanges in terms of publishers and subscribers. Publishers are clients that are either sending a request-response message and will wait for a response; or are sending a single, one way message and expect no response. Subscribers care about these messages for one reason or another and thus subscribe to these messages. This is the essence of the Publish-Subscribe, or more succinct “Pub-Sub” messaging pattern. A one-way pub-sub  message exchange pattern is modeled to my left, and again to my right to build on a concrete example. Purchases, be they on-line or at brick-and-mortar retail outlets typically involve a point-of-sale (POS) system. </p> <p>One of the first things a smart, modern POS software does when a unit is sold is to update inventory on that product so that the company can make proactive, intelligent decisions about managing inventory levels. In most cases, this is an administrative function, that is (or should be) transparent to the customer. When an order/sale is placed, an event occurs which is of interest to an Inventory Service that is responsible for decrementing the inventory count on a shared store. Of course, this is just one of several things that likely need to happen when an order is placed. Credit card authorization as well as fulfillment (whatever that means in the context of the purchase) needs to take place as shown below on your left. </p> <p>All of a sudden things are more complex than they were before. I want to decouple the POS Client from the downstream business of authorizing a credit card and shipping the product to the customer’s doorstep. Depending on the context, the credit authorization process may be request-response or one-way. For most high-volume online retailers, the financial outcome of <a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_10.png"><img style="background-image: none; border-right-width: 0px; margin: 5px 5px 2px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="left" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb_4.png" width="323" height="157" /></a>the transaction is transparent to the purchasing experience. Ever gotten an email from Amazon.com after you made your purchase letting you know that your order is in a pending state because you need to update your expiration date on file so it can authorize your credit card? This asynchronous approach is common to facilitate scale and performance, and it is also good business. </p> <p>It is very important to note that when the credit card authorization is designed as one-way, there are a number of guarantees that must be made. First, the Credit Service <em>must</em> receive the message, no matter how busy the front-end or back-end services are. Second, but of equal importance, is that the Credit Service <em>must</em> receive the message <em>once and only once. </em>Failure to deliver on the first or second guarantee will lead to lost revenue, either due to lost transactions or very disgruntled customers.</p> <p>Using queues is a first step towards achieving these desired outcomes. However, now we need to reason about who should have the responsibility of sending the message to each subscriber? It can’t be the POS Client, because we want to decouple it from this kind of intimate knowledge. Adding this responsibility to each subscriber is also just as bad, or arguably worse. <a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_12.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb_5.png" width="250" height="249" /></a></p> <p>What we need is an intermediary that forms both a logical and physical relationship between publishers and subscribers such that the minimum degree of coupling is accomplished between the two and no more. This is exactly what a topic provides. </p> <p>Topics are nothing new. They have been the mainstay of JMS-based systems for years, and thus have proven their usefulness in the field of distributed computing as a great way to logically associate actions to events, thus achieving pub-sub in a minimally coupled manner. </p> <p>In our scenario, when a sale occurs, the POS Client publishes a message to the “Orders” topic to signal a new order event. At this point, corresponding subscribers are notified by the topic. This logical relationship is modeled to your right. Each one of the subscribers might receive a copy of the same message, in which case we would define the message exchange pattern as multi-cast. It is also possible-and likely- that each service exposes a different contract and thus, transformation between a canonical message and the expected message must take place, but this is a subject for a later post.</p> <p>How the subscribers receive the message, be it one-way or request-response, is a physical implementation decision. In the classic sense, the logical abstraction of a topic affords us some latitude in choosing a physical transport that will fuse the publisher and subscriber(s) together.  </p> <p><em><strong>Note:</strong> Theory aside, everything I am sharing here is based on my experience over the last few days jumping into these early bits. I am not an expert on the implementation of these capabilities or the features of the CTP and am merely sharing my learnings and thoughts as I explore these exciting new features. If you have questions, know of a different or better way to do something as it applies to the CTP, or have any any corrections, please use the comments below and I’ll gladly consider them and/or share them with the product team and post updates back here.</em></p> <p><strong>Exploring Azure AppFabric Service Bus V2</strong> Topics</p> <p>In Azure AppFabric Service Bus V2, the physical transport used in Topics is Azure AppFabric Service Bus Queues, which allows us to harness the physical advantages of queues and the logical abstraction that topics provide to design our distributed solutions at internet scale.</p> <p>If you’ve played with the Azure AppFabric Service Bus Queues, or read my <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">introduction to this series</a> you might be wondering what makes Azure AppFabric Service Bus Topic so special. So far, you might be thinking that we could accomplish much of what I’ve discussed with Queues and you wouldn’t be alone. I struggled with this initially as well. </p> <p>The way that Queues and Topics are implemented in the current technology preview, Topics don’t really seem all that useful until you want to refine <em>when </em>or under <em>what conditions </em>a Subscriber should receive a message beyond simply being subscribed to a Topic, and this can be pretty powerful.</p> <p>In fact, we can code the scenario shown in the <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">article on Queues</a> to be functionally equivalent with Topics without immediately gaining much.</p> <p><strong>Creating</strong> <strong>Topics</strong> <strong>and Subscriptions</strong></p> <p>Start by creating a ServiceBusNamespaceClient and MessagingFactory just as before:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: ServiceBusNamespaceClient namespaceClient = <span style="color: rgb(0,0,255)">new</span> ServiceBusNamespaceClient( </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: ServiceBusEnvironment.CreateServiceUri( </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 3: "<span style="color: rgb(139,0,0)">sb</span>", serviceNamespace, </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 4: <span style="color: rgb(0,0,255)">string</span>.Empty), </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 5: sharedSecretCreds); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 6: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 7: MessagingFactory messagingFactory = MessagingFactory.Create( </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 8: ServiceBusEnvironment.CreateServiceUri( </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 9: "<span style="color: rgb(139,0,0)">sb</span>", </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 10: serviceNamespace, </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 11: <span style="color: rgb(0,0,255)">string</span>.Empty), </pre></pre> <p>Next, create a Topic called “Orders”: </p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: Topic ordersTopic = namespaceClient.CreateTopic("<span style="color: rgb(139,0,0)">Orders</span>");</pre></pre> <p>The underlying queue infrastructure is created for you.</p> <p>Now, create a subscription for the Inventory Service on the “Orders” topic:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: Subscription inventoryServiceSubscription = ordersTopic.AddSubscription("<span style="color: rgb(139,0,0)">InventoryServiceSubscription</span>");</pre></pre> <p>At this point, the creation of the Topic and Subscription above would take place in a management context without regard to, or any knowledge of the actual publisher or subscriber(s). </p> <p>I would expect tooling either from Microsoft or the community or both to start to crop up soon to provide a user experience for these types of management chores, including the ability to enumerate Queues, <b style="background-color: #a0ffff; color: black">Topics</b>, etc. For example, before I create a Topic, I need to ensure that the Topic doesn’t already exist or I will get an <a href="http://twitter.com/#!/rickggaribay/status/74226182958227457">MessagingEntityAlreadyExistsException</a>. I used the GetQueues method on the namespace client, and if the Topic or Queue entity exists, use the DeleteQueue or DeleteTopic method.</p> <p><strong>Publishing on a Topic</strong></p> <p>Now, the client/publisher creates a TopicClient and MessageSender and sends the message on the Orders Topic:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: TopicClient pOSClientPublisher = messagingFactory.CreateTopicClient("<span style="color: rgb(139,0,0)">Orders</span>"); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 3: MessageSender msgSender = pOSClientPublisher.CreateSender(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 4: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 5: Order order = <span style="color: rgb(0,0,255)">new</span> Order(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 6: order.OrderId = 42; </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 7: order.Products.Add("<span style="color: rgb(139,0,0)">Kinect</span>", 70.50M); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 8: order.Products.Add("<span style="color: rgb(139,0,0)">SamsungFocus</span>", 199.99M); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 9: order.Total = order.Products["<span style="color: rgb(139,0,0)">Kinect</span>"] + order.Products["<span style="color: rgb(139,0,0)">SamsungFocus</span>"]; </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 10: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 11: var msg = BrokeredMessage.CreateMessage(order); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 12: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 13: msgSender.Send(msg); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 14: msgSender.Close();</pre></pre> <p>Note that the client/publisher knows nothing about the subscriber. It is only bound to a logical Topic called “Orders” on line 1 above. It is running in some other process somewhere in the world (literally) that has an internet connection and can make an outbound connection on TCP port 9354***.</p> <p><strong>Subscribing to a Topic</strong></p> <p>On the receiving end, a SubscriptionClient is created along with a MessageReciever. The SubscriptionClient instance is created from the MessagingFactory instance which accepts the name of the topic and the subscription itself.</p> <p>Note the RecieveMode is the same as before which will have the effect of ensuring that the Inventory Service Subscriber receives the message at most once (FWIW, I think PublisherClient and SubscriberClient make more sense that SubscriptionClient and TopicClient respectively, but the intent of the classes is pretty clear and again, these are early bits so expect changes as the team gets feedback and continues to bake the API):</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: SubscriptionClient inventoryServiceSubscriber = messagingFactory.CreateSubscriptionClient("<span style="color: rgb(139,0,0)">Orders</span>", "<span style="color: rgb(139,0,0)">InventoryServiceSubscription</span>"); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 3: MessageReceiver msgReceiver = inventoryServiceSubscriber.CreateReceiver(ReceiveMode.PeekLock); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 4: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 5: var recdMsg = msgReceiver.Receive(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 6: msgReceiver.Close(); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 7: </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 8: var recdOrder = recdMsg.GetBody&lt;Order&gt;(); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 9: </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 10: Console.WriteLine("<span style="color: rgb(139,0,0)">Received Order {0} on {1}.</span>", recdOrder.OrderId, "<span style="color: rgb(139,0,0)">Inventory Service Subscriber</span>");</pre></pre> <p>The code above would be wrapped into a polling algorithm that allows you to have fine control over the polling interval, which as Clemens Vasters pointed out in a side conversation recently is a key capability that allows you to throttle your subscribers. The samples in the SDK show a polling technique which works, but it would be nice to see an option for setting some config and letting the API do this for you. </p> <p>Regardless of the approach you take to checking for messages, the only thing the subscriber knows about is the Topic name and the name of the subscription on line 1 above (having to provide the subscription name in addition to the topic name, seems a bit redundant to me and more coupling than is needed). </p> <p><strong>Multiple Subscribers</strong></p> <p>At this point, we’ve emulated the functionality of the <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">Queuing example shown in my first post in the series</a>.</p> <p>While we’ve increased our level of abstraction, and are no longer thinking about (or care) about the fact that there’s a queue in between the publisher and subscriber, so far, topics haven’t bought us much just yet…</p> <p>Think back to the scenario above. There are two other services that care about orders. We can create subscriptions for them just as we did for the Inventory Service at management/configuration time:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: Subscription fulfillmentServiceSubscription = ordersTopic.AddSubscription("<span style="color: rgb(139,0,0)">FulfillmentServiceSubscription</span>"); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: Subscription creditServiceSubscription = ordersTopic.AddSubscription("<span style="color: rgb(139,0,0)">CreditServiceSubscription</span>");</pre></pre> <p>Of course, new subscriptions can be added long after the Topic has been created, and this is one of the many powerful aspects of this logical abstraction from publishers and subscribers. This approach introduces agility into your solutions because you can add subscribers with minimal friction, and in a fully location transparent manner.</p> <p>As with the publisher (TopicClient), subscribers (SubscriberClients) live in their own process anywhere in the world with an internet connection and can be fired up at will. If one is offline, or unavailable, the message will be queued (provided that previous subscribers have peeked the message (ReceiveMode.PeekLock) as opposed to popping it off the queue (ReceiveMode.ReceiveAndDelete). Below is the simple code for adding listeners/Subscribers for the Credit Service and Fulfillment Service:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: // Credit Service Subscriber </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: SubscriptionClient creditServiceSubscriber = messagingFactory.CreateSubscriptionClient("<span style="color: rgb(139,0,0)">Orders</span>", "<span style="color: rgb(139,0,0)">CreditServiceSubscription</span>"); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 3: </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 4: msgReceiver = creditServiceSubscriber.CreateReceiver(ReceiveMode.PeekLock); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 5: recdMsg = msgReceiver.Receive(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 6: msgReceiver.Close(); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 7: </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 8: recdOrder = recdMsg.GetBody&lt;Order&gt;(); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 9: </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 10: Console.WriteLine("<span style="color: rgb(139,0,0)">Received Order {0} on {1}.</span>", recdOrder.OrderId, "<span style="color: rgb(139,0,0)">Credit Service Subscriber</span>"); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 11: </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 12: // Fulfillment Service Subscriber </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 13: SubscriptionClient fulfillmentServiceSubscriber = messagingFactory.CreateSubscriptionClient("<span style="color: rgb(139,0,0)">Orders</span>", "<span style="color: rgb(139,0,0)">FulfillmentServiceSubscription</span>"); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 14: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 15: msgReceiver = fulfillmentServiceSubscriber.CreateReceiver(ReceiveMode.PeekLock); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 16: recdMsg = msgReceiver.Receive(); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 17: msgReceiver.Close(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 18: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 19: recdOrder = recdMsg.GetBody&lt;Order&gt;(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 20: </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 21: Console.WriteLine("<span style="color: rgb(139,0,0)">Received Order {0} on {1}.</span>", recdOrder.OrderId, “<span style="color: rgb(139,0,0)">Fulfillment Service Subscriber</span>"<span style="color: rgb(139,0,0)">);</span></pre></pre> <p>Creati<a href="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_16.png"><img style="background-image: none; border-right-width: 0px; margin: 4px 0px 4px 2px; padding-left: 0px; padding-right: 0px; display: inline; float: right; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" align="right" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/image_thumb_7.png" width="415" height="53" /></a>ng two additional SubscriptionClients for the Credit Service and Fulfillment Service results in all three subscribers getting the message as shown on the right. Again, in my examples, I am running each subscriber in the same process, but in the real world, these subscribers could be deployed anywhere in the world provided they can establish a connection to TCP 9354.</p> <p><strong>Rules/Actions, Sessions/Groups</strong></p> <p>Now, what if we wanted to partition the subscribers such that in addition to subscribing to a Topic, additional logic could be evaluated to determine if the subscribers are really interested in the message? Our online retailer probably (err, hopefully) has a centralized inventory management system and credit card processor, but may have different fulfillment centers across the world. </p> <p>Based on the customer’s origin, the order should go to the closest fulfillment center to minimize cost and ship times (i.e. North America, South America, Africa, East, Europe, Asia, Australia).</p> <p>Azure AppFabric Service Bus V2 supports this approach with Sessions, Rules and Actions. I group these into the idea of a message pipeline. In addition to the subscriptions, the Topic evaluates additional context or content of the published message configured at management time to introduce some additional filtering and very lightweight orchestration. The topic subscription is the right place for this to happen because again, it is a management-time task. Publishers and subscribers merely send/receive messages. It is the benefit of a logically centralized, yet physically distributed messaging model that affords us the ability to manage these details in a centralized way.</p> <p>You can create a RuleDescription to evaluate some property or field in the message that indicates country of origin, and as an action, set a property on the message to identify the fulfillment center.</p> <p>To illustrate this, first, I’ve added two properties to the BrokerMessage that I am publishing on the “Orders” Topic. I’ll use these properties when I configure my rule and action next:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: msg.Properties.Add("<span style="color: rgb(139,0,0)">CountryOfOrigin</span>", "<span style="color: rgb(139,0,0)">USA</span>"); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: msg.Properties.Add("<span style="color: rgb(139,0,0)">FulfillmentRegion</span>", "<span style="color: rgb(139,0,0)"></span>");</pre></pre> <p><font face="Verdana">Notice that in line 2 above, I’ve intentionally created the “FulfillmentRegion” property with an empty string, since we are going to apply some logic to determine the fulfillment region. </font></p> <p><font face="Verdana">Now, I use a RuleDescription and SqlFilterExpression to determine if the CountryOfOrigin is the United States. If the SqlFilterExpression evaluates to true, then the SqlFilterAction fires and sets the FulfillmentRegion  to “North America”:</font></p> <font face="Verdana"> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: RuleDescription fulfillmentRuleDescription = <span style="color: rgb(0,0,255)">new</span> RuleDescription(); </pre> <pre style="background-color: rgb(255,255,255); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 2: fulfillmentRuleDescription.FilterExpression = <span style="color: rgb(0,0,255)">new</span> SqlFilterExpression("<span style="color: rgb(139,0,0)">CountryOfOrigin = 'USA'</span>"); </pre> <pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 3: fulfillmentRuleDescription.FilterAction = <span style="color: rgb(0,0,255)">new</span> SqlFilterAction("<span style="color: rgb(139,0,0)">set fulfillmentRegion='North America'</span>");</pre></pre> <p>Of course, in the real world, there would be a more sophisticated process for identifying the country of origin, but simple, contrived examples make it so that articles get published. <img class="wlEmoticon wlEmoticon-winkingsmile" alt="Winking smile" src="http://rickgaribay.net/images/rickgaribay_net/Windows-Live-Writer/AppFabric-Service-Bus-V2-CTP-Topics_12716/wlEmoticon-winkingsmile_2.png" /></p> <p>The evaluation and any corresponding actions must fire when the message is in-flight as any actions taken could influence the routing of the message, as with the example above which will meet a subscription rule we’ll configure on the Fulfillment Service Description next. </p> <p>OK, so now we have some properties we can play with and we’ve defined a RuleDescription. The last thing we need to do is modify the FulfillmentServiceSubscription to include the RuleDescription I just created. This makes the FulfillmentSubscription conditional, based on the conditions we've defined in the instance of the RuleDescription called fulfillmentRuleDescription:</p> <pre style="border-bottom: rgb(206,206,206) 1px solid; border-left: rgb(206,206,206) 1px solid; padding-bottom: 5px; background-color: rgb(251,251,251); min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: rgb(206,206,206) 1px solid; border-right: rgb(206,206,206) 1px solid; padding-top: 5px"><pre style="background-color: rgb(251,251,251); margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> 1: Subscription fulfillmentServiceSubscription = ordersTopic.AddSubscription("<span style="color: rgb(139,0,0)">FulfillmentServiceSubscription</span>", fulfillmentRuleDescription);</pre></pre> <p> <br />Now, when I run my code, all three subscribers receive the order message just as before, however this time, we know that the only reason that the Fulfillment Service is getting the message is because it is acting as the North America fulfillment center. If I modify the CountryOfOrigin property in line 1 in the 3rd code sample up from here to anything but “North America” the Fulfillment Service will not receive the message at all.</p> <p>As I continue to model out my subscribers, I could create a subscription for each fulfillment center that is capable of receiving real-time orders and then create RuleDescriptions accordingly. This would allow me to distribute fulfillment geographically (good for scale, reliability and happy customers) as well as ensuring that I am always only pulling back messages that I need. If, during peak times around holidays, the volume of orders increases, I can simply add additional fulfillment subscribers for that region to ensure that packages ship as quickly as possible and that no orders are lost.</p> </font> <p><strong>Closing Thoughts</strong></p> <p>So far, I’m pretty impressed with the powerful messaging capabilities that Azure AppFabric Service Bus V2 Topics introduced in the May CTP, and I’m excited to see where things are going.</p> <p>As Azure AppFabric Service Bus matures further, I would love to see additional transport channels supported by Azure AppFabric Service Bus Topics. Just as with the creation of the Topic and Subscriptions as a management function, the transport would also be defined and created/configured at management time. This is really where the power and elegance of Topics shines through in my opinion because the publisher and subscriber don’t know or care about the transport- they’re just connecting to a topic and sending and/or receiving messages.</p> <p>By way of some nit picks, I think that PublisherClient makes more sense than TopicClient, and along with considering a modification to SubscriptionClient, having a PublisherClient and SubscriberClient that publish and subscribe to a Topic seems a lot cleaner and more intuitive to me.</p> <p>I’m also trying to get used the fact that we need Clients <em>and</em> Senders/Receivers. Again, to me it would seem more intuitive to simply have a PublisherClient and SubscriberClient that own the sending and receiving. Perhaps we’re jus seeing visible seams in the API due to the early nature, or there’s a good reason for this that I haven’t thought of yet.</p> <p>At PDC 10, the AppFabric team announced that they are investing in an “Integration Service” that will provide additional messaging capabilities by way of transformation and advanced mapping similar to how we leverage these capabilities in BizTalk today. I can see Topics getting much more robust when, in addition to modifying properties on the BrokerMessage, we can mediate and transform a message in-flight just before reaching a subscriber, and I can also think of some nice message enrichment patterns that would be very nice. </p> <p>*** One important thing to note is that in the current May CTP, Queues and Topics do not provide the same NAT/Firewall traversal capabilities of their relay siblings. For the .NET Messaging API (which I’ve been using to share my learnings thus far) as well as the WCF ServiceBusMessagingBinding, outbound TCP 9354 is required. Also note that the channel type is Net.Tcp (think WCF). This means that in the current CTP, the only way to ensure full interoperability across publishers/subscribers and guarantee an outbound connection (assuming HTTP ports aren’t locked down) is to use the REST API, but I suspect we’ll see more parity of this important feature across client types for Queues and Topics. </p> <p><strong>What’s Next?</strong></p> <p>There’s still much to explore around sessions, filtering, the WCF ServiceBusMessagingBinding, the REST API and how we might bridge Azure AppFabric Service Bus with on-premise messaging capabilities. Exciting stuff- stay tuned!</p><img src="http://rickgaribay.net/aggbug/309.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2011/05/31/exploring-appfabric-service-bus-v2-may-ctp-topics.aspx Tue, 31 May 2011 10:23:00 GMT http://rickgaribay.net/archive/2011/05/31/exploring-appfabric-service-bus-v2-may-ctp-topics.aspx#feedback http://rickgaribay.net/comments/commentRss/309.aspx http://rickgaribay.net/services/trackbacks/309.aspx Bite-Sized SOA: Think Big, Start Small, Rinse and Repeat http://rickgaribay.net/archive/2009/05/31/bite-sized-soa-think-big-start-small-rinse-and-repeat.aspx <p>Please join my colleague, Todd Sussman and I on Wednesday, June 3rd as we share thoughts and best practices for delivering SOA to the enterprise.</p> <p>In this 1 hour free webcast we will:</p> <ul> <li>Discuss the organizational, technical and political challenges inherent to distributing business processes across geographical business assets, vendors and business units of varying maturity. </li> </ul> <ul> <li>Provide insight and guidance directly from the field on how to bring business, technical and vendor teams together to achieve the shared vision and promise of SOA using state-of-the-art technology from Microsoft and the .NET partner ecosystem including specific discussions around WCF, Microsoft Business Rules Engine (BRE) and Neuron ESB. </li> </ul> <ul> <li>Provide real-world metrics from this success story that can be used to plan and measure success in your SOA initiatives. </li> </ul> <p>Register here: <a title="https://www.clicktoattend.com/invitation.aspx?code=137585" href="https://www.clicktoattend.com/invitation.aspx?code=137585">https://www.clicktoattend.com/invitation.aspx?code=137585</a></p><img src="http://rickgaribay.net/aggbug/245.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2009/05/31/bite-sized-soa-think-big-start-small-rinse-and-repeat.aspx Sun, 31 May 2009 21:00:06 GMT http://rickgaribay.net/archive/2009/05/31/bite-sized-soa-think-big-start-small-rinse-and-repeat.aspx#feedback http://rickgaribay.net/comments/commentRss/245.aspx http://rickgaribay.net/services/trackbacks/245.aspx