Declarative Services is one of the new features included in the .NET framework 4.0. In a nutshell, declarative services are WCF services modeled and implemented entirely in XAML. This feature is fundamentally enabled by extending Windows Workflow Foundation (WF) 4.0 with the capability of modeling WCF contracts using XAML. You can read more details about declarative services on the MSDN documentation. Even if you are not entirely familiar with WF as a technology, I am sure you can see the advantages of implementing services in a declarative languages.
Some of the most challenging aspects of Service Oriented (SO) solutions such as versioning, management and governance are notably increased by the fact that most enterprise web services are developed entirely using imperative languages such as C# or Java. Why is that? Well, to give you an example, think about the process that we have to go through in order to change a WCF services that has been running on a production system. In the best case, this process will involve deploying some assemblies to the GAC or to a particular directory, changing some references and restarting some service hosts. Now multiply that order of complexity by the number of services you have on your enterprise and the best you are going to get is a huge headache :)
In order to address some of these challenges, many developers have turned to dynamic languages such as Ruby or Python looking for a more declarative approach to implement services. Although none of the WS stacks built on dynamic languages is nearly as powerful as WCF they are certainly easier to modify and maintain. Declarative services represent an evolution of this paradigm that leverages the benefits of the XAML WF dialect.
XAML-only workflows has become one of the most popular features of the first two versions of WF. The ability of writing logic using an XML-based language drastically improves the versioning, management and other important aspects of software solutions based on WF. Declarative services can be seen as an attempt to extend the same benefits onto the world of WCF services.
In medium to large environments, one of the great benefits of declarative services would be the ability of centrally store the service definition and implementation in a database or any other data repository. This approach will improve the ability to version, modify, document or query services while still leveraging all the capabilities of the WCF runtime. For instance, we could envision a solution on which a custom WCF service host that loads declarative services dynamically from a database. The following diagram illustrates that approach.
It turns out that there is a simple but elegant solution for implementing this pattern using WCF-WF 4.0. Let's start with the following database that can be used host XAML service definitions as well as part of the endpoint address configuration.
Fundamentally, a declarative service definition will be stored in the XAMLService table. Essentially the service column will store the XAML implementation and contract of the WCF service. Additionally some of the details associated with the service host will be kept in the HostConfig table. This is not a real world examples by any stretch of the imagination. On the contrary, we are trying to keep things as simple as possible in order to correctly illustrate the fundamental concepts.
We will abstract the communication with the database using an ADO.NET Entity Model that maintains an almost one to one mapping with the physical database.
Having completed the ADO.NET EF model we can implement a custom WCF service host that dynamically loads the service definition from a database and initializes it using the existing XAML services functionalities.
1: public class WorkflowRepositoryServiceHost:
2: System.ServiceModel.Activities.WorkflowServiceHost
3: { 4: private Guid serviceID;
5: private static XAMLService currentDBService;
6:
7: public WorkflowRepositoryServiceHost(Guid serviceid):
8: this(LoadServiceDefinition(serviceid),
BuildServiceEndpoints(serviceid))
9: { 10:
11: }
12:
13: public WorkflowRepositoryServiceHost(Service serviceDefinition,
params Uri[] baseAddresses) :
14: base(serviceDefinition, baseAddresses)
15: { 16: ServiceMetadataBehavior mtdBehavior = new ServiceMetadataBehavior();
17: mtdBehavior.HttpGetEnabled = true;
18: this.Description.Behaviors.Add(mtdBehavior);
19: }
20:
21:
22: protected override void OnOpening()
23: { 24: base.OnOpening();
25: }
26:
27: private static Service LoadServiceDefinition(Guid serviceid)
28: { 29: XAMLDBEntities entities= new XAMLDBEntities();
30: IEnumerable<XAMLService> query= from s in entities.XAMLServices
where s.id == serviceid select s;
31: if (query.Count<XAMLService>() > 0)
32: { 33: List<string> endpoints = new List<string>();
34: MemoryStream stream = new MemoryStream();
35: currentDBService= query.First<XAMLService>();
36: XElement.Parse(currentDBService.Service, LoadOptions.None).
Save(stream);
37: stream.Seek(0, SeekOrigin.Begin);
38:
39: Service service = (Service)XamlServices.Load(stream);
40:
41: return service;
42: }
43: else
44: return null;
45:
46: }
47:
48: private static Uri[] BuildServiceEndpoints(Guid serviceid)
49: { 50: if (null == currentDBService)
51: LoadServiceDefinition(serviceid);
52:
53: List<Uri> uris = new List<Uri>();
54: currentDBService.HostConfigs.Load();
55: var endpointQuery = from e in currentDBService.HostConfigs select e;
56: foreach (HostConfig c in endpointQuery)
57: uris.Add(new Uri(String.Format(http://localhost:{0}/{1},
c.Port, c.Path)));
58: return uris.ToArray<Uri>();
59: }
60: }
Essentially, our custom service host extends the default workflow services (lines 1-2) and dynamically instantiate a XAML service (line 39) together with parts of the endpoint configuration from the database (lines 48-59). In this model, the service implementation could be updated real time in the database without any further deployment actions. The changes will be effective the next time the host starts.
Even though this is a very simplistic scenario, hopefully it will give you a starting point to realize the benefits of declarative services in traditional service oriented environments.
Thanks to all the folks who attended to my session about WOA at SOAWorld 2009. I got a lot of interesting questions from an always sharp New York audience :). You can get the slide deck here…
This afternoon I will be presenting a session about Web Oriented Architectures (WOA) at SOAWorld. The session explores the concepts behind real world architectures based on the principles of REST and how they represent an interesting alternative to traditional SOA.
The SOAWorld team always manages to put together a great speaker lineup including some of the top SOA practicioners in the world. Among many other things, I would recommend attending to the "Business Value" panel that Anne Thomas Manes and Miko Matsumura will deliver tonight.
As you might be aware, Tellago (my new venture ) has been steadily growing during last year. We are still looking for talented architects that would like to join our team. Specifically, we are have a few openings for BizTalk Architects and developers. If you are skilful with BizTalk technologies and you are crazy enough to join our team please drop me a line at jesus dot rodriguez at tellago dot com or at jobs at tellago dot com.
Next Monday I will be presenting two sessions at VSLive Las Vegas. The first session is about the WCF 4.0 extensibility model and it covers almost all the major extensibility points of the different WCF subsystems such as messaging, security, instancing, etc.
The second session is about building services using WCF and WF 4.0. Here we will cover some of the major changes in the WF 4.0 programming model that improve the service development and management experience
I am trying to keep both sessions very practical which means we are going to spend a lot of time in Visual Studion going through code. Additionally, as much as possible, the demostrations will highlight real world scenarios that will give the audience a better sense of how to better take advantage of this technologies.
If you attending to VSLive and you are interested on WF and WCF 4.0 you should come to my session. I promise to keep things interesting ;).
Following my previous post, I’ve decided to start blogging some examples of the use of Axum on distributed programming scenarios. The purpose of these samples is not to detail the specific features of the Axum language but rather to highlight some practical scenarios that can be improved by the combination of Axum and other technologies.
As any other CLR-based language, Axum will require to interoperate seamlessly with other Microsoft technologies in order to gain adoption in the real world. Distributed or Service Oriented systems are some of the areas on which Axum’s capabilities for modeling and executing highly concurrent tasks can drastically improve the way we implement some message exchange scenarios with technologies like WCF.
In order to illustrate some of these concepts, let’s try implementing a classic message load generation scenario on which a client needs to distribute multiple copies of a message to a specific service endpoint. These types of mechanism have been traditionally implemented by frameworks such as SOAPUI or LoadRunner.
For the simplicity of this sample let’s use the service illustrated in the following code.
Our client application will interact with the service using WCF’s channel API (we can consider a similar implementation using a service proxy). Creating WCF artifacts such as messages or channels can introduce potential side effects into Axum’s runtime. In order to mitigate these side effects, we can abstract the access to the message and channel factories using the following isolated class.
1: isolated class ClientContext
2: { 3: [Readable]
4: public static ChannelFactory<IRequestChannel> channelFactory;
5: public static MessageBuffer messageBuffer;
6: }
The highlighted isolated clause instructs Axum that the class has been optimized for concurrent access. Having this component, we can create an Axum agent that sends a single message to the service using an IRequestChannel. The following code illustrates that technique.
1: channel RequestReplyChannel
2: { 3: input bool sendRequest;
4: output bool success;
5: }
6:
7: private agent RequestReplyAgent : channel RequestReplyChannel
8: { 9: public RequestReplyAgent()
10: { 11: var sendRequest= receive(PrimaryChannel::sendRequest);
12: unsafe
13: { 14: var requestMessage= ClientContext.messageBuffer.CreateMessage();
15: var clientChannel= ClientContext.channelFactory.CreateChannel();
16: var responseMessage= clientChannel.Request(requestMessage);
17: clientChannel.Close();
18: PrimaryChannel::success <-- true ;
19:
20: }
21:
22:
23: }
24:
25: }
Notice that the agent exposes two ports that use Boolean values to indicate whether to send a message to the WCF service and whether the response was successful or not. This simple design can enable interesting message exchange scenarios like collecting all the successful responses and all SOAP faults into separate lists that can be communicated back to the caller. Additionally, we should consider the fact that passing WCF message objects as part of Axum ports introduces some challenges given a lot potential side effects.
At this point, we just need to implement the code that activates multiple instances of the previous agent asynchronously. We can accomplish this by sending a Boolean message to the our Axum agent for each WCF message we want to send to our target service. After receiving the message, the agent will retrieve an instance of the WCF message and the channel factory from the isolated context class. At that point, the agent will create a new IRequestChannel instance using the channel factory and it will send the message to the WCF service.
1: public domain Program
2: { 3: private writer agent MainAgent : channel Microsoft.Axum.Application
4: { 5: public MainAgent()
6: { 7: Message baseMessage= null;
8: ChannelFactory<IRequestChannel> factory= null;
9:
10:
11: unsafe
12: { 13: XmlDictionaryReader msgreader = XmlDictionaryReader.CreateDictionaryReader(XmlReader.Create("C:\\Projects\\Tellago\\WCFPerformance\\Services\\SampleServices\\SampleClients\\Messages\\EchoMessage.xml")); 14: baseMessage = Message.CreateMessage(msgreader , Int32.MaxValue, MessageVersion.Soap11);
15: baseMessage.Headers.Action= "Action";
16: factory= new ChannelFactory<IRequestChannel>(new BasicHttpBinding(),
17: new EndpointAddress("http://localhost:9092/SampleServices/Service.svc")); 18: ClientContext.channelFactory= factory;
19: ClientContext.messageBuffer= baseMessage.CreateBufferedCopy(Int32.MaxValue);
20:
21: }
22:
23: for(int index= 0; index<= 10000; index++)
24: { 25: var wcfAgent= RequestReplyAgent.CreateInNewDomain();
26: wcfAgent::sendRequest <-- true;
27: }
28:
29: Console.ReadLine();
30:
31: PrimaryChannel::Done <-- Signal.Value;
32: }
33:
34: }
Notice that the creation of the message buffer and channel factory has been enclosed within an unsafe code block. This technique allow Axum to execute code that introduces potential side effects.
After executing this program, multiple copies of the original message will be sent to our sample service.
My good friend and colleague Pablo Cibraro will be presenting a MSDN WebCast tomorrow about the capabilities, relationships and differences of emerging security standards such as OpenID, OAuth and LiveID. The WebCast is targeting Microsoft’s Latinoamerica developer community and will be conducted in Spanish :(
If you follow Pablo’s weblog, you might have read some of his recent posts about RESTful services security and its relationship with WCF. If you are interested on the options available for implementing security capabilities on RESTful services and you are fluent in Spanish you MUST attend to Pablo’s WebCast , he has promised to keep things interesting ;).
Last week Microsoft announced the first version of Axum. In a nutshell, Axum is a domain specific language (DSL) for modeling coordination and concurrency scenarios in .NET applications. Although Axum is still an incubation project and there is no final word on whether it will be productized, we should all agree that this represents a remarkable effort to enhance the .NET language ecosystem to embrace the next generation of applications based on multi-core architectures.
At first, Axum might seem a little “different” for developers accustomed to the traditional OO paradigm. This is fundamentally based on fact that this new language embraces the concepts of functional programming and messaging passing paradigms. It is understandable that a lot of developers in the .NET community will question the need for a new language for concurrency especially after similar efforts in technologies such as the .NET parallel extensions, F# and the Common Concurrency Runtime (CCR). Among these recent technologies, the CCR has made significant strides introducing new paradigms for addressing concurrency scenarios. In that sense, it does not come as a surprise that Axum uses the CCR as the runtime components underneath the language constructs.
Beyond any skepticism, we should see Axum as another step towards the renaissance of functional and messaging passing programming paradigms in the software industry. Outside the .NET community, similar tendencies can be seen by the increasing popularity of languages such as Erlang or Scala that intend to address similar type of scenarios. Contrary to the traditional school of thought that these type of languages are only relevant in academic environments, we keep finding more and more real world applications that are powered by the use of functional languages and specifically the message passing paradigm.
For thus of us working in distributed systems, I can see a few reasons while we should embrace this new type of programming technique.
- Scalability: Passing messages across side effect free tasks is a naturally scalable approach for distributed applications. It is not surprising that some of the most scalable systems in the world leverage on languages that follow similar principles to Axum. For instance, it’s well known that Amazon’s Simple DB has been entirely built on Erlang or that Twitter has relied on Scala to address some of their notorious scalability issues.
- Task partitioning: Axum forces developers to think how to split the functionality of an application into a set of concurrent tasks that can communicate via messages. This is a very familiar approach to distributed system programmers who have been using messaging distribution techniques for years now.
- Task distribution: One of the features that differentiates Axum from similar languages is its ability to partition an application into a set of isolated agents that can communicate either locally or remotely. In that sense, Axum relies on WCF as a mechanism for distributing tasks in a single server or across thousands of machines.
- Concurrent Service Choreographies: Orchestrating concurrent services interactions it’s a very common and equally challenging aspects of SO systems. These scenarios have been traditionally addressed by integration technologies such as BizTalk Servers or Windows Workflow Foundation. Even when using these technologies, implementing concurrent and coordinated interactions across distributed services typically requires large amounts of infrastructure code. For instance, implementing a very simple scenario that requires distributing a message across ten different services, collecting all the successful response and all the errors on those separate lists and aggregate them into a single response is far from trivial in most, if not all, of the existing integration frameworks.
I am happy to announce another top architect that has recently joined out team. Dwight Goins joined Tellago as a Sr. Solutions Architect and is currently working in one of the biggest BTS Server deployments in the world.
Dwight is a frequent speaker at Microsoft events including the Microsoft SOA&BPM Conference and local and international BizTalk User Groups, and other events. In a previous life, he traveled the world as a premier BizTalk Consultant/Advisor/Trainer to MS Russia, MS Beijing, HP Shanghai, MS Prague, HP Prague, MS Portugal, MS India, HP India. As an author, he wrote the Microsoft BizTalk Server 2006 Exam, and worked with some of the "Big Ballers" of the industry like Microsoft, HP, Xterprise, US Airways and etc. His blog can be found at http://dwightgoins.blogspot.com/
Welcome onboard Dwight!! We are proud to have you.
Continuing the list of recent additions to our team, we are thrilled to announce that Pablo Cibraro has joined Tellago as a Sr. Solutions Architect. Pablo is a phenomenal programmer and one of the authorities in Microsoft Connected Systems technologies. He is a Microsoft Connected Systems MVP and a member of the prestigious Connected Systems Advisors group. He regularly blogs at http://weblogs.asp.net/cibrax about WCF, Geneva, Web Services Security and many other topics.
We are happy to have him and I am particularly excited because now I have somebody to argue with me about security topics all the time.
More Posts
Next page »