Wednesday, 11 January 2017

Introduction 

In this blog, I will demonstrate how to implement in an hybrid architecture, a mule integration application that exposes micro-services API via Mule API Gateway within a mule on premise server and apply all the management tasks using the Anypoint Platform that is on the CloudHub.

I will also demonstrate how to apply a simple policy on the deployed Users API via a Proxy that is wired to the backed API services. The advantage of using this proxy is to add another layer to enforce the API protection against malicious attacks. 

API Requirement 

For the sake of this blog demonstration, I will use a sample API with two endpoints described as follow:
Endpoint that retrieves a collection of users.
Endpoint that retrieves a user by a provided id.

API Design

Mulesoft has a great tool called API Designer in Anypoint Platform – API Manager, that facilitates API design using RAML (REST API Modeling Language). To access the API designer a developer must create an account and login using: https://anypoint.mulesoft.com
Using the API Manager, add new API and provide the following information:
API Name: Users API
Version name: 1.0
API Endpoint: http://localhost:8081/api
Description: Users API Example for Demo

The API Manager shows the created API definition as in the following screenshot:
 
API Manager

To start designing the API, click on Edit API designer.
The following screenshot shows the RAML file and its content in the API Designer, to view properly the RAML content, refer to the code in Git: https://github.com/fattouh/users-api.git

API Designer
Note that the keyword secureBy: oauth_2_0 that applies oauth2 must be removed at this point and only added when oauth2 will be applied using external provider.  This will be explained in another blog post.

The RAML file is using includes for users and user JSON example files: users-example.json and user-example.json.

users-example.json file content:
[{
"id": 1,
"name": "Bouchaib Fattouh",
"username": "testuser",
"email": "fattouh@prolearn.com",
"address": {
   "street": "Kevin Street",
   "suite": "Apt. 556",
   "city": "Montreal",
   "zipcode": "H3E2E5",
   "state": "QC",
   "country": "CA"
} ,
"phone": "1-514-736-8031 x56442",
"website": "prolearn.com"
}]
  
user-example.json file content:
{
"id": 1,
"name": "Bouchaib Fattouh",
"username": "testuser",
"email": "fattouh@prolearn.com",
"address": {
      "street": "Kevin Street",
      "suite": "Apt. 556",
     "city": "Montreal",
     "zipcode": "H3E2E5",
     "state": "QC",
     "country": "CA"
},
"phone": "1-514-736-8031 x56442",
"website": "prolearn.com"
}

Create the users-api application 

Using the API administration, export the users.raml and the examples JSON files in a local folder, this file will be used to create the users-api application using the APIKit. The following screenshot shows the project specifics to create in Anypoint Studio:
Anypoint Studio Project
The complete application code is published in Git: https://github.com/fattouh/users-api.git
For the sake of demonstration, the application is using a mock repository service: com.prolearn,usersRepository to load the application with a collection of users in a Map when it is started. In a real world scenario all users or a specific user with a given id will be retrieved from a backed database.
The application can be tested initially using in Anyppint Studio and the API Console. Recall that at this point the securedBy: oauth_2_0 is not used.

Server registration

Using the Runtime Manager, click on Servers and Add Server as shown in the following screenshot:
Mule On premise registration
 Use the displayed command to register the mule on premise server with a name:
./amc_setup -H b480fdf1-001a-4a12-93cb-762f09c11a38---29586 server-name
 On my local machine directory changed to installed Mule standalone:
/Documents/mule-enterprise-standalone-3.8.2/bin
./amc_setup -H b480fdf1-001a-4a12-93cb-762f09c11a38---29586 onpremise-esb
On CloudHub Runtime Manager, Mule on premise server will be shown as the following screenshot with the provided name onpremise-esb. The status is shown as Disconnected because the server is not started yet:
On premise server registered

Application Deployment

Start mule server from the bin using: ./mule
login to Anypoint platform and note that the server namely: onpremise-esb status has switched to : Connected. 
Deploy the application using Runtime Manager on CloudHub by selecting the server: onpremise-esb.

Application Deployment


Conduct the two following tests using RESTClient or Postman: 
http://localhost:8081/api/users : will display a collection of users in JSON format
http://localhost:8081/api/users/4 : will display the user by id=4 in JSON format
Endpoints tests

Note that if we have deployed the application with the name users-api on CloudHub, we would have used the following URIs to perform the identical tests:
http://users-api.cloudhub.io/api/users
http://users-api.cloudhub.io/api/users/4
At this step, we know that application is running in the on premise server. In the next section I will create a proxy application to this Users API using the API Manager on the Anypoint Platform.
Deploy the API Proxy
In this section, I ill revert back to the API administration within the API Manager and create the proxy endpoint using the same window as illustrated by the screenshot in the API Design section:
Click Configure  endpoint and use the following specifics for the proxy API configuration as illustrated in the following screenshot:
Check Endpont with proxy
Type :                                 RAML
Implementation URI:         http://localhost:8081/api
Scheme:                             HTTP
Port:                                   8082 
Path:                                  /api-proxy 

Proxy Endpoint config


 Click Save & deploy will show the following, select the onpremise-esb server and deploy:
 
Proxy API deployment



When the deployment is complete the application status is shown as Active as illustrated in the following screenshot:

 
Proxy API Active

Proxy Test

Using RESTClient entering the following URIs with GET method will display respectively the collection of all users and a user by id : 4
http://localhost:8082/api-proxy/users
http://localhost:8082/api-proxy/users/4 

Summary Recapitulation

1. Created Users API RAML using the API Designer
2. Created users-api application using the RAML file in Anyppoint Studio.
3. Deployed application users-api in the registered on premise mule server using the Runtime Manager on the CloudHub.
4. Created a proxy for the Users API deployed in the API Gateway.

API Management

In the previous section we deployed the proxy application using the API Manager on CloudHub. This proxy is wired to the real Users API deployed on the on premise server and still does not add any value yet to our application; it is only behaving as a pass-through now. In this section I will show how to apply policies to the deployed API using the proxy application via the API Gateway management.
Add rate limitation policy:
Using the API administration page, click on the Policies tab as shown by the following screenshot:

API Policies application
 
Click on Rate limiting Policy
Rate limiting policy application
 
Click on Apply will show the following window, enter 2 requests per minutes and Apply
Rate limiting: 2 Requests / minute





To test the rate limiting policy applied, use RESTClient and hit the endpoint: 
http://localhost:8082/api-proxy/users
This call will display the collection of users for two calls in a minute, the third call will display the message: API calls exceeded, this message illustrates the rate limiting policy in action as it is also indicated by the response headers as follow:
Response headers:
Status Code: 429 Too Many Requests
Date: Mon, 05 Dec 2016 19:24:32 GMT
Transfer-Encoding: chunked
X-RateLimit-Limit: 2
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 55925 

In the counter part the call to the application users-api that is deployed on the on premise server will always return the expected results via either URIs because there is no calls limitation on it:
http://localhost:8081/api/user
http://localhost:8081/api/users/4

In the next post I will show how to Enforce the use of an OAuth 2.0 access token issued through an OAuth 2.0 external provider.