Dynamic HTTP Proxy with Mule

By | March 9, 2014

In this post I will show a proof-of-concept for a dynamic HTTP proxy implemented using Mule.

Principle

The proxy forwards HTTP request using the context and relative path parts of the request URL to determine the server and port to which the request is to be forwarded.
In the example in this article a SOAP web service will be deployed to listen to the following URL:

In the above URL, the server and port is localhost:8182, the context and relative path parts of the URL is “services/GreetingService”.
The example program will be deployed to listen to requests at the following URL:

In order to invoke the GreetingService via the HTTP proxy, the endpoint URL will look like this:

Motivation

The main motivation for the dynamic HTTP proxy is the ability to be able to add new HTTP proxies with a minimum of effort and without having to restart the proxy.

Limitations of the Example Program

Lacking from the example program to make it useable in a production environment are:

  • Error handling.
  • Retrieval of configuration from database.
    In the example, a simple map is used to store mapping between the HTTP relative path and the destination server. This does of course not allow for dynamically modifying the proxy configuration.
  • Support for additional HTTP verbs.
    In the example program only support for the HTTP verbs GET and POST have been implemented. It is trivial to add support for additional HTTP verbs as needed.
  • Handling of HTTP parameters.
    The example program does not consider HTTP parameters but these are considered to be part of the HTTP relative path.
  • Support for HTTPS.

There are probably additional things that one would consider lacking – feel free to add suggestions in the comments!

A Service to Proxy

The example program will be implemented in a Mule Project in SpringSource Tool Suite with the MuleStudio plug-in installed. Any Eclipse-based IDE with the MuleStudio plug-in installed.

In order to be have a service to proxy, a simple SOAP greeting-service is implemented using one Mule configuration file and one Java class.
The Mule configuration contains the following configuration:

The Java class implementing the service looks like this:

Server Information Bean Class

Instances of the server information bean class holds information about a server which to forward requests to.

The reasons for storing this information in a dedicated bean class is to make it easy to extend the class with additional information, to facilitate migration of storage to a database and to keep the different kinds of data stored in the Mule context to a minimum.

Dynamic HTTP Proxy Mule Configuration

The dynamic HTTP proxy Mule configuration is implemented as follows:

Note that:

  • A map named “pathToServerAndPortMapping” is configured using Spring XML.
    This map contains the mapping between context and relative path of a URL to the server to which requests are to be forwarded, as discussed above.
  • The map contains an entry for “services/GreetingService?wsdl”.
    As discussed in the section on limitations of the example program, it currently does not handle HTTP parameters. I also wanted more than one single mapping in order to make the example more interesting.
  • There is an element setting the property “outboundPath” immediately after the HTTP inbound endpoint.
    The slightly complicated expression in the value attribute is used to remove the context part of incoming HTTP requests. The context part of the dynamic HTTP proxy can be changed without requiring modifications of the expression. However, if you want to add another part to the URL which should not be regarded when determining which server to forward a request to, this expression need to be modified.
  • An <enricher> is used to retrieve the correct instance of the ServerInformationBean class.
    Instead of using a Groovy script, the enricher should perform a database query.
    In addition, there is no error handling for the case where there is no server information available for a particular key.
  • There is a <choice> element containing multiple outbound HTTP endpoints.
    The outbound HTTP endpoints only differ as far as the method attribute is concerned. The reason for having to use the <choice> element and multiple HTTP outbound endpoints is that Mule does not allow for expressions to be entered in the method attribute.

Test the Example Program

The example program is now complete and can be started by right-clicking the project in the IDE and selecting Run As -> Mule Application.
When the Mule instance has started up, try issuing a request to the following URL in a browser of your choice:

You should see the WSDL of the greeting service.
Using soapUI, try sending a request to the greeting service. You should receive a greeting containing the current date and time.
Next, add a new endpoint to the request in soapUI and enter the following URL:

Then send the request again from soapUI. You should receive the same kind of response as when communicating directly with the greeting service:

If examining the console log in the IDE, output similar to the following four lines should be present (if not, try changing the log level to ERROR and repeat send a request again):

In a browser, issue a request for the greeting service’s WSDL using the following URL:

The four lines of console output sawn earlier now changes to:

From this we can see that different mappings come into effect depending on the outbound part of the URL.

7 thoughts on “Dynamic HTTP Proxy with Mule

    1. Ivan Krizsan

      If I would use the Mule proxy pattern, then I would have to modify my Mule configuration file each time I wanted to add a new proxy.
      Depending on my production environment, I might also have to stop and restart the Mule server on which my proxies are deployed.
      With the dynamic proxy, I just add proxy configuration in the database and the new proxy is in place, without having to modify any Mule configuration files or stop and restart any Mule server.
      If you have a small number of proxies, then using the Mule proxy pattern is fine.

      Reply
  1. Jan Petersen

    Hi Ivan,

    Excellent article. Any chance that you could provide the source/project for this?

    Thanks

    Reply
    1. Ivan Krizsan

      Hi Jan!
      The entire source code is in the article.
      Lately I have thought about writing a more complete configurable HTTP proxy based on the proof-of-concept in this article. If I do this, I will post something on this blog.
      Best wishes!

      Reply
  2. Easwar

    Hi Ivan,
    I’m looking for Dynamic Proxy in HTTP Connector where we use proxy name, port, username and password to connect to external vendors. We have a situation where we can have more than one vendor and we need to use different username and password for each vendor to connect using proxy, how can we read this information dynamically? rather than creating individual http connector for each vendor.

    Thanks,
    Easwar.

    Reply
    1. Christina

      Hi Easwar,
      We have the same trouble recently,how to realize the Dynamic Proxy in HTTP Connector. We want to consult you if you have a breakthrough about the problem. Hope to get your help.
      Thanks,
      Christina.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *