SESSION CODE: ASI302 ©2010 IDesign Inc., portions © 2010 Microsoft Corporation All rights reserved.

Download Report

Transcript 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