MuleSoft Proxy - A Super Deep Dive
Introduction
Probably it's yet another blog on API Proxy in MuleSoft, but I will try to deep dive in it to expose the internal stuffs which is a real fun.
API Proxy
Proxy is nothing but a small program or application which answers for the actual application. It's same as your special friend in your college shouting out "Present sir/ma'am" for you while the professor is doing the traditional roll-call and you are off for a movie. So, I will not enter in too much detail of it and will directly go to hands on.
MuleSoft Proxy
The complete API development process can be divided into two parts as shown in the below diagram. I am considering a fully cloud deployment infrastructure. It will be slightly different when you deploy the Mule applications in on-premise deployment infrastructure .
API Development
Below things happen in this phase.
- API Specification creation
1. Create the API Specification in Design Center
2. Test the API resources with the Mock backend provided by the Anypoint Platform.
3. Publish the API Specification to the Exchange so that anyone across the organization can make use of it.
2. API Specification implementation
1. Once we have our API Specification ready now we can implement it in Anypoint Studio.
2. Create a project in Anypoint Studio. Download the API Specification from Exchange and import it to the project and implement it.
3. Alternatively you can import the API Specification directly from Exchange to your project in Anypoint Studio. Either way it's the same at the end.
4. Once the actual Business Logic is implemented in the Anypoint Studio project, deploy the project to CloudHub.
5. At this point we are done with the API Development process.
API Governance
This is the second phase. At this point we have our API implemented and deployed in CloudHub (Mule Runtime). Definitely you can access this API by invoking the direct URL.
But, it's not secure. Anyone can access the API and make burst requests to kill your servers. Also, we did not apply any security policies in the API implementation to focus only on the actual business logic.
So, who should handle the security of the API and controlled access? It's the API Manager. API Manager is responsible to apply all the security policies to the API. And how does the API Manager do it? It's through API Proxy.
Now, below things happen in this phase.
1. Let's manage our API. So, where is our API? It's in the Exchange. Remember that we published the API Specification to the Exchange right in the first phase.
2. Import the API Specification (or API) from the Exchange and create a Proxy.
3. Finally deploy the proxy to CloudHub.
Deployed Applications
Ok. Let us analyze a bit what has been deployed to the CloudHub until now. There are two Mule applications deployed to the CloudHub (Mule Runtime).
1. The API Implementation (Actual business logic).
2. The API Proxy (It was deployed behind the scene).
I am talking about these:
In the above diagram first one is the actual API implementation and second is the Proxy.
Now let's analyze the proxy application. For doing so I just downloaded the Proxy application and imported it to the Anypoint Studio. Below is a screen shot of the Proxy application generated by API Manager when we deployed the proxy.
The flow is quite simple. It simply invokes the actual API implementation application which is already deployed. It uses the below config.properties for the referenced values.
So far so good. Now, let's create one more proxy for the same API.
Now, you can see that the Status of the first proxy is Active while the second is Unregistered. What do they mean?
It means that for the Active proxy, there is a corresponding Mule Application (the Proxy Application) deployed in CloudHub.
Question is how does the deployed mule application relate to the proxy?
It's easy. It's happening through the Instance Id of the API Proxy.
Show me the code!!!!
In the proxy application, open the main flow and in the Global Elements tab you can see the API Autodiscovery configuration. It does the whole magic for you. The ${api.id} value is coming from the config.properties file.
I will discuss in detail regarding how API Autodiscovery works in the next section.
Now, it's easy why the another proxy is in Unregistered state.
The answer is that there is not any Mule Application deployed in CloudHub that is working for the instance id of the proxy i.e 17676174.
Now, if you create a Mule Application and configure an API Autodiscovery element with the API instance id 17676174 and deploy it in CloudHub the proxy will be in Active status.
API Autodiscovery
Let's do some cool experiments. I am just creating a clean environment so that you don't get bugged.
Step 1
Delete all the Mule Applications deployed in CloudHub. Alternatively you can create a clean environment for this experiment .
Step 2
Delete all the API Proxies.
Step 3
Let's register a new API Proxy. The API specification is already published in the Exchange. So, just wire it up. This is my API Proxy configuration.
Save it and you will have an API Instance ID generated by the platform as shown below.
Note that API Instance ID and Autodiscovery ID are the same.
Step 3
Please do not deploy the API Proxy to CloudHub. So, at this point we have an API Proxy or API Instance in an Unregistered state.
Why it is not Active?
Because there is no corresponding Mule Application deployed that are polling on the Proxy or Instance.
Step 4
Great. Now at this point, we have a Proxy or Instance in our API Manager which is in the Cloud. And, it's still useless because it's not active. So, in this step let's give life to it.
We can give a new life to it directly from our localhost standalone Mule ESB server or even from the Anypoint Studio.
Using Anypoint Studio
Let's create a project named ag-my-proxy. I just created a flow with a Http Listener on port 9999 and path as /*. In the Global Elements section, I added an API Autodiscovery element and added the below configuration.
This configuration is the heart to give life to our proxy or instance.
<api-gateway:autodiscovery/>
When this element is configured in a Mule Application the extension responsible for API spawns up. Below is the complete class name.
com.mulesoft.mule.runtime.gw.deployment.ApiDeploymentCoreExtension
And it's found in
mule-module-api-deployment-4.x jar
The next thing is, how does our application (that will be run in our Anypoint Studio) connect to the API Instance or Proxy that is in the API Manager which is a cloud service.
It's also easy to know. When the class ApiDeploymentCoreExtension is initialized it internally initialize an another class called
com.mulesoft.mule.runtime.gw.api.config.GatewayConfiguration
Which is found in another jar called,
api-gateway-api-1.4.0
Now let's check the GatewayConfiguration class. In its constructor it initializes another class called,
com.mulesoft.mule.runtime.gw.api.config.PlatformClientConfiguration
Which is found in:
api-gateway-api-1.4.0
Now let's check the PlatformClientConfiguration class. Here we go:
You can see that there are tons of configurations regarding our Anypoint platform and these configurations we need to provide somehow so that when our project ag-my-proxy is deployed anywhere (Standalone Mule ESB, Anypoint Studio, or CloudHub) it can connect to the platform and thereby giving life to the proxy/instance created.
Cool stuff!!!
Let's scroll a bit down the class PlatformClientConfiguration:
Can you see that the client_id and client_secret are System Properties. These values can be provided in Anypoint Studio as shown below.
The client_id & client_secret belong to the credentials of my organization.
Now Run the ag-my-proxy project. You should be able to see the below lines in the logs of Anypoint Studio.
Now let's check the status of our proxy in the API Manager.You can see that its status is now Active as shown below. (It takes some time.)
Using Standalone Mule ESB
We can configure a standalone Mule ESB with the below values in the wrapper.conf
Then deploy the application in the standalone server and that's it.
Execution of the Proxy
Remember that we have developed our ag-my-proxy application with a Http listener on port 9999 and path /*. We did not implement any logic in it and so it will do nothing. So, let's execute the application some number of times.
Wait for some minutes and let's open the API Proxy in the API Manager.
Voila! It has collected the statistics. And note that we are executing the proxy in our local machine. Is not it cool?
Now, let's add a security policy to the API Proxy/instance.
Let's execute the same command.
Now, I get the below response and guess what it's well expected.
Now let us modify the logic of the ag-my-proxy application so that it actually proxies calls to the actual business logic implemented.
Actual Business Logic
Below is my API Specification and hello-world is the application that is implementing the actual business logic.
It's running in http port 8081 and base path /api/*.
Proxy Logic
It's simply invoking the actual business logic implementation which is running in a separate Mule Application i.e hello-world.
Note: Temporarily , I have removed the security policy from the API Proxy.
Now, if we execute the the proxy it will invoke the actual business logic application and we can see the output as shown below.
Conclusion
The whole experiment can be summarized in the below diagram.
Things we have in API Manager (Cloud) are:
1. The API Instance
2. Policies
3. Analytics
Things we have in our local system (on-premise)are:
1. The implementation project of the Proxy/Instance
2. The implementation of the actual business logic of the API specification
It's kind of hybrid deployment. Another approach is you can deploy the proxy and API implementation in CloudHub and then it will be a fully cloud deployment as shown below.
Check that either in CloudHub or on-premise Mule ESB we need to deploy 2 Mule applications. The proxy application is nothing but a simple application with an API Autodiscovery configuration to poll on the API Instance ID created in the API Manager and additionally a HTTP Request component to invoke the actual API implementation.
So, what about putting the API Autodiscovery component in the API implementation project itself? Is it going to work?
Let's explore this in the next article.
Happy learning !!!