The WSO2 API Manager has the capabilities to work with Failover endpoints as well as load balanced endpoints. In this blog, we are going to create an API with the Failover endpoint from within the API Manager. We will use the API Manager 3.2.0.
Setting up API Manager
I am not going to describe how to install the API Manager. What needs to be installed is of course Java. If you do not already have it, the API Manager 3.2.0 supports Java 8 and 11, both Oracle and OpenJDK.. Take a look at the documentation if you want or need more information. After setting Java_home you can download the zip file with the API Manager and unpack it. This will work on both windows as well as Linux / Mac OS. Please visit this blog on how to install WSO2 products.
Wiremock
To mock the APIs, for the failover I am using WireMock, a simple Java based application. I am running it locally and it deploys mock APIs on port 8080 by default. For your setup, you can have it running locally or on a server as well.
You can find instructions on how to run WireMock in this article by my colleague Dusan Dević. In these instructions it’s mentioned that a mock can be created using a mapping file. For this blog we need some mappings in WireMock. I am creating three mock API’s. api_6, api_7 and api_8.
Below is the api_6 mock-endpoint (api6.json) that responds too late for a regular (not configured) endpoint.
{
"request": {
"method": "GET",
"url": "/api_6"
},
"response": {
"status": 200,
"body": "30 seconds passed so here I am!",
"fixedDelayMilliseconds": 30000,
"headers": {
"Content-Type": "application/json" }
}
}
This is api_7 (api7.json) that responds without delay, API 8 is a carbon copy of this, however of course with a different url (api_8) and name (api8.json).
{
"request": {
"method": "GET",
"url": "/api_7"
},
"response": {
"status": 200,
"body": "Here I am API 7. no delay",
"fixedDelayMilliseconds": 0,
"headers": {
"Content-Type": "application/json" }
}
}
You can see the mocked endpoints responses using for instance SoapUI.
Creating a new API called Failover with API Manager
Let us start by creating a new API called Failover.
Open the API Publisher by going to https://localhost:9443/publisher. Login with the admin-account and select the design new rest API option from the menu in the API publisher.
Fill in the following details with regards to the API definition:
The details are:
Name | Failover |
Context | fail |
Version | 1.0 |
Endpoint | http://[your-hostname]:8080/api_6 |
Business plan(s) | Gold |
Press ‘create’ to create the API. This is the overview screen.
Design configurations in API Manager
In this blog we focus mainly on the technical setup of the failover endpoints. It is good to realize that the Devportal (formerly known as store) is a place where developers can find, try-out and subscribe to your APIs. Like any store that advertises something, it is important that you also spend time on the non technical issues like documentation (how to use the API), tags to improve findability and a nice image that makes the API stand out. This is done in the Design Configuration tab.
I have made a custom logo. If you want to change it as well, press on design configurations and upload a logo of your choice.
Upload the logo to the API and make the following changes to design configuration.
Name | failoverlogo |
Description | Failover API |
Publisher Access Control | All |
Designer Portal Visibility | Public |
Tags | Failover |
Press ‘Save’ to save the changes.
Go to resources and remove all the wildcards resources that were created by default, APART FROM GET /*. Normally you would never have wildcard resources as they are a security risk. An API definition should be as closed as possible. However, for sake of brevity, we will allow the wildcard resource.
Press ‘Save’ to save the changes.
On the overview screen click on the endpoints and you’ll see the following contents:
Click on ‘Not Configured’ on the Load Balance and Failover Configurations.
Select Failover as endpoint type and add 2 failover endpoints by copying the original endpoint (pointing to api_6) and use api_7 and api_8 as additional failover endpoints as shown in the below screenshot.
For the first endpoint (api_6) change the advanced configuration to the following. Add the error codes 101503, 101504, 101505, 101507 by selecting them in the dropdown.
Typically, you would do this for all endpoints, but since the api_6 is the only one responding late this will suffice. To speed it up I have set the Connection Timeout to 5000 ms.
Save to store the changes.
Publish the API in the lifecycle definition and go to the Devportal to see the API. Subscribe to the API, generate a token, copy it, and try out the API using Soap UI.
SoapUI
In SoapUI create a new REST project based on the URL https://localhost:8243/fail/1.0. The Authentication needs to be set to Oauth 2.0 and the generated Access Token copied to the Access Token field in Soap UI. You can however also configure it to generate the token in Soap UI. We will not go into details other than telling you that in that case click the Get Token button in the Authorization window and fill in the required details. The information can be found in the Devportal.
After some time, you will get a response. Due to the failover configuration in the API Manager, you should see the response of the second endpoint, api_7, in our list of endpoints.
On the console you can see what was happening.
[2021-04-26 12:36:04,889] INFO - EndpointContext Endpoint : failover--v1.0_APIproductionEndpoint_0 with address http://localhost:8080/api_6 has been marked for SUSPENSION, but no further retries remain. Thus it will be SUSPENDED.
[2021-04-26 12:36:04,893] WARN - EndpointContext Suspending endpoint : failover--v1.0_APIproductionEndpoint_0 with address http://localhost:8080/api_6 - current suspend duration is : 100ms - Next retry after : Mon Apr 26 12:36:04 CEST 2021
[2021-04-26 12:36:04,901] WARN - FailoverEndpoint Endpoint [failover--v1.0_APIproductionEndpoint] Detect a Failure in a child endpoint : Endpoint [failover--v1.0_APIproductionEndpoint_0]
[2021-04-26 12:36:04,919] WARN - TimeoutHandler Expiring message ID : urn:uuid:1609bac3-228b-4698-b78f-430e778c2fe2; dropping message after ENDPOINT_TIMEOUT of : 5 seconds for Endpoint [failover--v1.0_APIproductionEndpoint_1], URI : http://localhost:8080/api_6, Received through API : admin--failover:v1.0
[2021-04-26 12:36:09,039] WARN - SynapseCallbackReceiver Synapse received a response for the request with message Id : urn:uuid:1609bac3-228b-4698-b78f-430e778c2fe2 and correlation_id : null But a callback is not registered (anymore) to process this response