Hi,

in my previous post in August by this thread I promised to give a status
update how the things worked out using camel-spring-ws to implement a
webservice
client calling a webservice (through HTTP-Proxy to Extranet) expecting a
strong authentication (client-certificate). All in one, it simply worked
like a charm!

As I feel myself owing a lot to the apache camel community, I would like to
give some hints to other community user about the way I went for it but by
no
means this should be understood as the only and the best way to go for it.
Please also apologize me for my poor English.

At the end of the day, it came out that *no* extra spring
customization/configuration was required concerning the
HTTP-Connection-Setup (see David Valeri
comments on this thread), as the default implementation of
org.springframework.ws.transport.WebServiceMessageSender invoked (that's
org.springframework.ws.transport.http.HttpUrlConnectionMessageSender)
was simply good enough for a succesful SSL-Handshake with the server. The
reason for that is pretty simple as it uses

java.net.URLConnection.openConnection();

which is smart enough to return a matching/meaningful extension of
java.net.URLConnection under SUN-JDK, that's
sun.net.www.protocol.https.DelegateHttpsURLConnection
which is capable of initiating the SSL-Handshake. See also this screenshot 
http://camel.465427.n5.nabble.com/file/n4872087/debug.jpeg debug.jpeg 

As the camel-spring-ws doesn't yet support the camel's own TLS-Configuration
(see Claus comments on this thread), I went for plain old java style to
configure
the keystore/truststore etc. For that I used the spring's own SpEL in my
setup, something like this:

        <bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                <property name="location" value="file:config/egris.properties" 
/>
        </bean>

        <bean id="systemPropertiesSetter"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
                <property name="targetObject" value="#{systemProperties}" />
                <property name="targetMethod" value="putAll" />
                <property name="arguments">
                        <util:properties>
                                <prop 
key="https.proxyHost">${https.proxyHost}</prop>
                                <prop 
key="https.proxyPort">${https.proxyPort}</prop>
                                <prop 
key="javax.net.debug">${javax.net.debug}</prop>
                                <prop 
key="javax.net.ssl.keyStore">${javax.net.ssl.keyStore}</prop>
                                <prop
key="javax.net.ssl.keyStorePassword">${javax.net.ssl.keyStorePassword}</prop>
                                <prop 
key="javax.net.ssl.trustStore">${javax.net.ssl.trustStore}</prop>
                                <prop
key="javax.net.ssl.trustStorePassword">${javax.net.ssl.trustStorePassword}</prop>
                                ...
                                ...
                        </util:properties>
                </property>
        </bean>

The application is a one-single-shot-application, by that I mean that it
get's kicked-off by some external processes causing it to assemble the input
and make
the call and finally shutdown the JVM. For this purpose I made use of
camel's spring-Main [1], however as I had to shutdown the VM in *all* cases,
I did stop the
camel context in a *finally* block, as otherwise if something goes wrong
while calling the webservice through ProducerTemplate the Exception catched
through camel
itself (while routing) will be rethrown wrapped by CamelExecutionException
to the caller (that's me). On the other hand as there're camel's own
ThreadPools created
at runtime through JDK-API containing *non-daemon-threads* the process will
simply *hang*. To make it clear here some code:

    void start() throws Exception {
        main.start(); // this main is org.apache.camel.spring.Main
        template = main.getApplicationContext().getBean("producerTemplate",
ProducerTemplate.class);
    }

    Object request(final EgrisServiceChoice serviceChoice, final Object
payload) {
        return template.requestBodyAndHeader(EGRIS_ROUTE_URI, payload,
SERVICE_CHOICE_HEADER_NAME, serviceChoice);
    }

    void stop() throws Exception {
        main.stop();
    }

    public static void main(final String[] args) throws Exception {
      ...
      ...
      final Main main = new Main(); // this Main is the application's own
Main wrapping org.apache.camel.spring.Main, having the 3 methods above
      main.start();
      ...
      ...
      boolean failed = false;
      try {
          final Object response = main.request(serviceChoice, request);
          final String convertedResponse =
main.getCamelContext().getTypeConverter().mandatoryConvertTo(String.class,
response);
          LOGGER.info("received the terravis webservice response: {}",
convertedResponse);
      } catch (final Exception exp) {
          LOGGER.error("invocation of the terravis webservice failed: " +
exp.getMessage(), exp);
          failed = true;
      } finally {
          main.stop();
          System.exit(failed ? 1 : 0);
      }

      // not reached
    }

As you see stopping of the camel context is to be done in a *finally* block
for the reason explained before.

I hope these explanations will be helpful for other community users willing
to use camel-spring-ws.

[1]
http://camel.apache.org/running-camel-standalone-and-have-it-keep-running.html

Regards, Babak
PS: I also thank David/Claus alot for their help.
PS2: The application was developed under SUN/Oracle JDK1.6 *and*
successfully deployed under IBM JDK1.6.
PS3: This information could be also important regarding TLS/SSL security
hole:
http://www.oracle.com/technetwork/java/javase/documentation/tlsreadme2-176330.html


--
View this message in context: 
http://camel.465427.n5.nabble.com/need-some-advice-on-cxf-or-spring-ws-tp4643001p4872087.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply via email to