Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8321

How to store the external webservice response value in a flow variable using Enricher

I am stuck with a minor issue .. There is My Mule flow .. I am passing a SOAP payload to an external webservice from a Message Enricher component and the Idea is to get a particular attribute value from the external webservice response and store that value in a flow variable ... Now, the response of the external webservice response is as follow :-

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <getDesignationResponse xmlns="http://services.test.getDesignation.com/schema/MainData/V1">
         <DesignationCodeResult>Junior Developer</DesignationCodeResult>
         <Code>Success</Code>
      </getDesignationResponse>
   </soap:Body>
</soap:Envelope> 

Now here is my flow :-

 <flow name="testFlow1" doc:name="testFlow1">
   <http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="test" doc:name="HTTP"/>

<set-payload value="<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://services.test.getDesignation.com/schema/MainData/V1"><soapenv:Header/><soapenv:Body><v1:getDesignationRequest><v1:DesignationCode>jd</v1:DesignationCode></v1:getDesignationRequest></soapenv:Body></soapenv:Envelope>" doc:name="Set Payload"/>

  <enricher source="#[xpath://getDesignationResponse/DesignationCodeResult]" target="#[variable:myVal]" doc:name="Message Enricher">
  <processor-chain doc:name="Processor Chain">
    <http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8090/designation" responseTimeout="100000" doc:name="HTTP" />
    <mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>

     <logger message="Value from response #[xpath://getDesignationResponse/DesignationCodeResult]" level="INFO" doc:name="Logger"/>
   </processor-chain>           
</enricher> 

</flow>

Now you can see I am trying to store the value #[xpath://getDesignationResponse/DesignationCodeResult] to the Flow Variable myVal ..

Now I am getting following exception :-

Exception stack is:
1. Expression Evaluator "header" with expression "invocation:myVal" returned null but a value was required. (org.mule.api.expression.RequiredValueException)
  org.mule.expression.ExpressionUtils:235 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/RequiredValueException.html)
2. Expression Evaluator "header" with expression "invocation:myVal" returned null but a value was required. (org.mule.api.expression.RequiredValueException). Message payload is of type: String (org.mule.api.MessagingException)
  org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor:32 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/MessagingException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.mule.api.expression.RequiredValueException: Expression Evaluator "header" with expression "invocation:myVal" returned null but a value was required.
    at org.mule.expression.ExpressionUtils.getPropertyInternal(ExpressionUtils.java:235)
    at org.mule.expression.ExpressionUtils.getProperty(ExpressionUtils.java:85)
    at org.mule.expression.ExpressionUtils.getProperty(ExpressionUtils.java:72)
    + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************

But I have put a logger inside the Enricher <logger message="Value from response #[xpath://getDesignationResponse/DesignationCodeResult]" level="INFO" doc:name="Logger"/> and I am getting the value there .. But I am unable to assign the extracted value in the Flow Variable using Enricher ... Please help ..

Upvotes: 0

Views: 1198

Answers (3)

Anirban Sen Chowdhary
Anirban Sen Chowdhary

Reputation: 8321

So, As per David's suggestion , the solution is to correct the namespace issue , and the working code is :-

<mulexml:namespace-manager>
    <mulexml:namespace prefix="soapenv" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
    <mulexml:namespace prefix="vertu" uri="http://services.vertu.getDesignation.com/schema/MainData/V1"/>
</mulexml:namespace-manager>

Upvotes: 0

David Dossot
David Dossot

Reputation: 33413

First add namespace support:

<mulexml:namespace-manager>
    <mulexml:namespace prefix="soapenv" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
    <mulexml:namespace prefix="vertu" uri="http://services.vertu.getDesignation.com/schema/MainData/V1"/>
</mulexml:namespace-manager>

Then stop using the old deprecated expression syntax and use MEL instead:

<enricher
    source="#[xpath('//vertu:getDesignationResponse/vertu:DesignationCodeResult/text()').text]"
    target="#[flowVars['myVal']]">

Also if you want to keep the logger, add an object-to-string-transformer after the inbound HTTP endpoint in order to deserialize the response input stream to a String, which would be readable multiple times.

Upvotes: 0

user1760178
user1760178

Reputation: 6697

From the post if can be seen that the Response being posted has a namespace

xmlns="http://services.test.getDesignation.com/schema/MainData/V1"

The namespace http://services.test.getDesignation.com/schema/MainData/V1 should be registered in your mule config XML namespace manager.

Then the xpath will be able to recognize the xml element from the response properly

Updated answer based on the comment:

Try the following modified enricher part of your flow.

<enricher source="#[payload]" target="#[variable:myVal]" doc:name="Message Enricher">
    <processor-chain doc:name="Processor Chain">
    <http:outbound-endpoint exchange-pattern="request-response" method="POST" address="http://localhost:8090/designation" responseTimeout="100000" doc:name="HTTP" />
    <mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>
    <logger message="Value from response #[xpath://getDesignationResponse/DesignationCodeResult]" level="INFO" doc:name="Logger"/>
     <set-payload value="#[xpath://getDesignationResponse/DesignationCodeResult]" />
              </processor-chain>           
</enricher>

Hope this helps.

Upvotes: 1

Related Questions