HPC Pack SOA Tutorial I – Write your first SOA service and client

This series of blog posts introduces the SOA programming model for Microsoft HPC Pack 2016. This is the first blog post of the series and provides guidance to write your first SOA service and client. See the accompanying code sample to follow the steps in this article.

Note: Most of the general considerations for SOA for HPC Pack 2016 also apply to earlier versions of HPC Pack.

What is a SOA service?

Service-oriented architecture (SOA) is an approach to building distributed, loosely coupled systems.

With SOA, distinct computational functions are packaged as software modules called services. Unlike traditional HPC applications, an HPC SOA service exposes its functionality through a well-defined service interface which allows any application or process on the network to access the functionality of the service. Developers can implement service functionality by using any programming language, and can write original services or package existing dynamic-link libraries (DLLs) and IT investments as services.

Why SOA services?

HPC applications are typically classified as "message intensive" or "embarrassingly parallel." Message-intensive applications comprise sequential tasks. Embarrassingly parallel applications can be easily divided into large numbers of parallel tasks, with no dependency or communication between them.

SOA services are designed to solve the embarrassingly parallel problem. Compared with traditional HPC computation models, SOA services provide the following advantages:

  • Easier programming model: The interface of the SOA service is just a remote method. It makes the client application able to easily access the service.

  • Easier message exchange: Traditional HPC jobs require dealing with input and output files. SOA services allow client applications to easily transfer data between the client application and service.

Check the technical overview of cluster-enabled SOA application development for detail.

Getting started

To write a SOA program to run on an HPC Pack 2016 cluster, you need .net 4.5 or later and Visual Studio 2017.

To test your service you need to set up an HPC Pack Cluster to run your service. You can download HPC Pack 2016 from here.

Now we can start writing the SOA application. Let's say we need a service running on the HPC cluster to do math calculations. Then we need a client program for end users, because they cannot directly access the cluster. The client program submits the calculation request to the service and returns the result to the end users. To simplify the code, let's just use a simple addition calculation as an example.

Here are the steps to write a SOA application:

  • Step 1: Implement the service

  • Step 2: Deploy the service

  • Step 3: Implement the client

  • Step 4: Test the service

Step 1: Implement the service

Following code can be found in the CalculatorService project in the sample code .

A SOA service is a Windows Communication Foundation (WCF) service running on the HPC cluster. The SOA service is ideal for writing interactive, embarrassingly parallel applications, especially for calculation of complex algorithms.

A SOA service does not require too much extra effort beyond your algorithm. It's just a standard WCF service. The first step is to define the service contract, like the following code:

[ServiceContract]
public interface ICalculator
{
    [OperationContract]
    double Add(double a, double b);
}

The only extra code is to add the attribute, which can be recognized by WCF, of the interface and its methods. With the service contract the client can understand how to invoke the method and what parameters are required.

The next step is to implement the algorithm of the service:

public class CalculatorService : ICalculator
{
     public double Add(double a, double b)
     {
        return a + b;
     }
}

Step 2: Deploy the service

We need to deploy the service we just created to the HPC cluster. Before we deploy the service, we need one more step which is creating the SOA service configuration file. Create an XML file like the following:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="microsoft.Hpc.Session.ServiceRegistration"
             type="Microsoft.Hpc.Scheduler.Session.Configuration.ServiceRegistration, Microsoft.Hpc.Scheduler.Session, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
            <section name="service" type="Microsoft.Hpc.Scheduler.Session.Configuration.ServiceConfiguration, Microsoft.Hpc.Scheduler.Session, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="Everywhere" allowExeDefinition="MachineToApplication"/>
        </sectionGroup>
    </configSections>
    <microsoft.Hpc.Session.ServiceRegistration>
        <!--Change assembly path below-->
        <service assembly="\\fileshare\SOAServices\CalculatorService.dll" />
    </microsoft.Hpc.Session.ServiceRegistration>
</configuration>

Note that the name of the XML file must be as same as the service name. In this case, name it CalculatorService.config.

The only configurable part of the above configuration file is the path of the assembly. Change the highlighted part to the path of the DLL file in your cluster. It is recommended to put the DLL file in a shared folder which can be accessed by all compute nodes. This will save you time manually copying the DLL to all the computer nodes.

Now copy the service configuration file to the configuration file folder, which is under %CCP_HOME%\ServiceRegistration on the head node of the cluster. After copying the file, go to HPC Cluster Manager and navigate to Configuration -> Services to confirm that the CalculatorService is there. Notice that the service name is as same as the file name of the configuration file.

Now the next step is to enable HPC Pack to locate the dll file. Copy the DLL file to the folder you specified in the configuration file. (Note: If you specified a local path, you need to copy the DLL file to the corresponding path on all the compute nodes.)

Now you have successfully deployed the service. To verify that the deployment is successful, you can use a diagnostic tool in HPC Cluster Manager console to test the service. Right click CalculatorService, and then select Run SOA Service Loading Diagnostic Test. You can check the diagnostic result. Click Diagnostics, select the test result, and you can see the test result and the detailed information.

2746.clip_image0049_05047787.

A successful diagnostic result looks like this:

1665.clip_image0068_743CCCD8

Step 3: Implement the client

Following code can be found in the Clientproject in the sample code.

Now we need a client program to submit the calculation request. The client needs to invoke the service we just created remotely, so we need to leverage WCF to generate the proxy class for us. Visual Studio can simplify the whole process by using its service references functionality.

The suggested project organization in Visual Studio is to create different projects for the service and client programs, as shown in the following figure:

1641.clip_image0077_7F19AE20

We need to generate the proxy class for the client program based on the CalculatorService. Make sure the service project has been successfully built then click Add Service Reference, click Discover, and you should see the service you just created. Select the service and click Advanced.

7737.clip_image0097_4717BA3D

Important: In the advanced Service Reference Settings dialog box, ensure that Always generate message contracts is selected.

1460.clip_image0117_3F3FA1CE

Now we can write the HPC client code:

  1. Prepare the session info, which includes the head node address and the service name. Let's assume the head node host name is head.contoso.com and we are using the CalculatorService.

    SessionStartInfo info = new SessionStartInfo("head.contoso.com", "CalculatorService");
    
  2. With the SessionStartInfo object we can create a session to connect to the head node.

    using (Session session = Session.CreateSession(info)) {……}
    
  3. To be able to send requests and receive responses, you need to create a BrokerClient object.

    using (Session session = Session.CreateSession(info))
    {
        using (BrokerClient<ICalculator>client = new BrokerClient<ICalculator>(session)) {……}
    }
    
  4. With the BrokerClient, you can send requests and receive responses.

    using (BrokerClient<ICalculator>client = new BrokerClient<ICalculator>(session))
    {
        //send request
        AddRequest request = newAddRequest(1, 2);
        client.SendRequest<AddRequest>(request);
        client.EndRequests();
    
        //get response
        foreach (BrokerResponse<AddResponse>response in client.GetResponses<AddResponse>())
      {
         double result = response.Result.AddResult;
         Console.WriteLine("Add 1 and 2, and we get {0}", result);
      }
    }
    

Step 4: Test the service

Now you can test your service using your client program.

Run the client in the Visual Studio. If everything is working fine, you should see output like the following:

7462.clip_image0156_7ACF8AC1

Open HPC Cluster Manager, navigate to Job Management, and you can see the corresponding job.

Congratulations! You have successfully created and run your first SOA service. In our next blog post, we will introduce way of writing a service to handle a batch of client requests.