Section 2: Communicating with the Worker Role from a SharePoint Event Handler.

Overview

SharePoint event handlers to detect changes in list, libraries, and sites. These event handlers can call out to Azure Worker roles to perform long-running or resource-intensive operations. In this lab you will build a WCF Web Role to act as a front-end to the Worker Role and then call the Web Role from an event handler.

Objectives

In this lab, you will:

  • Learn to create a WCF Web Role that acts as a front-end for a Worker Role.
  • Learn to integrate a Worker Role with SharePoint event handlers.

System Requirements

You must have the following items to complete this lab:

Setup

This lab uses a Windows Live account to send flight status information via e-mail. If you do not have a Windows Live account, then proceed to https://signup.live.com.

This lab uses the Bing API to retrieve flight status information. In order to retrieve the flight information, you will need to have a developer application ID. If you do not have a developer application ID, proceed to https://www.bing.com/developers/createapp.aspx and sign up.

The Windows Azure SDK (included in Windows Azure Tools for Visual Studio) installs a simulation environment on your development machine for testing Azure applications locally before deploying them to the cloud. The simulation environment consists of the development fabric to host web and worker roles, and the development storage which simulates cloud blob, table and queue storage locally.

Development storage uses SQL Server as its underlying storage mechanism, and by default the SDK will attempt to configure it to use SQL Server Express. If you do not have SQL Server Express installed before installing the SDK, or you wish to simply use an existing SQL Server instance to host the development storage database, you must run the dsinit command to select the SQL Server instance where the database will be created.

Please see instructions below for how to run dsinit.

Using dsinit to Configure Development Storage

  1. Open a command prompt.
  2. Edit the following command line as appropriate for your environment, where [AzureSDKInstallDrive] is the drive where you installed the Azure SDK (or Windows Azure Tools for Visual Studio), and [YourSqlInstance] is the SqlServer where you want to create the development storage database.[AzureSDKInstallDrive]\ Program Files\Windows Azure SDK\v1.3\bin\devstore\dsinit.exe /sqlinstance:[YourSqlInstance]Example Command Line:“C:\Program Files\Windows Azure SDK\v1.3\bin\devstore\dsinit.exe” /sqlinstance:.
  3. Note that the sample command line above uses the value “.” for the sqlinstance argument, which specifies that the local default SQL instance will be used for development storage.

Exercises

This Hands-On Lab is comprised of the following exercises:

  1. Creating a WCF Web Role
  2. Publishing the Worker Role
  3. Calling the solution from an event handler

Estimated Time to complete this lab: 60 minutes

Exercise 1: Creating a WCF Web Role

In this exercise, you will create a WCF Web Role to act as a front-end to the Worker Role.

Task 1 – Creating The New WCF Web Role

In this task, you will add the new WCF Web Role to the existing application.

  1. In the FlightInfoWorkerProject, right click the Roles folder and select Add>>New Web Role Project.
  2. In the Add New Role Project dialog, select WCF Service Web Role.
  3. Name the new WCF Web Role FlightInfoWcfRole and click Add.
  4. Under the FlightInfoWorkerProject>>Roles folder, double-click FlightInfoWcfRole.
  5. Click the Settings tab.
  6. Click Add Setting.
  7. Name the setting DataConnectionString.
  8. Set the Type to Connection String.
  9. Click the ellipsis under Value.
  10. In the Storage Account Connection String dialog, select Use the Windows Azure Storage Emulator and click OK.

Task 2 – Initializing the Storage Connection

In this task, you initialize the storage connection to gain access to queue storage.

  1. In the Solution Explorer, right click the FlightInfoWcfRole project and select Add>>New Item.
  2. In the Add New Item dialog, select Global Application Class and click Add.
  3. Open Global.asax.cs for editing.
  4. Add the following references at the top of the file

    C#

    using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.Diagnostics; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.StorageClient;

  5. Add the following code to the Application_Start method.

    C#

    CloudStorageAccount.SetConfigurationSettingPublisher( (configName, configSetting) => { var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName); configSetting(connectionString); });

Task 3 – Implementing The WCF Web Role

In this task, you will implement the WCF Web Role. The WCF Web Role will drop a flight request into the queue for the Worker Role to process.

  1. Open IService1.cs for editing.
  2. Replace code with the following to define the interface.

    C#

    [OperationContract] void RequestFlightInfo( string FlightNumber, string Market, string ReturnAddress);

  3. Open Service1.cs for editing.
  4. Delete the code contained within the class definition.
  5. Add the following references at the top of the code file.

    C#

    using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.Diagnostics; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.StorageClient; using System.Xml.Linq;

  6. Add the following code to the RequestFlightInfo method.

    C#

    CloudStorageAccount sa = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); CloudQueueClient qc = sa.CreateCloudQueueClient(); CloudQueue q = qc.GetQueueReference("flightrequests"); q.CreateIfNotExist(); XDocument data = new XDocument( new XElement("Message", new XElement("Flight", FlightNumber), new XElement("Market", Market), new XElement("Email", ReturnAddress))); CloudQueueMessage m = new CloudQueueMessage(data.ToString(SaveOptions.DisableFormatting)); q.AddMessage(m);

Task 4 – Building and Testing

In this task, you will test the solution locally.

  1. Right click the FlightInfoWorkerProject and select Build Solution.
  2. Press F5 to start debugging.
  3. Verify that you can see the service definition.

    Figure 4

    Service Definition

Exercise 2: Publishing the Worker Role

Task 1 – Editing the Web.config File

In this task, you will edit the web.config file to support deployment to Azure.

  1. In the FlightInfoWcfRole project, open web.config for editing
  2. Modify the file to appear as follows.

    XML

    <?xml version="1.0"?> <configuration> <system.diagnostics> <trace> <listeners> <add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics"> </add> </listeners> </trace> </system.diagnostics> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <services> <service name="FlightInfoWcfRole.Service1" behaviorConfiguration="FlightInfoWcfRole.Service1 Behavior"> <endpoint address="" binding="basicHttpBinding" contract="FlightInfoWcfRole.IService1"> <identity> <dns value="localhost"/> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="FlightInfoWcfRole.Service1 Behavior"> <serviceMetadata httpGetEnabled="true"/> <useRequestHeadersForMetadataAddress> <defaultPorts> <add scheme="http" port="81"/> <add scheme="https" port="444"/> </defaultPorts> </useRequestHeadersForMetadataAddress> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration>

Task 2 – Publishing The Worker Role To Azure

In this task, you will publish the Worker Role to your Azure account.

  1. In Visual Studio, set the deployment configuration for the solution to Release.
  2. In the FlightInfoWorkerProject>Roles folder, double-click the FlightInfoWorkerRole.
  3. Click Settings.
  4. Click the ellipsis in the Value field for the DataConnectionString setting.
  5. In the Storage Account Connection String dialog, select Enter Storage Account Credentials.
  6. Enter your Account Name and Account Key.
  7. Select Use Default HTTP Endpoints and click OK.
  8. Click the ellipsis in the Value field for the Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString setting.
  9. In the Storage Account Connection String dialog, select Enter Storage Account Credentials.
  10. Enter your Account Name and Account Key.
  11. Select Use Default HTTPS Endpoints and click OK.
  12. Perform the same updates to the settings for the FlightInfoWebRole and FlightInfoWcfRole projects.
  13. In the Solution Explorer, right click the FlightInfoWorkerProject solution and select Clean Solution from the context menu.
  14. In the Solution Explorer, right click the FlightInfoWorkerProject solution and select Build Solution from the context menu.
  15. In the Solution Explorer, right click the FlightInfoWorkerProject and select Publish from the context menu.
  16. In the Deploy Windows Azure Project dialog, click Create Service Package Only and click OK.

    Figure 5

    Create Service Package

  17. Open Internet Explorer, and go to https://windows.azure.com. Login with your Azure credentials. If you do not have a Windows Azure Account, sign-up for a new one.
  18. In the Azure Portal, click New Hosted Service.

    Figure 6

    New Hosted Service

  19. In the Create a New Hosted Service dialog type Flight Info Queue in the Enter a Name for Your Service field.
  20. In the Enter a URL Prefix for Your Service field, enter a unique prefix for the service and make note of it for later use.
  21. In the Choose a Region or Affinity Group list, select a region for hosting the service.
  22. In the Deployment Options, select Deploy to Stage Environment.
  23. In the Deployment Name field, type Flight Info Queue.
  24. In the Package Location field, click Browse Locally.
  25. Browse to the FlightInfoWorkerProject.cspkg file and click Open.
  26. In the Configuration File field, click Browse Locally.
  27. Browse to the ServiceConfiguration.csfg file and click Open.
  28. In the Create a New Hosted Service dialog, click OK.
  29. When you receive a warning that the role has only one instance, click Yes to continue.

    Figure 7

    Warning Dialog

  30. Wait for Azure to complete the creation of the new Hosted Service, which will be indicated by a Ready status.
  31. After the deployment is complete, select Flight Info Queue service in the Azure Portal and click the Swap VIP button.

    Figure 8

    Swap VIP

  32. In the Swap VIPs dialog, click OK to move the Staging bits to Production.
  33. After the bits are moved into Production, locate the DNS Name in the Properties pane. Make note of the address exposed for communicating with the WCF Web Role. You will use this endpoint information later when calling from SharePoint.

Exercise 3: Create a SharePoint Event Handler

In this exercise, you will create a custom SharePoint list that will act as a local work queue for flight requests. When a new request is added, an event handler will fire that will call the WCF Web Role with the request.

Task 1 – Creating The SharePoint Project

In this task, you will create new SharePoint project.

  1. Start Visual Studio 2010.
  2. From the main menu, select File>>New>>Project.
  3. In the New Project dialog, select SharePoint>>2010>>Empty SharePoint Project.
  4. Name the new project FlightInfoEventHandler.
  5. Click OK.
  6. In the SharePoint Customization Wizard dialog, specify a Site Collection where the solution will be deployed.
  7. Select Deploy as Farm Solution and click Finish.
  8. In the Solution Explorer, right click the Features node and select Add Feature from the context menu.
  9. Change the Scope of the new feature to Site.
  10. In the Solution Explorer, right click the References node and select Add Service Reference from the context menu.
  11. In the Add Service Reference dialog, enter the address of the WCF Web Role you deployed earlier, which is the DNS Name concatenated with Service1.svc and located on port 8080.
  12. Type FlightInfoService in the Namespace field and click OK.

    Figure 9

    Add Service Reference

Task 2 – Creating a Content Type

In this task, you will create a content type that will be the basis for a new list definition.

  1. In the Solution Explorer, right-click the FlightInfoEventHandler project and select Add>>New Item from the context menu.
  2. In the Add New Item dialog, select Content Type.
  3. Name the new item FlightRequest and click Add.
  4. On the Choose Content Type Settings screen, choose to base the new content type on the Item content type and click Finish.
  5. In the Solution Explorer, open Elements.xml for editing.
  6. Modify the file to appear as follows.

    C#

    <?xml version="1.0" encoding="utf-8"?> <Elements xmlns="https://schemas.microsoft.com/sharepoint/"> <Field ID="{06611607-61BA-4933-80C7-71CFE3241B02}" Name="FlightNumber" DisplayName="Flight Number" Type="Text" Group="Azure Columns"/> <Field ID="{734ABB99-1FFB-4948-93FE-9CFBCE13D276}" Name="FlightMarket" DisplayName="Flight Market" Type="Text" Group="Azure Columns"/> <Field ID="{54E358F7-F27F-4298-AAD7-1612925EA584}" Name="ReturnAddress" DisplayName="Return Address" Type="Text" Group="Azure Columns"/> <!-- Parent ContentType: Item (0x01) --> <ContentType ID="0x01007484facc74ca4319b4deb5b5f9ef2352" Name="FlightInfoEventHandler - FlightRequest" Group="Custom Content Types" Description="My Content Type" Inherits="TRUE" Version="0"> <FieldRefs> <FieldRef ID="{06611607-61BA-4933-80C7-71CFE3241B02}" Name="FlightNumber" DisplayName="Flight Number"/> <FieldRef ID="{734ABB99-1FFB-4948-93FE-9CFBCE13D276}" Name="FlightMarket" DisplayName="Flight Market"/> <FieldRef ID="{54E358F7-F27F-4298-AAD7-1612925EA584}" Name="ReturnAddress" DisplayName="Return Address"/> </FieldRefs> </ContentType> </Elements>

Task 3 – Creating a List Definition

In this task, you will create a list definition based on the content type you created earlier.

  1. In the Solution Explorer, right-click the FlightInfoEventHandler project and select Add>>New Item from the context menu.
  2. .In the Add New Item dialog, select List Definition from a Content Type.
  3. Name the list definition FlightsRequestsListDef and click Add.
  4. In the Choose List Definition Settings dialog, change the Display Name to Flight Requests and click Finish.

Task 4 – Creating an Event Handler

In this task, you will create an event handler for the list.

  1. In the Solution Explorer, right-click the FlightInfoEventHandler project and select Add>>New Item from the context menu.
  2. In the Add New Item dialog, select Event Receiver and click Add.
  3. In the Choose Event Receiver Settings dialog, check An Item was added and click Finish.
  4. Open EventReceiver1.cs for editing.
  5. Place the following code in the ItemAdded method.

    C#

    string flightNumber = properties.ListItem["FlightNumber"].ToString(); string flightMarket = properties.ListItem["FlightMarket"].ToString(); string returnAddress = properties.ListItem["ReturnAddress"].ToString(); FlightInfoService.Service1Client client = new FlightInfoService.Service1Client(); client.RequestFlightInfo(flightNumber, flightMarket, returnAddress); properties.ListItem["Title"] += " (Sent)"; properties.ListItem.Update();

Task 5 – Deploying and Testing the Event Handler

In this task, you will deploy the SharePoint feature and test the communication with the WCF Web Role.

  1. Open the web.config file associated with the Site Collection where the feature will be deployed in Visual Studio for editing.
  2. Open the app.config associate with the FlightInfoEventHandler project and copy the contents of the <system.serviceModel> element into the <system.serviceModel> element in the SharePoint web.config file.
  3. Save the SharePoint web.config file.
  4. In the Solution Explorer, right-click the FlightInfoEventHandler project and select Build from the context menu.
  5. In the Solution Explorer, right-click the FlightInfoEventHandler project and select Deploy from the context menu.
  6. In the Internet Explorer, navigate to the Site Collection where the solution was deployed.
  7. Click on the list entitled FlightInfoEventHandler - ListInstance1.
  8. Click Add New Item and fill in a flight data request.

    Figure 10

    A Flight Status request from SharePoint

  9. Click Save.
  10. Verify that you received an e-mail with flight status information.

Summary

Event handlers are useful artifacts for receiving notification when things occur inside SharePoint. These event handlers can call out to other processes such as WCF Web Roles to perform functions. In this lab, you created a fully-featured solution using SharePoint event handlers and Azure Roles.