Announcement Announcement Module
Collapse
No announcement yet.
spring intergration - xpath transformer Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • spring intergration - xpath transformer

    Hi,
    I am trying to think what could be best solution to implement for below requirement....
    1. I need to read the incoming request payload which would have a attribute called version <soapenv:Header/>
    <soapenv:Body><v1:TestQueryRequest version="1.0">........</v1:TestQueryRequest> </soapenv:Body>
    </soapenv:Envelope>
    2. I need to read this value of version from the request message and then depending on the value i need to call a different router classes may be which would route this message to the endpoint. If the version is 1.0 i need to use different set of JAXB classes which are generated from V1.0 schema and so on for 2.0 or 3.0 ....

    I hope i am able to put my question correctly........

    Thanks, anyhelp or advice is appreciated.

  • #2
    I suggest you read the XML section of the reference manual.

    Most likely you'd need to use an XPath Router, and route to an appropriate unmarshalling transformer.

    Comment


    • #3
      Thank you, Let me go throught it and give it a shot. Will reach out to you in case of any problems. Thanks again,

      Comment


      • #4
        Hi,
        I tried to develop a solution today and i am facing below problem, Please help or advice.

        Error:- WARN - WebContainer : 0 - org.springframework.integration.gateway.MessagingG atewaySupport doSendAndReceive - failure occurred in gateway sendAndReceive
        org.springframework.integration.MessageDeliveryExc eption: no channel resolved by router and no default output channel defined

        Question:-I see the request payload hits the inbound gateway as well xpath router but seems like its not able to resolve the channel through the mapping i have implemented, Not sure if this is right way to do it...Could you please let me know what is the wrong thing i am doing here...

        Requirement:
        1. I need to grab the version value from message "paymentQueryRequest" Ex: 2.0.
        2. Based on the version i need to pass it to appropriate router class and method where i need to execute a some logic before i set the outbound service channel.
        3. Also i need to do unmarshalling before the control goes into router class/method so i can read the value of XML through JAXB classes.


        Code snippet:-
        Code:
           	<int-ws:inbound-gateway id="paymentQueryServiceGateway"
        		request-channel="paymentQueryRequestChannel" reply-channel="paymentQueryReplyChannel" />
        
        	<int:chain input-channel="paymentQueryRequestChannel" >
        	<int-xml:xpath-router resolution-required="false" xpath-expression-ref="channelIdentifier">	
        			<int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel"/>
        			<int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel"/>		
        	</int-xml:xpath-router>		
        	</int:chain>
        
        	<int-xml:xpath-expression id="channelIdentifier" expression=".//*[local-name()='PaymentQueryRequest']/@version"> 
        	</int-xml:xpath-expression>
        
        	<int:chain input-channel="paymentV1QueryRequestChannel" >
        		<int-xml:unmarshalling-transformer id="queryV1Unmarshaller" unmarshaller="queryMarshaller-v1.0"/>	
        		<int:router ref="routerForV1PaymentQueryBasedOnService" method="routePaymentQueryRequest"/>	
        	</int:chain>
        	
        	<int:chain input-channel="paymentV2QueryRequestChannel" >
        		<int-xml:unmarshalling-transformer id="queryV2Unmarshaller" unmarshaller="queryMarshaller-v2.0"/>	
        		<int:router ref="routerForV2PaymentQueryBasedOnService" method="routePaymentQueryRequest"/>	
        	</int:chain>			
        
        	<!-- channel defined -->
        	<int:channel id="paymentQueryRequestChannel" />	
        	<int:channel id="paymentQueryReplyChannel" />
        	<int:channel id="paymentV1QueryRequestChannel" />	
        	<int:channel id="paymentV2QueryRequestChannel" />
        
        Request payload:-
              <v2:paymentQueryRequest version="2.0">
              .............data elements...
              </v2:paymentQueryRequest>
        Any help or advice is appreciated. Thanks a lot,
        Last edited by Gary Russell; Aug 28th, 2013, 03:32 PM.

        Comment


        • #5
          does your XML doc declare any namespaces?

          Comment


          • #6
            Yes The request envelope would be
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:v1="http://www.abc.com/schemas/xyz/api/query/v1.0">

            OR
            <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
            xmlns:v2="http://www.abc.com/schemas/xyz/api/query/v2.0">
            The only change would be the version number....

            Before i posted this thread i tried using below attributes of xpath-expression but i got some kind of compile time error and then i removed it.
            ns-prefix="query" ns-uri="http://www.abc.com/schemas/xyz/api/query"

            Please suggest the correct way to use this if this is what is missing on my side...

            Thanks for the help
            Last edited by JeevanSpring; Aug 29th, 2013, 08:03 AM.

            Comment


            • #7
              Hi there, I thought the problem could be because of namespace and tried some things to mention few of them are below along with error, please advice. thanks in advance.

              Soultion 1:
              <!-- in this example it was suggested online that if i dont want to use namespaces then i can use local-name() funtion... -->
              <int-xml:xpath-router id="paymentQueryRouter" input-channel="paymentQueryRequestChannel" >
              <int-xml:xpath-expression id="entXpathExpression" expression="/*[local-name()='paymentQueryRequest']/@version">
              </int-xml:xpath-expression>
              <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel" />
              <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel" />
              </int-xml:xpath-router>

              Error - The following error occurred: no channel resolved by router and no default output channel defined

              Solution 2:
              <int-xml:xpath-router id="paymentQueryRouter" input-channel="paymentQueryRequestChannel" >
              <int-xml:xpath-expression id="entXpathExpression" expression="/paymentQueryRequest/@version">
              <!--Declared map of namespaces -->
              <map>
              <entry key="v1" value="http://www.abc.com/schemas/xyz/api/query/v1.0"/>
              <entry key="v2" value="http://www.abc.com/schemas/xyz/api/query/v2.0"/>
              </map>
              </int-xml:xpath-expression>
              <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel" />
              <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel" />
              </int-xml:xpath-router>
              Error: The following error occurred: no channel resolved by router and no default output channel defined

              Comment


              • #8
                I am preety sure now that the root cause is related to the namespace, i tested below xpath expressions through standalone program without having namespaces in my xml document and it gives me the values...
                XpathExpression: /EntitlementQueryRequest/@version
                Result=> 2.0

                However i need to get the same result using below xml document with dynamic namespaces, Please help or advice...

                <soapenv:Envelope
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:v2="http://www.abc.com/schemas/xyz/api/query/v2.0">
                <soapenv:Header/>
                <soapenv:Body>
                <v2:PaymentQueryRequest version="2.0">
                <!-- Data Elements go here-------->
                </v2:PaymentQueryRequest>
                </soapenv:Body>
                </soapenv:Envelope>

                One other issue i can't hard code the namespace since i might get different namespace as well for example:
                xmlns:v1="http://www.abc.com/schemas/xyz/api/query/v1.0
                xmlns:v2="http://www.abc.com/schemas/xyz/api/query/v2.0
                and the root element as v1:PaymentQueryRequest OR v2:PaymentQueryRequest

                Appreciate your help.

                Comment


                • #9
                  I just had a similar problem for a demo I am setting up, and this worked fine for me...

                  Code:
                  <int:chain input-channel="viaWebService">
                  	<int:transformer 
                  	   expression="'&lt;FahrenheitToCelsius xmlns=''http://tempuri.org/''&gt;&lt;Fahrenheit&gt;XXX&lt;/Fahrenheit&gt;&lt;/FahrenheitToCelsius&gt;'.replace('XXX', payload.toString())" />
                  	<int-ws:header-enricher>
                  		<int-ws:soap-action value="http://tempuri.org/FahrenheitToCelsius"/>
                  	</int-ws:header-enricher>
                  	<int-ws:outbound-gateway uri="http://www.w3schools.com/webservices/tempconvert.asmx"/>
                  	<int-xml:xpath-transformer  
                  		xpath-expression="/*[local-name()='FahrenheitToCelsiusResponse']/*[local-name()='FahrenheitToCelsiusResult']"/>
                  </int:chain>

                  Comment


                  • #10
                    The fahrenheit to celsius server returns this document
                    <?xml version="1.0" encoding="UTF-8"?><FahrenheitToCelsiusResponse xmlns="http://tempuri.org/"><FahrenheitToCelsiusResult>32.2222222222222</FahrenheitToCelsiusResult></FahrenheitToCelsiusResponse>
                    and I was able to extract the value using

                    <int-xml:xpath-transformer
                    xpath-expression="/*[local-name()='FahrenheitToCelsiusResponse']/*[local-name()='FahrenheitToCelsiusResult']"/>

                    Comment


                    • #11
                      Thanks,

                      Now i think its no more a namespace issue and something to do with routing and resolving the channel name, I tired below code and it didn't work, please advice.

                      Code:
                      <int-xml:xpath-router id="paymentQueryByVersionRouter" input-channel="paymentQueryRequestChannel" evaluate-as-string="true" ignore-send-failures="true">
                      <!-- I also tried with ignore-send-failures="false" and i get the same error as per the other thread at http://forum.springsource.org/showth...output-channel -->
                      <int-xml:xpath-expression expression="/*[local-name()='paymentQueryRequest']/@version"> </int-xml:xpath-expression>
                      <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel"/>
                      <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel"/>
                      </int-xml:xpath-router>


                      Error -No bean named '' is defined
                      StackTrace- Caused by: org.springframework.integration.support.channel.Ch annelResolutionException: failed to look up MessageChannel bean with name ''
                      at org.springframework.integration.support.channel.Be anFactoryChannelResolver.resolveChannelName(BeanFa ctoryChannelResolver.java:75)
                      at org.springframework.integration.router.AbstractMap pingMessageRouter.resolveChannelForName(AbstractMa ppingMessageRouter.java:164)

                      Thanks very much,

                      Comment


                      • #12
                        Thanks,

                        if i am not mistaken i think its no more a namespace issue now and something to do with routing and resolving the

                        channel name, I tired below code and it didn't work, please advice.

                        In the below code I also tried with ignore-send-failures="false" and i get the same error, i reffered to http://forum.springsource.org/showth...output-channel.

                        Code:
                        <int-xml:xpath-router id="paymentQueryByVersionRouter" input-channel="paymentQueryRequestChannel"

                        evaluate-as-string="true" ignore-send-failures="true">

                        <int-xml:xpath-expression expression="/*[local-name()='paymentQueryRequest']/@version">

                        </int-xml:xpath-expression>
                        <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel"/>
                        <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel"/>
                        </int-xml:xpath-router>


                        Error -No bean named '' is defined
                        StackTrace- Caused by: org.springframework.integration.support.channel.Ch annelResolutionException: failed to look up

                        MessageChannel bean with name ''
                        at

                        org.springframework.integration.support.channel.Be anFactoryChannelResolver.resolveChannelName(BeanFa ctoryChannelResolver

                        .java:75)
                        at

                        org.springframework.integration.router.AbstractMap pingMessageRouter.resolveChannelForName(AbstractMa ppingMessageRouter.j

                        ava:164)

                        Thanks very much,

                        Comment


                        • #13
                          Thanks,

                          Now i think its no more a namespace issue and something to do with routing and resolving the channel name, I tired below code and it didn't work, please advice.

                          Code:
                          <int-xml:xpath-router id="paymentQueryByVersionRouter" input-channel="paymentQueryRequestChannel" evaluate-as-string="true" ignore-send-failures="true">
                          <!-- I also tried with ignore-send-failures="false" and i get the same error as per the other thread at http://forum.springsource.org/showth...output-channel -->
                          <int-xml:xpath-expression expression="/*[local-name()='paymentQueryRequest']/@version"> </int-xml:xpath-expression>
                          <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel"/>
                          <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel"/>
                          </int-xml:xpath-router>


                          Error -No bean named '' is defined
                          StackTrace- Caused by: org.springframework.integration.support.channel.Ch annelResolutionException: failed to look up MessageChannel bean with name ''
                          at org.springframework.integration.support.channel.Be anFactoryChannelResolver.resolveChannelName(BeanFa ctoryChannelResolver.java:75)
                          at org.springframework.integration.router.AbstractMap pingMessageRouter.resolveChannelForName(AbstractMa ppingMessageRouter.java:164)

                          Thanks very much,

                          Comment


                          • #14
                            Please advice as i tried below code snippet and it didn't work....

                            <int-xml:xpath-router input-channel="paymentQueryRequestChannel" resolution-required="false"
                            xpath-expression-ref="xPathIdentifier">
                            <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel"/>
                            <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel"/>
                            </int-xml:xpath-router>

                            <int-xml:xpath-expression id="xPathIdentifier"
                            expression="/*[local-name()='paymentQueryRequest']/@version"> </int-xml:xpath-expression>

                            Thanks a lot

                            Comment


                            • #15
                              Please advice as i am getting below Error - no channel resolved by router and no default output channel defined
                              Stack Trace- WARN - WebContainer : 1 - org.springframework.integration.gateway.MessagingG atewaySupport doSendAndReceive - failure occurred in gateway sendAndReceive
                              org.springframework.integration.MessageDeliveryExc eption: no channel resolved by router and no default output channel defined
                              at org.springframework.integration.router.AbstractMes sageRouter.handleMessageInternal(AbstractMessageRo uter.java:148)
                              at org.springframework.integration.handler.AbstractMe ssageHandler.handleMessage(AbstractMessageHandler. java:73)
                              at org.springframework.integration.dispatcher.Unicast ingDispatcher.doDispatch(UnicastingDispatcher.java :115)
                              at org.springframework.integration.dispatcher.Unicast ingDispatcher.dispatch(UnicastingDispatcher.java:1 02)
                              at org.springframework.integration.channel.AbstractSu bscribableChannel.doSend(AbstractSubscribableChann el.java:77)

                              <int-xml:xpath-router input-channel="paymentQueryRequestChannel" resolution-required="false" xpath-expression-ref="xPathIdentifier">
                              <int-xml:mapping value="1.0" channel="paymentV1QueryRequestChannel"/>
                              <int-xml:mapping value="2.0" channel="paymentV2QueryRequestChannel"/>
                              </int-xml:xpath-router>

                              <int-xml:xpath-expression id="xPathIdentifier"
                              expression="/*[local-name()='paymentQueryRequest']/@version"> </int-xml:xpath-expression>

                              Thanks,

                              Comment

                              Working...
                              X