Deploy API Management with Service Fabric

This tutorial is part four of a series. Deploying Azure API Management with Service Fabric is an advanced scenario. API Management is useful when you need to publish APIs with a rich set of routing rules for your back-end Service Fabric services. Cloud applications typically need a front-end gateway to provide a single point of ingress for users, devices, or other applications. In Service Fabric, a gateway can be any stateless service designed for traffic ingress such as an ASP.NET Core application, Event Hubs, IoT Hub, or Azure API Management.

This tutorial shows you how to set up Azure API Management with Service Fabric to route traffic to a back-end service in Service Fabric. When you're finished, you have deployed API Management to a VNET, configured an API operation to send traffic to back-end stateless services. To learn more about Azure API Management scenarios with Service Fabric, see the overview article.

In this tutorial, you learn how to:

  • Deploy API Management
  • Configure API Management
  • Create an API operation
  • Configure a backend policy
  • Add the API to a product

In this tutorial series you learn how to:

Prerequisites

Before you begin this tutorial:

Network topology

Now that you have a secure Windows cluster or Linux cluster on Azure, deploy API Management to the virtual network (VNET) in the subnet and NSG designated for API Management. For this tutorial, the API Management Resource Manager template is pre-configured to use the names of the VNET, subnet, and NSG that you set up in the previous Windows cluster tutorial or Linux cluster tutorial. This tutorial deploys the following topology to Azure in which API Management and Service Fabric are in subnets of the same Virtual Network:

Picture caption

Sign in to Azure and select your subscription

Sign in to your Azure account select your subscription before you execute Azure commands.

Login-AzureRmAccount
Get-AzureRmSubscription
Set-AzureRmContext -SubscriptionId <guid>
az login
az account set --subscription <guid>

Deploy a Service Fabric back-end service

Before configuring API Management to route traffic to a Service Fabric back-end service, first you need a running service to accept requests. If you previously created a Windows cluster, deploy a .NET Service Fabric service. If you previously created a Linux cluster, deploy a Java Service Fabric service.

Deploy a .NET Service Fabric service

For this tutorial, create a basic stateless ASP.NET Core Reliable Service using the default Web API project template. This creates an HTTP endpoint for your service, which you expose through Azure API Management.

Start Visual Studio as Administrator and create an ASP.NET Core service:

  1. In Visual Studio, select File -> New Project.
  2. Select the Service Fabric Application template under Cloud and name it "ApiApplication".
  3. Select the ASP.NET Core service template and name the project "WebApiService".
  4. Select the Web API ASP.NET Core 1.1 project template.
  5. Once the project is created, open PackageRoot\ServiceManifest.xml and remove the Port attribute from the endpoint resource configuration:

    <Resources>
      <Endpoints>
        <Endpoint Protocol="http" Name="ServiceEndpoint" Type="Input" />
      </Endpoints>
    </Resources>
    

    Removing the port allows Service Fabric to specify a port dynamically from the application port range, opened through the Network Security Group in the cluster Resource Manager template, allowing traffic to flow to it from API Management.

  6. Press F5 in Visual Studio to verify the web API is available locally.

    Open Service Fabric Explorer and drill down to a specific instance of the ASP.NET Core service to see the base address the service is listening on. Add /api/values to the base address and open it in a browser, which invokes the Get method on the ValuesController in the Web API template. It returns the default response that is provided by the template, a JSON array that contains two strings:

    ["value1", "value2"]`
    

    This is the endpoint that you expose through API Management in Azure.

  7. Finally, deploy the application to your cluster in Azure. In Visual Studio, right-click the Application project and select Publish. Provide your cluster endpoint (for example, mycluster.southcentralus.cloudapp.azure.com:19000) to deploy the application to your Service Fabric cluster in Azure.

An ASP.NET Core stateless service named fabric:/ApiApplication/WebApiService should now be running in your Service Fabric cluster in Azure.

Create a Java Service Fabric service

For this tutorial deploy a basic web server, which echoes messages back to the user. The echo server sample application contains an HTTP endpoint for your service, which you expose through Azure API Management.

  1. Clone the Java getting started samples.

    git clone https://github.com/Azure-Samples/service-fabric-java-getting-started.git
    cd service-fabric-java-getting-started
    
  2. Edit Services/EchoServer/EchoServer1.0/EchoServerApplication/EchoServerPkg/ServiceManifest.xml. Update the endpoint so the service listens on port 8081.

    <Endpoint Name="WebEndpoint" Protocol="http" Port="8081" />
    
  3. Save ServiceManifest.xml, then build the EchoServer1.0 application.

    cd Services/EchoServer/EchoServer1.0/
    gradle
    
  4. Deploy the application to the cluster.

    cd Scripts
    sfctl cluster select --endpoint http://mycluster.southcentralus.cloudapp.azure.com:19080
    ./install.sh
    

    A Java stateless service named fabric:/EchoServerApplication/EchoServerService should now be running in your Service Fabric cluster in Azure.

  5. Open a browser and type in http://mycluster.southcentralus.cloudapp.azure.com:8081/getMessage, you should see "[version 1.0]Hello World!!!" displayed.

Download and understand the Resource Manager template

Download and save the following Resource Manager template and parameters file:

The following sections describe the resources being defined by the apim.json template. For more information, follow the links to the template reference documentation within each section. The configurable parameters defined in the apim.parameters.json parameters file are set later in this article.

Microsoft.ApiManagement/service

Microsoft.ApiManagement/service describes the API Management service instance: name, SKU or tier, resource group location, publisher information, and virtual network.

Microsoft.ApiManagement/service/certificates

Microsoft.ApiManagement/service/certificates configures API Management security. API Management must authenticate with your Service Fabric cluster for service discovery using a client certificate that has access to your cluster. This tutorial uses the same certificate specified previously when creating the Windows cluster or Linux cluster, which by default can be used to access your cluster.

This tutorial uses the same certificate for client authentication and cluster node-to-node security. You may use a separate client certificate if you have one configured to access your Service Fabric cluster. Provide the name, password, and data (base-64 encoded string) of the private key file (.pfx) of the cluster certificate that you specified when creating your Service Fabric cluster.

Microsoft.ApiManagement/service/backends

Microsoft.ApiManagement/service/backends describes the backend service that traffic is forwarded to.

For Service Fabric backends, the Service Fabric cluster is the backend instead of a specific Service Fabric service. This allows a single policy to route to more than one service in the cluster. The url field here is a fully qualified service name of a service in your cluster that all requests are routed to by default if no service name is specified in a backend policy. You may use a fake service name, such as "fabric:/fake/service" if you do not intend to have a fallback service. resourceId specifies the cluster management endpoint. clientCertificateThumbprint and serverCertificateThumbprints identify certificates used to authenticate with the cluster.

Microsoft.ApiManagement/service/products

Microsoft.ApiManagement/service/products creates a product. In Azure API Management, a product contains one or more APIs as well as a usage quota and the terms of use. Once a product is published, developers can subscribe to the product and begin to use the product's APIs.

Enter a descriptive displayName and description for the product. For this tutorial, a subscription is required but subscription approval by an admin is not. This product state is "published" and is visible to subscribers.

Microsoft.ApiManagement/service/apis

Microsoft.ApiManagement/service/apis creates an API. An API in API Management represents a set of operations that can be invoked by client applications. Once the operations are added, the API is added to a product and can be published. Once an API is published, it can be subscribed to and used by developers.

  • displayName can be any name for your API. For this tutorial, use "Service Fabric App".
  • name provides a unique and descriptive name for the API, such as "service-fabric-app". It is displayed in the developer and publisher portals.
  • serviceUrl references the HTTP service implementing the API. API management forwards requests to this address. For Service Fabric backends, this URL value is not used. You can put any value here. For this tutorial, for example "http://servicefabric".
  • path is appended to the base URL for the API management service. The base URL is common for all APIs hosted by an API Management service instance. API Management distinguishes APIs by their suffix and therefore the suffix must be unique for every API for a given publisher.
  • protocols determine which protocols can be used to access the API. For this tutorial, list http and https.
  • path is a suffix for the API. For this tutorial, use "myapp".

Microsoft.ApiManagement/service/apis/operations

Microsoft.ApiManagement/service/apis/operations Before an API in API Management can be used, operations must be added to the API. External clients use an operation to communicate with the ASP.NET Core stateless service running in the Service Fabric cluster.

To add a front-end API operation, fill out the values:

  • displayName and description describe the operation. For this tutorial, use "Values".
  • method specifies the HTTP verb. For this tutorial, specify GET.
  • urlTemplate is appended to the base URL of the API and identifies a single HTTP operation. For this tutorial, use /api/values if you added the .NET backend service or getMessage if you added the Java backend service. By default, the URL path specified here is the URL path sent to the backend Service Fabric service. If you use the same URL path here that your service uses, such as "/api/values", then the operation works without further modification. You may also specify a URL path here that is different from the URL path used by your backend Service Fabric service, in which case you also need to specify a path rewrite in your operation policy later.

Microsoft.ApiManagement/service/apis/policies

Microsoft.ApiManagement/service/apis/policies creates a backend policy, which ties everything together. This is where you configure the backend Service Fabric service to which requests are routed. You can apply this policy to any API operation. For more information, see Policies overview.

The backend configuration for Service Fabric provides the following request routing controls:

  • Service instance selection by specifying a Service Fabric service instance name, either hardcoded (for example, "fabric:/myapp/myservice") or generated from the HTTP request (for example, "fabric:/myapp/users/" + context.Request.MatchedParameters["name"]).
  • Partition resolution by generating a partition key using any Service Fabric partitioning scheme.
  • Replica selection for stateful services.
  • Resolution retry conditions that allow you to specify the conditions for re-resolving a service location and resending a request.

policyContent is the Json escaped XML contents of the policy. For this tutorial, create a backend policy to route requests directly to the .NET or Java stateless service deployed earlier. Add a set-backend-service policy under inbound policies. Replace "service-name" with fabric:/ApiApplication/WebApiService if you previously deployed the .NET backend service, or fabric:/EchoServerApplication/EchoServerService if you deployed the Java service.

<policies>
  <inbound>
    <base/>
    <set-backend-service 
        backend-id="servicefabric"
        sf-service-instance-name="service-name"
        sf-resolve-condition="@((int)context.Response.StatusCode != 200)" />
  </inbound>
  <backend>
    <base/>
  </backend>
  <outbound>
    <base/>
  </outbound>
</policies>

For a full set of Service Fabric back-end policy attributes, refer to the API Management back-end documentation

Set parameters and deploy API Management

Fill in the following empty parameters in the apim.parameters.json for your deployment.

Parameter Value
apimInstanceName sf-apim
apimPublisherEmail myemail@contosos.com
apimSku Developer
serviceFabricCertificateName sfclustertutorialgroup320171031144217
certificatePassword q6D7nN%6ck@6
serviceFabricCertificateThumbprint C4C1E541AD512B8065280292A8BA6079C3F26F10
serviceFabricCertificate <base-64 encoded string>
url_path /api/values
clusterHttpManagementEndpoint https://mysfcluster.southcentralus.cloudapp.azure.com:19080
inbound_policy <XML string>

certificatePassword and serviceFabricCertificateThumbprint must match the cluster certificate used to set up the cluster.

serviceFabricCertificate is the certificate as a base-64 encoded string, which can be generated using the following script:

$bytes = [System.IO.File]::ReadAllBytes("C:\mycertificates\sfclustertutorialgroup220171109113527.pfx");
$b64 = [System.Convert]::ToBase64String($bytes);
[System.Io.File]::WriteAllText("C:\mycertificates\sfclustertutorialgroup220171109113527.txt", $b64);

In inbound_policy, replace "service-name" with fabric:/ApiApplication/WebApiService if you previously deployed the .NET backend service, or fabric:/EchoServerApplication/EchoServerService if you deployed the Java service.

<policies>
  <inbound>
    <base/>
    <set-backend-service 
        backend-id="servicefabric"
        sf-service-instance-name="service-name"
        sf-resolve-condition="@((int)context.Response.StatusCode != 200)" />
  </inbound>
  <backend>
    <base/>
  </backend>
  <outbound>
    <base/>
  </outbound>
</policies>

Use the following script to deploy the Resource Manager template and parameter files for API Management:

$ResourceGroupName = "sfclustertutorialgroup"
New-AzureRmResourceGroupDeployment -ResourceGroupName $ResourceGroupName -TemplateFile .\apim.json -TemplateParameterFile .\apim.parameters.json -Verbose
ResourceGroupName="sfclustertutorialgroup"
az group deployment create --name ApiMgmtDeployment --resource-group $ResourceGroupName --template-file apim.json --parameters @apim.parameters.json 

Test it

You can now try sending a request to your back-end service in Service Fabric through API Management directly from the Azure portal.

  1. In the API Management service, select API.
  2. In the Service Fabric App API you created in the previous steps, select the Test tab and then the Values operation.
  3. Click the Send button to send a test request to the backend service. You should see an HTTP response similar to:

    HTTP/1.1 200 OK
    
    Transfer-Encoding: chunked
    
    Content-Type: application/json; charset=utf-8
    
    Vary: Origin
    
    Access-Control-Allow-Origin: https://apimanagement.hosting.portal.azure.net
    
    Access-Control-Allow-Credentials: true
    
    Access-Control-Expose-Headers: Transfer-Encoding,Date,Server,Vary,Ocp-Apim-Trace-Location
    
    Ocp-Apim-Trace-Location: https://apimgmtstuvyx3wa3oqhdbwy.blob.core.windows.net/apiinspectorcontainer/RaVVuJBQ9yxtdyH55BAsjQ2-1?sv=2015-07-08&sr=b&sig=Ab6dPyLpTGAU6TdmlEVu32DMfdCXTiKAASUlwSq3jcY%3D&se=2017-09-15T05%3A49%3A53Z&sp=r&traceId=ed9f1f4332e34883a774c34aa899b832
    
    Date: Thu, 14 Sep 2017 05:49:56 GMT
    
    
    
    
[
"value1",
"value2"
]
```

Clean up resources

A cluster is made up of other Azure resources in addition to the cluster resource itself. The simplest way to delete the cluster and all the resources it consumes is to delete the resource group.

Log in to Azure and select the subscription ID with which you want to remove the cluster. You can find your subscription ID by logging in to the Azure portal. Delete the resource group and all the cluster resources using the Remove-AzureRMResourceGroup cmdlet.

$ResourceGroupName = "sfclustertutorialgroup"
Remove-AzureRmResourceGroup -Name $ResourceGroupName -Force
ResourceGroupName="sfclustertutorialgroup"
az group delete --name $ResourceGroupName

Next steps

In this tutorial, you learned how to:

  • Deploy API Management
  • Configure API Management
  • Create an API operation
  • Configure a backend policy
  • Add the API to a product