How to enrich a node value in OM property? - wso2

Is it possible to enrich a specific node value with enrich mediator?
My goal is to enrich this xpath:
$ctx:OriginalPayload//Partner[identifiers/businessId = $ctx:CorrelationId]/identifiers/otherId
I have tried these examples:
$ctx:OriginalPayload//Partner/identifiers/otherId
//Partner/identifiers/otherId
//Partner/identifiers/otherId/text()
//Partner/identifiers/otherId/node()
All gave me this error:
ERROR - EnrichMediator Invalid Target object to be enrich.
I'm using this syntax:
<enrich>
<source xpath="//plat:CustomerAccountId"/>
<target xpath="//Partner/identifiers/otherId"/>
</enrich>
Below is my payload which i'm trying to enrich:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://iszkody.lsn.io/service/internal/ClaimService">
<soapenv:Header/>
<soapenv:Body>
<ns0:createClaimRequest>
<claim>
<InsClaimData VER="1">
<PartnerList>
<Partner>
<RoleList>
<Role>UBEZP</Role>
</RoleList>
<BusinessPartner>
<partnerType>person</partnerType>
<personData>
<firstName>JANUSZ</firstName>
<lastName>KOWALSKI</lastName>
<PESEL>83248328432</PESEL>
</personData>
<identifiers>
<businessId>123</businessId>
<otherId></otherId>
</identifiers>
</BusinessPartner>
</Partner>
</PartnerList>
</InsClaimData>
</claim>
</ns0:createClaimRequest>
</soapenv:Body>
</soapenv:Envelope>
It doesn't look like a problem with payload or xpath but more like the mediator doesn't implement custom type.

I just tested the following in WSO2 ESB 4.9.0 and also 4.8.1 and in both version the following proxy did work (I enrichted the otherId with the businessId):
<proxy xmlns="http://ws.apache.org/ns/synapse" name="Test_XPath" transports="http" xmlns:avintis="http://www.avintis.com">
<target faultSequence="faultSequence">
<inSequence>
<sequence key="initSequence" />
<log level="full"></log>
<log level="custom">
<property expression="$body//businessId" name="xpath" />
</log>
<log level="custom">
<property expression="$body//Partner/BusinessPartner/identifiers/businessId" name="xpath" />
</log>
<enrich>
<source xpath="//businessId" />
<target xpath="//otherId" />
</enrich>
<log level="full" />
</inSequence>
</target>
</proxy>
As you commented that you now use the *[local-name()='BusinessPartner'] syntax, this points out to be an issue with the namespaces. Try to use the correct namespace of the BusinessParter elements.

Related

WS02 Enrich mediator after end point call

I'm trying to use enrichment mediator to populate custom response from End point
my sequence
<sequence name="GetMySqlData" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<enrich description="AddProductData">
<source clone="true" type="inline">
<ProductDataMySqlDB xmlns="">
<code/>
<name/>
<description/>
<qty/>
</ProductDataMySqlDB>
</source>
<target action="child" xpath="//mediate"/>
</enrich>
<property expression="$ctx:ProductCode" name="code" scope="default" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:dat="http://ws.wso2.org/dataservice" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<dat:getInventoryByCode>
<dat:code>$1</dat:code>
</dat:getInventoryByCode>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('code')"/>
</args>
</payloadFactory>
<property name="HTTP_METHOD" scope="axis2" type="STRING" value="POST"/>
<property name="SOAPAction" scope="transport" type="STRING" value="getInventoryByCode"/>
<call>
<endpoint key="getInventoryByCode"/>
</call>
--PROBLEMS STARTS ---
<enrich description="code">
<source clone="true" xpath="//Entry/code"/>
<target xpath="//mediate/ProductDataMySqlDB/code"/>
</enrich>
<enrich description="name">
<source clone="true" xpath="//Body/Entries/Entry/name"/>
<target xpath="//mediate/ProductDataMySqlDB/name"/>
</enrich>
<enrich description="description">
<source clone="true" xpath="//Entries/Entry/description" />
<target xpath="//mediate/ProductDataMySqlDB/description"/>
</enrich>
<enrich description="qty">
<source clone="true" xpath="//m0:Entries/m0:Entry/m0:qty" xmlns:m0="http://ws.wso2.org/dataservice" />
<target xpath="//mediate/ProductDataMySqlDB/qty"/>
</enrich>
<log level="full">
<property expression="$body" name="MySQLResponse"/>
</log>
<loopback/>
</sequence>
response that I getting form endpoint is like
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<Entries xmlns="http://ws.wso2.org/dataservice">
<Entry>
<code>PR2</code>
<name>Product2</name>
<description>Product stored in MySQL</description>
<qty>-2</qty>
</Entry>
</Entries>
</soapenv:Body>
</soapenv:Envelope>
and the error in log are :
Specified node by xpath cannot be found. {org.apache.synapse.mediators.elementary.EnrichMediator}
Cannot Enrich message from an empty source. {org.apache.synapse.mediators.elementary.EnrichMediator}
so it looks like the xpath for my source is wrong
<enrich description="code">
<source clone="true" xpath="WHAT WOULD BE THE CORRECT PATH?"/>
<target xpath="//mediate/ProductDataMySqlDB/code"/>
</enrich>
thnks
In your message, 'Entry' and 'code' nodes belongs to a namespace "http://ws.wso2.org/dataservice" (look at the 'Entries' root node) : you should declare and use this namespace in your source xpath :
<source xmlns:ds="http://ws.wso2.org/dataservice" clone="true" xpath="//ds:Entry/ds:code"/>

wso2esb iterate throught wso2dss result

I want to write next target sequence of actions:
1. call DSS to receive a list of customers
2. enrich each customer's by separate call another DSS service.
So, I thought I should call callout mediator and then iterate it's result using iterator. But I can't understand what should I write in the iterator.
And another question - am I right, that the result of each iteration will be attached under the 'customer' tag?
Details:
XML which returned from DSS is next:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<customers xmlns="crm.crm.crm">
<customer>
<customerId>1</customerId>
<name>Customer #1</name>
<birthdate>2017-01-15T14:54:12.000+03:00</birthdate>
</customer>
</customers>
</soapenv:Body>
</soapenv:Envelope>
Sequence:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="BatchSequence" statistics="enable" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<log description="">
<property name="text" value="Start batch seq"/>
</log>
<payloadFactory description="create dss request" media-type="xml">
<format>
<soapenv:Envelope xmlns:crm="crm.crm.crm" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<crm:getCustomers>
<crm:batchSize>3</crm:batchSize>
</crm:getCustomers>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args/>
</payloadFactory>
<callout action="urn:getCustomers" description="dss: main object" initAxis2ClientOptions="false" serviceURL="http://192.168.3.32:9765/services/CrmDataService?wsdl">
<source type="envelope"/>
<target key="customers"/>
</callout>
<log description="">
<property expression="get-property('customers')" name="text"/>
</log>
<iterate description="Enrich customers" expression="/soapenv:Envelope/soapenv:Body/customers/customer" id="iterateId" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<target>
<sequence>
<property description="customerId" expression="/customerId" name="customerID" scope="default" type="STRING"/>
<log description="">
<property expression="get-property('customerID')" name="text"/>
</log>
</sequence>
</target>
</iterate>
<log description="">
<property name="text" value="End batch seq"/>
</log>
</sequence>
output:
[2017-01-27 10:17:17,371] INFO - LogMediator To: , MessageID: urn:uuid:d628e361-beb8-4c26-b06d-3901227ad76a, Direction: request, text = Start batch seq
[2017-01-27 10:17:18,558] INFO - LogMediator To: , MessageID: urn:uuid:d628e361-beb8-4c26-b06d-3901227ad76a, Direction: request, text = 1Customer #12017-01-15T14:54:12.000+03:002Customer #22016-12-16T14:54:20.000+03:003Customer #32016-10-27T14:54:21.000+03:00
[2017-01-27 10:17:18,559] WARN - RuntimeStatisticCollector Events occur after event collection is finished, event - urn_uuid_d628e361-beb8-4c26-b06d-3901227ad7
6a231160071781262
Update 1
Some working code. Not sure that this is correct, because I'm a little bit confusing for a PayloadFactory here..
<payloadFactory description="" media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>$1</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="get-property('customers')"/>
</args>
</payloadFactory>
<iterate continueParent="true" description="" expression="$body/crm:customers/crm:customer" sequential="true" xmlns:crm="crm.crm.crm">
<target>
<sequence>
<property expression="//crm:customerId" name="customerID" scope="default" type="STRING"/>
<log>
<property expression="get-property('customerID')" name="text"/>
</log>
</sequence>
</target>
</iterate>
Update 2
I figured a main problem - callout mediator doesnt' put response to the envelope context(if I understand right). So, we can't use just property to link it with iterator, so, in this case we should link them using smth like Payload factory. Not very usifull
If smbdy knows how to do it more simple(dirrect passing property to the iterator) - pls write to me.
Solution - to use Call medator. Works fine.
thanks to all!
xml nodes in the dss response belongs to a namespace "crm.crm.crm" and you must refer it in your xpath
with iterate mediatior, if you want to preserve source payload, you must use an attribute named preservePayload="true" and tell where the xml framents must be attached with the attribute attachPath ortherwise, inside interate's sequence, you will only have your xml fragment in the soap body
This is a sample that works without preserving source payload :
<iterate xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:crm="crm.crm.crm" expression="$body/crm:customers/crm:customer" id="iterateId">
<target>
<sequence>
<property expression="$body/crm:customer/crm:customerId" name="customerID" scope="default" type="STRING"/>
<log>
<property expression="get-property('customerID')" name="text"/>
</log>
</sequence>
</target>
</iterate>
By default, mediators after iterate will not be executed. If you want to continue the mediation, use attribute continueParent="true"

wso2/synapse service chaining: assign response from SOAP request as intput to another request

My desired sequence is the following:
Read message from queue
Transform
Make an SOAP call
Output SOAP response to another queue
Steps 1,2,3 work fine but when the message sent in Step 4, that I'm intending to contain the SOAP response, is empty. What am I doing wrong?
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="JmsToWsdlJms" transports="https,http,jms" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<enrich>
<source type="body" clone="true"/>
<target type="property" property="jms_body_text"/>
</enrich>
<property name="jms_body_text"
expression="get-property('jms_body_text')"
scope="default"/>
<xslt key="jmsMsgToSoapMsg_xslt">
<property name="jms_text" expression="get-property('jms_body_text')"/>
</xslt>
<log level="full">
<property name="After transformation" value="****"/>
</log>
<send>
<endpoint key="axisStockQuote"/>
</send>
<log level="full">
<property name="After callout" value="****"/>
</log>
<property name="OUT_ONLY" value="true"/>
<send>
<endpoint key="jmsQueue2"/>
</send>
</inSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>text/plain; charset=ISO-8859-1</default>
</rules>
</parameter>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">cn=tro_Q_JMS1</parameter>
</proxy>
You can use 'send receive' instead of the send mediator. Something like,
<send receive="jmsQueue2Sequence">
<endpoint key="axisStockQuote"/>
</send>
So that the response of axisStockQuote will be sent to the jmsQueue2Sequence. Refer [1] for more info.
[1] https://docs.wso2.com/display/ESB481/Send+Mediator

Converting a SOAP request to a HTTP 200 return on wsO2 ESB

I have a instance where I need to implement a proxy service that takes a SOAP message, forwards it to an internal system (SOAP) and returns a HTTP 200 response to the original server.
Basically the response should be completely void of any soap detail (there's technically no output message in the WSDL that I have to implement).
Here's what I have so far (which simply takes the request & echos it back as the response):
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="ExampleHttp200Return"
transports="http"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log level="full" separator=", - inSequence: received - "/>
<header name="To" action="remove"/>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="SC_ACCEPTED" value="false" scope="axis2"/>
<property name="HTTP_SC" value="200" scope="axis2"/>
<send/>
</inSequence>
</target>
<description/>
</proxy>
If you want to send back an empty response, you can add that before send mediator :
<property name="messageType" scope="axis2" value="text/plain"/>
<enrich>
<source type="inline">
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
<soapenv:Header/>
<soapenv:Body>
<text xmlns="http://ws.apache.org/commons/ns/payload"/>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>

WSO2 ESB - JMS response from endpoint with XML payload shows up as Text

I am using WSO2 ESB to send a JMS message (XML payload) to an endpoint and then to read a return JMS message (on another queue) from the same endpoint (which also sends an XML payload). The problem I am facing is that the return JMS message from the endpoint, even though it is an XML payload, comes in as a text message.
Here is what I see in WSO2 for the JMS message (with XML payload) sent back by the endpoint:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<axis2ns2:text xmlns:axis2ns2="http://ws.apache.org/commons/ns/payload">
<?xml version="1.0" encoding="UTF-8"?>
<Sys1Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Sys1-ack-nack.xsd">
<security>
<statusInfo>
<ARMStatus>ARM_ACK</ARMStatus>
<Sys1Status>Sys1_ACK</Sys1Status>
<FinalStatus>ACK</FinalStatus>
</statusInfo>
<upstreamIdentifier>
<tradeId>459609</tradeId>
<messageId>12345678</messageId>
<assetId>6M2</assetId>
<issueDescription>IRS RTP 3.12 19MAY11 JP</issueDescription>
<productType>SWAPTION</productType>
</upstreamIdentifier>
</security>
</Sys1Response>
</axis2ns2:text>
</soapenv:Body>
</soapenv:Envelope>
This is the WSO2 proxy definition.
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.ESBRegistry">
<parameter name="localRegistry">/</parameter>
<parameter name="cachableDuration">15000</parameter>
</registry>
<proxy name="ToWSO2"
transports="jms"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<property name="transport.jms.ContentTypeProperty"
value="Content-Type"
scope="axis2"/>
<log level="full"/>
<call>
<endpoint>
<address uri="jms:/ToSys1?transport.jms.ConnectionFactoryJNDIName=QueueConnectionFactory&java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory&java.naming.provider.url=tcp://localhost:61616&transport.jms.DestinationType=queue&transport.jms.ReplyDestinationType=queue&transport.jms.ReplyDestination=FromSys1&transport.jms.ContentType=application/xml"/>
</endpoint>
</call>
<log level="full"/>
</inSequence>
<outSequence>
<log level="full"/>
<drop/>
</outSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.Destination">ToWSO2</parameter>
</proxy>
<sequence name="fault">
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
</log>
<drop/>
</sequence>
<sequence name="main">
<in>
<log level="full"/>
<filter source="get-property('To')" regex="http://localhost:9000.*">
<send/>
</filter>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
</definitions>
Would appreciate help in resolving this. Many thanks in advance!