In WSO2 ESB, I have created an rest API. This API needs to connect to two different services, and combine the results.
For this, I use an API, with in de insequence a clone mediator that sends out the appropriate messages. This works fine.
In the outsequence, I use a logger to see the incoming messages. Both are json and come back ok. I then want to use an aggregate mediator to combine the two. With this, I have two issues:
when using a rootElementProperty to place the two items under one parent, a NPE happens,
when using enrich mediators or whatever else to make a correct message, and ending with send, the resulting message is never sent back.
What can be the cause of this?
This is the actual API:
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="Cale-StreetsAPI" context="/Cale-StreetsAPI">
<resource methods="GET" uri-template="/getStreets?lat={lat}&lon={lon}&radius={radius}">
<inSequence>
<property name="aggRoot" scope="default">
<red:jsonObject xmlns:red="redora"/>
</property>
<log description="">
<property name="lat" expression="get-property('uri.var.lat')"/>
<property name="lon" expression="get-property('uri.var.lon')"/>
<property name="radius" expression="get-property('uri.var.radius')"/>
</log>
<clone continueParent="true" id="deCartaStreets">
<target>
<sequence>
<sequence key="DeCartaDDS"/>
</sequence>
</target>
<target>
<sequence>
<sequence key="DeCartaReverseGeo"/>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<property name="messageType" value="application/xml" scope="axis2" type="STRING" description="messageType"/>
<log level="full" description="">
<property name="WSANSWER" value="true"/>
</log>
<aggregate>
<completeCondition>
<messageCount min="2" max="-1"/>
</completeCondition>
<onComplete expression="$body/jsonObject">
<enrich>
<source clone="true" xpath="$body//jsonObject"/>
<target type="property" property="ResultItems"/>
</enrich>
<log level="custom">
<property name="ResultItems" expression="get-property('ResultItems')"/>
</log>
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<JsonResponse xmlns="dummy"/>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<enrich>
<source type="property" clone="true" property="ResultItems"/>
<target xmlns:red="dummy" action="child" xpath="//red:JsonResponse"/>
</enrich>
<log level="full" description="">
<property name="AGGREGATE_END" value="true"/>
</log>
<property name="messageType" value="application/json" scope="axis2" type="STRING" description="messageType"/>
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence>
<log level="full" category="WARN"/>
</faultSequence>
</resource>
</api>
I faced the same problem you did. According to number of posts over Internet APIs doesn't support aggregation.
So my solution was to introduce aggregating Proxy service which did all the job where API just made a call to that proxy service.
So if you modify your solution as follows you should be able to achieve what you expect:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="AggregatingProxy" transports="local https http" startOnLoad="true" trace="disable">
<target>
<inSequence>
<log level="full"/>
<property name="enclosing_element">
<result xmlns=""/>
</property>
<clone continueParent="true">
<property name="aggRoot" scope="default">
<red:jsonObject xmlns:red="redora"/>
</property>
<log description="">
<property name="lat" expression="get-property('uri.var.lat')"/>
<property name="lon" expression="get-property('uri.var.lon')"/>
<property name="radius" expression="get-property('uri.var.radius')"/>
</log>
<clone continueParent="true" id="deCartaStreets">
<target>
<sequence>
<sequence key="DeCartaDDS"/>
</sequence>
</target>
<target>
<sequence>
<sequence key="DeCartaReverseGeo"/>
</sequence>
</target>
</clone>
</clone>
</inSequence>
<outSequence>
<property name="messageType" value="application/xml" scope="axis2" type="STRING" description="messageType"/>
<log level="full" description="">
<property name="WSANSWER" value="true"/>
</log>
<aggregate>
<completeCondition>
<messageCount min="2" max="-1"/>
</completeCondition>
<onComplete expression="$body/jsonObject">
<enrich>
<source clone="true" xpath="$body//jsonObject"/>
<target type="property" property="ResultItems"/>
</enrich>
<log level="custom">
<property name="ResultItems" expression="get-property('ResultItems')"/>
</log>
<enrich>
<source type="inline" clone="true">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<JsonResponse xmlns="dummy"/>
</soapenv:Body>
</soapenv:Envelope>
</source>
<target type="envelope"/>
</enrich>
<enrich>
<source type="property" clone="true" property="ResultItems"/>
<target xmlns:red="dummy" action="child" xpath="//red:JsonResponse"/>
</enrich>
<log level="full" description="">
<property name="AGGREGATE_END" value="true"/>
</log>
<property name="messageType" value="application/json" scope="axis2" type="STRING" description="messageType"/>
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence>
<log level="full" category="WARN"/>
</faultSequence>
</target>
</proxy>
API Configuration:
<api xmlns="http://ws.apache.org/ns/synapse" name="Cale-StreetsAPI" context="/Cale-StreetsAPI">
<resource methods="GET" uri-template="/getStreets?lat={lat}&lon={lon}&radius={radius}">
<inSequence>
<call>
<endpoint>
<address uri="http://localhost:8280/services/AggregatingProxy" format="soap12"></address>
</endpoint>
</call>
<respond/>
</inSequence>
</resource>
</api>
This actually worked out for me and hopefully will help you too.
Also consider using:
<property name="enclosing_element">
<result xmlns=""/>
</property>
...
<onComplete expression="$body/jsonObject" enclosingElementProperty="enclosing_element">
In case your service return different type of results.
Thanks,
Vladimir.
Related
Good afternoon, I am new to the WSO2 EI (ESB) and I am trying to make an API to consume a SOAP WebService and take it to Json, the question is that I am trying to do it but when I get the answer it indicates an error which does not give me many details.
I am defining my API as follows
<api xmlns="http://ws.apache.org/ns/synapse" name="findSubscriberBalanceBS" context="/APW/Subscriber/FindSubscriberBalanceBS" version="1.0.0" version-type="context">
<resource methods="POST" uri-template="/executeService" faultSequence="fault">
<inSequence>
<property name="messageType" value="application/json" scope="axis2" type="STRING"/>
<property name="payload" expression="json-eval($)"/>
<log>
<property name="payload" expression="$ctx:payload"/>
</log>
<property name="country" expression="json-eval($.FindSubscriberBalanceBS.Header.country)"/>
<property name="lang" expression="json-eval($.FindSubscriberBalanceBS.Header.lang)"/>
<property name="entity" expression="json-eval($.FindSubscriberBalanceBS.Header.entity)"/>
<property name="system" expression="json-eval($.FindSubscriberBalanceBS.Header.system)"/>
<property name="subsystem" expression="json-eval($.FindSubscriberBalanceBS.Header.subsystem)"/>
<property name="origin" expression="json-eval($.FindSubscriberBalanceBS.Header.origin)"/>
<property name="userId" expression="json-eval($.FindSubscriberBalanceBS.Header.userId)"/>
<property name="operation" expression="json-eval($.FindSubscriberBalanceBS.Header.operation)"/>
<property name="destiny" expression="json-eval($.FindSubscriberBalanceBS.Header.destiny)"/>
<property name="timestamp" expression="json-eval($.FindSubscriberBalanceBS.Header.timestamp)"/>
<property name="msgType" expression="json-eval($.FindSubscriberBalanceBS.Header.msgType)"/>
<property name="subscriberId" expression="json-eval($.FindSubscriberBalanceBS.Body.findSubscriberBalanceRequest.subscriberId)"/>
<log>
<property name="subscriberId" expression="$ctx:subscriberId"/>
</log>
<call-template target="validateRequestTemplate">
<with-param name="schemaUri" value="conf:/schemas/findSubscriberBalanceBS.json"/>
<with-param name="responseJsonTitle" value="FindSubscriberBalanceBS"/>
<with-param name="responseBodyTitle" value="findSubscriberBalanceResponse"/>
<with-param name="origin" value="{$ctx:destiny}"/>
<with-param name="destiny" value="{$ctx:origin}"/>
<with-param name="timestamp" value="{$ctx:timestamp}"/>
</call-template>
<log>
<property name="country" expression="$ctx:country"/>
<property name="lang" expression="$ctx:lang"/>
<property name="entity" expression="$ctx:entity"/>
<property name="system" expression="$ctx:system"/>
<property name="subsystem" expression="$ctx:subsystem"/>
<property name="origin" expression="$ctx:origin"/>
<property name="userId" expression="$ctx:userId"/>
<property name="operation" expression="$ctx:operation"/>
<property name="destiny" expression="$ctx:destiny"/>
<property name="timestamp" expression="$ctx:timestamp"/>
<property name="msgType" expression="$ctx:msgType"/>
<property name="subscriberId" expression="$ctx:subscriberId"/>
</log>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ericsson.com/OCS/OCS_Provision_types/v1">
<soapenv:Header/>
<soapenv:Body>
<v1:queryTotalBalanceRequest>
<v1:queryCommonInfo/>
<v1:subscriberId>
<v1:e164Number>$1</v1:e164Number>
</v1:subscriberId>
</v1:queryTotalBalanceRequest>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg xmlns:ns2="http://org.apache.synapse/xsd" xmlns:ns="http://org.apache.synapse/xsd" evaluator="xml" expression="$ctx:subscriberId"/>
</args>
</payloadFactory>
<log level="full"/>
<header name="SOAPAction" scope="transport" value="queryTotalBalance"/>
<header name="Accept" scope="transport" value="text/xml"/>
<call>
<endpoint key="altamiraWebServiceEndpoint"/>
</call>
<log level="full"/>
<log level="custom">
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" name="httpcode return -> " expression="get-property('axis2', 'HTTP_SC')"/>
</log>
</inSequence>
</resource>
</api>
The SOAP WebService I am calling has the following Request and Response:
REQUEST
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ericsson.com/OCS/OCS_Provision_types/v1">
<soapenv:Header/>
<soapenv:Body>
<v1:queryTotalBalanceRequest>
<v1:queryCommonInfo/>
<v1:subscriberId>
<v1:e164Number>4242441160</v1:e164Number>
</v1:subscriberId>
</v1:queryTotalBalanceRequest>
</soapenv:Body>
</soapenv:Envelope>
POST http://10.161.79.62:9103/OCS/BalanceManagement-Service_v1 HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "queryTotalBalance"
Content-Length: 439
Host: 10.161.79.62:9103
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.5 (Java/12.0.1)
RESPONSE
HTTP/1.1 200 OK
Date: Mon, 12 Jul 2021 15:29:35 GMT
Transfer-Encoding: chunked
Content-Type: text/xml;charset="utf-8"
X-Powered-By: Servlet/2.5 JSP/2.1
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns3:queryTotalBalanceResponse xmlns="http://schemas.xmlsoap.org/ws/2002/04/secext" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://www.ericsson.com/OCS/OCS_Provision_types/v1" xmlns:ns4="http://schemas.xmlsoap.org/ws/2004/08/addressing">
<ns3:balance exponent="-5">11878385641649</ns3:balance>
<ns3:negativeBalance exponent="-1">0</ns3:negativeBalance>
</ns3:queryTotalBalanceResponse>
</S:Body>
</S:Envelope>
However, I get the following error in the logs:
[2021-07-12 15:12:23,283] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /APW/Subscriber/FindSubscriberBalanceBS/executeService, MessageID: urn:uuid:d930df60-153a-4350-8f90-dba26d5056bd, Direction: request, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ericsson.com/OCS/OCS_Provision_types/v1"><soapenv:Body><v1:queryTotalBalanceRequest><v1:queryCommonInfo/><v1:subscriberId><v1:e164Number>4242441160</v1:e164Number></v1:subscriberId></v1:queryTotalBalanceRequest></soapenv:Body></soapenv:Envelope>
[2021-07-12 15:12:23,296] ERROR {org.apache.synapse.transport.passthru.util.RelayUtils} - Error while building Passthrough stream org.apache.axiom.om.OMException: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character '"' (code 34) in DOCTYPE declaration; expected a space between public and system identifiers
at [row,col {unknown-source}]: [1,55]
I do not understand where the error comes from, if I have to tackle the soap output in another way, the truth if this error cannot happen to take it to JSON.
I have a proxy service to search a user in multiple systems and should return the combined responses in JSON format.I get the responses combined but instead of getting it in JSON format I get the responses in XML format.
I can see JSON responses in WSO2 server logs as below:
[2016-07-19 07:26:58,249] INFO - LogMediator To: http://www.w3.org/2005/08/addr
essing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:895c4303-6de5-49
88-a4d1-c06275582841, Direction: response, Component = Application2, Payload: {
"findUsers":[
{"id":"20","add_state":"0","remove_state":"0","supervisor_id_name":"","idc_id":"
3","backup_supervisor_name":"","backup_supervisor":"","business_unit_id":"","com
pany":"companyb","creation_date":"2016-05-11 18:02:42.0","deletion_date":"","dep
artment":"922","display_name":"Kevin Mollo (companyb)","email_address":"Kevin.Mo
llo#companyb.com","exception_count":"","first_name":"Kevin","is_terminated":"Fal
se","job_status":"Active","last_name":"Mollo","legacy_employee_id":"171352","sup
ervisor_id":"","termination_date":"","title":"Broadband Technician","unique_id":
"9000070","user_id":"user71","violation_count":""}
]
}
[2016-07-19 07:26:58,888] INFO - LogMediator To: http://www.w3.org/2005/08/addr
essing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:0cee9dc3-b6e6-48
81-9bdd-a89ec22999a7, Direction: response, Component = Application1, Payload: {"vi
ewableIdentityAttributes":{"Email":"Kevin.Mollo#companyb.com","cn":"Kevin Mollo"
,"Last Name":"Mollo","First Name":"Kevin"},"assignedRoles":[],"listAttributes":[
"First Name","Last Name","Email","cn"]}
However, I don't get response in JSON format after calling the proxy url.
Below is my ESB configuration:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="SPRSAPproxy"
transports="http,https"
statistics="disable"
trace="disable"
startOnLoad="true">
<target>
<inSequence>
<log/>
<clone>
<target>
<sequence>
<property name="Application" value="Application1"/>
<property name="messageType"
value="application/xacml+json"
scope="axis2"
type="STRING"/>
<property name="Authorization"
expression="fn:concat('Basic ', base64Encode('username:password'))"
scope="transport"/>
<send>
<endpoint>
<address uri="http://hostname1:8080/identityiq/rest/identities/9000070"/>
</endpoint>
</send>
</sequence>
</target>
<target>
<sequence>
<property name="Application" value="Application2"/>
<property name="messageType"
value="application/json"
scope="axis2"
type="STRING"/>
<send>
<endpoint>
<address uri="http://hostname2:8080/aveksa/command.submit?cmd=findUsers&format=json&unique_id=9000070"/>
</endpoint>
</send>
</sequence>
</target>
</clone>
</inSequence>
<outSequence>
<log level="full" description="">
<property name="Component" expression="get-property('Application')"/>
</log>
<aggregate>
<completeCondition>
<messageCount min="2"/>
</completeCondition>
<onComplete expression="/">
<property name="messageType"
value="application/xacml+json"
scope="axis2"
type="STRING"
description="messageType"/>
<enrich>
<source clone="true" xpath="/"/>
<target type="body"/>
</enrich>
<send/>
</onComplete>
</aggregate>
</outSequence>
<faultSequence>
<log level="full" category="WARN"/>
</faultSequence>
</target>
<description/>
</proxy>
I get the response as below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header/><soapenv:Body><jsonObject><findUsers><id>20</id><add_state>0</add_state><remove_state>0</remove_state><supervisor_id_name></supervisor_id_name><idc_id>3</idc_id><backup_supervisor_name></backup_supervisor_name><backup_supervisor></backup_supervisor><business_unit_id></business_unit_id><company>companyb</company><creation_date>2016-05-11 18:02:42.0</creation_date><deletion_date></deletion_date><department>922</department><display_name>Kevin Mollo (companyb)</display_name><email_address>Kevin.Mollo#companyb.com</email_address><exception_count></exception_count><first_name>Kevin</first_name><is_terminated>False</is_terminated><job_status>Active</job_status><last_name>Mollo</last_name><legacy_employee_id>171352</legacy_employee_id><supervisor_id></supervisor_id><termination_date></termination_date><title>Broadband Technician</title><unique_id>9000070</unique_id><user_id>user71</user_id><violation_count></violation_count></findUsers></jsonObject><soapenv:Envelope><soapenv:Header/><soapenv:Body><jsonObject><viewableIdentityAttributes><Email>Kevin.Mollo#companyb.com</Email><cn>Kevin Mollo</cn><Last Name>Mollo</Last Name><First Name>Kevin</First Name></viewableIdentityAttributes><listAttributes>First Name</listAttributes><listAttributes>Last Name</listAttributes><listAttributes>Email</listAttributes><listAttributes>cn</listAttributes></jsonObject></soapenv:Body></soapenv:Envelope></soapenv:Body></soapenv:Envelope>
Please let me know how I can get the JSON response.
Any help would be greatly appreciated.
You can set the messageType to application/json instead of application/xacml+json in outSequence and try.
<property name="messageType" value="application/json" scope="axis2" type="STRING" description="messageType"/>
Also there is no application/xacml+json message formatters and message builders shipped with WSO2 ESB by default. If you need to use these formats you have to write your own formatters and builders and configure them in axis2.xml file.
Below is the proxy implemented in WSO2 ESB 4.8.1, this return response in binary format as shown next to the proxy code. Response is expected in the xml response.
Note: This proxy returns xml response in WSO2 ESB 4.9.0 as expected.
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="postIDMPCall-withheader"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<in>
<property name="ContentType" value="text/xml" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<payloadFactory media-type="xml">
<format>
<organizationList xmlns="">
<Organization>
<sourceRecordId>132</sourceRecordId>
<idmpRecordId>0</idmpRecordId>
<orgName>depcomp</orgName>
<smeNumber/>
<psmflCode/>
<countryCode>AF</countryCode>
<shortName/>
<remarks/>
<address>addressgger</address>
<city>mys</city>
<state>kar</state>
<postalCode>234</postalCode>
<contactPhone/>
<phoneExtension/>
<faxNumber/>
<faxExtension/>
<webSite/>
<active>YES</active>
<organizationId/>
</Organization>
</organizationList>
</format>
<args/>
</payloadFactory>
<log>
<property name="before call" expression="$body"/>
</log>
<property name="user" value="system" scope="default" type="STRING"/>
<property name="password"
value="Password2#"
scope="default"
type="STRING"/>
<header name="_user" scope="transport" expression="get-property('user')"/>
<header name="_password"
scope="transport"
expression="get-property('password')"/>
<log>
<property name="header" expression="get-property('user')"/>
</log>
<call blocking="true">
<endpoint>
<address uri="http://<ipaddress>:<port>/<rest-Services-path>/UpdateOrganization"
format="rest"/>
</endpoint>
</call>
<log>
<property name="after call" expression="$body"/>
</log>
<property name="messageType" value="text/xml" scope="axis2" type="STRING"/> <header name="To" scope="default" action="remove"/>
<property name="RESPONSE" value="true"/>
<send/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<drop/>
</in>
</inSequence>
</target>
</proxy>
1.Logs:
[ESB] [2016-05-04 15:10:27,222] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: /services/postIDMPCall-withheader.postIDMPCall-withheaderHttpSoap12Endpoint, WSAction: urn:mediate, SOAPAction: urn:mediate, MessageID: urn:uuid:b5814442-977e-43ed-9cc9-f60faa46c5c2, Direction: request, before call = <soapenv:Body xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><organizationList><Organization><sourceRecordId>132</sourceRecordId><idmpRecordId>0</idmpRecordId><orgName>depcomp</orgName><smeNumber></smeNumber><psmflCode></psmflCode><countryCode>AF</countryCode><shortName></shortName><remarks></remarks><address>addressgger</address><city>mys</city><state>kar</state><postalCode>234</postalCode><contactPhone></contactPhone><phoneExtension></phoneExtension><faxNumber></faxNumber><faxExtension></faxExtension><webSite></webSite><active>YES</active><organizationId></organizationId></Organization></organizationList></soapenv:Body> {org.apache.synapse.mediators.builtin.LogMediator}
TID: [0] [ESB] [2016-05-04 15:10:27,230] INFO {org.apache.synapse.core.axis2.TimeoutHandler} - This engine will expire all callbacks after : 120 seconds, irrespective of the timeout action, after the specified or optional timeout {org.apache.synapse.core.axis2.TimeoutHandler}
TID: [0] [ESB] [2016-05-04 15:10:31,066] INFO {org.apache.synapse.mediators.builtin.LogMediator} - To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:cee9a5c2-1f64-4ff3-a6bd-712785567f8d, Direction: request, after call = <soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><axis2ns1:binary xmlns:axis2ns1="http://ws.apache.org/commons/ns/payload">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8b3JnYW5pemF0aW9uUmVzcG9uc2VMaXN0PgogICAgPE9yZ2FuaXphdGlvbj4KICAgICAgICA8c291cmNlUmVjb3JkSWQ+MTMyPC9zb3VyY2VSZWNvcmRJZD4KICAgICAgICA8aWRtcFJlY29yZElkPjE3MTY5PC9pZG1wUmVjb3JkSWQ+CiAgICAgICAgPHN1Y2Nlc3M+U1VDQ0VTUzwvc3VjY2Vzcz4KICAgICAgICA8ZXJyb3I+Tm8gRXJyb3JzPC9lcnJvcj4KICAgIDwvT3JnYW5pemF0aW9uPgo8L29yZ2FuaXphdGlvblJlc3BvbnNlTGlzdD4K</axis2ns1:binary></soapenv:Body> {org.apache.synapse.mediators.builtin.LogMediator}
2.Response received in binary format:
<axis2ns6:binary xmlns:axis2ns6="http://ws.apache.org/commons/ns/payload">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8b3JnYW5pemF0aW9uUmVzcG9uc2VMaXN0PgogICAgPE9yZ2FuaXphdGlvbj4KICAgICAgICA8c3VjY2Vzcz5GQUlMVVJFPC9zdWNjZXNzPgogICAgICAgIDxlcnJvcj5SZWNvcmQgaXMgbm90IHByb2Nlc3NlZCBzdWNjZXNzZnVsbHkuIFBsZWFzZSBQcm92aWRlIHZhbGlkIFJlcXVlc3QgWE1MPC9lcnJvcj4KICAgIDwvT3JnYW5pemF0aW9uPgo8L29yZ2FuaXphdGlvblJlc3BvbnNlTGlzdD4K</axis2ns6:binary>
To convert an XML payload to JSON, set the messageType property to application/json in the axis2 scope before sending message to an endpoint.
<property name="messageType" value="application/json" scope="axis2"/>
I am not sure why you only have inSequence .
And you are logging both before and after call content inside inSequence.
Can you use outSequence and check ? i.e
<outSequence>
<property name="messageType" value="application/json" scope="axis2"/>
<send/>
</outSequence>
Please check that you have enabled the binary message builder/formatter in /repository/conf/axis2/axis2.xml. If so, disable binary message builder and use default message builders/formatters and try this again.
Am working with Wso2esb 4.9.0,
I have a service which selects data from database and gives response in JSON format.
Proxy service:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="GetMquestionMobile3.0"
transports="https http"
startOnLoad="true"
trace="disable"
statistics="enable">
<description/>
<target>
<inSequence onError="fault">
<property name="messageType" value="application/json" scope="axis2"/>
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
<property name="userid" expression="get-property('transport', 'userid')"/>
<property name="ModifiedOn" expression="get-property('transport', 'ModifiedOn')"/>
<property name="username" expression="get-property('transport', 'username')"/>
<property name="password" expression="get-property('transport', 'password')"/>
<property name="PartyBranchID"
expression="//FieldValue/text()"
scope="default"
type="STRING"/>
<property name="usercode"
expression="fn:substring-before(get-property('username'),'|')"
scope="default"
type="STRING"/>
<property name="clientid"
expression="fn:substring-after(get-property('username'),'|')"
scope="default"
type="STRING"/>
<payloadFactory media-type="xml">
<format>
<p:Getmquestions_Mobile xmlns:p="http://ws.wso2.org/dataservice">
<p:clientid>$1</p:clientid>
<p:modifiedon>$2</p:modifiedon>
</p:Getmquestions_Mobile>
</format>
<args>
<arg evaluator="xml" expression="get-property('clientid')"/>
<arg evaluator="xml" expression="get-property('ModifiedOn')"/>
</args>
</payloadFactory>
<send receive="MquestionMobile_Seq33.0">
<endpoint>
<address uri="http://localhost:9764/services/mquestions_DataService3.0/"
format="soap11">
<suspendOnFailure>
<errorCodes>101500,101501,101506,101507,101508,101503,50000</errorCodes>
<initialDuration>30</initialDuration>
<progressionFactor>1.0</progressionFactor>
<maximumDuration>300</maximumDuration>
</suspendOnFailure>
</address>
</endpoint>
</send>
</inSequence>
<outSequence onError="fault">
<send/>
</outSequence>
</target>
</proxy>
Sequence:
<sequence xmlns="http://ws.apache.org/ns/synapse"
name="MquestionMobile_Seq33.0"
statistics="enable">
<property name="messageType" value="application/json" scope="axis2"/>
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true"/>
<property name="HTTP_METHOD" value="POST" scope="axis2"/>
<property xmlns:ns="http://org.apache.synapse/xsd"
xmlns:s="http://ws.wso2.org/dataservice"
name="Datalist"
expression="//s:Datalist"
scope="default"
type="STRING"/>
<property xmlns:ns="http://org.apache.synapse/xsd"
xmlns:s="http://ws.wso2.org/dataservice"
name="Total"
expression="count(//s:Datalist)"
scope="default"
type="STRING"/>
<filter xmlns:ns="http://org.apache.synapse/xsd"
xpath="get-property('Total')='0.0'">
<then>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<payloadFactory media-type="json">
<format>
{"ResponseJSON":{"Body":{"Datalist":"Not Found"},"Status":"404"}}
</format>
<args/>
</payloadFactory>
<send/>
</then>
<else>
<property name="RESPONSE" value="true" scope="default" type="STRING"/>
<property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
<payloadFactory media-type="json">
<format>{"ResponseJSON" : {"Body" :$1,"Status" :"200","Total" :"$2"}}</format>
<args>
<arg evaluator="json" expression="$.Body"/>
<arg evaluator="xml" expression="get-property('Total')"/>
</args>
</payloadFactory>
<send/>
</else>
</filter>
</sequence>
This service gives me the response as shown below
{"jsonObject":{"ResponseJSON" :
{"Body" :
{"Datalist":[
{"ComboValues":"Yes,No","QuestionType":0,"Tag":-1,"Question":"LogBooks","IsAVPT":-1,"QuestionId":989181535979317,"DataSize":-1.0,"ToolTip":-1,"IsFollowup":-1},
{"ComboValues":"Yes,No","QuestionType":0,"Tag":null,"Question":"MasterRegister","IsAVPT":-1,"QuestionId":989181536700214,"DataSize":-1.0,"ToolTip":null,"IsFollowup":-1},
{"ComboValues":null,"QuestionType":0,"Tag":null,"Question":"OthersRecords","IsAVPT":-1,"QuestionId":989181536732983,"DataSize":-1.0,"ToolTip":null,"IsFollowup":-1}]},"Status":"200","Total":"3.0"}}}
I don't want to see the jsonObject in my response, how can i avoid this in my JSON response and get the response as below
{"ResponseJSON" :
{"Body" :
{"Datalist":[
{"ComboValues":"Yes,No","QuestionType":0,"Tag":-1,"Question":"LogBooks","IsAVPT":-1,"QuestionId":989181535979317,"DataSize":-1.0,"ToolTip":-1,"IsFollowup":-1},
{"ComboValues":"Yes,No","QuestionType":0,"Tag":null,"Question":"MasterRegister","IsAVPT":-1,"QuestionId":989181536700214,"DataSize":-1.0,"ToolTip":null,"IsFollowup":-1},
{"ComboValues":null,"QuestionType":0,"Tag":null,"Question":"OthersRecords","IsAVPT":-1,"QuestionId":989181536732983,"DataSize":-1.0,"ToolTip":null,"IsFollowup":-1}]},"Status":"200","Total":"3.0"}}
DS Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<Body xmlns="http://ws.wso2.org/dataservice">
<Datalist>
<Question>LogBooks</Question>
<QuestionId>989181535979317</QuestionId>
<QuestionType>0</QuestionType>
<ComboValues>Yes,No</ComboValues>
<IsFollowup>-1</IsFollowup>
<IsAVPT>-1</IsAVPT>
<DataSize>-1.0</DataSize>
<ToolTip>-1</ToolTip>
<Tag>-1</Tag>
<weightage>1.00</weightage>
</Datalist>
<Datalist>
<Question>Master Register</Question>
<QuestionId>989181536700214</QuestionId>
<QuestionType>0</QuestionType>
<ComboValues>Yes,No</ComboValues>
<IsFollowup>-1</IsFollowup>
<IsAVPT>-1</IsAVPT>
<DataSize>-1.0</DataSize>
<ToolTip/>
<Tag/>
<weightage>1.00</weightage>
</Datalist>
<Datalist>
<Question>Others Records</Question>
<QuestionId>989181536732983</QuestionId>
<QuestionType>0</QuestionType>
<ComboValues/>
<IsFollowup>-1</IsFollowup>
<IsAVPT>-1</IsAVPT>
<DataSize>-1.0</DataSize>
<ToolTip/>
<Tag/>
<weightage>1.00</weightage>
</Datalist>
</Body>
</soapenv:Body>
</soapenv:Envelope>
You can use an enrich mediator to remove jsonObject from response body like below.
<enrich>
<source clone="true" xpath="$body//jsonObject//ResponseJSON"/>
<target type="body"/>
</enrich>
You can add a log mediator after enrich mediator and check the changed body.
Hope this will help you.
In side ESB mediator communications take place as SOAP messages. when you send JSON request or when ESB received JSON response what ESB does in convert that to xml / soap message by adding tag to prevent multi rooted xml.
try to use
<property name="messageType" value="application/json" scope="axis2"/>
before send / call. this will automatically remove your jsonObject from response. but if you want to convert response to xml from json then you need to manually modify using enrich mediator
make sure json formatter enabled in axis2.xml
I am trying transaction management in wso2 esb. I have a single database and a proxy to test transaction management, success case is working properly, but failure case it is not roll backing.
My Proxy:
<proxy name="a" transports="http https jms" startOnLoad="true">
<description/>
<target>
<inSequence>
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<transaction action="new"/>
<log level="custom">
<property name="text" value="** Reporting to the Database esbdb**"/>
</log>
<dbreport useTransaction="true">
<connection>
<pool>
<dsName>jdbc/db</dsName>
</pool>
</connection>
<statement>
<sql>delete from company1 where name =?</sql>
<parameter xmlns:m1="http://services.samples/xsd"
xmlns:m0="http://services.samples"
expression="//m0:return/m1:symbol/child::text()"
type="VARCHAR"/>
</statement>
</dbreport>
<log level="custom">
<property name="text" value="** Reporting to the Database esbdb1**"/>
</log>
<dbreport useTransaction="true">
<connection>
<pool>
<dsName>jdbc/db</dsName>
</pool>
</connection>
<statement>
<sql>INSERT into company2 values (?,'c4',?)</sql>
<parameter xmlns:m1="http://services.samples/xsd"
xmlns:m0="http://services.samples"
expression="//m0:return/m1:symbol/child::text()"
type="VARCHAR"/>
<parameter xmlns:m1="http://services.samples/xsd"
xmlns:m0="http://services.samples"
expression="//m0:return/m1:last/child::text()"
type="DOUBLE"/>
</statement>
</dbreport>
<transaction action="commit"/>
<send/>
</outSequence>
<faultSequence>
<property name="SET_ROLLBACK_ONLY" value="true" scope="axis2"/>
<log level="custom">
<property name="Transaction Action" value="Rollbacked"/>
</log>
<transaction action="rollback"/>
</faultSequence>
</target>
</proxy>
My master-datasource.xml
<providers>
<provider>org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader</provider>
</providers>
<datasources>
<datasource>
<name>WSO2_CARBON_DB</name>
<description>The datasource used for registry and user manager</description>
<jndiConfig>
<name>jdbc/WSO2CarbonDB</name>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<url>jdbc:h2:repository/database/WSO2CARBON_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000</url>
<username>wso2carbon</username>
<password>wso2carbon</password>
<driverClassName>org.h2.Driver</driverClassName>
<maxActive>50</maxActive>
<maxWait>60000</maxWait>
<testOnBorrow>true</testOnBorrow>
<validationQuery>SELECT 1</validationQuery>
<validationInterval>30000</validationInterval>
</configuration>
</definition>
</datasource>
<datasource>
<name>DS1</name>
<jndiConfig>
<name>jdbc/db</name>
</jndiConfig>
<definition type="RDBMS">
<configuration>
<dataSourceClassName>com.atomikos.jdbc.AtomikosDataSourceBean</dataSourceClassName>
<dataSourceProps>
<property name="xaDataSourceClassName">com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</property>
<property name="uniqueResourceName">jdbc/db</property>
<property name="xaProperties.databaseName">esb_sp_sample</property>
<property name="xaProperties.user">root</property>
<property name="xaProperties.password">root</property>
<property name="xaProperties.URL">jdbc:mysql://localhost:3306/esb_sp_sample</property>
<property name="poolSize">10</property>
</dataSourceProps>
</configuration>
</definition>
</datasource>
What could be the problem?
Note: I have also tried with https://docs.wso2.com/display/ESB481/Transaction+Mediator+Example having one database and 2 tables in it, but with MySQL.
I think you are missing the
<send/>
Tag at the end of your fault sequence. Your fault sequence should be as follows.
<faultSequence>
<property name="SET_ROLLBACK_ONLY" value="true" scope="axis2"/>
<log level="custom">
<property name="Transaction Action" value="Rollbacked"/>
</log>
<transaction action="rollback"/>
<send/>
</faultSequence>