Clone mediator is used to send same massage
to multiple endpoints. It basically clone same message to multiple message based
on our requirement and send it to multiple endpoints. We can aggregate the
response which we get from the multiple endpoints and show as one response.
Requirement:
Suppose there is a requirement where we
have to get the entire IT employee details who all works overseas. We have
different databases and different places and each database has employee
records. We have only one input parameter which is department, all I need is IT
employee details.
Solution:
DSS:
<data name="EmployeeDetailsNZ" enableBatchRequests="false" enableBoxcarring="false" serviceStatus="active"> <description>This provides Employee details</description> <config id="EMPDS"> <property name="org.wso2.ws.dataservice.driver">oracle.jdbc.driver.OracleDriver</property> <property name="org.wso2.ws.dataservice.protocol">jdbc:oracle:thin:SYSTEM/SYSTEM@localhost:1521/xe</property> <property name="org.wso2.ws.dataservice.user">SYSTEM</property> <property name="org.wso2.ws.dataservice.password">SYSTEM</property> <property name="org.wso2.ws.dataservice.minpoolsize"></property> <property name="org.wso2.ws.dataservice.maxpoolsize"></property> <property name="org.wso2.ws.dataservice.validation_query"></property> </config> <query id="EmpDetailsQuery" useConfig="EMPDS"> <sql>select * from EMP_DETAILS_NZ where DEPARTMENT_V=?</sql> <result element="EmployeeDetails" rowName="EmployeeData" defaultNamespace="http://shriwithjava.blogspot.co.nz/"> <element name="EmployeeId" column="EMP_ID_N" xsdType="xs:string" /> <element name="EmployeeName" column="EMP_NAME_V" xsdType="xs:string" /> <element name="EmployeeAddress" column="EMP_ADD_V" xsdType="xs:string" /> <element name="Department" column="DEPARTMENT_V" xsdType="xs:string" /> </result> <param name="Department" paramType="SCALAR" sqlType="STRING" type="IN" /> </query> <operation name="getEmployeeDetails"> <description></description> <call-query href="EmpDetailsQuery"> <with-param name="Department" query-param="Department" /> </call-query> </operation> </data>
DSS request and response format:
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:shr="http://shriwithjava.blogspot.co.nz/"> <soapenv:Header/> <soapenv:Body> <shr:getEmployeeDetails> <shr:Department>IT</shr:Department> </shr:getEmployeeDetails> </soapenv:Body> </soapenv:Envelope>
Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <EmployeeDetails xmlns="http://shriwithjava.blogspot.co.nz/"> <EmployeeData> <EmployeeId>201</EmployeeId> <EmployeeName>Shri</EmployeeName> <EmployeeAddress>Auckland</EmployeeAddress> <Department>IT</Department> </EmployeeData> <EmployeeData> <EmployeeId>202</EmployeeId> <EmployeeName>Bhajan</EmployeeName> <EmployeeAddress>Wellington</EmployeeAddress> <Department>IT</Department> </EmployeeData> </EmployeeDetails> </soapenv:Body> </soapenv:Envelope>
ESB Changes:
I have created a service which will get all
the details of the overseas employee for different department. I will call all the
endpoints (Indian, USA and New Zealand employee details) and aggregate the
response into one. I have to use same input and that will be cloned for each endpoint
from the clone mediator.
Synapse
Code:
<definitions> <proxy name="OverseasEmpDetailsProxy" transports="http" startOnLoad="true" trace="disable" statistics="enable"> <target inSequence="OverseasEmpDetails_IN" outSequence="OverseasEmpDetails_OUT" faultSequence="CommonFaultHandler"/> <publishWSDL key="OverseasEmpDetails_wsdl"/> </proxy> <localEntry key="OverseasEmpDetails_wsdl" src="file:repository/conf/employee/OverseaseEmployee.wsdl"/> <sequence name="OverseasEmpDetails_IN"> <clone> <target> <endpoint key="NZEmployeeDetails_EPR"/> </target> <target> <endpoint key="INDEmployeeDetails_EPR"/> </target> <target> <endpoint key="USAEmployeeDetails_EPR"/> </target> </clone> </sequence> <sequence name="OverseasEmpDetails_OUT"> <aggregate> <completeCondition> <messageCount min="-1" max="-1"/> </completeCondition> <onComplete xmlns:shr="http://shriwithjava.blogspot.co.nz/" expression="//shr:EmployeeDetails/shr:EmployeeData"> <send/> </onComplete> </aggregate> </sequence> <endpoint name="NZEmployeeDetails_EPR"> <address uri="http://localhost:9763/services/EmployeeDetailsNZ"> <timeout> <duration>10000</duration> <responseAction>fault</responseAction> </timeout> <suspendOnFailure> <errorCodes>101500,101501,101506,101507,101508</errorCodes> <progressionFactor>0.0</progressionFactor> </suspendOnFailure> <markForSuspension> <errorCodes>101504,101505</errorCodes> </markForSuspension> </address> </endpoint> <endpoint name="INDEmployeeDetails_EPR"> <address uri="http://localhost:9763/services/EmployeeDetailsIndia"> <timeout> <duration>10000</duration> <responseAction>fault</responseAction> </timeout> <suspendOnFailure> <errorCodes>101500,101501,101506,101507,101508</errorCodes> <progressionFactor>0.0</progressionFactor> </suspendOnFailure> <markForSuspension> <errorCodes>101504,101505</errorCodes> </markForSuspension> </address> </endpoint> <endpoint name="USAEmployeeDetails_EPR"> <address uri="http://localhost:9763/services/EmployeeDetailsUSA"> <timeout> <duration>10000</duration> <responseAction>fault</responseAction> </timeout> <suspendOnFailure> <errorCodes>101500,101501,101506,101507,101508</errorCodes> <progressionFactor>0.0</progressionFactor> </suspendOnFailure> <markForSuspension> <errorCodes>101504,101505</errorCodes> </markForSuspension> </address> </endpoint> <sequence name="CommonFaultHandler"> <log level="custom"> <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> <header name="To" action="remove"/> <drop/> </sequence> </definitions>
Restart the ESB and load the WSDL in SOAP
UI results will look like:
Request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:shr="http://shriwithjava.blogspot.co.nz/"> <soapenv:Header/> <soapenv:Body> <shr:getEmployeeDetails> <shr:Department>IT</shr:Department> </shr:getEmployeeDetails> </soapenv:Body> </soapenv:Envelope>
Response:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Body> <EmployeeDetails xmlns="http://shriwithjava.blogspot.co.nz/"> <EmployeeData> <EmployeeId>201</EmployeeId> <EmployeeName>Shri</EmployeeName> <EmployeeAddress>Auckland</EmployeeAddress> <Department>IT</Department> </EmployeeData> <EmployeeData> <EmployeeId>202</EmployeeId> <EmployeeName>Bhajan</EmployeeName> <EmployeeAddress>Wellington</EmployeeAddress> <Department>IT</Department> </EmployeeData> <EmployeeData> <EmployeeId>004</EmployeeId> <EmployeeName>Viru</EmployeeName> <EmployeeAddress>Kanpur</EmployeeAddress> <Department>IT</Department> </EmployeeData> <EmployeeData> <EmployeeId>111</EmployeeId> <EmployeeName>Tahseen</EmployeeName> <EmployeeAddress>New York</EmployeeAddress> <Department>IT</Department> </EmployeeData> <EmployeeData> <EmployeeId>113</EmployeeId> <EmployeeName>JD</EmployeeName> <EmployeeAddress>Washington</EmployeeAddress> <Department>IT</Department> </EmployeeData> </EmployeeDetails> </soapenv:Body> </soapenv:Envelope>
You can see the response from different service
have been merged into one and we only sent a single request with a department parameter.