Automatische Proxywahl für Mule ESB Webservices

2 Kommentare

Wenn man Services in Mule konfiguriert wird man einige benutzen, welche externe Services aufrufen. Allerdings hängt es von der Umgebung ab, ob und für welche Hosts ein Proxy Server verwendet werden muss. Um die Rekonfiguration von Mule je Umgebung zu vermeiden benutzen wir einen automatischen Proxy Connector. Da ich den ganz nett finde möchte ich Ihn Euch gerne näher bringen. Vielleicht ist er auch für Euch nutzbar

<https:connector name="autoProxy">
  <spring:property name="proxyHostname">
    <spring:bean class="org.springframework.jndi.JndiObjectFactoryBean">
      <spring:property name="jndiName" value="/jndi/config/proxyHost" />
      <spring:property name="defaultObject" value="" />
    </spring:bean>
  </spring:property>
  <spring:property name="proxyPort">
    <spring:bean class="org.springframework.jndi.JndiObjectFactoryBean">
      <spring:property name="jndiName" value="/jndi/config/proxyPort" />
      <spring:property name="defaultObject" value="0" />
    </spring:bean>
  </spring:property>
  <service-overrides dispatcherFactory="de.codecentric.mule.HttpAutoProxyMessageDispatcherFactory" />
  <https:tls-key-store path="/mule.keystore" keyPassword="changeit" storePassword="changeit"/>
  <https:tls-server path="/mule.keystore" storePassword="changeit"/>
</https:connector>

Wie man leicht sieht verwenden wir eine eigene MessageDispatcherFactory, welche die Parameter ProxyHost und ProxyPort aus JNDI ausliest und einen SSL Keystore mit dem berühmten changeit Passwort übergibt.
Diesen Connector verwendet man dann einfach über connector-ref

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

Die Factory selbst ist supereinfach:

public class HttpAutoProxyMessageDispatcherFactory
  extends AbstractMessageDispatcherFactory {
  public MessageDispatcher create(OutboundEndpoint endpoint) throws MuleException {
    return new HttpAutoProxyMessageDispatcher(endpoint);
  }
}

Die Implementierung des HttpAutoProxyMessageDispatcher ist auch einfach, enthält hier aber zwei hardcodierte Hosts welche nicht geproxied werden sollen. Hier kann man gerne noch Verbesserungen einfließen lassen.

public class HttpAutoProxyMessageDispatcher
  extends HttpClientMessageDispatcher {
 
  private final boolean hasProxy;
  private final String proxyHost;
  private final int proxyPort;
 
  public HttpAutoProxyMessageDispatcher(OutboundEndpoint endpoint) {
    super(endpoint);
    this.proxyHost = ((HttpConnector) endpoint.getConnector()).getProxyHostname();
    this.proxyPort = ((HttpConnector) endpoint.getConnector()).getProxyPort();
    this.hasProxy = StringUtils.isNotBlank(proxyHost);
  }
 
  @Override
  protected HostConfiguration getHostConfig(URI uri) throws URISyntaxException {
    String host = uri.getHost();
    HostConfiguration config = new HostConfiguration();
    config.setHost(host, uri.getPort(), Protocol.getProtocol(uri.getScheme().toLowerCase()));
    if (hasProxy && !isLocalhost(host)) {
      config.setProxy(proxyHost, proxyPort);
    }
    return config;
  }
 
  private boolean isLocalhost(String host) {
    return "localhost".equals(host) || "127.0.0.1".equals(host);
  }
 
}

Setzt man die Konfiguration so um, muss lediglich im JNDI jeder Umgebung der Proxy eingestellt sein. Mule wird dann automatisch den Proxy verwenden falls gesetzt und die Konfiguration selbst kann unangetastet bleiben.

Update: Mule 3.2

Kürzlich erschienene Versionen von Mule erleichtern das Implementieren des HttpAutoProxyMessageDispatchers:

public class HttpAutoProxyMessageDispatcher extends
    HttpClientMessageDispatcher implements MessageDispatcher {
 
  public HttpAutoProxyMessageDispatcher(OutboundEndpoint endpoint) {
    super(endpoint);
  }
 
  @Override
  protected HostConfiguration getHostConfig(URI uri) throws Exception {
    Protocol protocol = Protocol.getProtocol(uri.getScheme().toLowerCase());
    String host = uri.getHost();
    int port = uri.getPort();
    HostConfiguration config = new HostConfiguration();
    config.setHost(host, port, protocol);
    if (!isLocalhost(host) && StringUtils.isNotBlank(connector.getProxyHostname())) {
      config.setProxy(connector.getProxyHostname(), connector.getProxyPort());
    }
    return config;
  }
 
  private boolean isLocalhost(String host) {
    return "localhost".equals(host) || "127.0.0.1".equals(host); 
  }
}

Autor

Fabian Lange

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *