API Management Integration with Service Fabric Backend
Published May 22 2020 07:41 AM 5,648 Views
Microsoft

The APIM instance will act as the gateway to the Service Fabric backend. The SF application used in this example can be found here: https://github.com/hakashya/APIM-with-Service-Fabric. You may clone the repository to replicate the results for your reference.

Certificate Handling:

The certificate used for creating the Service Fabric cluster is called the cluster certificate. In this example, this is a self-signed certificate. For the API Management instance to communicate with the service fabric backend, we need the cluster certificate to be uploaded to the API Management instance. The steps to do that is as follows:

  • Locate the certificate on your machine:
    CertScreenshot.png

     

  • Navigate to the Certificates blade on the Azure Portal for the APIM instance of interest:
    HarshaKashyap_1-1590156848548.png

     

  • Click on the “Add” button, marked as the 3rd step. Once this button is clicked, a wizard opens on the right, where the certificate can be uploaded. Select the right .pfx file that was located at the beginning of this section. Also, enter the password which protects the certificate. Once this is completed, click on the “Add” button on the bottom right corner marked as the 5th step.
  • Once the certificate is uploaded to the APIM instance, it can be used by the APIM instance for accessing the back end that is protected by the certificate.

Configuring the Backend Service for API Management Instance:

We will be adding a transformation policy for the API Management instance to redirect the calls towards the Service Fabric backend. To do this, the prerequisite is that a backend entity must be added to the API Management instance. As of now, it can only be done using REST APIs and PowerShell. Below is an example using REST API.

 

Details about the Service Fabric backend service used in this example:

The REST API reference for creating a backend entity is here: https://learn.microsoft.com/en-us/rest/api/apimanagement/current-ga/backend/create-or-update?tabs=HT... 

 

The API takes subscription ID, resource group name, API Management service name, and an identifier for the backend entity (which is equivalent to the name of the backend entity). Please note that the backend entity is just a representation of the Service Fabric application in API Management, but it is not the actual Service Fabric service itself.

 

The body of the PUT request, for this example, is:

 

 

 

 

{
	"properties": {
		"description": "Service Fabric Backend for APIM",
		"protocol": "http",
		"url": "fabric:/SFBackendForAPIM/WebAPI_Backend",
		"resourceId": "https://servicefabricbackend.eastus.cloudapp.azure.com:19080/",
		"tls": {
			"validateCertificateChain": "false"
		},
		"properties": {
			"serviceFabricCluster": {
				"managementEndpoints": [
					"https://servicefabricbackend.eastus.cloudapp.azure.com:19080"
				],
				"clientCertificatethumbprint": "76E97E3A746CB85AB83E431BDEB01C6DB168244B",
				"serverCertificateThumbprints": [
					"76E97E3A746CB85AB83E431BDEB01C6DB168244B"
				],
				"maxPartitionResolutionRetries ": 5
			}
		}
	}
}

 

 

 

 

  • The protocol specifies whether the backend is RESTful service (http) or SOAP service (soap).
  • The url specifies that the call should go to fabric:/<SFServiceName>/<SFApplication>. The fabric:/ is a call made to the naming service of the Service Fabric cluster. This url returns one partition with its listeners for the Application that was specified. We then make a call to this partition after resolution. In this example, the service name is SFBackendForAPIM, and the Application Name is WebAPI_Backend:
    HarshaKashyap_2-1590156848551.png

     

  • The resource ID is the same as the management endpoint.
  • The tls section elaborates the security features. In this example, since the certificate that is being used is self-signed, we are not validating the certificate chain. For a production cluster, it is recommended that validateCertificateChain is set to true, for security purposes.
  • The management endpoint belongs to the Service Fabric backend.
  • maxPartitionResolutionRetries property is used to inform the APIM service that it should attempt partition resolution exercise up to 5 times per partition (or instances, in case of stateless services).

The response for the above request is as follows:

 

 

 

 

{
	"id": "/subscriptions/cbxxxxxx-xxxx-xxxx-ac0f-99e4b64d2634/resourceGroups/SFCluster-RG/providers/Microsoft.ApiManagement/service/apimservicefabric/backends/sfbackend",
	"type": "Microsoft.ApiManagement/service/backends",
	"name": "sfbackend",
	"properties": {
		"title": null,
		"description": "Service Fabric Backend for APIM",
		"url": "fabric:/SFBackendForAPIM/WebAPI_Backend",
		"protocol": "http",
		"resourceId": "https://servicefabricbackend.eastus.cloudapp.azure.com:19080/",
		"properties": {
			"serviceFabricCluster": {
				"managementEndpoints": [
					"https://servicefabricbackend.eastus.cloudapp.azure.com:19080"
				],
				"clientCertificateThumbprint": "76E97E3A746CB85AB83E431BDEB01C6DB168244B",
				"serverCertificateThumbprints": [
					"76E97E3A746CB85AB83E431BDEB01C6DB168244B"
				],
				"maxPartitionResolutionRetries": 5
			}
		},
		"tls": {
			"validateCertificateChain": false
		}
	}
}

 

 

 

 

In case you do not know certain specifics about the Service Fabric cluster, you can always use the PowerShell cmdlet Get-AzServiceFabricCluster (https://docs.microsoft.com/en-us/powershell/module/az.servicefabric/Get-AzServiceFabricCluster?view=...) to gather information.

 

You may use any REST client to do this. The request with Postman would look something like the following:

HarshaKashyap_3-1590156848558.png

 

 

Configuring an API in APIM to access the backend:

We are all set to make use of the backend that we set up in the previous few sections. Now we shall create an API on the APIM instance, that could call the created backend service. The steps are as follows:

  • Navigate to the APIs blade on the API Management instance, and click on “Blank API” card, as shown below:
    HarshaKashyap_4-1590156848562.png

     

  • Fill in the details for the Blank API as follows:
    HarshaKashyap_5-1590156848563.png

     

  • Click on the "Add operation" button. Since this sample application is configured to receive simple GET requests, I am configuring a GET operation.
    HarshaKashyap_6-1590156848567.png

     

The GET URL would be the path to access our service. In this example, the controller in the application maps the route to /api/values, therefore, that route is given to the GET URL as the path. As the APIM instance and the SF Cluster are on the same VNet, they can communicate using private IP address. When a call is made to the naming service, it returns the private IPs for the listeners. The GET URL would then be appended to form the actual URL that is called. For example, if the naming service returns 10.0.0.5:20001 as the private IP of the instance serving our request, then the final URL which is called by the APIM is http://10.0.0.5:20001/api/values

 

APIM Policy Definition:

This the crucial step of action. The calls coming to the API management is redirected based on the policy we set. We will be using the set-backend policy (https://docs.microsoft.com/en-us/azure/api-management/api-management-transformation-policies#SetBack...). The steps are:

  • Click on the </> icon on the “Inbound Processing”, as shown in this screenshot:
    HarshaKashyap_7-1590156848569.png

     

  • The set-backend policy is placed in the inbound section, as shown here:
    HarshaKashyap_8-1590156848573.png

The policy statement is:

 

 

 

 

<set-backend-service backend-id="sfbackend" sf-resolve-condition="@((int)context.Response.StatusCode != 200 || context.LastError?.Reason == "BackendConnectionFailure" || context.LastError?.Reason == "Timeout")" sf-listener-name= "HttpServiceEndpoint" />

 

 

 

 

  • Once the policy is saved, the integration between the Service Fabric cluster and API Management is complete.

Understanding the policy:

  • When the request hits the API Management service, it must pass through all the levels of APIM policies.
  • When we use the set-backend policy in the inbound section, we are changing the backend service to the one mentioned in the policy rather than the actual backend that was configured while creating the API.
  • In this example, we did not create an actual backend during the API creation, but we set the backend for all the inbound requests using the set-backend policy. As shown in the previous section: Configuring the Backend Service for API Management Instance, the name of the backend was “sfbackend”. This is the same name that is given as a value to the APIM policy as well. It means that the APIM instance picks up the details from the created backend entity.
  • The sf-resolve-condition refers to the retry condition. We had set the number of retries to 5, when we created the backend. Therefore, it ensures that if the sf-resolve-condition is met, there is an attempt to retry the partition resolution. In this case, the resolve condition is met if the response code from the backend is not 200, or if there is a Backend Connection Failure, or a Timeout while receiving a response from the backend.
  • Sf-listener-name indicates that when the naming service returns a list of listeners for a machine on the SF cluster serving our request, the listener with the name HttpServiceEndpoint must be chosen to make the request. Essentially, the name of the listener mentioned in the policy is the name of the listener chosen for making the request.

 

Validating the Set Up:

For any process, validation is necessary and crucial. For testing out if the set-up works, we can navigate to the “Test” tab on the Azure Portal for the APIM, for that Operation under the API. Below is the elaboration of the process:

  • Navigate to the test tab, and click on the API Operation
  • Hit the send button at the bottom.
  • The response seen has been received by the APIM instance. The response on your test tab should look like the following:
    HarshaKashyap_9-1590156848577.png

     

Understanding the Trace:

The trace section of the API call gives detailed insight into the process that takes place from the moment you hit send, till the moment you see the response on your screen. This allows us to perform analysis, debug our API, troubleshoot any issues, with the help of the trace. The trace for this example is available here: https://raw.githubusercontent.com/hakashya/APIM-with-Service-Fabric/master/WebAPI_Backend/apimtrace-....

 

An interesting thing to note is that, although we have specified that the maxPartitionResolutionRetries values for the APIM backend entity as 5, the number of resolution calls are 18 in this trace. The explanation for the same is as follows:

  • The SF Cluster used for in this example has 3 nodes. Each retry involves trying to elicit a response from all the machines until one of them successfully responds where the retry condition fails. If the retry condition succeeds, then there shall be another attempt to retry.
  • The retry condition fails if the response status code received is 200. If it is anything else, there will be more attempts at retrying until the desirable response is received or if it exceeds the max retry count.
  • Since this sample application responds with status code 204 always, the APIM instance exceeds the max retry count and returns the last response it received (successful or unsuccessful).
  • The first time, it attempts to get status code of 200 from the machine with IP 10.0.0.4. But it receives 204. So, it attempts to elicit the response from 10.0.0.5, and 10.0.0.6 successfully. When all these machines respond with 204, the APIM instance must evaluate the retry logic.
  • Since the first attempt is not a retry, the second attempt is considered the first retry.
  • This means that it will retry all the machines in the cluster running the application in each retry attempt. Since I have 3 machines, and max retry count is 5, I shall have 3 x 5 = 15 retries.
  • This means that I shall have 3 first attempts and 15 retries, therefore, I will have a total of 18 attempts to get the response code of 204.
  • This number can be cut short if the total resolution timeout is reached. It is not unheard of to see lesser than 18 attempts.

 

Additional Points to Note:

  • For the SF application to return multiple endpoints, you will have to configure your <Application>.cs file and ServiceManifest file appropriately. For ensuring that one of the endpoint is HTTPS, you may follow the document: https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-tutorial-dotnet-app-enable-http....
  • Since the APIM acts as a gateway to the Service Fabric application in the backend, the APIM is put on the External VNet mode. You may choose to put the APIM on internal VNet, and expose the APIM endpoints using Application Gateway. The documentation for the same is: https://techcommunity.microsoft.com/t5/azure-paas-developer-blog/integrating-api-management-with-app....
  • APIM is used as a gateway/ingress point in front of stateless service. The following questions provide more clarity into the relation between APIM and SF:
    • How APIM forwarding in response to instances changes of stateless service, specifically, how soon can it react to instance change?
      As soon as one of the request fails with error triggering re-resolve condition. By default it’s a failure to connect to instance IP:Port but more conditions can be added through APIM policy.
    • How soon can a new instance added get traffic?
      APIM has sliding expiration cache of partition information with 10 minutes timeout which is invalidated by re-resolve. So, as long as all existing instances are up and healthy and requests targeting given partition come at least every 10 minutes, new nodes will not be added to the rotation. Cache is in memory and getting cleaned when APIM restarts but this is not predictable and cannot be triggered by the user.
    • How soon can forwarding to an old instance stop?
      It is the same situation as when a new instance is added. When the request to this old instance fails, it triggers the re-resolve condition, and stops the traffic flowing to the old instance.
    • Does it provide its own probe mechanism in addition to relying on SF naming?
      Today, APIM doesn’t have probes and is not subscribed for address change notifications.

Appendix A:

 

 

 

$cert = New-SelfSignedCertificate -DnsName servicefabricbackend.eastus.cloudapp.azure.com -CertStoreLocation "cert:\LocalMachine\My" -KeyLength 2048 -KeySpec "KeyExchange"

$password = ConvertTo-SecureString -String "qwerty" -Force -AsPlainText

Export-PfxCertificate -Cert $cert -FilePath ".\apimsfcert.pfx" -Password $password

 


For more reference and ARM template deployments refer https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-tutorial-deploy-api-management

 

Co-Authors
Version history
Last update:
‎Jan 11 2023 01:27 AM
Updated by: