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

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>

Related

salesforcerest.update not working in WSO2 EI 6.1.1

I am doing Salesforce update operation using Salesforce Rest connector in wso2 ei. problem here is record not updated, it shows below exception after forming request payload.
Exception:
|**TID: [-1234] [] [2019-12-06 05:03:05,191] ERROR {org.apache.synapse.commons.json.JsonUtil} - #getNewJsonPayload. Could not save JSON payload. Invalid input stream found. MessageID: urn:uuid:33275d28-c55d-4a9e-bbcd-17d60cc38d1e {org.apache.synapse.commons.json.JsonUtil}
TID: [-1234] [] [2019-12-06 05:03:05,192] ERROR {org.apache.synapse.mediators.transform.PayloadFactoryMediator} - Error creating JSON Payload from source Lead {org.apache.synapse.mediators.transform.PayloadFactoryMediator}**
Code Snippet:
<api xmlns="http://ws.apache.org/ns/synapse" name="TestImageAPI" context="/imageapi">
<resource methods="GET" protocol="http https">
<inSequence>
<log level="custom" separator=",**, " description="FaultSequence">
<property name="=====TestImageAPI=====" value="called===="/>
</log>
<property name="ValuationId" value="00Q5500000AGHikEAH" scope="default" type="STRING"/>
<property name="First_Image_Name__c" value="cbimage" scope="default" type="STRING"/>
<property name="ObjectName" value="Lead" scope="default" type="STRING"/>
<payloadFactory media-type="json" description="Form Response Payload">
<format>{"Lead_Type__c":"$1"}</format>
<args>
<arg value="Phone"/>
</args>
</payloadFactory>
<property name="fieldAndValue" expression="json-eval($.)" scope="default" type="STRING"/>
<log level="custom">
<property name="===FirstImagepayload=====" expression="$ctx:fieldAndValue"/>
</log>
<sequence key="QRSag_VBSalesforceInitializer" description="Load Configurations"/>
<salesforcerest.init>
<accessToken>{$ctx:accessToken}</accessToken>
<apiVersion>{$ctx:apiVersion}</apiVersion>
<hostName>{$ctx:hostName}</hostName>
<refreshToken>{$ctx:refreshToken}</refreshToken>
<clientSecret>{$ctx:clientSecret}</clientSecret>
<clientId>{$ctx:clientId}</clientId>
<apiUrl>{$ctx:apiUrl}</apiUrl>
<registryPath>{$ctx:registryPath}</registryPath>
<intervalTime>{$ctx:intervalTime}</intervalTime>
</salesforcerest.init>
<property name="SalesforceAccessToken" expression="json-eval($.access_token)" scope="default" type="STRING"/>
<log level="full"/>
<property xmlns:ns="http://org.apache.synapse/xsd" name="Authorization" expression="fn:concat('Bearer ', get-property('SalesforceAccessToken'))" scope="transport" type="STRING" description="Authorization"/>
<salesforcerest.update>
<sObjectName>{$ctx:ObjectName}</sObjectName>
<Id>{$ctx:ValuationId}</Id>
<fieldAndValue>{$ctx:fieldAndValue}</fieldAndValue>
</salesforcerest.update>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Note: Added Salesforce Rest connector in both server as well as ESB Project
Could anyone please give me a solution??
I have achieved the above mentioned use case. FYI,
<property description="Authorization" expression="fn:concat('Bearer ', get-property('SalesforceAccessToken'))" name="Authorization" scope="transport" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<payloadFactory description="Form Response Payload" media-type="json">
<format>{"First_Image_Name__c":"$1"}</format>
<args>
<arg evaluator="xml" expression="$ctx:First_Image_Name__c"/>
</args>
</payloadFactory>
<log level="custom">
<property expression="json-eval($.)" name="===FirstImagepayload====="/>
</log>
<property expression="json-eval($.)" name="fieldAndValue" scope="default" type="STRING"/>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property name="OUT_ONLY" scope="default" type="STRING" value="false"/>
<property expression="fn:concat($ctx:instance_url,'/services/data/v47.0/sobjects/Product2/',$ctx:StockID)" name="uri.var.ImageUpload" scope="default" type="STRING"/>
<property description="Authorization" expression="fn:concat('Bearer ', get-property('SalesforceAccessToken'))" name="Authorization" scope="transport" type="STRING" xmlns:ns="http://org.apache.synapse/xsd"/>
<log level="custom">
<property expression="$ctx:uri.var.ImageUpload" name="===SalesforceLink========="/>
</log>
<call description="ImageuploadEndpoint">
<endpoint>
<http method="patch" uri-template="{uri.var.ImageUpload}"/>
</endpoint>
</call>
<log level="full" separator="=== First Image Name Update Response ==="/>

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>

WSO2ESB: How to add <?xml into the message sent to POX endpoint

I'm using wso2ei 6.0.0 and I have a simple task - send specific xml message via POST to the endpoint.
I have API configured like this:
<api xmlns="http://ws.apache.org/ns/synapse" name="glisTest" context="/glisTest">
<resource methods="GET" uri-template="/{sampleid}">
<inSequence>
<property name="PRESERVE_WS_ADDRESSING" value="false"/>
<payloadFactory media-type="xml">
<format>
<register />
</format>
</payloadFactory>
<log level="full"/>
<property name="messageType" value="application/xml" scope="axis2" type="STRING"/>
<property name="HTTP_METHOD" value="post" scope="axis2" type="STRING"/>
<send>
<endpoint>
<address uri="https://localhost/manager" encoding="UTF-8" format="pox"/>
</endpoint>
</send>
</inSequence>
<outSequence>
<log level="full"/>
<send/>
</outSequence>
</resource>
</api>
But service is expected
<?xml version="1.0" encoding="UTF-8" ?>
to be inserted at the beginning and wso2 do not do it (I just added debug logging for org.apache.synapse.transport.http.wire and I see it simple send
<register/>
As result, it does not recognize message as an xml and returm me error.
Question - how to tell synapse to add this special xml header to the message?

In WSO2 ESB, how to store cookies and use them later for authentication?

I have a service that I am calling, which is returning back cookies with authentication info. How do I store the cookies, and use them later?
This is not working for me. I see the cookies being returned back, but I don't see it getting set.
<!-- LOGON CALL -->
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" name="setCookieHeader" expression="$trp:cookie"></property>
<payloadFactory media-type="xml">
<format><somexml></somexml></format>
</payloadFactory>
<call>
<endpoint>
<address uri="http://serviceurl.domain.com" format="pox"></address>
</endpoint>
</call>
<log>
<property name="cookie" expression="get-property('setCookieHeader')"></property>
</log>
<!-- The Above Log statement prints correctly -->
<!-- Second Service CALL -->
<property xmlns:ns="http://org.apache.synapse/xsd" xmlns:ns3="http://org.apache.synapse/xsd" name="setCookieHeader" expression="$trp:cookie"></property>
<payloadFactory media-type="xml">
<format><somexml></somexml></format>
</payloadFactory>
<call>
<endpoint>
<address uri="http://serviceurl.domain.com" format="pox"></address>
</endpoint>
</call>
To get cookies from the response :
<property name="setCookieHeader" expression="$trp:Set-Cookie" scope="default" type="STRING"/>
To set cookies for the next request :
<property name="Cookie" expression="$ctx:setCookieHeader" scope="transport"/> <!-- if setCookieHeader has been initialized before -->
Or
<property name="Cookie" expression="$trp:Set-Cookie" scope="transport"/>

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.