//

Automatic Proxy Selection for Mule ESB Webservices

29.3.2010 | 2 minutes of reading time

When configuring mule, you might find out that some of your services need to call external parties. Depending on your deployment scenario there needs to be a proxy server involved. However this might change for various test stages, some need, some don’t, some need them only for specific domains and like that.
To reduce configuration overhead we have created an automatic proxy selector used for our services. Because I think its neat, I want to share it with you.

1<https:connector name="autoProxy">
2  <spring:property name="proxyHostname">
3    <spring:bean class="org.springframework.jndi.JndiObjectFactoryBean">
4      <spring:property name="jndiName" value="/jndi/config/proxyHost" />
5      <spring:property name="defaultObject" value="" />
6    </spring:bean>
7  </spring:property>
8  <spring:property name="proxyPort">
9    <spring:bean class="org.springframework.jndi.JndiObjectFactoryBean">
10      <spring:property name="jndiName" value="/jndi/config/proxyPort" />
11      <spring:property name="defaultObject" value="0" />
12    </spring:bean>
13  </spring:property>
14  <service-overrides dispatcherFactory="de.codecentric.mule.HttpAutoProxyMessageDispatcherFactory" />
15  <https:tls-key-store path="/mule.keystore" keyPassword="changeit" storePassword="changeit"/>
16  <https:tls-server path="/mule.keystore" storePassword="changeit"/>
17</https:connector>
18

As you can see we configured a Connector which creates this MessageDispatcherFactory, it passes the configuration obtained from JNDI to it and also adds a keystore for ssl connections to it (with the great default password changeit :-))
Using it is then straightforward:

1  <outbound-endpoint address="https://external.service/endpoint" synchronous="true" connector-ref="autoProxy">
2

The Factory itself is dead simple:

1public class HttpAutoProxyMessageDispatcherFactory
2  extends AbstractMessageDispatcherFactory {
3  public MessageDispatcher create(OutboundEndpoint endpoint) throws MuleException {
4    return new HttpAutoProxyMessageDispatcher(endpoint);
5  }
6}
7

The HttpAutoProxyMessageDispatcher implementation is easy was well. And contains a few hardcoded hosts that should not be proxied. Feel free to improve that part:

1public class HttpAutoProxyMessageDispatcher
2  extends HttpClientMessageDispatcher {
3 
4  private final boolean hasProxy;
5  private final String proxyHost;
6  private final int proxyPort;
7 
8  public HttpAutoProxyMessageDispatcher(OutboundEndpoint endpoint) {
9    super(endpoint);
10    this.proxyHost = ((HttpConnector) endpoint.getConnector()).getProxyHostname();
11    this.proxyPort = ((HttpConnector) endpoint.getConnector()).getProxyPort();
12    this.hasProxy = StringUtils.isNotBlank(proxyHost);
13  }
14 
15  @Override
16  protected HostConfiguration getHostConfig(URI uri) throws URISyntaxException {
17    String host = uri.getHost();
18    HostConfiguration config = new HostConfiguration();
19    config.setHost(host, uri.getPort(), Protocol.getProtocol(uri.getScheme().toLowerCase()));
20    if (hasProxy && !isLocalhost(host)) {
21      config.setProxy(proxyHost, proxyPort);
22    }
23    return config;
24  }
25 
26  private boolean isLocalhost(String host) {
27    return "localhost".equals(host) || "127.0.0.1".equals(host);
28  }
29 
30}
31

When you applied this pattern you only need to make sure JNDI information regarding the proxy is correct on each environment, and the mule configuration will automatically adapt to it.

Update: Mule 3.2

Recent Versions of Mule made it even easier to implement the HttpAutoProxyMessageDispatcher:

1public class HttpAutoProxyMessageDispatcher extends
2    HttpClientMessageDispatcher implements MessageDispatcher {
3 
4  public HttpAutoProxyMessageDispatcher(OutboundEndpoint endpoint) {
5    super(endpoint);
6  }
7 
8  @Override
9  protected HostConfiguration getHostConfig(URI uri) throws Exception {
10    Protocol protocol = Protocol.getProtocol(uri.getScheme().toLowerCase());
11    String host = uri.getHost();
12    int port = uri.getPort();
13    HostConfiguration config = new HostConfiguration();
14    config.setHost(host, port, protocol);
15    if (!isLocalhost(host) && StringUtils.isNotBlank(connector.getProxyHostname())) {
16      config.setProxy(connector.getProxyHostname(), connector.getProxyPort());
17    }
18    return config;
19  }
20 
21  private boolean isLocalhost(String host) {
22    return "localhost".equals(host) || "127.0.0.1".equals(host); 
23  }
24}
25

share post

Likes

0

//

More articles in this subject area\n

Discover exciting further topics and let the codecentric world inspire you.

//

Gemeinsam bessere Projekte umsetzen

Wir helfen Deinem Unternehmen

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.