PDC Recap: Applications and Communications Roadmap: Platform Presents and Futures

Don Box's Spoutlet

Syndication

For those who couldn't make it to PDC, here's the content from the "Lap Around CSD" talk that I gave with Mike Vernal, Doug Walter, and Dharma Shukla.
 
The flow of the talk was (Term-Definition-Haiku-XML-code)+.  Here's the basic content formatted fairly hastily for this blog entry:
 

Message
Noun, An XML-compatible unit of information exchanged by programs
 
Message, oh Message
The Truth Is On The Wire
There Is Nothing Else
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:A="
http://schemas.xmlsoap.org/ws/2004/08/addressing">
    <S:Header>
        <A:Action>http://schemas.microsoft.com/demo/ListProcesses</A:Action>
    </S:Header>
    <S:Body />
</S:Envelope>
    static void Main() { // mysvc
        Message request = Message.CreateMessage(XmlReader.Create(Console.In));
        Message reply = null;
        Console.WriteLine(request.Headers.Action);
 
        if (request.Headers.Action == "http://schemas.microsoft.com/demos/ListProcesses")
        {
            var query =
                new XElement("Processes",
                    from p in Process.GetProcesses()
                    select new XElement("ProcessData",
                        new XElement("Name", p.ProcessName),
                        new XElement("WorkingSet", p.WorkingSet)));
 
            reply = Message.CreateMessage(
                request.Version,
                "
http://schemas.microsoft.com/demos/ProcessListing",
                new XBodyWriter(query));
        }
        else
        {
            reply = Message.CreateMessage(
                request.Version,
                MessageFault.CreateFault(
                    new FaultCode("InvalidAction"),
                    new FaultReason(
                    string.Format("Action {0} not recoginized", request.Headers.Action))
                )
            );
        }
        reply.WriteTo(new XmlTextWriter(Console.Out));
    }

Contract
Noun, An XML-compatible description of a set of message exchanges
 
To Marry Our Apps,
Your Contract Or My Contract?
Both Color The Dance…
<wsdl:definitions
    targetNamespace="
http://schemas.microsoft.com/demos/csdlap/contracts"
    xmlns:tns="
http://schemas.microsoft.com/demos/csdlap/contracts"
    xmlns:wsa="
http://schemas.xmlsoap.org/ws/2004/08/addressing"
    xmlns:s="
http://www.w3.org/2001/XMLSchema"
    xmlns:wsdl="
http://schemas.xmlsoap.org/wsdl/"
>
    <wsdl:types>
        <xs:schema elementFormDefault="qualified" xmlns:xs="
http://www.w3.org/2001/XMLSchema">
            <xs:complexType name="ProcessData">
                <xs:sequence>
                    <xs:element minOccurs="0" name="Name" nillable="true" type="xs:string" />
                    <xs:element minOccurs="0" name="WorkingSet" type="xs:int" />
                </xs:sequence>
            </xs:complexType>
            <xs:element name="ProcessData" nillable="true" type="ProcessData" />
            <xs:element name="Processes">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element minOccurs="0" maxOccurs="unbounded"
                                  name="ProcessData" nillable="true" type="ProcessData" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </wsdl:types>
    <wsdl:message name="ListProcessesMessage" />
    <wsdl:message name="ProcessListingMessage">
        <wsdl:part name="Processes" element="Processes" />
    </wsdl:message>
    <wsdl:portType name="ProcessManagementContract">
        <wsdl:operation name="GetProcesses">
            <wsdl:input wsa:Action="
http://schemas.microsoft.com/demos/ListProcesses" message="tns:ListProcessesMessage" />
            <wsdl:output wsa:Action="
http://schemas.microsoft.com/demos/ProcessListing" message="tns:ProcessListingMessage" />
        </wsdl:operation>
    </wsdl:portType>
</wsdl:definitions>

static void Main() { // requestgen
    ListProcessesMessage request = new ListProcessesMessage();
    Message msg = TypedMessageConverter.ToMessage(request);
    msg.WriteTo(new XmlTextWriter(Console.Out));
}
 
static void Main() { // replysync
    Message msg = Message.CreateMessage(XmlReader.Create(Console.In));
    ProcessListingMessage reply = TypedMessageConverter.FromMessage<ProcessListingMessage>(msg);
    foreach (ProcessData proc in reply.Processes)
        Console.WriteLine("{0,-30}{1}", proc.Name, proc.WorkingSet);
}
 
; poor-man's orchestration langauge
C:\demodir> requestgen | mysvc | replysync
 

Service
Noun, A collection of XML-compatible named messaging endpoints
An Endpoint Per Chance,
Address, Binding, and Contract,
That Is What Matters!
 
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <system.serviceModel>
        <services>
            <service type="ProcessManagementService">
                <endpoint contract="UniversalContract"
                          binding="basicHttpBinding"
                          address="
http://localhost/demo/pdclap" />
                <endpoint
                    contract="UniversalContract"
                    binding="wsHttpBinding"
                    address="
http://localhost/myPath/infocard"
                    bindingConfiguration="infoCardBinding"
                />
                <endpoint
                    contract="UniversalContract"
                    binding="wsHttpBinding"
                    address="
http://localhost/myPath/ws"
                />
 
            </service>
        </services>
        <client>
           <endpoint
                configurationName="myEndpoint"
                contract="ProcessManagementContract"
                binding="wsHttpBinding"
                address="
http://localhost/myPath/ws"
                />
        </client>
    </system.serviceModel>
</configuration>
 
// the client program that uses asynchronous passing of statically typed messages
        static void Main(string[] args) 
        {
            ListProcessesMessage request = new ListProcessesMessage();
 
            ProcessManagementContract channel =
                ChannelFactory.CreateChannel<ProcessManagementContract>(
                "myEndpoint");
 
            IAsyncResult result = channel.BeginGetProcesses(request, null, null);
 
            while (!result.IsCompleted)
            {
                Console.WriteLine("waiting ...");
                System.Threading.Thread.Sleep(500);
            }
 
            ProcessListingMessage reply = channel.EndGetProcesses(result);
 
            foreach (ProcessData p in reply.Processes)
            {
                Console.WriteLine("{0,-30}{1,10}", p.Name, p.WorkingSet);
            }
 
        }
 
// the "universal" contract used by the service to allow any message to arrive

[ServiceContract]
public interface UniversalContract
{
    [OperationContract(Action = "*", ReplyAction = "*")]
    Message HandleMessage(Message request);
}
 
// our service implementation that parrots the Console.In|Out program from "Message"
public class ProcessManagementService : UniversalContract
{
    public Message HandleMessage(Message request)
    {
        Message reply = null;
        if (request.Headers.Action == "
http://schemas.microsoft.com/demos/ListProcesses")
        {
            var query =
                new XElement("Processes",
                    from p in Process.GetProcesses()
                    select new XElement("ProcessData",
                        new XElement("Name", p.ProcessName),
                        new XElement("WorkingSet", p.WorkingSet)));
 
            reply = Message.CreateMessage(
                request.Version,
                "
http://schemas.microsoft.com/demos/ProcessListing",
                new XBodyWriter(query));
        }
        else
        {
            reply = Message.CreateMessage(
                request.Version,
                MessageFault.CreateFault(
                    new FaultCode("InvalidAction"),
                    new FaultReason(string.Format("Action {0} not recoginized", request.Headers.Action))
                )
            );
        }
        return reply;
    }
}
// the hosting code for our service
    static void Main(string[] args)
    {
        ServiceHost host = new ServiceHost(typeof(ProcessManagementService));
        host.Open();
 
        foreach (EndpointListener listener in host.EndpointListeners)
            Console.WriteLine(listener.Listener.LocalAddress);
 
        Console.WriteLine("Service Started!");
        Console.ReadLine();
 
        host.Close();
    }

Claim
Noun, An XML-compatible assertion that helps establish a digital identity
“I’m Me,” I Assert!
And If You Don’t Believe Me,
Trust The Issuer!
  
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"
            xmlns:A="http://schemas.xmlsoap.org/ws/2004/08/addressing">
            xmlns:SEC="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-260secext-1.0.xsd">
    <S:Header>
        <A:Action>http://schemas.microsoft.com/demo/ListProcesses</A:Action>
        <SEC:Security>... Gudginesque XML goes here ...</SEC:Security>
    </S:Header>
    <S:Body />
</S:Envelope>
        if (OperationContext.Current.ServiceSecurityContext != null)
        {
            foreach (ClaimSet cs in OperationContext.Current.ServiceSecurityContext.AuthorizationContext)
            {
                foreach (Claim claim in cs)
                {
                    Console.WriteLine(claim);
                }
            }
        }

Workflow
Noun, An XML-compatible program that combines domain-specific activities
 
A XAML Runtime:
Now You Too Can Be Chris Brumme;
Is It Possible?
 
 
// myapp.xaml
<?Mapping XmlNamespace="http://schemas.microsoft.com/winfx/2005/workflow/activities"
          ClrNamespace="System.Workflow.Activities"
          Assembly="System.Workflow.Activities" ?>
 
<?Mapping ClrNamespace="PDC" Assembly="WriteLine" XmlNamespace="http://fabrikam.com/domainstuff" ?>
 
<SequentialWorkflow
   xmlns:wl="http://fabrikam.com/domainstuff"
   xmlns:x="Definition"
   ID="wf"
   x:Class="MyApplication"
   xmlns="http://schemas.microsoft.com/winfx/2005/workflow/activities"
>
  <Parallel ID="xxxx">
    <Sequence ID="UUUUU" >
      <Delay TimeoutDuration="00:00:05" ID="xx7" />
      <wl:WriteLine Text="One" ID="xx1" />
      <wl:WriteLine Text="Two" ID="xx2" />
      <wl:WriteLine Text="Three" ID="xx3" />
    </Sequence>
    <Sequence ID="UUUUUUUUUUUUUU" >
      <wl:WriteLine Text="Four" ID="xx4" />
      <wl:WriteLine Text="Five" ID="xx5" />
    </Sequence>
  </Parallel>
</SequentialWorkflow>
 
// myactivity.cs
using System;
using System.Workflow.ComponentModel;
 
namespace PDC {
    public class WriteLine : Activity {
        string text;
        public string Text {
           get { return text; }
           set { text = value; }
        }
 
        protected override Status Execute(ActivityExecutionContext aec) {
            // enterprise-ready business logic goes here...
            Console.WriteLine("Contoso-Fabrikam: {0}", text);
            return Status.Closed;
        }
    }
}
 
// shell hosting program
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
 

namespace XomlShell {
    class Program {
        static void Main(string[] args) {
            string xomlPath = args[0];
            string[] refs = new string[args.Length - 1];
            Array.Copy(args, 1, refs, 0, refs.Length);
 
            WorkflowCompilerParameters p = new WorkflowCompilerParameters(refs);
            p.GenerateInMemory = true;
 
            WorkflowCompilerResults results = new WorkflowCompiler().CompileFromFile(p, xomlPath);
            if (results.Errors.HasErrors) {
                foreach (object error in results.Errors)
                    Console.WriteLine(error);
            }
            else {
                Assembly assm = results.CompiledAssembly;
 
                AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) {
                    if (e.Name == assm.GetName().ToString())
                        return assm;
                    return null;
                };
 
                Type workflowType = null;
                foreach (Type type in assm.GetTypes())
                    if (typeof(IRootActivity).IsAssignableFrom(type)) {
                        workflowType = type;
                        break;
                    }
 
                WorkflowRuntime runtime = new WorkflowRuntime();
                runtime.StartRuntime();
                System.Threading.ManualResetEvent ev = new System.Threading.ManualResetEvent(false);
 
                runtime.WorkflowCompleted += delegate(object s, WorkflowCompletedEventArgs eee) {
                    ev.Set();
                };
 
                WorkflowInstance instance = runtime.StartWorkflow(workflowType);
                ev.WaitOne();
            }
 
        }
 
    }
}

Future
Noun, An XML-compatible world that supports collaboration between programmers and civilians
 
 
Code Versus Data?
Is That Really The Question?
Both Must Coexist…
 
 

Posted Sep 22 2005, 07:01 PM by don-box

Comments

Don Box wrote re: PDC Recap: Applications and Communications Roadmap: Platform Presents and Futures
on 09-22-2005 3:33 PM
My God, this looks ugly.
Kevin Dente wrote re: PDC Recap: Applications and Communications Roadmap: Platform Presents and Futures
on 09-22-2005 5:23 PM
WPF, XAML
WCF, WWF, LINQ
Oy, so much to learn
Javier G. Lozano wrote re: PDC Recap: Applications and Communications Roadmap: Platform Presents and Futures
on 09-23-2005 10:24 AM
This is some deep stuff! I agree with Kevin so much to learn, so little time.
Himadrish Laha wrote re: PDC Recap: Applications and Communications Roadmap: Platform Presents and Futures
on 09-27-2005 8:39 PM
Great Job!!!

Wish you all the best for next realese paper :)

Cheers!
Himadrish
mauros@UGIdotNET wrote Microsoft Windows Workflow Foundation
on 09-29-2005 10:14 AM
Nicholas Hill wrote re: PDC Recap: What a load of Boddox?
on 10-07-2005 3:48 PM
Don,

You are a really good salesman. What do you think an Architect is?
Kirk Allen Evans' Blog wrote Replicating the Demo from the PDC05 COM200 Session
on 11-14-2005 1:04 PM
If you didn't attend PDC05 this year and missed the COM200 - Applications and Communications Roadmap:...

Add a Comment

(required)  
(optional)
(required)  
Remember Me?