Archive for the ‘Cloud’ Category.

Host WCF Services in IIS with Service Bus Endpoints

Update: To see how to leverage Windows Azure AppFabric Autostart to activate the WCF Service, please see AutoStart WCF Services to Expose them as Service Bus Endpoints.


Vishal Chowdhary, a Senior Test Lead on the Azure AppFabric team, recently posted a whitepaper on hosting WCF services with Service Bus endpoints from IIS.  This whitepaper provides two solutions to a (previously) significant challenge in hosting WCF services in IIS that connect to the Azure AppFabric Service Bus.

The primary challenge is activation. As Vishal writes, “For the on-premise WCF service to start receiving messages from the Service Bus in the cloud (aka Relay Service), the on-premises service opens an outbound port and creates a bidirectional socket for communication.  It connects to the Service Bus, authenticates itself, and starts listening to calls from the relay service before the client sends its requests.”  He goes on to say that “IIS/WAS relies on message-based activation & will launch the host only after the first request comes in.”  Consequently, until the first message is received by IIS the service will never establish a connection to the Service Bus; with no connection to the Service Bus, it will never receive a message.  A bit of a dilemma.

In the whitepaper, Vishal points out two ways to resolve this challenge:

  • IIS Application Warm-Up
  • ASP.NET 4.0 Auto-Start

In this post, I’m going to highlight exactly how to go about using IIS Application Warm-Up to get a WCF service hosted in IIS 7.5 to receive messages from the Service Bus.  This post borrows heavily from Visha’s whitepaper; I strongly suggest you spend the time to read the entire paper.

  1. If you’re using .NET 4.0, you must setup .NET 4.0 to work with the Azure AppFabric SDK.
  2. Create a new ASP.NET Web Application project called EchoSample in Visual Studio 2010 using .NET 4.0.
  3. To validate this approach, we want this project hosted in IIS.  Right-click the project and choose Properties.  Select the Web tab, and switch from Use Visual Studio Development Server to Use Local IIS Web server and click Create Virtual Directory.
  4. Add the Microsoft.ServiceBus reference from the “C:\%Program Files%\Windows Azure platform AppFabric SDK\V1.0\Assemblies\” folder.
  5. You have to create a custom BehaviorExtensionElement for the ServiceRegistrySettings to make the discoverability policy ‘Public’ in the configuration file.  Consequently, we need to create a class that we’ll call MyServiceRegistrySettingsElement that inherits the BehaviorExtensionElement.
public class MyServiceRegistrySettingsElement : BehaviorExtensionElement
{
    public override Type BehaviorType
    {
        get { return typeof(ServiceRegistrySettings); }
    }
    protected override object CreateBehavior()
    {
        return new ServiceRegistrySettings()
        {
            DiscoveryMode = this.DiscoveryMode,
            DisplayName = this.DisplayName
        };
    }
    [ConfigurationProperty("discoveryMode", DefaultValue = DiscoveryType.Private)]
    public DiscoveryType DiscoveryMode
    {
        get { return (DiscoveryType)this["discoveryMode"]; }
        set { this["discoveryMode"] = value; }
    }
    [ConfigurationProperty("displayName")]
    public string DisplayName
    {
        get { return (string)this["displayName"]; }
        set { this["displayName"] = value; }
    }
}
  1. Now, let’s add a new WCF Service called EchoService to the project.  Remove the existing method in the ServiceContract and create the following GetData method in the IEchoService.cs file.
[OperationContract]
string GetData(int value);
  1. Also, update the EchoService.svc.cs with the implementation of the GetData method.
public string GetData(int value)
{
    if (value < 0)
        throw new ApplicationException("Negative values not allowed!!!");

    Thread.Sleep(value);
    return string.Format("You entered: {0}", value);
}
  1. Now we need to update the web.config settings.  This is fairly extensive. Be sure and replace YOUR_NAMESPACE, YOUR_ISSUER_NAME, and YOUR_ISSUER_SECRET with your own values.
<system.serviceModel>
  <extensions>
    <behaviorExtensions>
      <add name="ServiceRegistrySettings"
            type="EchoSample.MyServiceRegistrySettingsElement, EchoSample,
                  Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </behaviorExtensions>
  </extensions>
  <services>
    <clear />
    <service behaviorConfiguration="MyServiceTypeBehavior"
              name="EchoSample.EchoService">
      <endpoint
         address="http://localhost/EchoSample/EchoService.svc/LocalEchoService"
         binding="basicHttpBinding"
         bindingConfiguration="BasicHttpConfig"
         name="Basic" contract="EchoSample.IEchoService" />
      <endpoint
         address="https://YOUR_NAMESPACE.servicebus.windows.net/EchoServiceHttp/"
         behaviorConfiguration="sharedSecretClientCredentials"
         binding="basicHttpRelayBinding"
         bindingConfiguration="HttpRelayEndpointConfig"
         name="RelayEndpoint"
         contract="EchoSample.IEchoService" />
      <endpoint
         address="sb://YOUR_NAMESPACE.servicebus.windows.net/EchoServiceNetTcp/"
         behaviorConfiguration="sharedSecretClientCredentials"
         binding="netTcpRelayBinding"
         bindingConfiguration="NetTcpRelayEndpointConfig"
         name="RelayEndpoint"
         contract="EchoSample.IEchoService" />
    </service>
  </services>
  <bindings>
    <basicHttpBinding>
      <binding name="BasicHttpConfig" />
    </basicHttpBinding>
    <!--service bus binding-->
    <basicHttpRelayBinding>
      <binding name="HttpRelayEndpointConfig">
        <security relayClientAuthenticationType="RelayAccessToken" />
      </binding>
    </basicHttpRelayBinding>
    <netTcpRelayBinding>
      <binding name="NetTcpRelayEndpointConfig">
        <security relayClientAuthenticationType="RelayAccessToken" />
      </binding>
    </netTcpRelayBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="sharedSecretClientCredentials">
        <transportClientEndpointBehavior credentialType="SharedSecret">
          <clientCredentials>
            <sharedSecret issuerName="YOUR_ISSUER_NAME"
                          issuerSecret="YOUR_ISSUER_SECRET" />
          </clientCredentials>
        </transportClientEndpointBehavior>
        <ServiceRegistrySettings discoveryMode="Public" />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="MyServiceTypeBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>


At this point, once you compile and build the solution, the service will not automatically connect to the Service Bus; this is because IIS/WAS waits until the first service call to activate.  Consequently, if you load the WCF service in the browser it will activate the service and establish a connection to the Service Bus (you can confirm by checking https://YOUR_NAMESPACE.servicebus.windows.net/).  So, we’re close, but not yet there.

To get the service to automatically establish the connection to the Service Bus, we’ll use the Application Warm-Up extension for IIS 7.5.

  1. Download and install the Application Warm-Up extension for IIS 7.5.  This gives us the ability to proactively load and initialize processes before the first request arrives.  In addition to improving responsiveness it also gives us the ability to connect our WCF service to the Azure AppFabric Service Bus.
  2. In IIS, select your virtual application EchoSample.  Double-click the Application Warm-Up feature, and click Settings.  Check the Start Application Pool ‘ASP.NET v4.0’ when service started checkbox.

Application Warm-Up settings

  1. Add a new request to register EchoService.svc as a warm-up request for the application.  Right-click and choose Add Request.  Enter EchoService.svc, and click OK.  You should now see it in the Request URL list.

Application Warm-Up add request

Application Warm-Up

And that’s it!  The service is now automatically started and “warmed up” by IIS.  To test, recycle the Application Pool and restart the web site.  Then, hit your Service Bus endpoint and confirm that you’re services are running.

Publicly Listed Services

Now, even if we restart the computer, the WCF service will reestablish the connection to the Service Bus because IIS 7.5, through the Application Warm-Up Extensions, will automatically refresh.

Now, to complete the test, let’s build a quick Console application to connect to the WCF service via the Service Bus.

  1. Create a new Console Application project called Client.
  2. Add a reference to the Microsoft.ServiceBus and System.ServiceModel.
  3. Add a link to the IEchoService.cs file in the EchoSample project.  Right-click the project, choose Add Existing, and change Add to Add as Link.

Add Existing Item - Add As Link 

  1. Update the Program.cs file with the following code.  Be sure and replace YOUR_NAMESPACE, YOUR_ISSUER_NAME, and YOUR_ISSUER_SECRET with your own values.
class Program
{
    static void Main(string[] args)
    {
        // Determine the system connectivity mode based on the command line
        // arguments: -http, -tcp or -auto  (defaults to auto)
        ServiceBusEnvironment.SystemConnectivity.Mode = GetConnectivityMode(args);
        string serviceNamespace = "YOUR_NAMESPACE";
        string issuerName = "YOUR_ISSUER_NAME";
        string issuerSecret = "YOUR_ISSUER_SECRET";
        // create the service URI based on the service namespace
        Uri serviceUri = ServiceBusEnvironment.CreateServiceUri("sb",
            serviceNamespace, "EchoServiceNetTcp");
        //Uri serviceUri = ServiceBusEnvironment.CreateServiceUri(
        //    "https", serviceNamespace, "EchoServiceHttp");
        // create the credentials object for the endpoint
        TransportClientEndpointBehavior sharedSecretServiceBusCredential =
            new TransportClientEndpointBehavior();
        sharedSecretServiceBusCredential.CredentialType =
            TransportClientCredentialType.SharedSecret;
        sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName =
            issuerName;
        sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret =
            issuerSecret;
        // create the channel factory loading the configuration
        //BasicHttpRelayBinding myBinding = new BasicHttpRelayBinding();
        NetTcpRelayBinding myBinding = new NetTcpRelayBinding();
        EndpointAddress myEndpoint = new EndpointAddress(serviceUri);
        ChannelFactory<IEchoService> channelFactory =
            new ChannelFactory<IEchoService>(myBinding, myEndpoint);
        // apply the Service Bus credentials
        channelFactory.Endpoint.Behaviors.Add(sharedSecretServiceBusCredential);
        // create and open the client channel
        IEchoService channel = channelFactory.CreateChannel();
        Console.WriteLine("Enter text to echo (or [Enter] to exit):");
        string input = Console.ReadLine();
        while (input != String.Empty)
        {
            try
            {
                Console.WriteLine("Server echoed: {0}",
                    channel.GetData(Int32.Parse(input)));
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.Message);
            }
            input = Console.ReadLine();
        }
        if (((IClientChannel)channel).State != CommunicationState.Faulted)
            ((IClientChannel)channel).Close();
        else
            ((IClientChannel)channel).Abort();
        channelFactory.Close();
    }
    static ConnectivityMode GetConnectivityMode(string[] args)
    {
        foreach (string arg in args)
        {
            if (arg.Equals("/auto", StringComparison.InvariantCultureIgnoreCase)
                 || arg.Equals("-auto", StringComparison.InvariantCultureIgnoreCase))
            {
                return ConnectivityMode.AutoDetect;
            }
            else if (arg.Equals("/tcp", StringComparison.InvariantCultureIgnoreCase)
                 || arg.Equals("-tcp", StringComparison.InvariantCultureIgnoreCase))
            {
                return ConnectivityMode.Tcp;
            }
            else if (arg.Equals("/http", StringComparison.InvariantCultureIgnoreCase)
                 || arg.Equals("-http", StringComparison.InvariantCultureIgnoreCase))
            {
                return ConnectivityMode.Http;
            }
        }
        return ConnectivityMode.AutoDetect;
    }


When you run the console application, it will connect to your WCF service through the Service Bus.  Run it to validate. You can also uncomment some of the code to use BasicHttpRelayBinding instead of NetTcpRelayBinding to try out a different configuration.

The ability to host a WCF service in IIS that exposes itself on the Service Bus is a significant milestone.  This opens up a number of fantastic opportunities and scenarios that otherwise would have been extremely difficult to accomplish.

New Role: Technical Evangelist for Azure AppFabric

I am excited to share that I’m taking the role of Technical Evangelist for the Windows Azure platform, focused on the Azure AppFabric.  I’m joining James Conard’s team that focuses on Windows Azure platform evangelism, working with David Aiken, Ryan Dunn, Zach Owens, and Vittorio Bertocci – truly an all-star team!  Oh, and I hope to spend a lot more time with Jack Greenfield, Clemens Vasters, Justin Smith, and everyone else on the AppFabric team!

So, what is the Windows Azure platform AppFabric (other than a mouthful)?

What is the Windows Azure platform AppFabric?

That’s one of the things I hope to de-mystify in my new role.  Expect to see me talking a lot about it in the future.

The best part about focusing on the Azure AppFabric is that it doesn’t restrict me to just one technology – because the Azure AppFabric is the glue that integrates and secures applications across the Internet, I’ll get to leverage the entire Windows Azure platform, various mobile platforms, web technologies, and almost everything else in our technology stack – not to mention interoperability with other platforms!

So, what does taking this role mean?

  • I’m moving the entire family to Redmond, WA. Incidentally, want to buy a house in Glen Ellyn, IL?
  • I hope to spend more time in Visual Studio than in Outlook.
  • I’m going to spend a lot more time writing blog posts and recording screen casts.  Lots of really neat things to share.
  • I’ll continue speaking at events like PDC, TechEd, and MIX, and hope to hit even more online and local events.
  • I want to work with all of you to find new and interesting ways to leverage the Azure AppFabric.

I am leaving an amazing group of people here in Central Region DPE.  I want to thank everyone on my team – both local and extended – for making my time as an Architect Evangelist enjoyable and fulfilling.

See you soon in Redmond!

Significant updates to the SQL Azure Migration Wizard

George Huey has done it again!  He has just published some significant updates to the SQL Azure Migration Wizard.

Previously, I’ve described the SQL Azure Migration Wizard as a tool that helps you migrate your SQL Server database into SQL Azure.  This is still true, but now, thanks to updates made by George Huey, you can also migrate from SQL Azure-to-SQL Server and SQL Azure-to-SQL Azure.  These are significant updates to the tool!

Please watch the following video for an updated explanation of the tool:

As I said, the updates made by George enable all the following scenarios for database migration …

  • SQL Server-to-SQL Azure
  • SQL Azure-to-SQL Server
  • SQL Azure-to-SQL Azure

These last two updates are significant!  Take a look at this thread on the SQL Azure Migration Wizard codeplex site – the user had a scenario where they wanted to migrate a 1 GB database in SQL Azure into a 10 GB database in SQL Azure.

Please take a look at the SQL Azure Migration Wizard up on Codeplex, where you can download the source code and/or binaries.

Leveraging WMI in an Azure Web Role

How to Leverage the RoleEntryPoint in an Azure Web Role

Windows Azure One of the advantages to the approach our teams building the Windows Azure Platform have taken is flexibility.  Recently, when I spoke at the Day of Cloud presentation, I recall Don Schwarz from Google making these two points (you can see video of his talk here):

  • You can’t spin up your own threads in Google App Engine.
  • You build your applications according to how Google thinks your apps should be built (the argument being that Google knows how to run highly available services at scale, which I think is a fair statement).

Now to be fair, there are good reasons for this – the Google App Engine has a number of very good use cases (Don Schwarz demonstrated one of them when showing the audience a multiplayer game running on Google App Engine).

Note: I’d like state for the record that I mean no criticism of other cloud vendors (i.e. Amazon, Google, and SalesForce).  I think each of them have a place in the market, and exhibit various strengths.  That said, I do believe that the Windows Azure Platform stands out as the only real platform that can bridge the chasm between cloud services and on-premises software. (Note to self: back this statement up in a future blog post.)

I would argue, however, that most enterprise developers require a little more flexibility when building out enterprise class applications.  The Windows Azure Platform provides this flexibility (I mean, come on – sometimes you just want to execute some native code!).

I decided to test how far I could take this flexibility in Windows Azure.

I am a big fan of Worker Roles in Windows Azure.  I really like the idea of having an asynchronous, “headless” service that’s working for me in the background.  I wanted to see if I could spin up an equivalent to a Worker Role in a Web Role, so that in addition to having my Web application running in a Web Role I could also get a service running in the background.

Why would I want to do this?  Well, here are a few of reasons:

  • Asynchronous logging service running in every Azure instance (whether a web or worker role); this service might take information from the event log and write it to an Azure table.
  • Clean-up operations (i.e. temporary scratch writes, etc.)
  • Opening and managing socket connections to the service bus (this is my favorite scenario).

The list could go on.  Hopefully you get the point.

So, how would you do this?  Again, given the flexibility of the platform, there are many ways you can do this.  Below you’ll find one simple way.

1. Create a new cloud services project, and add a web role.

2. Create a new class and inherit from Microsoft.ServiceHosting.ServiceRuntime.RoleEntryPoint.  You’ll have to override the Start and RoleStatus methods.

using Microsoft.ServiceHosting.ServiceRuntime;
using System.Threading;

namespace Web
{
    public class MyWebWorkerRole : RoleEntryPoint
    {
        public override void Start()
        {
            while (true)
            {
                RoleManager.WriteToLog("Information", "The worker role is running.");

                Thread.Sleep(5000);
            }
        }

        public override RoleStatus GetHealthStatus()
        {
            return RoleStatus.Healthy;
        }
    }
}

3. Create a Global.asax page.

4. Create a method where you initialize and start and initialize your class that inherits from RoleEntryPoint.

private void StartWorkerRole()
{
    MyWebWorkerRole myWebWorkerRole = new MyWebWorkerRole();
    myWebWorkerRole.Initialize();
    myWebWorkerRole.Start();
}

5. Create local threading variables that you will use to run your method.

public class Global : System.Web.HttpApplication
{
    System.Threading.ThreadStart ts;
    System.Threading.Thread t;

    ...

5. Update the Application_BeginRequest method to invoke your method on a new thread.  Be sure and check to see if the thread is already running, otherwise it will get started multiple times.

protected void Application_BeginRequest(object sender, EventArgs e)
{
    if (t == null)
    {
        ts = new System.Threading.ThreadStart(StartWorkerRole);
        t = new System.Threading.Thread(ts);
        t.Start();
    }
}

And that should do it.  Now you have a class that will run asynchronously in all your Web Role instances.  And since it inherits from the RoleEntryPoint, you can leverage this technique for both your Web and Worker Role instances.  I’d recommend placing this class in a separate class library and adding a reference to it from your various projects.

Note: It is highly probable that there will be some changes to the APIs and assemblies come PDC.  While these concepts will stay valid, the underlying code will probably change.  If this happens, I’ll be sure and provide an update.

I hope this helps!