Коннектор Mule ESB Riak: как настроить конечные точки HTTP через SSL

У меня вопрос по разъему Mule Riak и возможностям его конфигурации. Я хочу настроить коннектор с использованием конечной точки HTTPS. Теперь соединитель содержит org.mule.modules.riak.config.RiakHttpClientConfigurationAdapter, а не Mule HttpConnector.

Чтобы сделать свой подход более понятным, я попробовал следующую конфигурацию:

<http:connector name="HTTP_HTTPS" cookieSpec="netscape"
    validateConnections="true" sendBufferSize="0" receiveBufferSize="0"
    receiveBacklog="0" clientSoTimeout="10000" serverSoTimeout="10000"
    socketSoLinger="0" doc:name="HTTP-HTTPS" />

<spring:beans>
    <spring:bean id="riakclient"
        class="org.mule.modules.riak.config.RiakHttpClientConfigurationAdapter">
        <spring:property name="httpClient" ref="HTTP_HTTPS"></spring:property>
    </spring:bean>
</spring:beans>

Конечно, это не удается:

Cannot convert value of type [org.mule.transport.http.HttpConnector] to required type
[org.apache.http.client.HttpClient] for property 'httpClient': no matching editors or conversion
strategy found

Теперь, можете ли вы придумать способ на самом деле повторно использовать существующий HttpConnector (со всей этой настройкой конфигурации SSL)? На самом деле я не хочу снова настраивать HttpClient и добавлять его в клиент riak.

РЕДАКТИРОВАТЬ 1: обновлено с учетом подхода Дэвида. Я добавил следующую конфигурацию, чтобы выполнить часть отражения:

<spring:beans>
    <!-- get class instance of HttpsConnector for reflection -->
    <spring:bean id="httpsConnectorClass"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <spring:property name="targetObject" ref="HTTP_HTTPS">
        </spring:property>
        <spring:property name="targetMethod">
            <spring:value>getClass</spring:value>
        </spring:property>
    </spring:bean>

    <!-- get method via reflection of HttpsConnector for reflection -->
    <spring:bean id="httpsConnectorMethod"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <spring:property name="targetObject" ref="httpsConnectorClass">
        </spring:property>
        <spring:property name="targetMethod">
            <spring:value>getMethod</spring:value>
        </spring:property>
        <spring:property name="arguments">
            <spring:list>
                <spring:value>doClientConnect</spring:value>
                <spring:value type="java.lang.Class"></spring:value>
            </spring:list>
        </spring:property>
    </spring:bean>

    <!-- set method accessible -->
    <spring:bean id="httpsConnectorMethodAccessible"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <spring:property name="targetObject" ref="httpsConnectorMethod">
        </spring:property>
        <spring:property name="targetMethod">
            <spring:value>setAccessible</spring:value>
        </spring:property>
        <spring:property name="arguments">
            <spring:list>
                <spring:value>true</spring:value>
            </spring:list>
        </spring:property>
    </spring:bean>

    <!-- call accessible doClientConnect() to retrieve HttpClient -->
    <spring:bean id="httpClientFromConnector"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <spring:property name="targetObject" ref="HTTP_HTTPS">
        </spring:property>
        <spring:property name="targetMethod">
            <spring:value>doClientConnect</spring:value>
        </spring:property>
    </spring:bean>

    <spring:bean id="riakclient"
        class="org.mule.modules.riak.config.RiakHttpClientConfigurationAdapter">
        <spring:property name="httpClient" ref="httpClientFromConnector"></spring:property>
    </spring:bean>
</spring:beans>

К сожалению, вызов уже не работает в части отражения. То, что я делаю в Spring, должно быть эквивалентно этой части Java:

    HttpsConnector https = new org.mule.transport.http.HttpsConnector(null);
    https.getClass().getMethod("doCientConnect", null).setAccessible(true);

При запуске Mule я получаю следующее исключение в части отражения этого bean-компонента:

    <spring:bean id="httpsConnectorMethod"
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <spring:property name="targetObject" ref="httpsConnectorClass">
        </spring:property>
        <spring:property name="targetMethod">
            <spring:value>getMethod</spring:value>
        </spring:property>
        <spring:property name="arguments">
            <spring:list>
                <spring:value>doClientConnect</spring:value>
                <spring:value type="java.lang.Class"></spring:value>
            </spring:list>
        </spring:property>
    </spring:bean>

Исключение:

ERROR 2014-08-26 11:33:22,021 [main] org.mule.module.launcher.application.DefaultMuleApplication: null
java.lang.NoSuchMethodException: org.mule.transport.http.HttpConnector.doClientConnect()
at java.lang.Class.getMethod(Class.java:1665)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.util.MethodInvoker.invoke(MethodInvoker.java:273)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'httpsConnectorMethod'

РЕДАКТИРОВАТЬ 2: класс помощника пакет com.mule.httpclient;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.http.client.HttpClient;
import org.mule.modules.riak.config.RiakHttpClientConfigurationAdapter;
import org.mule.transport.http.HttpsConnector;

public class HttpClientAdapter {

    private HttpsConnector httpsConnector;
    private org.mule.modules.riak.config.RiakHttpClientConfigurationAdapter riakClient;

    public HttpClientAdapter() {
    }

    public void setHttpsConnector(HttpsConnector httpsConnector) {
        this.httpsConnector = httpsConnector;
        this.riakClient = new org.mule.modules.riak.config.RiakHttpClientConfigurationAdapter();


        try {
            try {
              Class httpsClass = httpsConnector.getClass();
              Method method = httpsClass.getSuperclass().getDeclaredMethod("doClientConnect", null); 
              method.setAccessible(true);
              // Cast not working due to too different HttpClient versions (3.5 vs. 4.2)
              this.riakClient.setHttpClient((HttpClient) method.invoke(httpsConnector, null));
            } catch (IllegalAccessException | IllegalArgumentException
                | InvocationTargetException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public RiakHttpClientConfigurationAdapter getRiakClient() {
        return riakClient;
    }
}

Версии библиотеки HttpClient слишком сильно различаются, чтобы дело было успешным. Нужно будет как-то адаптировать и эти версии.

java.lang.ClassCastException: org.apache.commons.httpclient.HttpClient cannot be cast to org.apache.http.client.HttpClient

person brazo    schedule 25.08.2014    source источник
comment
Можете ли вы придумать способ на самом деле повторно использовать существующий HttpConnector - это загадка? Думаю, есть другой сайт для тизеров: Программирование пазлов и код для гольфа;)   -  person jww    schedule 25.08.2014
comment
Да, это называется геймификацией. ;)   -  person brazo    schedule 25.08.2014


Ответы (1)


Я могу придумать способ!

  1. Измените видимость doClientConnect на HTTP-коннектор Mule с setAccessible.
  2. Используйте Spring для получения экземпляра HttpClient с помощью этого метода.
  3. Ввести riakclient
  4. Выгода!
person David Dossot    schedule 25.08.2014
comment
Привет, Дэвид, спасибо за ответ. Если я посмотрю, я думаю, что вы в основном разработали разъем Riak, верно? :) Я действительно думал о создании нового RiakHttpsConnectorAdapter ... было бы самым чистым решением, не так ли. Тем не менее, изложенный вами подход очень прагматичный и приятный. Можете ли вы помочь мне с последними подробностями в моем отредактированном вопросе? - person brazo; 26.08.2014
comment
Создайте вспомогательный класс, в который вы вставляете коннектор HTTP_HTTPS (с прекрасным именем) и который предоставляет фабричный метод, вызывающий doClientConnect для получения экземпляра HttpClient и его возврата. - person David Dossot; 26.08.2014
comment
Сделал это, но столкнулся с проблемами несовместимости между коннекторами и HTTP-клиентом Mule. Я думаю, что все, что я напишу для дальнейшего развития, может стать усовершенствованием для клиента Riak. ;) - person brazo; 26.08.2014
comment
О, я вижу, что один из них - старый Http-клиент (3.x), а один - новый (4.x) ... Да, это не сработает :( - person David Dossot; 26.08.2014