Architecture & Design http://rickgaribay.net/category/6.aspx Architecture & Design en-US Rick G. Garibay rickgaribay@hotmail.com Subtext Version 1.9.5.176 New in AppFabric June CTP: AppFabric Application http://rickgaribay.net/archive/2011/06/21/new-in-appfabric-june-ctp-appfabric-application.aspx <p>Just about a month following the <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">AppFabric May CTP</a>, which featured exciting <a href="http://rickgaribay.net/archive/2011/05/17/appfabric-service-bus-v2-ctp.aspx">new investments in AppFabric Service Bus Messaging</a>, Microsoft has delivered a technology preview of the next wave of building composite solutions at enterprise scale with the <a href="http://blogs.msdn.com/b/appfabric/archive/2011/06/20/announcing-the-windows-azure-appfabric-june-ctp.aspx">release of the AppFabric June CTP</a> (to be clear, there are no changes to AppFabric Service Bus in this release).</p> <p>Composite applications are the evolution afforded us by the advancements of contract-first development and the trend towards packaging units of reuse into discrete, autonomous and interoperable services, be they domain-specific or addressing cross-cutting concerns such as security or caching. By separating concerns into units of work and composing them iteratively into larger solutions, complex systems can be planned, managed and developed in bite size pieces aiding in both planning, operations and developer economics. This approach is valuable to the development of enterprise solutions regardless of where they are deployed, but combined with a model for stitching these units of reuse together and a robust runtime and execution model that provides additional capabilities as a platform, AppFabric Applications capture the truest distillation of the value that can be obtained by building on the Azure platform today.</p> <p>Over a year and half ago, <a href="http://rickgaribay.net/archive/2010/01/15/is-.net-a-great-disruptor-of-the-decade.aspx">I asked</a> whether <a href="http://rickgaribay.net/archive/2010/01/15/is-.net-a-great-disruptor-of-the-decade.aspx">.NET was a great disruptor of the decade</a> and suggested that alone, .NET has certainly revolutionized the Microsoft developer platform, but combined with cloud computing has the potential to disrupt an entire industry. Today, AppFabric Applications give organizations investing in both cloud and hybrid a way to take full advantage of the Azure Service Model with first class support for WCF, WF Services and AppFabric Service Bus for building composite apps at very high enterprise scale. With caching, monitoring and persistence support equivalent to or better than Server AppFabric (parity of features has been a goal that I think Microsoft has kept and exceeded its promises on) and a scale out story that will form a new hosting paradigm across Appliance, Box and Cloud with AppFabric Container. This is the next evolution in the AppFabric platform vision and is a very important milestone.</p> <p>To learn more, there is an excellent video on AppFabric TV on Channel9 with <a href="http://twitter.com/#!/_karandeep">Karan Anand</a> which provides a great overview here: <a title="http://channel9.msdn.com/Shows/AppFabric-tv/AppFabrictv-Announcing-the-Windows-Azure-AppFabric-June-CTP" href="http://channel9.msdn.com/Shows/AppFabric-tv/AppFabrictv-Announcing-the-Windows-Azure-AppFabric-June-CTP">http://channel9.msdn.com/Shows/AppFabric-tv/AppFabrictv-Announcing-the-Windows-Azure-AppFabric-June-CTP</a>  </p> <p>In addition, <a href="http://twitter.com/#!/_karandeep">Karan</a> has posted a more detailed blog post here: <a title="http://blogs.msdn.com/b/appfabric/archive/2011/06/20/introducing-windows-azure-appfabric-applications.aspx" href="http://blogs.msdn.com/b/appfabric/archive/2011/06/20/introducing-windows-azure-appfabric-applications.aspx">http://blogs.msdn.com/b/appfabric/archive/2011/06/20/introducing-windows-azure-appfabric-applications.aspx</a></p> <p>Kudos to <a href="http://twitter.com/#!/_karandeep">Karan</a>, my friend <a href="http://twitter.com/#!/mwinkle">@mwinkle</a> and team for a great preview into this exciting new way to provide an easy button for building composite services at enterprise scale.</p><img src="http://rickgaribay.net/aggbug/311.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2011/06/21/new-in-appfabric-june-ctp-appfabric-application.aspx Wed, 22 Jun 2011 01:15:57 GMT http://rickgaribay.net/archive/2011/06/21/new-in-appfabric-june-ctp-appfabric-application.aspx#feedback http://rickgaribay.net/comments/commentRss/311.aspx http://rickgaribay.net/services/trackbacks/311.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 New Article: Practical Messaging Scenarios with WCF 4 http://rickgaribay.net/archive/2010/08/25/new-article-practical-messaging-scenarios-with-wcf-4.aspx <p><b></b></p> <p><b>Friends don’t let friends do point to point. </b>Anyone who has designed services to solve a business problem or built a distributed <img style="margin: 5px; display: inline" align="left" src="http://www.code-magazine.com/GetIssueCover.aspx?pk=b93aef06-0c65-4977-b997-941b18d56301" />composite application using service-oriented techniques has, consciously or not, discovered the hazards of client applications knowing too much about all of the services with which they interact.</p> <p>In my latest <a href="http://www.code-magazine.com/Article.aspx?quickid=1009051" target="_blank">article</a> for <a href="http://www.code-magazine.com/Index.aspx" target="_blank">CODE Magazine,</a> I provide a scenario-driven approach to introducing the Routing Service in WCF 4.0 including discussions on the following messaging patterns that help enable more flexible composite application designs:</p> <p>Virtual Endpoint/Message Broker</p> <p>High Availability</p> <p>Content-Based Routing</p> <p>Context-Based Routing</p> <p>Publish-Subscribe</p> <p>The article is now available online at CODE Magazine <a title="http://www.code-magazine.com/Article.aspx?quickid=1009051" href="http://www.code-magazine.com/Article.aspx?quickid=1009051">http://www.code-magazine.com/Article.aspx?quickid=1009051</a> as well as at news stands including Barnes and Noble.</p> <p>I hope you like it and as always, I welcome your feedback!</p><img src="http://rickgaribay.net/aggbug/286.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2010/08/25/new-article-practical-messaging-scenarios-with-wcf-4.aspx Wed, 25 Aug 2010 23:00:00 GMT http://rickgaribay.net/archive/2010/08/25/new-article-practical-messaging-scenarios-with-wcf-4.aspx#feedback http://rickgaribay.net/comments/commentRss/286.aspx http://rickgaribay.net/services/trackbacks/286.aspx Desert Code Camp 2010.1 &ndash; The Goods http://rickgaribay.net/archive/2010/05/19/desert-code-camp-2010.1-content.aspx <p> </p> <p>This was a great event as usual, and I really have to hand it to @jguadango, @coneybeer, Devry University and all the volunteers for putting this together. The logistics, facilities, scheduling and planning for 55+ sessions is not easy. </p> <p>I’ve presented at every Desert Code Camp since the very first one, so I think this one makes 6 or 7. Code Camp is always a great day to interact with Phoenix’s community of technologists through conversation, teaching and learning and this one was no exception.</p> <p>Below are the goods for each session, and as promised I’ve included videos of my WCF and AppFabric Service Bus demos.</p> <table border="0" cellspacing="0" cellpadding="2" width="704"> <tbody> <tr> <td valign="top" width="314"> <p align="center"><strong>Session</strong></p></td> <td valign="top" width="10"> <p align="center"><strong>Content</strong></p></td> <td valign="top" width="10"> <p align="center"><strong>Code</strong></p></td> <td valign="top" width="368"> <p align="center"><strong>Demo Vids</strong></p></td></tr> <tr> <td valign="top" width="314"><a href="http://www.desertcodecamp.com/Session.aspx?SessionId=78">Let the Good Guys in with Azure AppFabric Service Bus</a></td> <td valign="top" width="10"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 229px; padding-right: 0px; height: 66px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/DCC2010.1/Let%20the%20Good%20Guys%20in%20with%20Azure%20AppFabric%20Service%20Bus.pdf" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> <td valign="top" width="10"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 242px; padding-right: 0px; height: 60px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/DCC2010.1/Service%20Bus.zip" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> <td valign="top" width="368"> <table border="0" cellspacing="0" cellpadding="2" width="331"> <tbody> <tr> <td valign="top" width="472"><a href="http://www.youtube.com/watch?v=sTpZRaaeRcI" target="_blank">Demo1: Unicast One-Way Messaging with NetOneWayRelay Binding</a></td></tr> <tr> <td valign="top" width="472"><a href="http://www.youtube.com/watch?v=XZHczdUkB0U" target="_blank">Demo 2: Multicast On-Way Messaging with NetRelayBinding</a></td></tr> <tr> <td valign="top" width="472"><a href="http://www.youtube.com/watch?v=9K1DaZQ0zrk" target="_blank">Demo 3: World Peace &amp; Fireworks with NetTcpRelayBinding</a> (HD)</td></tr></tbody></table></td></tr> <tr> <td valign="top" width="314"><a href="http://www.desertcodecamp.com/Session.aspx?SessionId=79">Beyond the Whiteboard: Enforcing Conceptual Integrity with Visual Studio 2010</a></td> <td valign="top" width="10"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 234px; padding-right: 0px; height: 63px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/DCC2010.1/Beyond%20the%20Whiteboard%20-%20Enforcing%20Conceptual%20Integrity%20with%20Visual%20Studio%202010.pdf" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> <td valign="top" width="10"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 246px; padding-right: 0px; height: 70px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/DCC2010.1/Northwind.Online.Sample.zip" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> <td valign="top" width="368">N/A</td></tr> <tr> <td valign="top" width="314"><a href="http://www.desertcodecamp.com/Session.aspx?SessionId=77">New Features in WCF 4 that will Instantly Make you More Productive</a></td> <td valign="top" width="10"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 231px; padding-right: 0px; height: 63px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/DCC2010.1/New%20Features%20in%20WCF%204%20that%20will%20Instantly%20Make%20you%20More%20Productive.pdf" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> <td valign="top" width="10"><iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 242px; padding-right: 0px; height: 63px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/DCC2010.1/WCF4.zip" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> <td valign="top" width="368"> <table border="0" cellspacing="0" cellpadding="2" width="331"> <tbody> <tr> <td valign="top" width="329"><a href="http://www.youtube.com/watch?v=qj2ams-hs10" target="_blank">Demo 1: Convention over Configuration</a> (HD)</td></tr> <tr> <td valign="top" width="329"><a href="http://www.youtube.com/watch?v=T-rtnYpYe80" target="_blank">Demo 2: Dynamic Endpoint Discovery</a> (HD) </td></tr> <tr> <td valign="top" width="329"> <div></div> <div></div> <div><a href="http://www.youtube.com/watch?v=25S14AEKJGs" target="_blank">Demo 3: Monitoring Service Availability with WS-Discovery Announcements</a> (HD)</div></td></tr></tbody></table></td></tr></tbody></table> <p> </p> <p>If you have any comments or questions, drop me a line.</p><img src="http://rickgaribay.net/aggbug/283.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2010/05/19/desert-code-camp-2010.1-content.aspx Thu, 20 May 2010 02:16:02 GMT http://rickgaribay.net/archive/2010/05/19/desert-code-camp-2010.1-content.aspx#feedback 2 http://rickgaribay.net/comments/commentRss/283.aspx http://rickgaribay.net/services/trackbacks/283.aspx Visual Studio 2010 Ultimate Event Content Download http://rickgaribay.net/archive/2010/03/13/visual-studio-2010-ultimate-event-content-download.aspx <p>Thanks to all who came out to the event in Phoenix, Salt Lake City &amp; Las Vegas. We had a great turnout at all events with great questions and discussions.</p> <p>Remember that the conversation continues on <a target="_blank" href="http://twitter.com/#search?q=%23vs2010phx">twitter</a>. <a target="_blank" href="http://twitter.com/#search?q=%23vs2010slc"><img style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; MARGIN-RIGHT: 0px" title="image" border="0" alt="image" align="right" width="240" height="162" src="http://rickgaribay.net/Images/CustomContent/VisualStudio2010UltimateEventSaltLakeCit_8195/image_4.png" /></a> </p> <p>If you attended the event and have a question or comment for any of the presenters, use the following hashtags: </p> <ul> <li>Phoenix: #vs2010phx </li> <li>Salt Lake City: #vs2010slc </li> <li>Las Vegas: #vs2010vegas</li> </ul> <p align="center">Below are the presentations from all four sessions in each city:   </p> <p> </p> <table border="0" cellspacing="0" cellpadding="2" width="912"> <tbody> <tr> <td valign="top" width="190">Phoenix</td> <td valign="top" width="421">A Lap Around Visual Studio 2010</td> <td valign="top" width="473">Rick G. Garibay</td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/Lap%20Around%20VS%202010%20Garibay.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Phoenix</td> <td valign="top" width="421">Agile Management with TFS</td> <td valign="top" width="473"><a target="_blank" href="http://blogs.neudesic.com/blogs/brendon_birdoes/default.aspx">Brendon Birdoes</a></td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/TFS%202010%20Agile%20Management%20Brendon.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe>*</td> </tr> <tr> <td valign="top" width="190">Phoenix</td> <td valign="top" width="421">No More "No Repro"</td> <td valign="top" width="473"><a target="_blank" href="http://blogs.neudesic.com/blogs/brendon_birdoes/default.aspx">Brendon Birdoes</a></td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/No%20More%20No%20Repro%20Brendon.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe>*</td> </tr> <tr> <td valign="top" width="190">Phoenix</td> <td valign="top" width="421">Architecture for Everyone</td> <td valign="top" width="473">Rick G. Garibay</td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/Architecture%20for%20Everyone%20Garibay.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Salt Lake City</td> <td valign="top" width="421">A Lap Around Visual Studio 2010</td> <td valign="top" width="473">Rick G. Garibay</td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/Lap%20Around%20VS%202010%20Garibay.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Salt Lake City</td> <td valign="top" width="421">Agile Management with TFS</td> <td valign="top" width="473">Jeff Leite</td> <td valign="top" width="146">*<iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/TFS%202010%20Agile%20Project%20Management.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Salt Lake City</td> <td valign="top" width="421">No More "No Repro"</td> <td valign="top" width="473">Jeff Leite</td> <td valign="top" width="146">*<iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/No%20More%20No%20Repro.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Salt Lake City</td> <td valign="top" width="421">Architecture for Everyone</td> <td valign="top" width="473">Rick G. Garibay</td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/Architecture%20for%20Everyone%20Garibay.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Las Vegas</td> <td valign="top" width="421">A Lap Around Visual Studio 2010</td> <td valign="top" width="473">Rick G. Garibay</td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/Lap%20Around%20VS%202010%20Garibay.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Las Vegas</td> <td valign="top" width="421">Agile Management with TFS</td> <td valign="top" width="473">Mickey Williams</td> <td valign="top" width="146">*<iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/TFS%202010%20Agile%20Project%20Management.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Las Vegas</td> <td valign="top" width="421">No More "No Repro"</td> <td valign="top" width="473">Mickey Williams</td> <td valign="top" width="146">*<iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/No%20More%20No%20Repro.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> <tr> <td valign="top" width="190">Las Vegas</td> <td valign="top" width="421">Architecture for Everyone</td> <td valign="top" width="473">Rick G. Garibay</td> <td valign="top" width="146"><iframe style="PADDING-BOTTOM: 0px; BACKGROUND-COLOR: #fcfcfc; PADDING-LEFT: 0px; WIDTH: 250px; PADDING-RIGHT: 0px; HEIGHT: 59px; PADDING-TOP: 0px" title="Preview" marginheight="0" src="http://cid-df930ee6f91132fd.skydrive.live.com/embedrowdetail.aspx/Public/Talks/VS%202010%20Ultimate/Architecture%20for%20Everyone%20Garibay.pptx" frameborder="0" marginwidth="0" scrolling="no"></iframe></td> </tr> </tbody> </table> <p>* Note that content for all venues is very similar but may vary from presenter to presenter. <strike>All content for both venues will be available soon so please check back shortly.</strike></p><img src="http://rickgaribay.net/aggbug/275.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2010/03/13/visual-studio-2010-ultimate-event-content-download.aspx Sun, 14 Mar 2010 01:45:01 GMT http://rickgaribay.net/archive/2010/03/13/visual-studio-2010-ultimate-event-content-download.aspx#feedback http://rickgaribay.net/comments/commentRss/275.aspx http://rickgaribay.net/services/trackbacks/275.aspx .NET 4.0 and Visual Studio 2010 Beta 2 Announcements http://rickgaribay.net/archive/2009/10/19/264.aspx <p>.NET 4.0 and Visual Studio 2010 Beta 2 is now available to MSDN subscribers as of 9:30 AM PST. This release includes the new version of Connected Framework products like <a target="_blank" href="http://msdn.microsoft.com/wcf">WCF</a> and <a target="_blank" href="http://msdn.microsoft.com/wf">WF</a> 4.0, Entity Framework 4.0 and a host of additional new features across work streams including MEF, Parallel Extensions, and significant enhancements to Visual Studio Team System and Team Build.</p> <p>Having spent some time with both WCF and WF limited CTP, Beta and pre-Beta 2 bits, this release includes significant improvements, re-design and new features specifically around WCF and WF 4.0. If  you are like <a target="_blank" href="http://www.rickgaribay.net/contact.aspx">me</a>, you will likely welcome many of the designer enhancements in WF 4.0 and may lament a number of designer design changes within messaging activities. You’ll just need to rip off the shrink wrap on Beta 2 to find out yourself!</p> <p>I plan to start doing a significant amount of writing around WF 4.0 because I think that having been re-written from the ground up, WF 4.0 addresses many, many of the pain points in the 3.0 and 3.5 version, and I believe that WF + WCF 4.0 will lower the barrier of entry for writing workflow and service/model-oriented applications. In addition, the improvements within Workflow Services and the ease with which those new to WCF can get a service up and running are both significant and necessary to increasing the reach of these fantastic technologies.</p> <p>Another major area of VS 2010 I am excited about is in the new architecture and design tools in Microsoft Visual Studio Team System 2010 Architecture Edition which introduces new UML designers, use cases, activity diagrams, sequence diagrams and the ability to explore and visualize existing code, design and apply layering to enforce dependency rules, and physical designers to visualize, analyze, and refactor your software. In May of the year, I <a target="_blank" href="http://www.slideshare.net/stevenl/phoenix-session-5-architecture-without-big-design-up-front-garibay">demonstrated</a> how VS 2010 extends UML logical views into physical views of your code along with how to create relationships from these views to work items and project metrics, and how to programmatically transform models into patterns for other domains and disciplines.</p> <p>Needless to say, I’m excited about VS 2010 Beta 2, and am even more excited to announce that the official launch of Visual Studio 2010 will take place on March 22nd, 2010.</p> <p>Until then, you can download Beta 2 on October 21st here: <a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx">http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx</a></p> <p>Some other notes of interest:</p> <ul> <li>Microsoft is announcing a new, streamlined packaging lineup and licensing options for Visual Studio 2010 and MSDN. This includes an "Ultimate Offer" to help customers upgrade to the latest developer tools. For more information on the new packaging, licensing, and pricing of Visual Studio 2010, visit: <a href="http://go.microsoft.com/fwlink/?LinkID=166249">http://go.microsoft.com/fwlink/?LinkID=166249</a></li> <li>As you may have noticed, MSDN has undergone a significant redesign which includes new benefits for all MSDN subscribers: <a href="http://msdn.microsoft.com/en-us/default.aspx">http://msdn.microsoft.com/en-us/default.aspx</a></li> </ul> <p> </p> <p>March 22nd will be here before you know it, so jump on the Beta 2 bits now and get ready!</p> <p>Oh, and don’t forget, PDC 2009 is right around the corner. Register now for key insights you just won’t find at any other conference: <a title="http://microsoftpdc.com/" href="http://microsoftpdc.com/">http://microsoftpdc.com/</a></p><img src="http://rickgaribay.net/aggbug/264.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2009/10/19/264.aspx Mon, 19 Oct 2009 23:30:00 GMT http://rickgaribay.net/archive/2009/10/19/264.aspx#feedback 1 http://rickgaribay.net/comments/commentRss/264.aspx http://rickgaribay.net/services/trackbacks/264.aspx Unit Testing Microsoft Sync Framework 2.0 &amp; WCF http://rickgaribay.net/archive/2009/08/17/unit-testing-microsoft-sync-framework-amp-wcf.aspx <p>I just wrapped up some work for a client that entails exposing the Sync Framework 2.0 via WCF.</p> <p>We are using Sync Framework 2.0 CTP 2 to support occasionally connected client scenarios between applications deployed out in the edge and core services hosted in the client’s cloud. I am using WCF to wrap the Sync Fx APIs to support interoperable synchronization support via SOAP 1.1. This way, any client can on-ramp with the core services and essentially become self-provisioned by initiating and initial synchronization to download required data necessary to come on line. In addition, when events happen out on the edge, the client can synchronize each event back to the cloud using an upload semantic. </p> <p>There are many benefits to using the Sync Fx as opposed to rolling your own, and one benefit is the extremely simple provider model which makes basic synchronization scenarios a breeze, particularly between relational replicas such as SQL Server. Note however, that Sync Fx is fully extensible and capable of synchronizing any two memory streams. </p> <p>So, the basic idea is that given a SyncProvider for the local and remote replica, any two data sources/applications can be synchronized:</p> <p><a href="http://rickgaribay.net/Images/CustomContent/UnitTestingMicrosoftSyncFrameworkWCF_13226/image_5.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://rickgaribay.net/Images/CustomContent/UnitTestingMicrosoftSyncFrameworkWCF_13226/image_thumb_5.png" width="640" height="394" /></a> </p> <p>In my scenario, the local client out in the edge utilizes the out of the box SqlSyncProvider. The goal was to expose the cloud over HTTP using SOAP, which required some understanding of the underlying APIs. From there, it was simply a matter of wrapping the Sync Fx APIs in a service layer, so that I would arrive at something like this:</p> <p><a href="http://rickgaribay.net/Images/CustomContent/UnitTestingMicrosoftSyncFrameworkWCF_13226/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="image" border="0" alt="image" src="http://rickgaribay.net/Images/CustomContent/UnitTestingMicrosoftSyncFrameworkWCF_13226/image_thumb_6.png" width="640" height="371" /></a> </p> <p>By providing a proxy to the orchestrator, I was able to implement a proxy which is polymorphic with RelationalSyncProvider. </p> <p>Immediately it should be obvious that this is not your typical integration scenario. Essentially, I am extending a framework by exposing it over WCF so that any orchestrator can leverage the WebSyncProvider. </p> <p>I started the implementation by writing some tests. It was simple enough to extract an interface for the RelationalSyncProvider type because it is abstract. I used RhinoMocks to stub it, which worked great but where I ran into problems was in recording expectations on the return types because there are not a lot of test seams in the framework. With the absence of setters on main properties that I needed to assert, I needed a way to reach into the framework types and manipulate them so that I could develop the CUT  (in this case the ServiceContract implementation) independent of the framework.<a href="http://rickgaribay.net/Images/CustomContent/UnitTestingMicrosoftSyncFrameworkWCF_13226/clip_image002.jpg"><img style="border-right-width: 0px; margin: 5px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" align="right" src="http://rickgaribay.net/Images/CustomContent/UnitTestingMicrosoftSyncFrameworkWCF_13226/clip_image002_thumb.jpg" width="240" height="227" /></a></p> <p><a href="http://msdn.microsoft.com/en-us/library/bb514191.aspx" target="_blank">Publicize.exe</a> works pretty nicely for what I was looking for. </p> <p>For example, let’s say I want to stub a closed/framework type so that I can actually write my test without having to resort to integrating with the framework (which wouldn’t be a unit test at all), in this case, a couple of types in the Microsoft.Syncronization.dll assembly. </p> <p>I run Publicize.exe Microsoft.Syncronization.dll and it generates a shadow assembly called Microsoft.Syncronization_Accessor.dll, which takes all types, adds _Accessor and exposes all non-public members as public as shown in Reflector on the right. </p> <p>This pretty powerful. </p> <p>I can now stub the return type of any closed/framework class and test as long as I am asserting *properties*, which is pretty common:</p> <!-- code formatted by http://manoli.net/csharpformat/ --><style type="text/css"><![CDATA[ .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }]]></style> <div class="csharpcode"> <pre class="alt"><span class="lnum"> 1: </span> </pre> <pre><span class="lnum"> 2: </span> [TestMethod]</pre> <pre class="alt"><span class="lnum"> 3: </span> <span class="kwrd">public</span> <span class="kwrd">void</span> GetChangesShouldReturnNumberOfChangesApplied()</pre> <pre><span class="lnum"> 4: </span> {</pre> <pre class="alt"><span class="lnum"> 5: </span> MockRepository mockRepository = <span class="kwrd">new</span> MockRepository();</pre> <pre><span class="lnum"> 6: </span> </pre> <pre class="alt"><span class="lnum"> 7: </span> RelationalSyncProvider provider = mockRepository.Stub&lt;RelationalSyncProvider&gt;();</pre> <pre><span class="lnum"> 8: </span> </pre> <pre class="alt"><span class="lnum"> 9: </span> </pre> <pre><span class="lnum"> 10: </span> <span class="kwrd">using</span> (mockRepository.Record())</pre> <pre class="alt"><span class="lnum"> 11: </span> {</pre> <pre><span class="lnum"> 12: </span> </pre> <pre class="alt"><span class="lnum"> 13: </span> <span class="rem">// Set up the out parameter on RelationalSyncProvider Stub</span></pre> <pre><span class="lnum"> 14: </span> DbSyncContext changeDataRetriever = <span class="kwrd">new</span> DbSyncContext();</pre> <pre class="alt"><span class="lnum"> 15: </span> </pre> <pre><span class="lnum"> 16: </span> <span class="rem">// Set up ScopeProgress property on DbySyncContext instance</span></pre> <pre class="alt"><span class="lnum"> 17: </span> <span class="rem">/*</span></pre> <pre><span class="lnum"> 18: </span><span class="rem"> * Note that in order to test for number of changes applied, we need to reach into the</span></pre> <pre class="alt"><span class="lnum"> 19: </span><span class="rem"> * DbSyncScopeProgress and access the _totalChanges private member </span></pre> <pre><span class="lnum"> 20: </span><span class="rem"> * so that public properties can be asserted. This is because the TotalChanges property only has a </span></pre> <pre class="alt"><span class="lnum"> 21: </span><span class="rem"> * getter, so the only way to influence the value is through it's backing field.</span></pre> <pre><span class="lnum"> 22: </span><span class="rem"> */</span> </pre> <pre class="alt"><span class="lnum"> 23: </span> </pre> <pre><span class="lnum"> 24: </span> DbSyncScopeProgress dbSyncScopeProgress = <span class="kwrd">new</span> DbSyncScopeProgress();</pre> <pre class="alt"><span class="lnum"> 25: </span> </pre> <pre><span class="lnum"> 26: </span> <span class="rem">// Reference the actual object which will be accessed by the generated accessor</span></pre> <pre class="alt"><span class="lnum"> 27: </span> PrivateObject obj = <span class="kwrd">new</span> PrivateObject(dbSyncScopeProgress);</pre> <pre><span class="lnum"> 28: </span> </pre> <pre class="alt"><span class="lnum"> 29: </span> <span class="rem">// Generated accessor which wraps the type to be exposed using reflection.</span></pre> <pre><span class="lnum"> 30: </span> <span class="rem">// Instead of writing the reflection code manually, Publicize.exe was run against the real assembly,</span></pre> <pre class="alt"><span class="lnum"> 31: </span> <span class="rem">// which in turn generated reflection wrappers for *all* types.</span></pre> <pre><span class="lnum"> 32: </span> </pre> <pre class="alt"><span class="lnum"> 33: </span> DbSyncScopeProgress_Accessor dbSyncScopeProgressAccessor = <span class="kwrd">new</span> DbSyncScopeProgress_Accessor(obj);</pre> <pre><span class="lnum"> 34: </span> </pre> <pre class="alt"><span class="lnum"> 35: </span> <span class="rem">// Look ma, I am accessing a private field</span></pre> <pre><span class="lnum"> 36: </span> dbSyncScopeProgressAccessor._tablesProgress = <span class="kwrd">new</span> List&lt;DbSyncTableProgress&gt;();</pre> <pre class="alt"><span class="lnum"> 37: </span> </pre> <pre><span class="lnum"> 38: </span> </pre> <pre class="alt"><span class="lnum"> 39: </span> <span class="rem">// Now we need to repeat the same process again for this type, which is at the heart of what we need to</span></pre> <pre><span class="lnum"> 40: </span> <span class="rem">// gain access to.</span></pre> <pre class="alt"><span class="lnum"> 41: </span> DbSyncTableProgress dbSyncTableProgress = <span class="kwrd">new</span> DbSyncTableProgress();</pre> <pre><span class="lnum"> 42: </span> </pre> <pre class="alt"><span class="lnum"> 43: </span> <span class="rem">// Provides the accessor with a reference to the actual object</span></pre> <pre><span class="lnum"> 44: </span> obj = <span class="kwrd">new</span> PrivateObject(dbSyncTableProgress);</pre> <pre class="alt"><span class="lnum"> 45: </span> </pre> <pre><span class="lnum"> 46: </span> <span class="rem">// Generated accessor which wraps the type to be exposed using reflection.</span></pre> <pre class="alt"><span class="lnum"> 47: </span> <span class="rem">// Instead of writing the reflection code manually, Publicize.exe was run against the real assembly,</span></pre> <pre><span class="lnum"> 48: </span> <span class="rem">// which in turn generated reflection wrappers for *all* types.</span></pre> <pre class="alt"><span class="lnum"> 49: </span> DbSyncTableProgress_Accessor dbSyncTableProgressAccessor = <span class="kwrd">new</span> DbSyncTableProgress_Accessor(obj);</pre> <pre><span class="lnum"> 50: </span> </pre> <pre class="alt"><span class="lnum"> 51: </span> <span class="rem">// Set the _rowsApplied field so that the stubbed return instance of DbSyncScopeProgress can be asserted.</span></pre> <pre><span class="lnum"> 52: </span> dbSyncTableProgressAccessor._rowsApplied = 42;</pre> <pre class="alt"><span class="lnum"> 53: </span> </pre> <pre><span class="lnum"> 54: </span> <span class="rem">// Add the dbSyncTableProgress to the private collection</span></pre> <pre class="alt"><span class="lnum"> 55: </span> dbSyncScopeProgressAccessor._tablesProgress.Add(dbSyncTableProgress);</pre> <pre><span class="lnum"> 56: </span> </pre> <pre class="alt"><span class="lnum"> 57: </span> </pre> <pre><span class="lnum"> 58: </span> <span class="rem">// Now, set the property to our used and abused instance of DbSyncScopeProgress</span></pre> <pre class="alt"><span class="lnum"> 59: </span> changeDataRetriever.ScopeProgress = dbSyncScopeProgress;</pre> <pre><span class="lnum"> 60: </span> </pre> <pre class="alt"><span class="lnum"> 61: </span> <span class="rem">// Provider is implemented in COM so out params are prevelant (yuk)</span></pre> <pre><span class="lnum"> 62: </span> <span class="kwrd">object</span> changeDataRetrieverObj = changeDataRetriever;</pre> <pre class="alt"><span class="lnum"> 63: </span> </pre> <pre><span class="lnum"> 64: </span> <span class="rem">// Set the expectation</span></pre> <pre class="alt"><span class="lnum"> 65: </span> provider.GetChangeBatch(0, <span class="kwrd">null</span>, <span class="kwrd">out</span> changeDataRetrieverObj);</pre> <pre><span class="lnum"> 66: </span> </pre> <pre class="alt"><span class="lnum"> 67: </span> <span class="rem">// Initialize params</span></pre> <pre><span class="lnum"> 68: </span> SyncIdFormatGroup idFormats = <span class="kwrd">new</span> SyncIdFormatGroup();</pre> <pre class="alt"><span class="lnum"> 69: </span> SyncKnowledge destinationKnowledge = <span class="kwrd">new</span> SyncKnowledge();</pre> <pre><span class="lnum"> 70: </span> ForgottenKnowledge sourceForgottenKnowledge = <span class="kwrd">new</span> ForgottenKnowledge();</pre> <pre class="alt"><span class="lnum"> 71: </span> </pre> <pre><span class="lnum"> 72: </span> <span class="rem">// Stub the return, including the object reference to DbSyncContext</span></pre> <pre class="alt"><span class="lnum"> 73: </span> LastCall.Return(<span class="kwrd">new</span> ChangeBatch(idFormats, destinationKnowledge, sourceForgottenKnowledge))</pre> <pre><span class="lnum"> 74: </span> .OutRef(changeDataRetrieverObj).IgnoreArguments();</pre> <pre class="alt"><span class="lnum"> 75: </span> }</pre> <pre><span class="lnum"> 76: </span> </pre> <pre class="alt"><span class="lnum"> 77: </span> IRelationalSyncManager manager = <span class="kwrd">new</span> RelationalSyncManager();</pre> <pre><span class="lnum"> 78: </span> </pre> <pre class="alt"><span class="lnum"> 79: </span> <span class="rem">// Inject the stub</span></pre> <pre><span class="lnum"> 80: </span> manager.Provider = provider;</pre> <pre class="alt"><span class="lnum"> 81: </span> </pre> <pre><span class="lnum"> 82: </span> SyncKnowledge localKnowledge = <span class="kwrd">new</span> SyncKnowledge();</pre> <pre class="alt"><span class="lnum"> 83: </span> DbSyncContext returnedContext = <span class="kwrd">new</span> DbSyncContext();</pre> <pre><span class="lnum"> 84: </span> returnedContext.ScopeProgress = <span class="kwrd">new</span> DbSyncScopeProgress();</pre> <pre class="alt"><span class="lnum"> 85: </span> </pre> <pre><span class="lnum"> 86: </span> </pre> <pre class="alt"><span class="lnum"> 87: </span> var changeBatch = manager.GetChanges(0, localKnowledge, <span class="kwrd">out</span> returnedContext);</pre> <pre><span class="lnum"> 88: </span> </pre> <pre class="alt"><span class="lnum"> 89: </span> DbSyncContext context = returnedContext;</pre> <pre><span class="lnum"> 90: </span> </pre> <pre class="alt"><span class="lnum"> 91: </span> Assert.IsTrue(context.ScopeProgress.TotalChangesApplied ==42);</pre> <pre><span class="lnum"> 92: </span> </pre> <pre class="alt"><span class="lnum"> 93: </span> }</pre> </div> <p> </p> <p>There is a bit of work here, but with a bit of elbow grease thanks to Visual Studio Test Tools, RhinoMocks, reflection and a little code generation the framework is testable.</p><img src="http://rickgaribay.net/aggbug/256.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2009/08/17/unit-testing-microsoft-sync-framework-amp-wcf.aspx Tue, 18 Aug 2009 04:46:33 GMT http://rickgaribay.net/archive/2009/08/17/unit-testing-microsoft-sync-framework-amp-wcf.aspx#feedback 2 http://rickgaribay.net/comments/commentRss/256.aspx http://rickgaribay.net/services/trackbacks/256.aspx Phoenix Visual Studio Team System Big Event was BIG! http://rickgaribay.net/archive/2009/05/11/phoenix-visual-studio-team-system-big-event-was-big.aspx <p>Thanks to all who came out for the <a href="http://rickgaribay.net/archive/2009/04/13/phoenix-visual-studio-team-system-big-event-is-coming-to.aspx">Visual Studio Team System Big Event on Thursday, May 7th</a>! <a href="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/DSCN0480.jpg"><img style="border-right: 0px; border-top: 0px; margin: 5px; border-left: 0px; border-bottom: 0px" height="100" alt="DSCN0480" src="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/DSCN0480_thumb.jpg" width="244" align="right" border="0" /></a>We had a great time with the Microsoft Developer Evangelist team, Microsoft Technical Specialists,  MVPs and influencers who at the end of the full day of action packed training left no doubt that Visual Studio Team System is <strong>BIG</strong>! </p> <p><a href="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/P5070484.jpg"><img style="border-right: 0px; border-top: 0px; margin: 5px; border-left: 0px; border-bottom: 0px" height="184" alt="P5070484" src="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/P5070484_thumb.jpg" width="244" align="left" border="0" /></a>Dan Weinman, Senior Consultant at Neudesic kicked off with the keynote on  "<b>Development Best Practices &amp; How Microsoft Helps</b>" and set the stage for what the day full of training had in store. Dan talked about the various roles that VSTS supports and how each role comes together to enact process under a single tool that maximizes transparency and communication on Agile teams.  </p> <p>Next, Brendon Birdoes, Principal Consultant at Neudesic delivered a great talk on <a href="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/P5070488.jpg"><img style="border-right: 0px; border-top: 0px; margin: 5px; border-left: 0px; border-bottom: 0px" height="184" alt="P5070488" src="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/P5070488_thumb.jpg" width="244" align="right" border="0" /></a>Test-Driven-Development with Visual Studio. Brendon covered unit testing, including test first development and showed off the refactoring capabilities right within the IDE  along with code coverage. Brendon talked about how important code coverage and quality assertions are to ensuring that your unit tests are as useful as possible in maintaining high degrees of quality within your software projects. </p> <p>Following the excellent session on TDD, Visual Studio Team System MVP Dave McKinstry delivered a session entitled ""It Works on My Machine!" Closing the Loop Between Development &amp; Testing" which discussed the close integration between testing tools in Visual Studio Team System and the code itself which minimizes the cost and complexity in task switching.</p> <p>We were then treated by another excellent talk by Rob Bagby, Developer Evangelist on "Treating Databases as First-Class Citizens in Development". In this session, Rob made clear that <a href="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/P5070489.jpg"><img style="border-right: 0px; border-top: 0px; margin: 5px; border-left: 0px; border-bottom: 0px" height="184" alt="P5070489" src="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/P5070489_thumb.jpg" width="244" align="right" border="0" /></a>database work can no longer hide from unit testing and how the Database Project in Visual Studio Team System makes synchronizing DDL and DML objects seamless and eminently testable. </p> <p><a href="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/DSCN0481.jpg"><img style="border-right: 0px; border-top: 0px; margin: 5px; border-left: 0px; border-bottom: 0px" height="184" alt="DSCN0481" src="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/DSCN0481_thumb.jpg" width="244" align="left" border="0" /></a>I was lucky enough to show off the new Visual Studio Team System 2010 Team Architect bits which include fully compliant UML 2.1 diagram support as well as assembly, namespace, class and method visualization using the VSTS 2010 Architecture Explorer.  I talked about VSTS 2010 Team Architect being yet another clear signal of Microsoft's commitment to modeling which is, and will continue to manifest itself in technologies like Windows Workflow, BizTalk Server, Entity Framework, and Quadrant to name just a few. As a Connected Systems guy, VS2010 Team Architect is really going to go a long way in helping me and my teams visualize the problem domain and partition our big balls of mud into the right architecture.  </p> <p>Speaking of which, I think my favorite new modeling feature in Team Architect is the Layer Diagram which lets you define your layers and then validate them at build time! What this means is that<a href="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/DSCN0482.jpg"><img style="border-right: 0px; border-top: 0px; margin: 5px; border-left: 0px; border-bottom: 0px" height="184" alt="DSCN0482" src="http://rickgaribay.net/Images/CustomContent/PhoenixVisualStudioTeamSystemBigEventwas_EE11/DSCN0482_thumb.jpg" width="244" align="right" border="0" /></a> I can use a layer diagram to define separation of concerns and single responsibility principle and then make sure that team members are honoring the layer rules. It is just awesome to be able to map namespaces to a layer diagram, wire it up to the automated build and keep violations from every being delivered.</p> <p>The day winded up with a great talk by Steve Lange, Technical Specialist on how to get the most out of TFS. The session was aptly called "Bang for Your Buck" Getting the Most out of Team Foundation Server, and Steve gave away some great tips on things you can do with your investment in TFS that you may not have even known about. </p> <p>I want to thank Steve and Rob for inviting us to speak at this event. The room was full of great folks with lots of passion and great questions which is exactly what we like to see at these events. If you have any follow up questions that I wasn't able to get answered at the event, please don't hesitate to <a href="http://rickgaribay.net/contact.aspx">contact me</a>.</p><img src="http://rickgaribay.net/aggbug/241.aspx" width="1" height="1" /> Rick G. Garibay http://rickgaribay.net/archive/2009/05/11/phoenix-visual-studio-team-system-big-event-was-big.aspx Tue, 12 May 2009 00:29:16 GMT http://rickgaribay.net/archive/2009/05/11/phoenix-visual-studio-team-system-big-event-was-big.aspx#feedback http://rickgaribay.net/comments/commentRss/241.aspx http://rickgaribay.net/services/trackbacks/241.aspx SOA Patterns Book http://rickgaribay.net/archive/2008/03/01/soa-patterns-book.aspx <p>Excellent SOA Patterns book underway with a public preview and collaboration site here: <font face="Arial"><a href="http://www.soapatterns.org/">http://www.soapatterns.org/</a></font></p> <p>Several of us at Neudesic have either contributed, are reviewing or are contributing candidate patterns based on proven practices.</p> <p>I would encourage anyone to check out this resource and add it to your architecture and design toolbox.</p><img src="http://rickgaribay.net/aggbug/168.aspx" width="1" height="1" /> Rick G. Garibay - The more I learn, the less I kno http://rickgaribay.net/archive/2008/03/01/soa-patterns-book.aspx Sat, 01 Mar 2008 14:28:11 GMT http://rickgaribay.net/archive/2008/03/01/soa-patterns-book.aspx#feedback http://rickgaribay.net/comments/commentRss/168.aspx http://rickgaribay.net/services/trackbacks/168.aspx Managed Windows NT Services, Application Domains & Principal Policy http://rickgaribay.net/archive/2007/05/10/managed-windows-nt-services-application-domains--principal-policy.aspx <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><font color="#ff0000">Update to orginal post:</font> After doing some more research, the actual problem turned out to be that the legacy Windows NT service never specified the WindowsPrincipal and had nothing to do with the Gateway assembly. In fact, it turns out that when you load a class using Activator.CreateInstanceFrom(), the class loads into the same parent application domain. I've updated the solution below appropriately.</span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Thanks to <a href="http://www.west-wind.com/weblog/">Rick Strahl</a> for clarifying the Activator.CreateInstanceFrom(), app domain behavior. You can also find an <a href="http://www.code-magazine.com/article.aspx?quickid=0211081&amp;page=1">excellent article</a> by Rick in CoDe magazine that covers this extensively: <font face="Arial"><a href="http://www.code-magazine.com/article.aspx?quickid=0211081&amp;page=1">http://www.code-magazine.com/article.aspx?quickid=0211081&amp;page=1</a></font></span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">- - -</span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">I recently ran into a security problem in a somewhat typical scenario for which the specific details I imagine are fairly esoteric because I was unable to find anything relevant on the web or on <a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1556266&amp;SiteID=1">MSDN forums</a>. It is amazing how easy it is to forget (or at least suffer from delayed recall) fundamental aspects of the framework when you are in the thick of it and trying to ship a product!</span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">So, </span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">I figured I’d post an overview of the scenario and the solution to the problem in hopes of helping anyone else who runs into this.<o:p></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p><strong>Scenario</strong></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">A common approach for setting up any kind of automated process is to use a Windows NT service which is continually running, monitoring a queue or database for records/messages that represent events for wich some work should be performed. For example, I can have a Windows NT Service monitor a private queue every 5 seconds, and when a message is available, process it (whatever process means for the given service). <o:p></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">One option for the processing bit would be to raise and event and delegate the work out to a method that would maintain all of the event handling logic. This handler could reside in a single class within the same assembly as the service, but for obvious reasons this could quickly get unruly and introduce a maintanance nightmare. If every time you need to change the event handling business logic you had to recompile and redeploy the service executable, although you might be building job security, you'd find yourself getting frustrated at best and at worst, you would be tightly coupled to a single assembly making it difficult to leverage this pattern in a more abstract, loosely coupled manner.</span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">One possible solution might be</span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> to apply a typical publish and subscribe pattern where the Windows NT service polls a backing store (or ideally was notified automagically) and when a record (or message) meets a specific criteria fire an event. The event would then be mapped to a delegate which implements the handling of the event. However, to keep the implementation of the handler from being static and hard coded, we could further delegate the implementation of the work to an external component, making the original event handling delegate only worry about the plumbing for dispatching the work to another component. Ideally, this would allow a plug and play approach where assemblies could be "dropped" in and just work. Of course, this would require that the message in a queue has some kind of metadata about the component to execute (such as assembly name, type and URI) and when the event is fired, the handler gets access to this URI and dispatches the call to it. <o:p></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">This is precisely what the System.Activator class allow you to. If you know the name of the assembly that contains the component you want to call, simply call the CreateInstanceFrom method on the Activator class. The CLR will then probe the local private directory for the assembly name, load it and instantiate an instance of the type. <strong>Figure 1</strong> below summarizes what this might look like.<o:p></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p> </o:p></span> </p> <p class="MsoNormal" align="center"><img alt="Figure 1" align="absMiddle" src="http://farm1.static.flickr.com/222/492763344_94ccf58a1d.jpg" /></p> <p class="MsoNormal" align="center"><strong><font size="1">Figure 1: Mock Sequence Diagram</font></strong></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">When the IGateway object is “unwrapped” and made available to the MyNTService Windows NT Service, the service can call a method (or methods) on the instance to do some work. To achieve polymorphism, since the Gateway component that is unwrapped implements the IGateway interface, the service is guaranteed to be able to call a particular method (Execute, in this case). </span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Figure 2 (below, right) provides a possible object model that supports this design.</span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">The purpose of the Gateway class is to serve as wrapper around a component/service call while maintaining location transparency. This can thought of as a "super proxy" and is really just the classic Service Gateway/Service Agent pattern. The MyNTService Windows NT Service  has no idea if the component is local to the machine or process or somewhere out in the cloud. <img alt="" hspace="8" align="right" vspace="8" src="http://farm1.static.flickr.com/202/492763346_41226f5269.jpg" />With this flexibility comes significant power in being able to make decisions on distribution in a post-deployment manner. <o:p></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">As the saying goes “<em>with great power comes great responsibility</em>”. Looking again at the sequence diagram in <strong>Figure 1</strong>, two important things need to be considered.<o:p></o:p></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">First, this scenario demonstrates WS-I Profle interop between a WCF service and a managed Windows NT Service running on .NET 1.1 CLR (pretty cool huh?). </span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Second, between every call in the sequence is an authentication and authorization boundary. Though impractical, the Gateway component could ensure that only the identity of the Windows account running the MyNTService Windows NT Service can call it’s Execute method. More importantly, however, the Gateway should flow the identity of the Windows account running the MyNTService Windows NT Service process to the WCF service that is out in the cloud so that the WCF service can authenticate and authorize the call. Pretty simple,right?</span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><strong><o:p>Problem</o:p></strong></span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Well, one of the things that may not be overly apparent is that the assembly in which the Gateway type that implements the IGateway interface resides will actually load in the same application domain that exists within the host NT service process. The MyNTService Windows NT Service knows NOTHING about the Gateway component (other than that it implements a standard interface). When an instance of the Gateway component is activated, we want to run in the security context of the parent process (of the MyNTService Windows NT Service ), however if the host application domain has not specifically set the the Principal Policy, the component will execute with no security context, or to be a bit more technical, will load using the default UnauthenticatedPrincipal enumeration flag. This basically means that the principal under which the MyNTService Windows NT Service is running will not be attached to the thread on which the Gateway component runs. <span style="mso-spacerun: yes"> </span>In fact, as the MSDN documentation for the System.Security.Principal.PrincipalPolicy enumeration states “Specifies how principal and identity objects should be created for an application domain. The default is <strong>UnauthenticatedPrincipal</strong>.”.</span></p> <p class="MsoNormal"><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><strong>Solution<o:p></o:p></strong></span></o:p></span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Those keen to the default behavior regarding application domains and Windows Principals already know where this is going, but for those who aren’t sure, stay with me. <o:p></o:p></span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Although the MyNTService Windows NT Service was running as a fixed domain account, the WCF service requires transport level authentication and uses role-based authorization to ensure the caller (MyNTService) is authorized. However, </span><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">calls from the MyNTService Windows NT Service via the Gateway were failing with <span style="COLOR: black"><strong>"The request failed with HTTP status 401: Authorization Required."</strong> </span></span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><span style="COLOR: black">I triple checked IIS security settings. My unit tests worked just fine. My test harness also worked and even browsing to the service’s metadata page was working. For some reason, the Gateway was calling the WCF service in a seamingly anonymous manner. This threw me for a loop for a couple of days.<o:p></o:p></span></span></p> <p><span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: Arial">Then, a few days ago, while in the shower (I get many of my “light-bulb on” moments in the shower or in my dreams for some odd reason) the solution hit me like a thunderbolt! The Gateway assembly was being loaded without an authenticated principal, and hence the solution was simple, sweet and elegant:<o:p></o:p></span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'">AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);</span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Now the Gateway took on the identity of the Windows AD account that was running the Windows NT Service process and was able to authenticate to and be authorized by the WCF service.</span></p> <p><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">You can find more info on principal policy and application domain behavior here: <font face="Arial"><a href="http://msdn2.microsoft.com/en-us/library/90395801.aspx">http://msdn2.microsoft.com/en-us/library/90395801.aspx</a></font></span></p> <p class="MsoNormal" align="center"><strong><font size="1"></font></strong></p><img src="http://rickgaribay.net/aggbug/133.aspx" width="1" height="1" /> Rick G. Garibay - The more I learn, the less I kno http://rickgaribay.net/archive/2007/05/10/managed-windows-nt-services-application-domains--principal-policy.aspx Thu, 10 May 2007 17:34:58 GMT http://rickgaribay.net/archive/2007/05/10/managed-windows-nt-services-application-domains--principal-policy.aspx#feedback 2 http://rickgaribay.net/comments/commentRss/133.aspx http://rickgaribay.net/services/trackbacks/133.aspx