WSO2 ESB: Display dataService response - sequence

How do you display the response returned by calling a webservice endpoint on a sequence?
Below is the sequence that I use. I would like to display the return value from the dataservice called "CDServiceEndpoint" on the wso2carbon.log. Is that possible? If not, how can I get the data displayed.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="ConcurGetADPExtractFlow" onError="GeneralErrorHandler">
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" name="current-context-details" expression="concat(get-property('current-context-details'), ', ConcurGetADPExtractFlow')" />
<property name="scenario" value="ConcurGetADPExtractFlow" />
<log level="custom">
<property name="DEBUGGING" value="ConcurGetADPExtractFlow" />
<property name="start-date" value="2015-02-23" />
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" name="End Date" expression="get-property('current-date')" />
</log>
<xslt key="Concur_Get_ADP_Extract_Transformation">
<property name="start-date" value="2015-03-02" />
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" name="end-date" expression="get-property('current-date')" />
</xslt>
<property name="post-data-service-sequence" value="ConcurTransformADPExtractFlow" />
<property name="OUT_ONLY" value="false" />
<send receive="DataServiceInvocationErrorFlow">
<endpoint key="ConcurDataServiceEndpoint" />
</send>
<description>Sends a request to the data service for the ADP extract data.</description>
</sequence>
Below is how my DataServiceInvocationErrorFlow looks like.
<sequence xmlns="http://ws.apache.org/ns/synapse" name="DataServiceInvocationErrorFlow">
<filter xmlns:ns="http://org.apache.synapse/xsd" xmlns:m="http://ws.wso2.org/dataservice" xmlns:ns3="http://org.apache.synapse/xsd" xpath="//m:DataServiceFault">
<then>
<log level="custom">
<property name="status" value="data-service-fault" />
</log>
<property name="error_message" expression="//m:DataServiceFault" />
<sequence key="GeneralErrorHandler" />
<drop />
</then>
<else>
<filter source="string-length(get-property('ERROR_MESSAGE'))" regex="0.0">
<then>
<filter xpath="//soapenv:Fault">
<then>
<log level="custom">
<property name="status" value="ERROR" />
</log>
<property name="error_message" expression="//soapenv:Fault" />
<sequence key="GeneralErrorHandler" />
<drop />
</then>
<else>
<log level="custom">
<property name="status" value="success response from DSS" />
</log>
<filter source="string-length(normalize-space(get-property('post-data-service-sequence')))" regex="0.0">
<then />
<else>
<property name="temp-post-data-service-sequence" expression="get-property('post-data-service-sequence')" />
<property name="post-data-service-sequence" value="" />
<sequence key="{get-property('temp-post-data-service-sequence')}" />
</else>
</filter>
</else>
</filter>
</then>
<else>
<property name="error_message" expression="get-property('ERROR_MESSAGE')" />
<sequence key="GeneralErrorHandler" />
<drop />
</else>
</filter>
</else>
</filter>
</sequence>

If by CDServiceEndpoint you meant ConcurDataServiceEndpoint, then you are already handling the response from that endpoint in your DataServiceInvocationErrorFlow sequence that you defined on the Send mediator, which by the way is confusingly named, since your receive sequence will run no matter if you get an error response or a good one. All you need to do is log it inside DataServiceInvocationErrorFlow using Log mediator.
Had you not defined a receive sequence on your Send mediator, the response would have gotten to your outSequence, where you can log it with Log mediator too.

Related

WSO2 EI: Can I use mediator to request another API and pass its response to the body request?

In my case, I want to add a dynamic value ("Bearer" + {access-token}) to the header mediator .
So before the header mediator, I want to invoke a get-token API and extract {access-token} element from its response. How can I get that ? Thank you so much.
You can achieve such requirements with mediation sequences. You can refer to this blog for more detailed instructions on how to develop a sequence for your requirement. The blog is written for the API Manager product, but nevertheless, you can follow the same to get it done in the EI.
A sample mediation sequence will be as following
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="oauth2-sequence" xmlns="http://ws.apache.org/ns/synapse">
<!-- token generation to the oauth server's token endpoint -->
<!-- add the base64 encoded credentials -->
<property name="client-authorization-header" scope="default" type="STRING" value="MDZsZ3BTMnh0enRhOXBsaXZGUzliMnk4aEZFYTpmdE4yWTdLcnE2SWRsenBmZ1RuTVU1bkxjUFFh" />
<property name="request-body" expression="json-eval($)" scope="default" type="STRING" />
<property name="resource" expression="get-property('axis2', 'REST_URL_POSTFIX')" scope="default" type="STRING" />
<!-- creating a request payload for client_credentials -->
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root xmlns="">
<grant_type>client_credentials</grant_type>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args></args>
</payloadFactory>
<!-- set related headers to call the token endpoint -->
<header name="Authorization" expression="fn:concat('Basic ', get-property('client-authorization-header'))" scope="transport" />
<header name="Content-Type" value="application/x-www-form-urlencoded" scope="transport" />
<property name="messageType" value="application/x-www-form-urlencoded" scope="axis2" type="STRING" />
<property name="REST_URL_POSTFIX" value="" scope="axis2" type="STRING" />
<!-- change the token endpoint -->
<call blocking="true">
<endpoint>
<http method="POST" uri-template="https://localhost:9443/oauth2/token" />
</endpoint>
</call>
<!-- append the acquired access token and make the call to the backend service -->
<property name="bearer-token" expression="json-eval($.access_token)" scope="default" type="STRING" />
<property name="REST_URL_POSTFIX" expression="get-property('resource')" scope="axis2" type="STRING" />
<header name="Authorization" expression="fn:concat('Bearer ', get-property('bearer-token'))" scope="transport" />
<payloadFactory media-type="json">
<format>$1</format>
<args>
<arg evaluator="xml" expression="get-property('request-body')" />
</args>
</payloadFactory>
<!-- perform a send or call to complete the execution of the backend service call in EI -->
</sequence>
Hope this helps you to start with implementation.

WSO2 as RPC server with RabbitMQ

I have a following task:
WSO2 listening a RabbitMQ (amqp) queue for incoming message, call some DB procedure and reply back to specified in incoming message queue (reply_to property) with specified Correlation Id (correlation_id property).
I used dynamic message routing with Default endpoint (named RabbitMQ_DefEP) and CorrelationId
I spend some time to gathering information to make this work. Here is working example
It may be useful for others
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="RabbitMQRPCTest01" startOnLoad="true" transports="rabbitmq" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<log description="" level="custom">
<property name="*****Rabbit MQ Start" value="********************************* headers"/>
</log>
<log level="headers"/>
<log description="" level="custom">
<property name="*****Rabbit MQ" value="********************************* full"/>
</log>
<log level="full"/>
<log description="CorrId" level="custom">
<property expression="$header" name="***Header="/>
<property expression="$body" name="***Body="/>
</log>
<property description="Get Correlation Id" expression="get-property('transport', 'rabbitmq.message.correlation.id')" name="corrid" scope="default" type="STRING"/>
<property description="Get Reply To" expression="get-property('transport', 'RABBITMQ_REPLY_TO')" name="replto" scope="default" type="STRING"/>
<log level="custom">
<property expression="get-property('corrid')" name="***CORRELATION ID="/>
<property expression="get-property('replto')" name="***REPLY_TO="/>
</log>
<payloadFactory description="Set payload for procedure call" media-type="xml">
<format>
<p:CallPing xmlns:p="http://ws.wso2.org/dataservice">
<p:req>$1</p:req>
</p:CallPing>
</format>
<args>
<arg evaluator="xml" expression="$body//ns:text" xmlns:ns="http://ws.apache.org/commons/ns/payload"/>
</args>
</payloadFactory>
<property description="HTTP_METHOD" name="HTTP_METHOD POST" scope="axis2" type="STRING" value="POST"/>
<property description="SOAPAction" name="SOAPAction" scope="transport" type="STRING" value=""/>
<property description="messageType" name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<log level="custom">
<property expression="$body" name="*****Procedure params"/>
</log>
<send>
<endpoint key="DMSB_CFTEP"/>
</send>
</inSequence>
<outSequence>
<log description="" level="custom">
<property name="*****Rabbit MQ Reply started" value="*********************************"/>
</log>
<log description="Full Log" level="full"/>
<header description="Build URI for AMQP" expression="fn:concat('rabbitmq:/AMQPProducerSample?rabbitmq.server.host.name=rabbitmq.ru&rabbitmq.server.port=5672&rabbitmq.server.user.name=monitor&rabbitmq.server.password=12345&rabbitmq.connection.factory=RabbitMQConnectionFactory&rabbitmq.exchange.name=&rabbitmq.queue.routing.key=', get-property('replto'))" name="To" scope="default"/>
<log description="" level="custom">
<property name="*****Rabbit MQ Reply END" value="*********************************"/>
</log>
<property description="Set Correlation Id" expression="get-property('corrid')" name="rabbitmq.message.correlation.id" scope="axis2" type="STRING"/>
<call>
<endpoint key="RabbitMQ_DefEP"/>
</call>
</outSequence>
<faultSequence>
<log level="custom">
<property expression="$body" name="****FAULT***************"/>
</log>
<log description="Log Props" level="full">
<property name="text" value="An unexpected error occured. Executing fault sequence"/>
<property expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
<property expression="get-property('ERROR_DETAIL')" name="detail"/>
<property expression="get-property('ERROR_EXCEPTION')" name="exception"/>
<property expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
</log>
</faultSequence>
</target>
<parameter name="rabbitmq.queue.name">esb</parameter>
<parameter name="rabbitmq.connection.factory">AMQPConnectionFactory</parameter>
</proxy>

Sending Content-Type application/x-www-form-urlencoded WSO2 ESB

I have been working in a service chaining that answers me with a Bearer Token using in WSO2 EMM.
I made a proxy in ESB and then I passed to a new sequence that makes the next call but this one receives a Content-Type application/x-www-form-urlencoded. I have been looking for some help so that I can find anything interesting.
This is my proxy
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="TokenService" startOnLoad="true" statistics="enable"
trace="enable" transports="http https" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<!--Aggregate incoming responses -->
<log level="full">
<property name="sequence" value="Paso 1 - request for client register"/>
</log>
<property description="Content-Type" name="ContentType"
scope="default" type="STRING" value="application/json"/>
<header name="Accept" scope="transport" value="application/json"/>
<payloadFactory description="Payload" media-type="json">
<format>{
"owner": "admin",
"clientName": "admin_emm",
"grantType":
"refresh_token password client_credentials",
"tokenScope": "prod"
}</format>
<args/>
</payloadFactory>
<send receive="Mensaje"/>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
</proxy>
This is my sequence that gets the response from the other service in my proxy
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="Mensaje" trace="enable" xmlns="http://ws.apache.org/ns/synapse">
<log level="custom">
<property expression="json-eval($.client_secret)"
name="client_secret" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
<log level="custom">
<property expression="json-eval($.client_id)" name="client_id" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
<log level="custom">
<property
expression="fn:concat('Basic ', base64Encode('client_id:client_secret'))"
name="Authorization" xmlns:ns="http://org.apache.synapse/xsd"/>
</log>
<property name="grant_type" value="password"/>
<property name="username" value="admin"/>
<property name="password" value="admin"/>
<property name="scope" value="default"/>
<header name="Accept" scope="transport" value="application/json"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root xmlns="">
<grant_type>$1</grant_type>
<username>$2</username>
<password>$3</password>
<scope>$4</scope>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$ctx:grant_type" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="$ctx:username" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="$ctx:password" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="$ctx:scope" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<property name="ContentType" value="application/x-www-form-urlencoded"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<call>
<endpoint name="Token">
<http method="POST" uri-template="https://localhost:9443/oauth2/token"/>
</endpoint>
</call>
<respond/>
</sequence>
Then when i run it i have an error of HTTP/1.1 415 Unsupported Media Type
Please, help
I got it this is the answer
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="Mensaje" trace="enable" xmlns="http://ws.apache.org/ns/synapse">
<property expression="json-eval($.client_secret)"
name="client_secret" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="json-eval($.client_id)" name="client_id" xmlns:ns="http://org.apache.synapse/xsd"/>
<property
expression="fn:concat(get-property('client_id'),':',get-property('client_secret'))"
name="Concatenados" xmlns:ns="http://org.apache.synapse/xsd"/>
<property expression="base64Encode(get-property('Concatenados'))"
name="Codificados" xmlns:ns="http://org.apache.synapse/xsd"/>
<property
expression="fn:concat('Basic ', get-property('Codificados'))"
name="Autorizacion" xmlns:ns="http://org.apache.synapse/xsd"/>
<property name="grant_type" value="password"/>
<property name="username" value="admin"/>
<property name="password" value="admin"/>
<property name="scope" value="default"/>
<payloadFactory media-type="xml">
<format>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<root xmlns="">
<grant_type>$1</grant_type>
<username>$2</username>
<password>$3</password>
<scope>$4</scope>
</root>
</soapenv:Body>
</soapenv:Envelope>
</format>
<args>
<arg evaluator="xml" expression="$ctx:grant_type" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="$ctx:username" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="$ctx:password" xmlns:ns="http://org.apache.synapse/xsd"/>
<arg evaluator="xml" expression="$ctx:scope" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<header name="Content-Type" scope="transport" value="application/x-www-form-urlencoded"/>
<header expression="get-property('Autorizacion')"
name="Authorization" scope="transport" xmlns:ns="http://org.apache.synapse/xsd"/>
<property name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<call>
<endpoint name="Token">
<http method="POST" uri-template="https://localhost:9443/oauth2/token"/>
</endpoint>
</call>
<respond/>
</sequence>
I had the same error. This is my solution, similar to previous but in Json:
<property name="scope" scope="default" type="STRING" value="myScope"/>
<payloadFactory media-type="json">
<format>{"grant_type":"password","username":"admin","password":"admin","scope":"$1"}</format>
<args>
<arg evaluator="xml" expression="get-property('scope')"/>
</args>
</payloadFactory>
<!-- authorization header with consumer-key:consumer-secret in Base64 -->
<header name="Authorization" scope="transport" value="Basic RUVyY0VRejFfU..."/>
<header name="Content-Type" scope="transport" value="application/x-www-form-urlencoded"/>
<property name="messageType" scope="axis2" type="STRING" value="application/x-www-form-urlencoded"/>
<call blocking="true">
<endpoint key="GetToken"/>
</call>

WSO2 ESB API configuration to send same post request to different Rest services

I need to send a post request to different REST services, below is the complete requirement.
I am using REST API configuration of WSO2 ESB
First I need to post a request to one service and based on successful posting then need to post this same to another service. But I need to obtain the response from first service and send it to fronend. But I do not need to obtain the response from second service.
Please find the API configuration below and help me.
<api xmlns="http://ws.apache.org/ns/synapse" name="test" context="/test">
<resource methods="POST DELETE PUT GET">
<inSequence>
<log level="custom">
<property name="Message Flow" value="Roovershof Plant Search API - IN"></property>
<property name="HTTP_METHOD IS###########" expression="$axis2:HTTP_METHOD"></property>
<property name="ip address" expression="get-property('axis2','REMOTE_ADDR')"></property>
<property name="Authorization" expression="get-property('transport','Authorization')"></property>
</log>
<property name="TIME_IN" expression="get-property('SYSTEM_TIME')" scope="default" type="LONG"></property>
<send>
<endpoint>
<address uri="service1"></address>
</endpoint>
</send>
<log level="custom">
<property name="Request Method :" expression="get-property('axis2', 'HTTP_METHOD')"></property>
</log>
<filter source="get-property('axis2', 'HTTP_SC')" regex="201">
<then>
<clone continueParent="true">
<target>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"></property>
<property name="messageType" value="application/json" scope="axis2"></property>
<property name="HTTP_METHOD" value="POST" scope="axis2"></property>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"></property>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"></property>
<send>
<endpoint>
<address uri="servicr2"></address>
</endpoint>
</send>
</target>
<target sequence="magento" />
</clone>
Your synapse configuration does not match your statement. You have to preserve the original message using enrich mediator and then make use the call mediator for your first endpoint invocation.
Then based on the results, you send the response back to your client and do the send call by reloading the message from the preservation.
<api xmlns="http://ws.apache.org/ns/synapse" name="TestApi" context="/TestContext">
<resource methods="POST GET">
<inSequence>
<log level="custom">
<property name="Message Flow" value="Roovershof Plant Search API - IN"></property>
<property name="HTTP_METHOD IS###########" expression="$axis2:HTTP_METHOD"></property>
<property name="ip address" expression="get-property('axis2','REMOTE_ADDR')"></property>
<property name="Authorization" expression="get-property('transport','Authorization')"></property>
</log>
<property name="TIME_IN" expression="get-property('SYSTEM_TIME')" scope="default" type="LONG"></property>
<enrich>
<source type="body" clone="true"></source>
<target type="property" property="INIT_MSG_PAYLOAD"></target>
</enrich>
<call>
<endpoint>
<address uri="service1"></address>
</endpoint>
</call>
<filter source="get-property('axis2', 'HTTP_SC')" regex="201">
<then>
<clone continueParent="true">
<target>
<sequence>
<respond></respond>
</sequence>
</target>
<target>
<sequence>
<enrich>
<source type="property" clone="true" property="INIT_MSG_PAYLOAD"></source>
<target type="body"></target>
</enrich>
<property name="REST_URL_POSTFIX" scope="axis2" action="remove"></property>
<property name="messageType" value="application/json" scope="axis2"></property>
<property name="HTTP_METHOD" value="POST" scope="axis2"></property>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2" type="STRING"></property>
<property name="OUT_ONLY" value="true" scope="default" type="STRING"></property>
<send>
<endpoint>
<address uri="servicr2"></address>
</endpoint>
</send>
</sequence>
</target>
</clone>
</then>
<else>
<respond/>
</else>
</filter>
</inSequence>
</resource>
</api>

How to add Authentication to my proxy service(get) in wso2 esb(4.6.0)please any one help me the procedure,i cant find much more on this?

These are the below proxy service and sequences...if i am running with empty curl command data is showing for get service,so that i want to authenticate that data
<proxy xmlns="http://ws.apache.org/ns/synapse" name="Get_meter_Mobile" transports="https,http" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence onError="fault">
<property name="CONTENT_TYPE" value="application/json" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="POST" scope="axis2" type="STRING"/>
<payloadFactory>
<format>
<mmeter xmlns=""/>
</format>
</payloadFactory>
<send receive="Get_meter_Mobile_seq">
<endpoint>
<address uri="http://localhost:9764/services/meter_DataService/" format="soap11"/>
</endpoint>
</send>
<property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')" scope="axis2" type="STRING"/>
<property name="ERROR_CODE" expression="get-property('ERROR_CODE')" scope="axis2" type="STRING"/>
<log level="full"/>
<property name="FORCE_ERROR_ON_SOAP_FAULT" value="true" scope="default" type="STRING"/>
</inSequence>
<outSequence>
<property name="CONTENT_TYPE" value="application/json" scope="axis2"/>
<log level="full"/>
<send/>
</outSequence>
</target>
<description></description>
</proxy>
You can achice this by applying POX security to your Proxy service. The blog post [1] will show you the steps to follow.
[1]. http://evanthika.blogspot.com/2012/12/pox-security-with-wso2-esb-proxy.html
Thank You,
Dharshana.