SESSION CODE: ASI302 ©2010 IDesign Inc., portions © 2010 Microsoft Corporation All rights reserved.
Download ReportTranscript SESSION CODE: ASI302 ©2010 IDesign Inc., portions © 2010 Microsoft Corporation All rights reserved.
SESSION CODE: ASI302 ©2010 IDesign Inc., portions © 2010 Microsoft Corporation All rights reserved About Juval Löwy Software architect Consults and trains on .NET architecture Microsoft's Regional Director for the Silicon Valley Recent book Programming WCF Services (2010 O’Reilly) Participates in the .NET/WCF design reviews Publishes at MSDN and other magazines Speaker at the major international development conferences Recognized Software Legend by Microsoft Contact at www.idesign.net About Clemens Vasters Principal Technical Lead Windows Azure AppFabric – Service Bus Feature Area Program Manager Architect Role Inbound Customer Requirements and Feedback Protocol and API Architecture and Prototyping Previously co-owned Training & Consulting business in Germany 100s of conferences & workshops in > 45 countries @clemensv on Twitter [email protected] Hosted In-House Storage Storage E-Commerce Front Outsourced Storage Ordering System Inventory / Shipping System PO SO ACK ACK Ready Shipped Delivered Order Accepted Order Processed Web Client Experience Hi-Fi Client Experience Integrate cloud and on-premise assets Interconnect across on-premise sites Service Remoting in Action Metadata Exchange Can expose metadata endpoints Unlike regular WCF No dedicated metadata binding tag MetadataExchangeBindings unaware of service bus Use regular service bus bindings instead <endpoint address binding contract /> <endpoint kind address binding /> = "sb://MyNamespace.servicebus.windows.net/MEX1" = "netTcpRelayBinding" = "IMetadataExchange" = "mexEndpoint" = "sb://MyNamespace.servicebus.windows.net/MEX2" = "netTcpRelayBinding" Metadata Exchange If adding MEX endpoint programmatically must also add credentials behavior Client tools do not deal well with service bus MEX No easy way to provide credentials Can use default endpoint behavior with SvcUtil.exe.config WCF-provided MEX helpers don't expose endpoint they interact with Cannot provide creds Compensate using reflection to set creds Instrumental with tools and frameworks MEX Explorer Combine discovery and announcements with MEX Windows Azure, Datacenter, Hosting, Amazon EC2, Google App Engine “Worker Role” App Instance App Instance Buf unicast unicast multicast NATs Client Client Client Client Client Client NetOnewayRelayBinding – Unicast NetEventRelayBinding – Multicast Plain HTTP programming model Long-polling, optional ‘peek/lock’ read model Fan-out via single-sender-multi-receiver multicast Fan-in via multi-sender-single-receiver unicast Service Bus as Events Hub Publisher Publisher Events Hub Subscriber Subscriber Subscriber Service Bus as Events Hub Light weight pub/sub system No administrative support No per-operation subscription Endpoint level only Service Bus as Events Hub Subscriber receives events it may not care about because it has a matching endpoint [ServiceContract] interface IMyEvents { [OperationContract(IsOneWay = true)] void OnEvent1(); [OperationContract(IsOneWay = true)] void OnEvent2(int number); [OperationContract(IsOneWay = true)] void OnEvent3(int number,string text); } <endpoint address = "sb://servicebus.windows.net/services/IMyEvents" binding = "netEventRelayBinding" contract = "IMyEvents" /> Service Bus as Events Hub To manage events at the operation level need to map URIs to operations not endpoints <endpoint name = "OnEvent1" address = "sb://MyNamespace.servicebus.windows.net/IMyEvents/OnEvent1" binding = "netOnewayBinding" contract = "IMyEvents" /> <endpoint name = "OnEvent2" address = "sb://MyNamespace.servicebus.windows.net/IMyEvents/OnEvent2" binding = "netOnewayBinding" contract = "IMyEvents" /> <endpoint name = "OnEvent3" address = "sb://MyNamespace.servicebus.windows.net/IMyEvents/OnEvent3" binding = "netOnewayBinding" contract = "IMyEvents" /> Service Bus as Events Hub Have as many hosts as subscribed operations all targeting same service type At run-time must recycle hosts and programmatically add each desired endpoint to specific host Tedious repetitive code Expensive Pay for connections Service Bus as Events Hub Streamline with Juval's ServiceBusEventsHost public class ServiceBusEventsHost : DiscoverableServiceHost { public ServiceBusEventsHost(Type serviceType,Uri baseAddress); public ServiceBusEventsHost(Type serviceType,Uri[] baseAddresses); /*Additional constructors */ //Can optionally specify binding public virtual NetOnewayRelayBinding RelayBinding {get;set;} public void SetBinding(string bindingConfigName); //Subscription management public void Subscribe(); public void Subscribe(Type contractType); public void Subscribe(Type contractType,string operation); public void Unsubscribe(); public void Unsubscribe(Type contractType); public void Unsubscribe(Type contractType,string operation); } Service Bus as Events Hub ServiceBusEventsHost used like regular host Requires namespace base address(es) Appends contract name to each base address Can accept binding to use Default for secure binding No need for config file Can look up binding from config Can subscribe or unsubscribe all operations on all contracts Can subscribe or unsubscribe all operations on specific contract Can subscribe or unsubscribe specific operation on specific contract [ServiceContract] interface IMyEvents { [OperationContract(IsOneWay = true)] void OnEvent1(); [OperationContract(IsOneWay = true)] void OnEvent2(int number); [OperationContract(IsOneWay = true)] void OnEvent3(int number,string text); } class MySubscriber: IMyEvents {...} string baseAddress = "sb://MyNamespace.servicebus.windows.net/"; ServiceBusEventsHost host = new ServiceBusEventsHost(typeof(MySubscriber),baseAddress); host.Open(); host.Subscribe(); host.Unsubscribe(typeof(IMyEvents),"OnEvent2"); host.Subscribe(); host.Unsubscribe(); Service Bus as Events Hub Subscriptions stored in dictionary Maps subscribed operations per contract Can add admin support Use a tool to manage subscriptions outside scope of host/service Manage subscriptions against host as needed Service Bus as Events Hub ServiceBusEventsHost adds endpoint per base address per contract [base address]/[contract name] Monitors all messages to that address and below Publishers send messages to endpoint whose address contains operation name [base address]/[contract name]/[operation] Message Buffers Every URI can host a buffer Sender Reader Message Buffers Buffer does not equate queue Not durable Data loss with catastrophic crash of service bus Not transactional Not long lasting messages Max is 10 minutes Buffers are limited Up to 50 messages In between queued calls and fire-and-forget calls Message Buffers Aimed at Async calls Chunky calls Mostly connected applications on somewhat shaky connections One-way calls Elastic Internet wire Message Buffers API similar to System.Messaging Interact with raw WCF messages not calls Multiple services can read from same buffer Contention possible Use manual locking Multiple clients can post to buffer Message Buffers All messages are one-way No results No errors No callbacks Message Buffers Can manage and create buffers with Juval's Service Bus Explorer Message Buffers Can manage and create buffers with the Juval's Service Bus Explorer Buffered Services Raw messages are somewhat more work Not object-oriented Not type safe May want to convert between service calls and raw messages Requires a lot of low level advanced work Buffered Services Automate with Juval's BufferedServiceBusHost<T> Used like a regular host Uri buffer = new Uri(@"https://MyNamespace.servicebus.windows.net/MyBuffer"); ServiceHost host = new BufferedServiceBusHost<MyService>(buffer); host.Open(); Buffered Services Monitors specified buffers Do not provide buffers in config Actual communication is raw messages Verifies all contracts are one-way Secures all calls Verifies buffers on opening Purges on close during debug Buffered Services Hosts service locally over IPC Opens an endpoint per service contract Treats per-session as per-call Like MSMQ Configures for multiple concurrent access Transport session never expires Listens on buffers in the cloud Retrieves each raw message from buffer Converts raw message to local call over IPC Re-creates IPC channel after error Buffered Services For client use Juval's BufferedServiceBusClient<T> Configure endpoint with buffer address or provide to constructor Verifies all operations are one-way [ServiceContract] interface IMyContract { [OperationContract(IsOneWay = true)] void MyMethod(int number); } class MyContractClient : BufferedServiceBusClient<IMyContract>,IMyContract { public void MyMethod(int number) { Enqueue(()=>Channel.MyMethod(number)); } } Response Service No way to get Results Errors Client can provide dedicated response buffer for service response Should pass response address and method ID in message headers Response Service Service Buffer Client Service Response Buffer Response Service Response Service Streamline service-side with Juval's ServiceBufferResponseBase<T> Proxy base class to enqueue response Specializes BufferedServiceBusClient<T> Host must be BufferedServiceBusHost<T> class MyCalculator : ICalculator { [OperationBehavior(TransactionScopeRequired = true)] public void Add(int number1,int number2) { int result = 0; ExceptionDetail error = null; try { result = number1 + number2; } //Don't rethrow catch(Exception exception) { error = new ExceptionDetail(exception); } finally { CalculatorResponseClient proxy = new CalculatorResponseClient(); proxy.OnAddCompleted(result,error); proxy.Close(); } } } Response Service Streamline client with Juval's ClientBufferResponseBase<T> Specializes BufferedServiceBusClient<T> Adds response context to headers Returns method ID from each operation Response Service class CalculatorClient : ClientBufferResponseBase<ICalculator> { public CalculatorClient(Uri responseAddress) : base(responseAddress) {} public void Add(int number1,int number2) { Enqueue(()=>Channel.Add(number1,number2)); } } Windows Azure, Datacenter, Hosting, Amazon EC2 (Windows) Socket Agent App Instance Socket Passthrough ACS NP Agent ASP.NET ADO.NET J2EE, JDBC, JMS HTTP/HTTPS Passthrough w/ URI Rewriting TDS Passthrough ACS Socket Bridge HTTP Bridge NP Bridge Exchange/Mail (SMTP/IMAP) Active Directory (LDAP) System Center (SNMP) … ERP, CRM, Custom Apps .NET, J2EE, ROR, PHP … SQL Server On-Premise Infra Apps & Services On-Premise Data Port Bridge Adding and Enabling Discovery Services Registry Can view ATOM feed of listening services in namespace Or one of its sub URI http://[namespace].servicebus.windows.net/[URI] Services Registry Programmatically process feed with Juval's ServiceBusGraph public class ServiceBusNode { public readonly string Address; public string Name {get;set;} public MessageBufferPolicy Policy {get;set;} } public class ServiceBusGraph { public ServiceBusNode[] DiscoveredEndpoints {get;} public ServiceBusGraph(string serviceNamespace, string issuer,string secret); //More members } Service Bus Explorer View with Juval's Service Bus Explorer Can administer buffers as well Discovery Discovery was designed for the Intranet Discovery is useful Loosely-coupled clients and services Dynamic addresses Easy deployment Service bus may support discovery in future Discovery Would be nice to combine benefit of loose deployment of discovery with unhindered connectivity of service bus Can substitute events binding for UDP Discovery requests Announcements Mimic WCF discovery behavior Solution Architecture Streamline with Juval's framework IServiceBusDiscovery for discovery requests Events relay binding Supported by discoverable services Provides reply address of client [ServiceContract] public interface IServiceBusDiscovery { [OperationContract(IsOneWay = true)] void DiscoveryRequest(string contractName,string contractNamespace, Uri[] scopesToMatch,Uri replayAddress); } Solution Architecture IServiceBusDiscoveryCallback for receiving services responses Exposed by clients Over one-way relay binding [ServiceContract] public interface IServiceBusDiscoveryCallback { [OperationContract(IsOneWay = true)] void DiscoveryResponse(Uri address, string contractName,string contractNamespace,Uri[] scopes); } Client Operation Event 3 1 IServiceBusDiscovery Discovery Requests Relay Service Relay Service IServiceBusDiscoveryCallback 2 Service Discoverable Host DiscoverableServiceHost Used like regular host To enable discovery must add discovery behavior and discovery endpoint Forward looking and compatible Discoverable Host Creates internal host for private service class implementing IServiceBusDiscovery Monitors discovery requests Address defaults to URI "DiscoveryRequests" Configurable via DiscoveryAddress property Uses plain events binding to receive requests Configurable via DiscoveryRequestBinding property Calls back client using IServiceBusDiscoveryCallback Uses plain one way binding Configurable via DiscoveryResponseBinding property Discoverable Host Uri baseAddress = new Uri("sb://..."); ServiceHost host = new DiscoverableServiceHost(typeof(MyService,baseAddress); //Address is dynamic host.AddServiceEndpoint(typeof(IMyContract),new NetTcpRelayBinding(), Guid.NewGuid().ToString()); host.Open(); Discovery Client For client use Juval's ServiceBusDiscoveryClient Modeled after DiscoveryClient public class ServiceBusDiscoveryClient : ClientBase<IServiceBusDiscovery>, IServiceBusProperties { protected Uri ResponseAddress {get;} public ServiceBusDiscoveryClient(string serviceNamespace,...); public ServiceBusDiscoveryClient(string endpointName); public ServiceBusDiscoveryClient(NetOnewayRelayBinding binding, EndpointAddress address); public FindResponse Find(FindCriteria criteria); } Discovery Client ServiceBusDiscoveryClient is proxy for IServiceBusDiscovery Defaults address to URI "DiscoveryRequests" Can provide constructors with different address Uses plain one-way binding to fire requests and responses Can provide constructors with different binding Find() hosts internal service supporting IServiceBusDiscoveryCallback Opens and closes host per call Service Bus Discovery Factory Encapsulate with Juval's discovery-based SB channel factory public static class ServiceBusDiscoveryFactory { public static T CreateChannel<T>(string serviceNamespace,... Uri scope = null) where T : class; public static T[] CreateChannels<T>(string serviceNamespace,... Uri scope = null) where T : class; } Announcements Can use events binding to support announcements Juval's IServiceBusAnnouncements [ServiceContract] public interface IServiceBusAnnouncements { [OperationContract(IsOneWay = true)] void OnHello(Uri address,string contractName,string contractNamespace, Uri[] scopes); [OperationContract(IsOneWay = true)] void OnBye(Uri address,string contractName,string contractNamespace, Uri[] scopes); } Client Operation Event 2 Announcements Relay Service IServiceBusAnnouncements 1 Service Announcements Automated with Juval's DiscoverableServiceHost Requires configuring announcements endpoint in discovery behavior Defaults to announcing on "AvailabilityAnnouncements" URI under service namespace Configurable via AnnouncementsAddress property Calls client using plain one way binding Configurable via AnnouncementsBinding property Fires event asynchronously Service Bus Discovery MEX Explorer supports discovery and announcements Resources Programming WCF Services 3rd Edition Juval Löwy, O'Reilly 2010 www.idesign.net Code library Coding standard Sample architecture report IDesign Method™ Master Classes Architect’s Master Class November 15-19, California http://www.idesign.net/idesign/download/IDesignCD.zip www.Microsoft.com/WindowsAzure/AppFabric http://msdn.microsoft.com/enus/azure/netservices.aspx http://blogs.msdn.com/b/netservices/ http://twitter.com/azure_appfabric http://www.microsoft.com/biztalk/ http://msdn.microsoft.com/biztalk/ http://blogs.msdn.com/biztalk_server_team_blog http://www.biztalkblogs.com/ www.appinfrastructure.com http://www.microsoft.com/appfabric http://msdn.microsoft.com/appfabric www.microsoft.com/teched www.microsoft.com/learning http://microsoft.com/technet http://microsoft.com/msdn Sign up for Tech·Ed 2011 and save $500 starting June 8 – June 31st http://northamerica.msteched.com/registration You can also register at the North America 2011 kiosk located at registration Join us in Atlanta next year