Sep 23, 2009

Unit Testing – A Book you have been waiting for

Does your project have low test coverage, unreadable test code, high investments in maintaining unit tests? Do you feel writing unit test being awkward and time consuming, questioning the overall benefit, not trusting some of the unit tests? Ever had discussions about fake/stubs/mocks, what is better Record-Replay or Arrange/Act/Assert (triple A) syntax, where to set up your fakes, differences between unit and integration tests, testing best practices, different tools and test frameworks?

No? Working as a hair dresser or what? Then you can easily forget about the following …

I just finished reading Roy Osherove’s (300 pages) book “The Art of Unit Testing” which is an easy but MUST-READ book, I’ve been waiting for a long time now. You do not have to agree with all of his views, but definitively opens up your mind concerning unit testing.

Go an get it. Or if you are a team lead or manager go and get a stack of it. Your investment will pay back soon!

Sep 22, 2009

VS MSTEST Test Run Deployment Item Error – DLL not trusted

I remember having this error for a couple of times already during the last few years – so I write a post of my own about the solution to the following issue:

Running Visual Studio 2008 (MSTEST) unit tests fails with:

Failed to queue test run '2009-09-22 17:11:11': Test Run deployment issue: The location of the file or directory 'sqlite3.dll' is not trusted.

image

There were some hints about using the caspol tool to add full trust to the assembly which DID NOT WORK FOR ME:

C:\Program Files\Microsoft Visual Studio 9.0\VC>caspol -m -ag 1.2 -url \\localhost\c$\project\tools\* FullTrust

Microsoft (R) .NET Framework CasPol 2.0.50727.4016
Copyright (c) Microsoft Corporation.  All rights reserved.

The operation you are performing will alter security policy.
Are you sure you want to perform this operation? (yes/no)
yes
Added union code group with "-url" membership condition to the Machine level.
Success

A better approach was:

1. Remove the reference to the dll from VS
2. Shut down VS
3. Right click the assembly (here the sqlite3.dll) und click the UNBLOCK button.
4. Restart Visual Studio
5. Re-add the reference to the file

image

(thanks to markrob35)

Sep 15, 2009

WLW Syntax Highlighting with CopyAsHtml

Some of my fellow blogger colleagues at my company hinted using SyntaxHighlighter to post source code. As I am using CopyAsHtml (Visual Studio plugin) for quite some time now and found out about the HTML view in Windows Live Writer

image

I keep sticking to it. Looks much better again:

   21 private void timer1_Tick(object sender, EventArgs e)

   22 {

   23     Color c = ColorUnderCursor.Get();

   24     this.label1.Text = "Color under cursor = " + c.ToArgb().ToString("x8") + " [hex]";

   25     this.label2.Text = c.ToArgb().ToString() + " [int]";

   26 }

Sep 14, 2009

Color under Cursor in C#

To easily “steal” some styles and colors from a given web app, I wrote the following little application to find out the color under the mouse pointer.

image

And here’s the code for the major parts:

using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace ColorUnderPixel
{
    public class ColorUnderCursor
    {
        [DllImport("gdi32")]
        public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetCursorPos(out POINT pt);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);

        /// <summary>
        /// Gets the System.Drawing.Color from under the mouse cursor.
        /// </summary>
        /// <returns>The color value.</returns>
        public static Color Get()
        {
            IntPtr dc = GetWindowDC(IntPtr.Zero);

            POINT p;
            GetCursorPos(out p);

            long color = GetPixel(dc, p.X, p.Y);
            return Color.FromArgb((int)color);
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
        public int X;
        public int Y;
        public POINT(int x, int y)
        {
            X = x;
            Y = y;
        }
    }
}

[Update] Please note that the hex values must be reversed to represent a RGB value like in a CSS

background-color: #3b5998;

Human Interaction Workflow

Windows Workflow Foundation 4.0 does not provide explicit framework classes or tools for workflow human interaction (e.g. waiting for a real actor of a workflow to make a decision how to continue).

Approach

Therefore we gave the following approach a try:

  1. Create a workflow with a SQL persistence extension that represent an order confirmation process
  2. Send email to actor, including a link to a ASP.NET application, a URL with request argument (the workflow instance id)
  3. Add a pick activity with two pickbranches, each including a aec.CreateNamedBookmark(<bm>)
  4. Create an ASP.NET application page to confirm a process, loading the workflow instance and calling ResumeNamedBookmark(<bm>)

Here a some details.

Bookmarks

To block the workflow and wait for human interaction we used the concept of “Bookmarks”. A bookmark is a named point in your workflow to unload and later resume. To create a bookmark and unload we created a simple custom activity:

public class CreateBookmark : NativeActivity
{
    public InArgument<string> Bookmark { get; set; }

    protected override void Execute(ActivityExecutionContext context)
    {
        context.CreateNamedBookmark(Bookmark.Get(context), new BookmarkCallback(BookmarkCallback));
    }

    private void BookmarkCallback(ActivityExecutionContext executionContext, Bookmark bookmark, object value)
    {
        executionContext.RemoveAllBookmarks();
    }
}

Sending Email

[Credits for this code to Alex]

Before we can unload our workflow we need to send an URL to the human. The link requests a page that resumes our workflow later on.

public class SendMailActivity : CodeActivity
{
    public InArgument<string> From { get; set; }
    public InArgument<string> To { get; set; }
    public InArgument<string> Subject { get; set; }
    public InArgument<string> Body { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        var fromAddress = new MailAddress(From.Get(context));
        var toAddress = new MailAddress(To.Get(context));

        var addresses = new MailAddressCollection();
        addresses.Add(toAddress);

        using (var message = new MailMessage(fromAddress, toAddress))
        {
            message.Subject = Subject.Get(context);
            message.Body = Body.Get(context);

            var mail = new SmtpClient("localhost", 25);
            mail.Send(message);
        }
    }
}

Get Workflow Instance Id

We did not find a simple way to get the workflow instance identifier in our workflow. To work around this we created another simple activity:

public class WorkflowIdActivity : CodeActivity<Guid>
{
    protected override void Execute(CodeActivityContext context)
    {
       Result.Set(context, context.WorkflowInstanceId);
    }
}

Pick and Pickbranch

To summarize: we have a workflow that sends a link to a human, persists and unloads. The question is now (the answer has cost me a beer) what WF4 construct to use to continue our workflow; resuming on two parallel branches. We used the pick and pickbranch activities and included a CreateBookmark trigger activity:

<p:Pick>
  <p:PickBranch>
    <p:PickBranch.Trigger>
      <w:CreateBookmark Bookmark="[‘Accepted’]" />
    </p:PickBranch.Trigger>
    <e:SendMailActivity Body="[‘Your order has been accepted’]" From="[‘goodboss@email.com’]" Subject="[‘Laptop order’]" To="[‘goodboss@email.com’]" />
  </p:PickBranch>
  <p:PickBranch>
    <p:PickBranch.Trigger>
      <w:CreateBookmark Bookmark="[‘Rejected’]" />
    </p:PickBranch.Trigger>
    <e:SendMailActivity Body="[‘Your order has been rejected’]" From="[‘badboss@email.com’]" Subject="[‘Laptop order’]" To="[‘badboss@email.com’]" />
  </p:PickBranch>
</p:Pick>

The Web Page

Last step is to build a simple web page, including a green and a red button. Note how we parsed the URL argument to get the workflow identifier.

public partial class OrderConfirmationForm : System.Web.UI.Page
{
    static SqlPersistenceProviderFactory persistenceProviderFactory;
    static AutoResetEvent instanceUnloaded = new AutoResetEvent(false);
    private Guid workflowId;

    protected void Page_Load(object sender, EventArgs e)
    {
       string id = this.Context.Request.Params["id"];
         workflowId = new Guid(id);
    }

    protected void btnAccept_Click(object sender, EventArgs e)
    {
        ResumeWorkflow("Accepted");
    }

   protected void btnDecline_Click(object sender, EventArgs e)
    {
        ResumeWorkflow("Rejected");
    }

    private void ResumeWorkflow(string bookmark)
    {
        SetupPersistence();

        PersistenceProvider persistenceProvider = persistenceProviderFactory.CreateProvider(workflowId);
        WorkflowInstance instance = WorkflowInstance.Load(new OrderProcessing(), persistenceProvider);
        instance.Extensions.Add(persistenceProvider);

        instance.OnUnloaded = () => instanceUnloaded.Set();

        instance.ResumeBookmark(bookmark, null);
        instanceUnloaded.WaitOne();

        ClosePersistence();
    }

    static void SetupPersistence()
    {
        persistenceProviderFactory = new SqlPersistenceProviderFactory(@"Database=Instances;Integrated Security=True", false, false, TimeSpan.FromSeconds(60));
        persistenceProviderFactory.Open();
    }

    static void ClosePersistence()
    {
        persistenceProviderFactory.Close();
    }
}

WIF (aka Geneva) Glossary

Federated claims-based security as implemented in Microsoft Windows Identity Foundation brings a set of terms that are important to understand. Because I did not find a glossary “out there” I put together a list of terms annotated with a definition (copied from other sources like K. Brown or written myself).

[Sorry: partly in German]

Term

Description

Claim

a bit of identity information such as name, email address, age, membership in the Sales role, and so on

Token

A security token is a serialized set of claims that is digitally signed by the issuing authority

STS

builds, signs, and issues security tokens according to the interoperable protocols

RP

an application that relies on claims

R-STS

the .NET Access Control Service features a Resource-STS: that R-STS can be configured for accepting tokens from specific IP-STSs, and perform various claim transformation including emitting authorization claims

IP-STS

Identity provider STS, like Live ID/passport, ADFS, Sun Metro, CA SiteMinder, IBM, Oracle

Issuer

Issuing authority like Domain Controller, Certificate Authority, Ausweisb├╝ro der Gemeinde/Kanton

Rule

Claims transformation rule (input -> output)

Federate

“verb├╝nden”, trust, establish base for SSO

Claims transformation

Values of input claims are transferred to output claim values (copied, constants, from claim type to other claim type). Mapping.

Scope

Container for rules and token settings (like token renewal, etc.).

Claim type

A URN string describing the meaning of a claim. There are standard claim types; you can add your own.

Action claim

Claim representing an ACS right (e.g. servicebus send/listen/etc.)

ClaimsAuthorizationManager

Modul/Handler used by an RP to implement special authorization. Also possible to do other claims transformation/mapping.

ACS

Azure .NET Services component for Identity und Access Control

Service Bus

Transparent, routed WCF web service through the cloud, providing quality of services.

   

Sep 9, 2009

Code Contracts in Visual Studio 2010

Currently still a Microsoft DevLabs Project (planned to be included in 4.0/VS2010) – Code Contracts is a very powerful tool “to sue your code”.

Definitions

Preconditions: Required state for a method to run successfully. Contract.Requires();
Postconditions: Guarantees condition that will always be true upon completion of a method. Contract.Ensures(Contract.Result<int>() != 0);
Assertions: Contract.Assert(); Contract.Assumer();
Object Invariants: guarantees about conditions that will always be true for the objects. [ContractInvariantMethod]protected void ObjectInvariant()

Code Contracts are inherited (seems correct decision according to OO substitution principle), but preconditions cannot be added, postconditions can. Interface contracts can be applied with attributes, passing a class to specifiy contract.

A basic concept is that your IL code is re-written with CC code (like it or not). Code can be statically checked or at runtime. In Visual Studio there is a new project settings tab “Code Contract”.

 

image

Unit Test Timeout

A nice feature we were just shown is that a mstest [TestMethod] can get a [Timeout(100)] attribute to allow long-running (hanging) tests from blocking your unit test run for too long:

image

WF 4.0 Persistence

Day 3 starts with a recap of what we have done so far with WF4, including the

Testing practices

we did. Important here:

  • isolate dependecies (e.g. web service send/receive activities)
  • design workflow for testability (like creating testable sub workflows and putting all the untestable plumbing activities into a top-level workflow

Today we will have a look at the new workflow persistence concepts in WF4.0. There are samples to look at.

Workflow persistence

is a must for long-running workflows. An important concept here are bookmarks which are a kind of marker for unloaded/persisted workflow instances that can be resumed. What was formerly known as workflow services are now extensions. A persistence provider creates a provider to persist your instances. There is one provider for SQL Server at the moment as far as we’ve seen.

static SqlPersistenceProviderFactory persistenceProviderFactory;
persistenceProviderFactory = new SqlPersistenceProviderFactory(@"Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\SampleInstanceStore.mdf; Integrated Security=True", false, false, TimeSpan.FromSeconds(60));
persistenceProviderFactory.Open();

// start, unload, run
WorkflowInstance instance = new WorkflowInstance(myWorkflow);
id = instance.Id; 
instance.Extensions.Add(persistenceProviderFactory.CreateProvider(id));
instance.OnIdle = () => IdleAction.Unload;
instance.OnUnloaded = () => instanceUnloaded.Set();
instance.Persist();
instance.Run();

// load, resume
PersistenceProvider persistenceProvider = persistenceProviderFactory.CreateProvider(id);
WorkflowInstance instance = WorkflowInstance.Load(activity, persistenceProvider);
instance.Extensions.Add(persistenceProvider); 
instance.OnUnloaded = () => instanceUnloaded.Set(); 
instance.ResumeBookmark(readLineBookmark, input);

persistenceProviderFactory.Close()

Code Generation with T4

The text templating engine (tt or t4) is part of the Visual Studio environment for quite a few version now. It can be used to generate static wrapper classes for workflow in and out arguments.

Static code (text) sections are mixed with dynamic C# code to emit the target file. My 3 minute sample here:

image

Syntax highlighting comes from tangible engineering VS plugin (a free edition exists).

Sep 8, 2009

HelloWorld Workflow Exercise

The task is creating a workflow that requests for a name (2 to 3 chars long) from the console and prints it, saying hello.

Creating a new VS2010 workflow Flowchart console application crashes first time, but restarting allows continuing.

We create a FlowChart workflow with a DoWhile activity, create a ReadlineActivity

image

image

assign the result of the code activity (string) to workflow variable (id):

image

press “F9” to add breakpoint in workflow designer and run it with “F5”:

Enter name:
l
Enter name:
leder
Enter name:
lem
Hello lem from WF4.0
Press any key to continue . . .

Now, we want to implement best practices and don’t block in an activity, so let’s refactor it to run asynchronous.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.Threading.Tasks;

namespace HelloWorldWorkflow
{
    /// <summary>
    /// Asynchronous code activity that does the bookmark plumbing code correctly.
    /// </summary>
    /// <typeparam name="T">Type of the return value.</typeparam>
    public abstract class AsyncCodeActivity<T> : CodeActivity<T>
    {
        /// <summary>
        /// Activity execution method.
        /// </summary>
        /// <param name="context">The code activity context.</param>
        protected override void Execute(CodeActivityContext context)
        {
            var asyncContext = context.SetupAsyncOperationBlock();
            var task = new Task((ac) =>
            {
                var asyncCtx = (AsyncOperationContext)ac;

                T ret = InternalExecute(context);

                asyncCtx.CompleteOperation(new BookmarkCallback(InternalCompleteAsyncWork), ret);
            }, asyncContext);
            task.Start();
        }

        /// <summary>
        /// Internal activity execution method.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected abstract T InternalExecute(CodeActivityContext context);

        /// <summary>
        /// Internal async code activity completion method.
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="bm"></param>
        /// <param name="ret"></param>
        protected virtual void InternalCompleteAsyncWork(ActivityExecutionContext ctx, Bookmark bm, object ret)
        {
            Result.Set(ctx, ret);
        }
    }
}

and my ReadlineActivity would look like this:

public class ReadlineActivity : AsyncCodeActivity<string>
{
    protected override string InternalExecute(System.Activities.CodeActivityContext context)
    {
        Console.Write("Enter name: ");
        string id = Console.ReadLine();
        return id;
    }
}

Much easier and less error prone!

Workflow Foundation 4.0

Now getting more technical with Alex, we start learning about the new framework and tools.

But first we do an excursion to other workflow tools existing: K2 blackpearl, skelta BPM.NET (looks interesting, 100% embeddable, designer), Aspouse.Workflow for .NET, AddFlow for .NET (looks depricated?!), Nintex Workflow 2007 (runs only in SharePoint).

(source: msdn.microsoft.com)

What’s new: new designer, new runtime, clearer data flow, new activities (no state-chart style yet, but new FlowChart), more activities, XAML only (no XOML), better WCF integration (WorkflowServiceHost, xamlx files for IIS activated workflows, threading based on ThreadPool, Rules and Expressions (as activities, no stand-alone engine yet, no forward-chaining (yet?), no vocabulary support), different programming models (WorkflowElement and WorkflowElement<T> as base type, with return value), bookmarks (set workflow to named idle state: aec.CreateNamedBookmarkus(“bm”, resumeCallback) and workflowInstance.ResumeBookmark(“bm”);), asynchronous operation: aec.SetupAsyncOperationBlock(); t = new Task(…), t.Start(); asyncContext.CompleteOperation(cb).

Backwards compatiblity: WF3 runs under .NET 4.0 (WF3.0), old activities incompatible with WF4.

Now let’s go hands-on.

Business Modeling

Day 2 is starting at 8 am with a very short introduction from Manuel into the modeling of business process. This should give all the foundations to dig into Windows Workflow Foundation 4.0 later today.

“BM is the creation of a model of an abstract but real business”. Like our software models, business models only represent a certain view onto a business. There is no just 1 correct model. “Modellieren = Hervorheben + Weglassen”. Models for an IT architect are typically much more detailed than for the business.

Types of diagrams: Business Use Case (BUCD), Activity, Business Analysis (BAM).

Process: Model –> Document –> Verify (iterate). BM Hamburger: Strategy –> Operations –> IT (business goals) and backwards (verification).

A business process: has a goal, input, output, needs resources, has impact.

Model diagram: shows business actors and business workers, swim lanes, activities, sequences, parallelism/joins, decision nodes, start and end node(s)

BPMN example (one possible notation; quite complex and very detailed; not suitable for business people, this is a model diagram for IT specialists):

(source: ebmpl.org)

BPEL example: very exact; executable model

Sep 7, 2009

.NET ServiceBus Exceptions

I would like to collect some common exceptions from the service bus here in this post.

Wrong solution name:

Unhandled Exception: System.ServiceModel.EndpointNotFoundException: No DNS entri
es exist for host mlede.servicebus.windows.net. ---> System.Net.Sockets.SocketEx
ception: No such host is known
   at System.Net.Dns.GetAddrInfo(String name)

Wrong password:

Unhandled Exception: System.ServiceModel.FaultException: authN failed: 'mleder'
of PasswordCredential (#<aGuid>)
   at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(Tim
eSpan timeout)
   at System.ServiceModel.Security.IssuanceTokenProviderBase`1.GetTokenCore(Time
Span timeout)

Timeout (happens quite often as the CTP cloud hosting infrastructure seems to be quite light weight):

Unhandled Exception: System.TimeoutException: The open operation did not complet
e within the allotted timeout of 00:01:00. The time allotted to this operation m
ay have been a portion of a longer timeout. ---> System.TimeoutException: The so
cket transfer timed out after 00:00:59.9098704. You have exceeded the timeout se
t on your binding. The time allotted to this operation may have been a portion o
f a longer timeout. ---> System.Net.Sockets.SocketException: A connection attemp
t failed because the connected party did not properly respond after a period of
time, or established connection failed because connected host has failed to resp
ond
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size,
SocketFlags socketFlags)

Problem with added ConnectionStatusBehavior:

“ConnectionStatusBehavior requires an IChannelListener that exposes IConnectionStatus”

Trying to emit service meta data:

System.ServiceModel.EndpointNotFoundException was unhandled
  Message="Could not connect to
http://servicebus.accesscontrol.windows.net/sts/username_for_certificate. TCP error code 10060: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 65.55.54.15:80. "
  Source="System.ServiceModel"
  StackTrace:
    Server stack trace:
       at System.ServiceModel.Channels.HttpOutput.WebRequestHttpOutput.GetOutputStream()
       at System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)

Cloud not reachable at the moment:

System.ServiceModel.CommunicationException was unhandled
  Message="Unable to reach servicebus.windows.net via TCP (818, 828) or HTTP (80, 443)"
  Source="Microsoft.ServiceBus"
  StackTrace:
       at Microsoft.ServiceBus.NetworkDetector.ChooseConnectivityModeForAutoDetect(Uri uri)

Service Bus Meta Data

The question came up how to emit WCF service meta data for possible clients. According to hhaaii this is not possible with wsHttRelayBinding but only with netTcpRelayBinding. netTcp did not work with svcutil so I tried the following:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="EndpointBehavior">
          <transportClientEndpointBehavior credentialType="UserNamePassword">
            <clientCredentials>
              <userNamePassword userName="<solution>" password="<password>" />
            </clientCredentials>
          </transportClientEndpointBehavior>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
         <serviceMetadata httpGetEnabled="true" httpGetUrl="meta" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Microsoft.ServiceBus.Samples.EchoService">
        <endpoint behaviorConfiguration="EndpointBehavior" binding="wsHttpRelayBinding"
          contract="Microsoft.ServiceBus.Samples.IEchoContract" />
        <endpoint address="mex" binding="wsHttpRelayBinding" bindingConfiguration=""
          name="MexEndpoint" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

The service started. Going to the service bus registry, clicking the service asked for my credentials

image

but then a Fault was generated:

image

Giving up, sorry.

Service Bus Registry: public discovery

One of the components in a SOA environment is the so-called service registry. A registry lists running services. In .NET Services there is a ATOM feed that shows your current publicly listed services:

image

The echoservice is only listed when a ServiceRegistrySettings behavior is added to the service endpoint:

IEndpointBehavior serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);
endpoint.Behaviors.Add(serviceRegistrySettings); 

Otherwise it is not publicly visible!

image

Unfortunately I could not add this registry behavior using app.config configuration. The WCF config editor tool does not even reflect on the behavior in the Microsoft.ServiceBus.dll. I’m not sure if I’m doing something wrong or this is not possible yet with July CTP.

Microsoft Azure .NET Services

The upcoming series of posts are dedicated to “Herr Hannes”.
Starting today with the Microsoft Azure platform is Mario, 7.9.09.

The main drivers to go into the Cloud are: Operation, Maintenance, Quality-of-Services, Security.

clip_image001

Windows Azure Platform (source blogs.msdn.com)

Introduction

Azure
  • Microsoft Windows Azure (Platform; compute/store/manage; open for 3rd party hosters)
    vs. Azure Services (Live Services, .NET Services, SQL Services, SharePoint Services, Dynamics CRM Services and more)
  • for application and service hosting (in the cloud)
  • Pricing & Licensing (2000 VM hours compute, 50 GB storage, 20 GB network throughput / day), then
    compute 0.12$/hour, storage = 0.15$, SQL Azure 1 GB 10$/month or 100$/month,
    .NET Services 0.15$/100k messages, 0.10$ bandwidth/GB
.NET Services
  • for .NET, Java, Ruby; REST, SOAP, RSS, ATOM. Focus on application integration and access control
    Quality of Services, flexible scale out
Service Bus
  • Patterns: Service Registry, Connectivity (relay or direct), pub/sub
    "abge-space-ter ESB", NAT/firewall traversal, HTTP and TCP (using ports 808, 818, 819, 828)
    Addressing: [http|sb]://solution.servicebus.windows.net/project/serviceXy , new schema prefix "sb" for TCP
      One-way connection relays,

Service Connectivity (source: msdn.microsoft.com)

Azure is building on existing assets such as WCF. WCF is enhanced in two areas:

  1. bindings (see below) and
  2. behaviors

WCF Bindings and new service bus Relay bindings:

BasicHttpBinding (BasicHttpRelayBinding)
WebHttpBinding (WebHttpRelayBinding)
WSHttpBinding (WSHttpRelayBinding)
WS2007HttpBinding (WS2007HttpRelayBinding)
WSHttpContextBinding (WSHttpRelayContextBinding)
WS2007HttpFederationBinding (WS2007HttpRelayFederationBinding)
NetTcpBinding (NetTcpRelayBinding)
NetTcpContextBinding (NetTcpRelayContextBinding)
n/a  (NetOnewayRelayBinding)
n/a  (NetEventRelayBinding)

Resources

So let’s do some hands-on. There’s a sample called EchoService in the SDK.

As always with WCF you create a contract:

[ServiceContract(Name = "IEchoContract", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
public interface IEchoContract
{
    [OperationContract]
    string Echo(string text);
}

implement the contract:

[ServiceBehavior(Name = "EchoService", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/")]
class EchoService : IEchoContract
{
    public string Echo(string text)
    {
        Console.WriteLine("Echoing: {0}", text);
        return text;           
    }
}

Configure the self-hosting console application in app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <services>
      <!-- Application Service -->
     
<service name="Microsoft.ServiceBus.Samples.EchoService">
        <endpoint contract="Microsoft.ServiceBus.Samples.IEchoContract"
                  binding="netTcpRelayBinding" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

Do the self-hosting:

// Determine the system connectivity mode based on the command line
// arguments: -http, -tcp or -auto  (defaults to auto)
ServiceBusEnvironment.SystemConnectivity.Mode = GetConnectivityMode(args);

Console.Write("Your Solution Name: ");
string solutionName = Console.ReadLine();
Console.Write("Your Solution Password: ");
string solutionPassword = ReadPassword();

// create the endpoint address in the solution's namespace
Uri address = ServiceBusEnvironment.CreateServiceUri("sb", solutionName, "EchoService");

// create the credentials object for the endpoint
TransportClientEndpointBehavior userNamePasswordServiceBusCredential = new TransportClientEndpointBehavior();
userNamePasswordServiceBusCredential.CredentialType = TransportClientCredentialType.UserNamePassword;
userNamePasswordServiceBusCredential.Credentials.UserName.UserName = solutionName;
userNamePasswordServiceBusCredential.Credentials.UserName.Password = solutionPassword;

// create the service host reading the configuration
ServiceHost host = new ServiceHost(typeof(EchoService), address);

// create the ServiceRegistrySettings behavior for the endpoint
IEndpointBehavior serviceRegistrySettings = new ServiceRegistrySettings(DiscoveryType.Public);

// add the Service Bus credentials to all endpoints specified in configuration
foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
{
    endpoint.Behaviors.Add(serviceRegistrySettings);
    endpoint.Behaviors.Add(userNamePasswordServiceBusCredential);               
}

// open the service
host.Open();

Console.WriteLine("Service address: " + address);
Console.WriteLine("Press [Enter] to exit");
Console.ReadLine();

// close the service
host.Close();

On the client side we are doing a similar thing using the ChannelFactory:

// create the service URI based on the solution name
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb", solutionName, "EchoService");

// create the credentials object for the endpoint
TransportClientEndpointBehavior userNamePasswordServiceBusCredential = new TransportClientEndpointBehavior();
userNamePasswordServiceBusCredential.CredentialType = TransportClientCredentialType.UserNamePassword;
userNamePasswordServiceBusCredential.Credentials.UserName.UserName = solutionName;
userNamePasswordServiceBusCredential.Credentials.UserName.Password = solutionPassword;

// create the channel factory loading the configuration
ChannelFactory<IEchoChannel> channelFactory = new ChannelFactory<IEchoChannel>("RelayEndpoint", new EndpointAddress(serviceUri));

// apply the Service Bus credentials
channelFactory.Endpoint.Behaviors.Add(userNamePasswordServiceBusCredential);

// create and open the client channel
IEchoChannel channel = channelFactory.CreateChannel();
channel.Open();

So what was added to WCF for Azure:

  • the binding (NetTcpRelayBinding)
  • a cloud rendez-vouz address (“sb://mleder.servicebus.windows.net/EchoService”)
  • a behavior (TransportClientEndpointBehavior) to pass Azure solution credentials
  • a behavior for the registry (ServiceRegistrySettings)

Behaviors and credentials above can also be done using config files and the Microsoft Service Configuration Editor tool:

image 

However, the new TransportClientEndpointBehavior has only one property (CrendentialType) that can be edited. Not very useful; hope this will be improved until release.

Sep 3, 2009

Blogging with Windows Live Writer

Not using one of Scot Hanselman’s The Big Ten Life and Work-Changing Utilities is rather provoking. So I decided to give Live Writer a try for blogging (which is infrequent I admit; because time or projects not permitting).

It’s free, it’s WYSIWYG, can insert (well) text,

pictures

DSCF1774

maps

Map picture

columns

Tool Impression
Live Writer nice and slim

tags

Technorati Tags: ,,,

spellcheck, etc.