Mule - Object to parameters in Database - database

I have this mule flow:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:db="http://www.mulesoft.org/schema/mule/db" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.5.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd">
<spring:beans>
<spring:bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="locations">
<spring:list>
<spring:value>configSQL.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
</spring:beans>
<db:generic-config name="BBDD_USER" doc:name="Generic Database Configuration" driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="${sql.url}/${sql.database};user=${sql.username};password=${sql.password}"/>
<flow name="sincro-sql" doc:name="sincro-sql">
<http:inbound-endpoint exchange-pattern="one-way" host="localhost" port="8042" doc:name="HTTP"/>
<logger message="#[message.payloadAs(java.lang.String)]" level="INFO" doc:name="JSON"/>
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="json.database.object.Data"/>
<db:stored-procedure config-ref="BBDD_USER" doc:name="Data" source="json.database.object.Data" streaming="true">
<db:parameterized-query><![CDATA[{ CALL dbo.ExecSQL(:table_name, :field_name) }]]></db:parameterized-query>
<db:in-param name="field_name" type="VARCHAR" value="field_test"/>
<db:in-param name="table_name" type="VARCHAR" value="table_test"/>
</db:stored-procedure>
</flow>
</mule>
It receives a JSON that I transform to object with a class that contains:
#JsonAutoDetect
public class Data{
private String table_name;
private String field_name;
public void setTableName(String table_name) {
this.table_name= table_name;
}
public String getTableName() {
return table_name;
}
public void setFieldName(String field_name) {
this.field_name= field_name;
}
public String getFieldName() {
return field_name;
}
}
And finally, I call to my database. How can I assign, for example, the property about the table name from the class to the parameter in the database element?
For example,
<db:in-param name="table_name" type="VARCHAR" value="PROPERTY OF CLASS"/>

Use MEL(Mule Expression Langauge) and standard Java method invocation. As Data is you payload, use #[payload.table_name] MEL will automatically use the getter for that field.

Related

Apache Camel + Karaf - Using Atmosphere-websocket as client

After having installed my Websocket on Apache Karaf, I am now trying to communicate with it through an Apache Camel blueprint using ATMOSPHERE WEBSOCKET. (I can reach it through a javascript websocket client)
I am getting the following error though :
Blueprint bundle allin.opcmid/0.0.3 is waiting for dependencies [(&(component=atmosphere-websocket)(objectClass=org.apache.camel.spi.ComponentResolver))]
My websocket registration looks like this :
#WebServlet(name = "Allin WebSocket Servlet", urlPatterns = { "/allin-websocket"})
public class AllinWSServlet extends WebSocketServlet {
#Override
public void configure(WebSocketServletFactory factory) {
factory.register(AllinWS.class);
}
}
And the header part of the websocket like this:
#Component(name = "allin-websocket", immediate = true)
#WebSocket
public class AllinWS {
#Reference
private HttpService httpService;
#Activate
public void activate() throws Exception {
httpService.registerServlet("/allin-websocket", new AllinWSServlet(), null, null);
}
Now when I am running my Apache Camel route installed on my Apache Karaf instance, I'm getting the error I have described above. The blueprint looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd
http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.1.0.xsd">
<camelContext id="opcm" xmlns="http://camel.apache.org/schema/blueprint">
<route id="rece">
<from uri="atmosphere-websocket:///allin-websocket" />
<log message="${body}"/>
<to uri="mock:result"/>
</route>
</camelContext>
</blueprint>
Best regards

Implementing a CXF Web service using Camel

I'm trying to expose a Code First Web service using Camel CXF Component. By assembling some of the available examples, I've come to the following route definition:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<bean id="productServiceImpl" class="com.demo.ws.CustomerServiceImpl" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:productServiceEndpoint" />
<bean ref="productServiceImpl" />
<!-- log input received -->
<to uri="log:output" />
</route>
</camelContext>
<cxf:cxfEndpoint id="productServiceEndpoint"
address="http://localhost:9001/productService" serviceClass="com.demo.ws.CustomerService" />
</beans>
The SEI and implementation classes I'm using are trivial:
#WebService(serviceName="customerService")
public interface CustomerService
{
public String getCustomerById(String customerId);
}
public class CustomerServiceImpl implements CustomerService
{
#Override
public String getCustomerById(String customerId)
{
System.out.println("Called with "+customerId);
return "Hello " +customerId;
}
}
When running the project, the Webservice the implementation class is called correctly, returning the String "Hello [name]", however the returned body from SOAPUI is empty:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body/>
</soap:Envelope>
Can you help me to produce the return value in the Response ?
Thank you
You should return a SOAP message :
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
SOAPBody body = soapMessage.getSOAPPart().getEnvelope().getBody();
QName payloadName = new QName("http://apache.org/hello_world_soap_http/types", "greetMeResponse", "ns1");
SOAPBodyElement payload = body.addBodyElement(payloadName);
SOAPElement message = payload.addChildElement("responseType");
message.addTextNode("Your custom message");
return soapMessage;
You can also take a look to the camel doc examples : http://camel.apache.org/cxf-example.html

spring camel test using multiple contexts

I have two camel contexts (A and B) at different xml using Spring. When I load just one context my junit works, but when a I try to load both contexts the Endpoint inject fail running junit.
So, someone have a sample how to use Test using multiple context with spring camel?
Spring Test
public class BaseSpringTest extends CamelSpringTestSupport
{
protected AbstractXmlApplicationContext createApplicationContext()
{
return new ClassPathXmlApplicationContext("camel-config.xml");
}
}
My file camel-config.xml
<beans>
<context:annotation-config/>
<import resource="classpath:camel-test-dao.xml" />
<import resource="classpath:camel-contextA.xml"/>
<import resource="classpath:camel-contextB.xml"/>
</beans>
My contexts:
<camelContext xmlns="camel.apache.org/schema/spring" id="contextA">
...
</camelContext>
<camelContext xmlns="camel.apache.org/schema/spring" id="contextB">
...
</camelContext>
My unit test, failing at inject Endpoint:
#EndpointInject(uri = "direct:myroute", context="contextB")
private Endpoint eFooTest;
Stacktrace:
org.apache.camel.spring.GenericBeansException: Error post processing bean: com.mycompany.test.FooTest; nested exception is java.lang.NullPointerException
at org.apache.camel.spring.CamelBeanPostProcessor.postProcessBeforeInitialization(CamelBeanPostProcessor.java:154)
at org.apache.camel.test.spring.CamelSpringTestSupport.postProcessTest(CamelSpringTestSupport.java:62)
at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:319)
at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:238)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NullPointerException
at org.apache.camel.impl.CamelPostProcessorHelper.matchContext(CamelPostProcessorHelper.java:84)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor$1.doWith(DefaultCamelBeanPostProcessor.java:181)
at org.apache.camel.util.ReflectionHelper.doWithFields(ReflectionHelper.java:73)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor.injectFields(DefaultCamelBeanPostProcessor.java:168)
at org.apache.camel.impl.DefaultCamelBeanPostProcessor.postProcessBeforeInitialization(DefaultCamelBeanPostProcessor.java:82)
at org.apache.camel.spring.CamelBeanPostProcessor.postProcessBeforeInitialization(CamelBeanPostProcessor.java:148)
... 31 more
Apparently there is a bug at CamelBeanPostProcessor, when there are more one context a null value is returned!
if (contexts != null && contexts.size() == 1) {
#XmlTransient
private final DefaultCamelBeanPostProcessor delegate = new DefaultCamelBeanPostProcessor() {
#Override
public CamelContext getOrLookupCamelContext() {
if (camelContext == null) {
if (camelId != null) {
LOG.trace("Looking up CamelContext by id: {} from Spring ApplicationContext: {}", camelId, applicationContext);
camelContext = applicationContext.getBean(camelId, CamelContext.class);
} else {
// lookup by type and grab the single CamelContext if exists
LOG.trace("Looking up CamelContext by type from Spring ApplicationContext: {}", applicationContext);
Map<String, CamelContext> contexts = applicationContext.getBeansOfType(CamelContext.class);
if (contexts != null && contexts.size() == 1) {
camelContext = contexts.values().iterator().next();
}
}
}
return camelContext;
}
Camel 2.16.2
Spring 4.1.5
JDK 1.7
JDK 1.8
Thanks #Jorge-c, but using routeContext we continuous having just one single CamelContext.
To use multiply contexts at unit test don't use CamelSpringTestSupport, there are a bug.
public class BaseSpringTest extends CamelSpringTestSupport {...}
Use "#RunWith(SpringJUnit4ClassRunner.class)"
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/camel-my-root-spring-config.xml")
public class BaseSpringJUnit4
{
#EndpointInject(uri = "direct:myroute", context="contextB")
private Endpoint eFooTest;
}
This works! Doesn't forget to put explicitilly context="contextB" in the endpoint annotation
Camel 2.16.2
Spring 4.1.5
JDK 1.7
JDK 1.8
I've been struggling with this for a while as well. Finally I managed a workaround which allows me to use the original routes xml files used in production but combined into a single camel context to be able to use it for testing. This way I'm able to inject mocks for bean endpoints and check the complete process by asserting on the mocks.
There are two different bundles. One from invoicing and another for emailing. The routes orchestrate the process.
First I externalized the routes on the production xml files. Spring context (invoicing-spring-context.xml) and routes (invoicing-routes.xml) file for invoicing bundle:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="invoicingCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="invoicingRoutes"/>
</camelContext>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<routeContext id="invoicingRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="planner" autoStartup="true">
<from uri="quartz://planner?cron=0+0+23+16+*+?" />
<to uri="direct:invoicing" />
</route>
<route id="invoicing" autoStartup="true">
<from uri="direct:invoicing?exchangePattern=InOut" />
<to uri="bean:invoicer?method=generateInvoices" />
<to uri="direct-vm:emailing" />
</route>
</routeContext>
</beans>
Spring context (emailing-spring-context.xml) and routes (emailing-routes.xml) for emailing bundle:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="emailingCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="emailingRoutes"/>
</camelContext>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
<routeContext id="emailingRoutes" xmlns="http://camel.apache.org/schema/spring">
<route id="emailing" autoStartup="true">
<from uri="direct-vm:emailing" />
<to uri="bean:emailer?method=createEmails" />
<to uri="bean:emailer?method=sendEmails" />
</route>
</routeContext>
</beans>
Then for testing purposes I created another spring context (complete-process-test-spring-context.xml) which imports both routes files:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
...
<camelContext id="completeProcessTestCamelContext"
xmlns="http://camel.apache.org/schema/spring">
<routeContextRef ref="invoicingRoutes"/>
<routeContextRef ref="emailingRoutes"/>
</camelContext>
</beans>
And the test class looks like:
public class CompleteProcessTest extends CamelSpringTestSupport {
#Test
public void completeProcess() {
...
invoicerMock.generateInvoices(EasyMock.isA(Exchange.class));
emailerMock.createEmails(EasyMock.isA(Exchange.class));
emailerMock.sendEmails(EasyMock.isA(Exchange.class));
EasyMock.replay(invoicerMock);
EasyMock.replay(emailerMock);
this.template.requestBody(this.context.getEndpoint("direct://invoicing"), "");
EasyMock.verify(invoicerMock);
EasyMock.verify(emailerMock);
}
#Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("classpath:/META-INF/spring/invoicing-routes.xml",
"classpath:/META-INF/spring/emailing-routes.xml",
"classpath:/META-INF/spring/complete-process-test-spring-context.xml");
}
...
}

Apache camel how to insert map value to data base using sql component

Apache camel how to insert map value to data base using SQL component
My Class file:
public class PolluxDataController {
List<PolluxData> stationsMasterList=new ArrayList<PolluxData>();
List<PolluxData> stationProccessedList=new ArrayList<PolluxData>();
Map<String,Object> stationMap=new HashMap<String,Object>();
#SuppressWarnings("unchecked")
public Map<String, Object> processPolluxData(Exchange exchange) throws Exception {
stationsMasterList= (List<PolluxData>) exchange.getIn().getBody();
for (PolluxData value:stationsMasterList){
System.out.println(value.getStationCode() +","+value.getStationShortDescription());
stationMap.put("id",value.getStationCode());
stationMap.put("ltr", value.getStationShortDescription());
}
return stationMap;
}
sql.properties file is:
sql.insertNewRecord=INSERT INTO GSI_DEVL.POLLUX_DATA(STID,CLLTR) VALUES(:#id,#ltr)
Context.xml is
<!-- configure the Camel SQL component to use the JDBC data source -->
<bean id="sqlComponent" class="org.apache.camel.component.sql.SqlComponent">
<property name="dataSource" ref="dataSource" />
</bean>
<bean name="polluxDataController" id="polluxDataController" class="com.nielsen.polluxloadspring.controller.PolluxDataController" />
<camelContext trace="false" xmlns="http://camel.apache.org/schema/spring">
<!-- use Camel property placeholder loaded from the given file -->
<propertyPlaceholder id="placeholder" location="classpath:sql.properties" />
<camel:route id="bindy-csv-marhalling-unmarshalling-exmaple" autoStartup="true">
<camel:from uri="file://D://cameltest//input?noop=true&delay=10" />
<camel:log message="CAMEL BINDY CSV MARSHALLING UNMARSHALLING EXAMPLE" loggingLevel="WARN"/>
<camel:unmarshal ref="bindyDataformat" >
<camel:bindy type="Csv" classType="com.nielsen.polluxloadspring.model.PolluxData" />
</camel:unmarshal>
<camel:log message="Station Details are ${body}" loggingLevel="WARN" />
<camel:bean ref="polluxDataController" method="processPolluxData" />
<camel:log message="Station Details after bean process ${body}" loggingLevel="WARN" />
<to uri="sqlComponent:{{sql.insertNewRecord}}" />
<log message="Inserted new NewTopic ${body[id]}" />
<log message="Inserted new NewTopic ${body[ltr]}" />
<camel:log message="COMPLETED BINDY SIMPLE CSV EXAMPLE" loggingLevel="WARN" />
</camel:route>
</camelContext>
Problem is this will insert only one row to database, but the file contains 2000 rows how can I acheive this
Change the Bean method as below
public class PolluxDataController {
List<PolluxData> stationsMasterList=new ArrayList<PolluxData>();
Map<String,Object> stationMap=null;
List<Map<String,Object>> stationProccessedList=new ArrayList<Map<String,Object>>();
#SuppressWarnings("unchecked")
public List<Map<String,Object>> processPolluxData(Exchange exchange) throws Exception {
stationsMasterList= (List<PolluxData>) exchange.getIn().getBody();
for (PolluxData value:stationsMasterList){
System.out.println(value.getStationCode() +","+value.getStationShortDescription());
stationMap=new HashMap<String,Object>();
stationMap.put("id",value.getStationCode());
stationMap.put("ltr", value.getStationShortDescription());
stationProccessedList.add(stationMap);
}
return stationProccessedList;
}
}
change the sql.properties by adding a parameter batch=true , by default this will insert everything in your list to the db not once record. If you want to select and insert only two records at a time then your business logic is wrong.
You map stationMap will contains only two entries. In for (PolluxData value:stationsMasterList) you always reset this two entries for each PolluxData. Only one map with two enties within - only one insert, not 2000. Something wrong in business logic (with algorithm of filling the map stationMap, maybe), I think.

Error while using iterator mediator in wso2esb

I'm using wso2esb 4.7.0 and wso2dss 3.1.0.My scenario is i wish to select all partybranch regarding particular clientid. For that purpose i have fire a query like :
select partybranchid,clientid from mpartybranch where clientid = 473906852857651
and it gives me list of 2 records like :
partybranchid clientid
-2500000000 473906852857651
796243010946586 473906852857651
I wish to split these two and find out address regarding each of them.I have use following query in dss that works seperately for me is :
select * from address where partybranchid = ? and clientid =?
Now i have use iterator mediator in wso2esb to implement this in single click.My configuration is :
<iterate xmlns:f="http://ws.wso2.org/dataservice" continueParent="true" preservePayload="true" expression="//f:Datalist" id="iterate1" sequential="true">
<target>
<sequence>
<property xmlns:s="http://ws.wso2.org/dataservice" name="partybranchid1" expression="//s:partybranchid/text()" scope="default" type="STRING"/>
<property xmlns:s="http://ws.wso2.org/dataservice" name="latitude" expression="get-property('latitude')"/>
<property xmlns:s="http://ws.wso2.org/dataservice" name="longitude" expression="get-property('longitude')"/>
<property xmlns:s="http://ws.wso2.org/dataservice" name="radius" expression="get-property('radius')"/>
<payloadFactory media-type="xml">
<format>
<p:select_addresses_op xmlns:p="http://ws.wso2.org/dataservice">
<p:latitude>$1</p:latitude>
<p:longitude>$2</p:longitude>
<p:radius>$3</p:radius>
<p:objectid>$4</p:objectid>
</p:select_addresses_op>
</format>
<args>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('latitude')" evaluator="xml"/>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('longitude')" evaluator="xml"/>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('radius')" evaluator="xml"/>
<arg xmlns:s="http://ws.wso2.org/dataservice" expression="get-property('partybranchid1')" evaluator="xml"/>
</args>
</payloadFactory>
<property name="FORCE_SC_ACCEPTED" value="true" scope="axis2"/>
<property name="messageType" value="application/json" scope="axis2"/>
<send receive="spatial_seq3">
<endpoint>
<address uri="http://localhost:9764/services/Aspatialtrial_Dataservice/" format="soap11"/>
</endpoint>
</send>
</sequence>
</target>
</iterate>
This configuration is working but doesn't give expected output.Following are the outputs at client side and server side:
At server side(ESB) output :
[2014-09-25 09:52:30,941] INFO - LogMediator To: /services/spatial_proxy_test, MessageID: urn:uuid:c91c22b6-245f-49f7-bf30-65561c87050f, Direction: request, userid = null, username = vikash|214057357158656, password = gbadmin
[2014-09-25 09:52:30,953] INFO - TimeoutHandler This engine will expire all callbacks after : 120 seconds, irrespective of the timeout action, after the specified or optional timeout
[2014-09-25 09:52:31,286] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:9fa3c017-27f5-405e-a11b-33a9fa9a8f44, Direction: response, kk = true, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Body><ResponseJSON><Body><Datalist><Authentication>true</Authentication></Datalist></Body></ResponseJSON></soapenv:Body></soapenv:Envelope>
[2014-09-25 09:52:32,148] INFO - LogMediator FORCE_ERROR_ON_SOAP_FAULT = true, partybranchid1 = -2500000000796243010946586, latitude = 18.975, longitude = 72.8258, radius = 10
[2014-09-25 09:52:32,344] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:c635aa03-36ac-4af7-8b01-9bb31b35f4ef, Direction: response, Datalist values logged = <Datalist xmlns="http://ws.wso2.org/dataservice"><addressid>457492199890748451</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist>, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><DataCollection xmlns="http://ws.wso2.org/dataservice"><Datalist><addressid>457492199890748451</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist></DataCollection></soapenv:Body></soapenv:Envelope>
[2014-09-25 09:52:32,345] INFO - LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:e77556c0-b722-4f91-879b-1cbb4ae20aec, Direction: response, Datalist values logged = <Datalist xmlns="http://ws.wso2.org/dataservice"><addressid>456211760366486560</addressid><geocode>POINT(19.0769048 72.8570555)</geocode></Datalist><Datalist xmlns="http://ws.wso2.org/dataservice"><addressid>456217678470710306</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist>, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><DataCollection xmlns="http://ws.wso2.org/dataservice"><Datalist><addressid>456211760366486560</addressid><geocode>POINT(19.0769048 72.8570555)</geocode></Datalist><Datalist><addressid>456217678470710306</addressid><geocode>POINT(18.975 72.8258)</geocode></Datalist></DataCollection></soapenv:Body></soapenv:Envelope>
at client side output
{"ResponseJSON":{"Body":{"Datalist":{"addressid":"457492199890748451","geocode":"POINT(18.975 72.8258)"}},"Status":"200","Total":"1.0"}}
And request is :
curl -v -H "Accept: application/json" -H "Content-Type:application/json" -H "ModifiedOn:0" -H "username:vikash|214057357158656" -H "password:gbadmin" -d '{"usercode":"suresh","clientid":"473906852857651","longitude":"72.8258","radius":"10","latitude":"18.975"}' http://youtility-desktop:8282/services/spatial_proxy_test
Server side log shows that it is iterating fine but at client side gives response of one iteration only.Why so?IS their any changes regarding sequence options like ContinueParent or preservepayload etc..?Please let me know..
I test your scenario last night, my proxy look like this:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="AddressProxy"
transports="https http"
startOnLoad="true"
trace="disable">
<description/>
<target>
<inSequence>
<property xmlns:p="http://www.example.org/Address/"
name="clientid"
expression="//p:getAddress/clientid"
scope="default"
type="STRING"/>
<sequence key="conf:/sequencesStackOverFlow/getmpartybranch"/>
</inSequence>
<outSequence>
<aggregate>
<completeCondition>
<messageCount min="-1" max="2"/>
</completeCondition>
<onComplete xmlns:add="http://ws.wso2.org/dataservice"
expression="//add:Addresses/add:Address">
<send/>
</onComplete>
</aggregate>
</outSequence>
</target>
<publishWSDL key="conf:/wsdls/Address.wsdl"/>
</proxy>
And the sequences used in the insequence:
conf:/sequencesStackOverFlow/getmpartybranch
<sequence xmlns="http://ws.apache.org/ns/synapse">
<payloadFactory media-type="xml">
<format>
<dat:getmpartybranch xmlns:dat="http://ws.wso2.org/dataservice">
<dat:clientid>$1</dat:clientid>
</dat:getmpartybranch>
</format>
<args>
<arg xmlns:ns="http://org.apache.synapse/xsd" expression="get-property('clientid')" evaluator="xml"></arg>
</args>
</payloadFactory>
<send receive="conf:/sequencesStackOverFlow/iterOvermpartybranch">
<endpoint>
<address uri="http://127.0.0.1:5555/services/mpartybranch"></address>
</endpoint>
</send>
</sequence>
conf:/sequencesStackOverFlow/iterOvermpartybranch
<sequence xmlns="http://ws.apache.org/ns/synapse">
<iterate xmlns:ns="http://org.apache.synapse/xsd" xmlns:ds="http://ws.wso2.org/dataservice" expression="//ds:DataCollection/ds:Datalist" id="iterate1" sequential="true">
<target>
<sequence>
<property name="partybranchid" expression="//ds:partybranchid/text()" scope="default" type="STRING"></property>
<property name="clientid" expression="//ds:clientid/text()" scope="default" type="STRING"></property>
<log>
<property name="PARTYID" expression="get-property('partybranchid')"></property>
<property name="CLIENTID" expression="get-property('clientid')"></property>
</log>
<payloadFactory media-type="xml">
<format>
<dat:getselect_addresses xmlns:dat="http://ws.wso2.org/dataservice">
<dat:objectid>$1</dat:objectid>
<dat:clientid>$2</dat:clientid>
</dat:getselect_addresses>
</format>
<args>
<arg expression="get-property('partybranchid')" evaluator="xml"></arg>
<arg expression="get-property('clientid')" evaluator="xml"></arg>
</args>
</payloadFactory>
<log level="full"></log>
<send>
<endpoint>
<address uri="http://127.0.0.1:5555/services/getAddress" format="soap12"></address>
</endpoint>
</send>
</sequence>
</target>
</iterate>
</sequence>
You need to use the aggregate mediator to collect the responses and create one unique message to return to the client. Check my outsequence. In my case I just need to use the transformer mediator to change my payload according to the WSDL.

Resources