Automatische Proxywahl für Mule ESB Webservices

1 Kommentar

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); 
  }
}
Avatar

Fabian Lange ist Lead Agent Engineer bei Instana und bei der codecentric als Performance Geek bekannt. Er baut leidenschaftlich gerne schnelle Software und hilft anderen dabei, das Gleiche zu tun.
Er kennt die Java Virtual Machine bis in die letzte Ecke und beherrscht verschiedenste Tools, die JVM, den JIT oder den GC zu verstehen.
Er ist beliebter Vortragender auf zahlreichen Konferenzen und wurde unter anderem mit dem JavaOne Rockstar Award ausgezeichnet.

Über 1.000 Abonnenten sind up to date!

Die neuesten Tipps, Tricks, Tools und Technologien. Jede Woche direkt in deine Inbox.

Kostenfrei anmelden und immer auf dem neuesten Stand bleiben!
(Keine Sorge, du kannst dich jederzeit abmelden.)

* Hiermit willige ich in die Erhebung und Verarbeitung der vorstehenden Daten für das Empfangen des monatlichen Newsletters der codecentric AG per E-Mail ein. Ihre Einwilligung können Sie per E-Mail an datenschutz@codecentric.de, in der Informations-E-Mail selbst per Link oder an die im Impressum genannten Kontaktdaten jederzeit widerrufen. Von der Datenschutzerklärung der codecentric AG habe ich Kenntnis genommen und bestätige dies mit Absendung des Formulars.

Kommentare

Kommentieren

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