Camel
  1. Camel
  2. CAMEL-6084

SOAP over JMS does not work with camel-cxf endpoint

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.10.0
    • Fix Version/s: 2.9.6, 2.10.4, 2.11.0
    • Component/s: camel-cxf
    • Labels:
      None
    • Estimated Complexity:
      Unknown

      Description

      If we would like to use SOAP over JMS using CXF & Camel (2.10),that fails.

      The CXF endpoint receives well the incoming request from the JMS queue

      [aultMessageListenerContainer-1] HelloWorldServicePortType INFO  Inbound Message
      ----------------------------
      ID: 1
      Content-Type: text/xml
      Headers: {JMSMessageType=[text]}
      Payload: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hel="http://helloworld.mycompany.redhat.com">
         <soapenv:Header/>
         <soapenv:Body>
            <hel:sayHello>
               <hel:name>fred</hel:name>
            </hel:sayHello>
         </soapenv:Body>
      </soapenv:Envelope>
      
      --------------------------------------
      [aultMessageListenerContainer-1] route1 INFO  SOAP Request received message
      [aultMessageListenerContainer-1] route1 INFO  Mock service replied
      
      

      but the response is not returned by CXF neither published in a (reply) queue.

      Here is the Camel Route
      
          @Override
          public void configure() throws Exception {
      
      from("cxf:bean:endpoint.service.worklist?dataFormat=MESSAGE")
                      .convertBodyTo(String.class)
                      .log("SOAP Request received message")
      .setHeader("JMSReplyTo").constant("supervisorworklist.response")
                      .transform().constant(response) // RESPONSE = SOAP MESSAGE
                      .log("Mock service replied");
      
          }
      
      

      & Config

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:camel="http://camel.apache.org/schema/spring"
             xmlns:osgi="http://www.springframework.org/schema/osgi"
             xmlns:cxf="http://camel.apache.org/schema/cxf"
             xmlns:jms="http://cxf.apache.org/transports/jms"
             xsi:schemaLocation="
             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
             http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
             http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
             http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf-2.10.0-spring.xsd
             http://cxf.apache.org/transports/jms http://cxf.apache.org/schemas/configuration/jms.xsd">
      
      
          <bean id="jms.connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
             <!-- <property name="brokerURL" value="vm://myEmbeddedBroker?broker.persistent=false" />-->
              <property name="brokerURL" value="tcp://localhost:61616"/>
          </bean>
      
          <bean id="jms.config.service" class="org.apache.cxf.transport.jms.JMSConfiguration">
              <property name="connectionFactory" ref="jms.connectionFactory" />
              <property name="targetDestination" value="supervisorworklist" />
              <property name="replyDestination" value="supervisorworklist.response"/>
          </bean>
      
          <bean id="logginOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
          <bean id="logginInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
      
          <!--  Producer Endpoint -->
          <cxf:cxfEndpoint id="endpoint.service.worklist"
                           address="jms://"
      serviceClass="com.redhat.mycompany.helloworld.HelloWorldService"
                           serviceName="s:HelloWorldService"
                           endpointName="s:HelloWorldOverJms"
                           xmlns:s="http://helloworld.atos.redhat.com">
      
              <cxf:features>
                  <bean xmlns="http://www.springframework.org/schema/beans"
      class="org.apache.cxf.transport.jms.JMSConfigFeature">
                      <property name="jmsConfig" ref="jms.config.service" />
                  </bean>
              </cxf:features>
      
               <cxf:inInterceptors>
                   <ref bean="logginInInterceptor"/>
               </cxf:inInterceptors>
      
               <cxf:outInterceptors>
                   <ref bean="logginOutInterceptor"/>
               </cxf:outInterceptors>
          </cxf:cxfEndpoint>
      
      
          <camelContext xmlns="http://camel.apache.org/schema/spring">
              <package>com.redhat.mycompany.cxf</package>
          </camelContext>
      
      </beans>
      

        Activity

        Hide
        Charles Moulliard added a comment - - edited

        wsdl used

        <?xml version="1.0" encoding="UTF-8" standalone="no"?>
        <wsdl:definitions
                xmlns:impl="http://helloworld.mycompany.redhat.com"
                xmlns:jms="http://cxf.apache.org/transports/jms"
                xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:soapjms="http://www.w3.org/2010/soapjms/"
                targetNamespace="http://helloworld.mycompany.redhat.com">
            <wsdl:types>
                <schema xmlns="http://www.w3.org/2001/XMLSchema"
                        elementFormDefault="qualified"
                        targetNamespace="http://helloworld.mycompany.redhat.com">
        
                    <element name="sayHello">
                        <complexType>
                            <sequence>
                                <element name="name" type="xsd:string"/>
                            </sequence>
                        </complexType>
                    </element>
        
                    <element name="sayHelloResponse">
                        <complexType>
                            <sequence>
                                <element name="sayHelloReturn" type="xsd:string"/>
                            </sequence>
                        </complexType>
                    </element>
                </schema>
            </wsdl:types>
        
            <wsdl:message name="sayHelloResponse">
                <wsdl:part element="impl:sayHelloResponse" name="parameters">
                </wsdl:part>
            </wsdl:message>
        
            <wsdl:message name="sayHelloRequest">
                <wsdl:part element="impl:sayHello" name="parameters">
                </wsdl:part>
            </wsdl:message>
        
            <wsdl:portType name="HelloWorld">
                <wsdl:operation name="sayHello">
                    <wsdl:input message="impl:sayHelloRequest" name="sayHelloRequest">
                    </wsdl:input>
                    <wsdl:output message="impl:sayHelloResponse" name="sayHelloResponse">
                    </wsdl:output>
                </wsdl:operation>
            </wsdl:portType>
        
            <wsdl:binding name="HelloWorldSoapBinding" type="impl:HelloWorld">
                <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
                <wsdl:operation name="sayHello">
                    <wsdlsoap:operation soapAction=""/>
                    <wsdl:input name="sayHelloRequest">
                        <wsdlsoap:body use="literal"/>
                    </wsdl:input>
        
                    <wsdl:output name="sayHelloResponse">
                        <wsdlsoap:body use="literal"/>
                    </wsdl:output>
                </wsdl:operation>
            </wsdl:binding>
        
            <wsdl:binding name="HelloWorldSoap_JMS_Binding" type="impl:HelloWorld">
                <wsdlsoap:binding style="document" transport="http://cxf.apache.org/transport/jms"/>
                <wsdl:operation name="sayHello">
                    <wsdlsoap:operation soapAction=""/>
                    <wsdl:input name="sayHelloRequest">
                        <wsdlsoap:body use="literal"/>
                    </wsdl:input>
        
                    <wsdl:output name="sayHelloResponse">
                        <wsdlsoap:body use="literal"/>
                    </wsdl:output>
                </wsdl:operation>
            </wsdl:binding>
        
            <wsdl:service name="HelloWorldService">
                <wsdl:port binding="impl:HelloWorldSoapBinding" name="HelloWorld">
                    <wsdlsoap:address location="http://localhost:8080/WebService/services/HelloWorld"/>
                </wsdl:port>
        
                <wsdl:port binding="impl:HelloWorldSoap_JMS_Binding" name="HelloWorldOverJms">
                    <jms:address
                            destinationStyle="queue"
                            jndiConnectionFactoryName="ConnectionFactory"
                            jndiDestinationName="dynamicQueues/test.soap.jmstransport.queue">
                        <jms:JMSNamingProperty name="java.naming.factory.initial"
                                               value="org.apache.activemq.jndi.ActiveMQInitialContextFactory"/>
                        <jms:JMSNamingProperty name="java.naming.provider.url" value="vm://localhost"/>
                    </jms:address>
                </wsdl:port>
            </wsdl:service>
        </wsdl:definitions>
        
        
        Show
        Charles Moulliard added a comment - - edited wsdl used <?xml version= "1.0" encoding= "UTF-8" standalone= "no" ?> <wsdl:definitions xmlns:impl= "http: //helloworld.mycompany.redhat.com" xmlns:jms= "http: //cxf.apache.org/transports/jms" xmlns:wsdl= "http: //schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap= "http: //schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd= "http: //www.w3.org/2001/XMLSchema" xmlns:soapjms= "http: //www.w3.org/2010/soapjms/" targetNamespace= "http: //helloworld.mycompany.redhat.com" > <wsdl:types> <schema xmlns= "http: //www.w3.org/2001/XMLSchema" elementFormDefault= "qualified" targetNamespace= "http: //helloworld.mycompany.redhat.com" > <element name= "sayHello" > <complexType> <sequence> <element name= "name" type= "xsd:string" /> </sequence> </complexType> </element> <element name= "sayHelloResponse" > <complexType> <sequence> <element name= "sayHelloReturn" type= "xsd:string" /> </sequence> </complexType> </element> </schema> </wsdl:types> <wsdl:message name= "sayHelloResponse" > <wsdl:part element= "impl:sayHelloResponse" name= "parameters" > </wsdl:part> </wsdl:message> <wsdl:message name= "sayHelloRequest" > <wsdl:part element= "impl:sayHello" name= "parameters" > </wsdl:part> </wsdl:message> <wsdl:portType name= "HelloWorld" > <wsdl:operation name= "sayHello" > <wsdl:input message= "impl:sayHelloRequest" name= "sayHelloRequest" > </wsdl:input> <wsdl:output message= "impl:sayHelloResponse" name= "sayHelloResponse" > </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name= "HelloWorldSoapBinding" type= "impl:HelloWorld" > <wsdlsoap:binding style= "document" transport= "http: //schemas.xmlsoap.org/soap/http" /> <wsdl:operation name= "sayHello" > <wsdlsoap:operation soapAction=""/> <wsdl:input name= "sayHelloRequest" > <wsdlsoap:body use= "literal" /> </wsdl:input> <wsdl:output name= "sayHelloResponse" > <wsdlsoap:body use= "literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:binding name= "HelloWorldSoap_JMS_Binding" type= "impl:HelloWorld" > <wsdlsoap:binding style= "document" transport= "http: //cxf.apache.org/transport/jms" /> <wsdl:operation name= "sayHello" > <wsdlsoap:operation soapAction=""/> <wsdl:input name= "sayHelloRequest" > <wsdlsoap:body use= "literal" /> </wsdl:input> <wsdl:output name= "sayHelloResponse" > <wsdlsoap:body use= "literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name= "HelloWorldService" > <wsdl:port binding= "impl:HelloWorldSoapBinding" name= "HelloWorld" > <wsdlsoap:address location= "http: //localhost:8080/WebService/services/HelloWorld" /> </wsdl:port> <wsdl:port binding= "impl:HelloWorldSoap_JMS_Binding" name= "HelloWorldOverJms" > <jms:address destinationStyle= "queue" jndiConnectionFactoryName= "ConnectionFactory" jndiDestinationName= "dynamicQueues/test.soap.jmstransport.queue" > <jms:JMSNamingProperty name= "java.naming.factory.initial" value= "org.apache.activemq.jndi.ActiveMQInitialContextFactory" /> <jms:JMSNamingProperty name= "java.naming.provider.url" value= "vm: //localhost" /> </jms:address> </wsdl:port> </wsdl:service> </wsdl:definitions>
        Hide
        Willem Jiang added a comment - - edited

        Hi Charles,

        I just wrote a simple test case by using the jms transport as you did. I can reproduce the error when I use the JMS URI or not.
        It looks like there are something wrong with the jms continuation which the cxf consumer is used by default.
        You can work around it by using the synchronous=true on the camel-cxf endpoint like this

        from("cxf:bean:jmsEndpoint?synchronous=true")...
        

        I will keep on digging that.

        Willem

        Show
        Willem Jiang added a comment - - edited Hi Charles, I just wrote a simple test case by using the jms transport as you did. I can reproduce the error when I use the JMS URI or not. It looks like there are something wrong with the jms continuation which the cxf consumer is used by default. You can work around it by using the synchronous=true on the camel-cxf endpoint like this from( "cxf:bean:jmsEndpoint?synchronous= true " )... I will keep on digging that. Willem
        Hide
        Willem Jiang added a comment -

        The JMSContinuation doesn't support to be called suspend and consume at the same thread. It is in the old design of cxf 2.2.x, which means you cannot called continuation suspend method before you setup the callback when continuation is ready.
        Before I find a way to enhance the feature from CXF side, we should not support to use JMSContinuation anymore. I will commit the code to let CxfConsumer switch to sync invocation mode when it find the JMSContinuation is used.

        Show
        Willem Jiang added a comment - The JMSContinuation doesn't support to be called suspend and consume at the same thread. It is in the old design of cxf 2.2.x, which means you cannot called continuation suspend method before you setup the callback when continuation is ready. Before I find a way to enhance the feature from CXF side, we should not support to use JMSContinuation anymore. I will commit the code to let CxfConsumer switch to sync invocation mode when it find the JMSContinuation is used.
        Hide
        Charles Moulliard added a comment -

        Hi Willem,

        Thx. Do you mean that until now SOAP over JMS should not be used anymore (till next change) and we use by example this camel route to support same feature ?

        from("jms:queue:input").setExchangePattern(ExchangePattern.InOnly).unmarshal(soap).to("bean:callBackend").marshal(soap).to("jms:queue.replyQueue);
        
        Show
        Charles Moulliard added a comment - Hi Willem, Thx. Do you mean that until now SOAP over JMS should not be used anymore (till next change) and we use by example this camel route to support same feature ? from( "jms:queue:input" ).setExchangePattern(ExchangePattern.InOnly).unmarshal(soap).to( "bean:callBackend" ).marshal(soap).to("jms:queue.replyQueue);
        Hide
        Willem Jiang added a comment -

        Hi Charles,

        You can keep use the SOAP over JMS by setting the option of synchronous=true, it will force the cxf consumer use the sync invocation to wrok around the issue that we meet.

        I just want to say we can not use JMSContinuation which is key point to camel-cxf async invocation any more before we find a good solution in CXF.

        Show
        Willem Jiang added a comment - Hi Charles, You can keep use the SOAP over JMS by setting the option of synchronous=true, it will force the cxf consumer use the sync invocation to wrok around the issue that we meet. I just want to say we can not use JMSContinuation which is key point to camel-cxf async invocation any more before we find a good solution in CXF.

          People

          • Assignee:
            Willem Jiang
            Reporter:
            Charles Moulliard
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development