I'm using Apache Camel 2.20.0 and deploying a REST service using REST DSL with a HTTP scheme.
I'm referencing sslContextParameters with hard coded values and all works just fine.
I can't find a way of externalizing the resource into a properties file. So far I've tried with Camel PropertiesComponent and also Spring PropertyPlaceholderConfigurer and BridgePropertyPlaceholderConfigurer and I want to be able to do the following in the config:
<camel:sslContextParameters camelContextId="camelContext1" id="routeSSLContextParameters">
<camel:keyManagers keyPassword="{{mypassword}}">
<camel:keyStore password="{{mypassword}}"
resource="{{mykeystore}}" type="JKS"/>
</camel:keyManagers>
<camel:trustManagers>
<camel:keyStore password="{{mypassword}}"
resource="{{mykeystore}}" type="JKS"/>
</camel:trustManagers>
</camel:sslContextParameters>
I've also tried putting ${} as per Spring properties, this also does not work.
Would it be possible to tell me where I'm going wrong?
Try adding the BridgePropertyPlaceholderConfigurer to your Spring Context and use the ${} placeholder:
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- bridge spring property placeholder with Camel -->
<!-- you must NOT use the <context:property-placeholder at the same time,
only this bridge bean -->
<bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer">
<property name="location" value="classpath:com/stackoverflow/camel/labs/keys.properties" />
</bean>
<camel:camelContext id="exampleSsl" />
<camel:keyStoreParameters id="ksp" camelContextId="exampleSsl" resource="${keyStoreParameters.resource}" type="${keyStoreParameters.type}" provider="${keyStoreParameters.provider}" password="${keyStoreParamerers.password}" />
</beans>
The properties file:
keyStoreParameters.resource=/users/home/server/keystore.jks
keyStoreParameters.type=jks
keyStoreParameters.provider=jks
keyStoreParamerers.password=test
And the unit test:
public class SSLPlaceholderCamelTest extends CamelSpringTestSupport {
#Test
public void test() {
assertNotNull(super.context);
KeyStoreParameters ksp = (KeyStoreParameters)super.applicationContext.getBean("ksp");
assertThat(ksp.getType(), is("jks"));
assertThat(ksp.getProvider(), is("jks"));
assertThat(ksp.getResource(), is("/users/home/server/keystore.jks"));
assertThat(ksp.getPassword(), is("test"));
}
#Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("com/stackoverflow/camel/labs/SSLPlaceholderCamelTest.xml");
}
}
EDIT:
Yeah, I've tested with camel:sslContextParameters and the properties weren't bidden. You could access it via context and set programmatic (Setting Client Authentication On the Server Side):
KeyStoreParameters ksp = (KeyStoreParameters)context.getBean("keystore");
KeyStoreParameters tsp = (KeyStoreParameters)context.getBean("truststore");
KeyManagersParameters kmp = new KeyManagersParameters();
kmp.setKeyStore(ksp);
kmp.setKeyPassword("keyPassword");
SSLContextServerParameters scsp = new SSLContextServerParameters();
scsp.setClientAuthentication(ClientAuthentication.REQUIRE);
SSLContextParameters scp = (SSLContextParameters)context.getBean("sslContext");
scp.setServerParameters(scsp);
scp.setKeyManagers(kmp);
SSLContext context = scp.createSSLContext();
SSLEngine engine = scp.createSSLEngine();
The context:
<camel:keyStoreParameters id="keystore"
camelContextId="exampleSsl" resource="${keyStoreParameters.resource}"
type="${keyStoreParameters.type}" provider="${keyStoreParameters.provider}"
password="${keyStoreParamerers.password}" />
<camel:keyStoreParameters id="trustsore"
camelContextId="exampleSsl" resource="${keyStoreParameters.resource}"
type="${keyStoreParameters.type}" provider="${keyStoreParameters.provider}"
password="${keyStoreParamerers.password}" />
<camel:sslContextParameters id="sslContext" camelContextId="exampleSsl" />
Just "autowire" it in your Camel Context.
This is what I did in the end:
1.Use Spring/Camel properties bridge:
<bean class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer" id="springProperties">
<property name="location" value="classpath:application.properties"/>
</bean>
2.Set up the SSLContext Parameters from Spring:
<bean class="org.apache.camel.util.jsse.SSLContextParameters" id="routeSSLContextParameters">
<property name="keyManagers" ref="routeKeyManagers"/>
<property name="trustManagers" ref="routeTrustManagers"/>
<property name="serverParameters" ref="routeSSLContextServerParameters"/>
</bean>
<bean class="org.apache.camel.util.jsse.KeyManagersParameters" id="routeKeyManagers">
<property name="keyStore" ref="routeKeystore"/>
<property name="keyPassword" value="${keyStorePassword}"/>
</bean>
<bean class="org.apache.camel.util.jsse.TrustManagersParameters" id="routeTrustManagers">
<property name="keyStore" ref="routeTruststore"/>
</bean>
<bean class="org.apache.camel.util.jsse.SSLContextServerParameters" id="routeSSLContextServerParameters">
<property name="clientAuthentication" value="REQUIRE"/>
</bean>
<keyStoreParameters id="routeKeystore" password="${keyStorePassword}" resource="${keyStoreResource}" type="JKS" xmlns="http://camel.apache.org/schema/spring"/>
<keyStoreParameters id="routeTruststore" password="${trustStorePassword}" resource="${trustStoreResource}" type="JKS" xmlns="http://camel.apache.org/schema/spring"/>
Reference the SSLContext in the restconfiguration
<restConfiguration apiContextPath="api-docs" bindingMode="json" component="restlet" contextPath="/mytest" enableCORS="true"
host="localhost" port="9090" scheme="https">
<endpointProperty key="sslContextParameters" value="#routeSSLContextParameters"/>.....
Related
We have an issue in the application that the jms message commit on the ibm mq takes hours to complete which inturn causing the log space filling up in ibm mq and also JVM hung issues on the application side. To resolve this, I tried implementing the transaction timeout on the route, jms component etc. But nothing looks to be working.
There are 3 routes in the application
To Read message (Start route)
Deliver/Send message
Error Route (sending to error queue)
The Route definitions are below,
Input/Consumer Route
public class InputRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
from("wmqInConsumer:{{mq.inputQueue}}?concurrentConsumers={{num.consumers}}&maxConcurrentConsumers={{max.num.consumers}}&defaultTaskExecutorType=ThreadPool&preserveMessageQos=true").routeId("input-route").setHeader("Message_Key").method("headerEnricher", "setKey").inOnly("direct:deliver-normal-route-1");
}
}
Deliver Route
public class DeliverRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
from("direct:deliver-normal-route-1").transacted("PROPAGATION_REQUIRES_NEW").inOnly("direct:deliver-route-2");
from("direct:deliver-route-2").process("myServicesProcessor").split()
.method("messageSplitterBean", "splitMessage").shareUnitOfWork().stopOnException()
.toD("wmqDeliverJms:${headers.Deliver}?preserveMessageQos=true");
}
}
Error Route
public class ErrorRoute extends SpringRouteBuilder {
#Override
public void configure() throws Exception {
from("direct:errorChannelRoute").transacted("PROPAGATION_REQUIRES_NEW").inOnly("direct:errorChannelRoute-1");
from("direct:errorChannelRoute-1").process("errorServicesProcessor").split()
.method("messageSplitterBean", "splitErrorMessage").shareUnitOfWork().stopOnException()
.toD("wmqDeliverJms:${headers.Deliver}?preserveMessageQos=true");
}
}
Here the transaction timeouts I tried based on the Camel documentation. But It's not working and I don't see transaction timeout happening in the trace logs too. Also, not sure what will happen to the message if the timeout occurs. Will it go to error queues or full rollback for a retry??
On Input Route, transactionTimeout=10
from("wmqInConsumer:{{mq.inputQueue}}?concurrentConsumers={{num.consumers}}&maxConcurrentConsumers={{max.num.consumers}}&defaultTaskExecutorType=ThreadPool&preserveMessageQos=true&transactionTimeout=10").routeId("input-route").setHeader("Message_Key").method("headerEnricher", "setKey").inOnly("direct:deliver-normal-route-1");
On Input Route JMS Component,
<bean id="wmqInConsumer" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="myConnectionFactory" />
<property name="transacted" value="true" />
<property name="transactionTimeout" value="30"></property> -->
</bean>
On Deliver Route JMS Component,
<bean id="wmqDeliverJms" class="org.apache.camel.component.jms.JmsComponent">
<property name="connectionFactory" ref="myConnectionFactory" />
<property name="destinationResolver" ref="myJmsDestinationResolver" />
<property name="transacted" value="true" />
<property name="transactionTimeout" value="30"></property>
</bean>
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
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.
I need to set the use-x-forwarded-headers Http header in camel-cxf like the below and make it as an OSGi bundle to be deployed in Karaf.
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<init-param>
<param-name>use-x-forwarded-headers</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I don't want to package this as a WAR, instead i want to make it an OSGi bundle.
Hence, i created a class which extends CXFNonSpringServlet as the code below and set the init-params,
public class XForwadedServlet extends CXFNonSpringServlet {
#Override
protected void loadBus(ServletConfig sc) {
sc.getServletContext().setInitParameter("use-x-forwarded-headers",
"true");
super.loadBus(sc);
Bus bus = getBus();
BusFactory.setDefaultBus(bus);
// createFactoryBean();
}
#Override
public void init(ServletConfig sc) throws ServletException {
sc.getServletContext().setInitParameter("use-x-forwarded-headers",
"true");
super.init(sc);
}
And here's my camel route,
<cxf:cxfEndpoint id="serviceEndpoint"
address="http://localhost:8123/cxf/testCxfRedirect"
loggingFeatureEnabled="true" serviceClass="com.redhat.HelloServiceImpl">
</cxf:cxfEndpoint>
<camelContext trace="false" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:serviceEndpoint"/>
<log message="${body}" loggingLevel="INFO"/>
<bean ref="clientAddress" method="getClientAddress"/>
</route>
</camelContext>
<bean id="destinationRegistry" class="org.apache.cxf.transport.http.DestinationRegistryImpl">
</bean>
<bean id="osgiServlet" class="com.redhat.XForwadedServlet">
<constructor-arg ref="destinationRegistry"></constructor-arg>
<constructor-arg value="true"></constructor-arg>
</bean>
Through soapui, i set the X-Forwarded-For header as below,
Address: http://localhost:8123/cxf/testCxfRedirect
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=[""], X-Forwarded-For=[http://google.com]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHello xmlns:ns1="http://redhat.com/"><arg0 xmlns="http://redhat.com/">Test</arg0></ns1:sayHello></soap:Body></soap:Envelope>
--------------------------------------
How can i register the CXFNonSpringServlet in OSGi Blueprint container with setting that init-params ?
Is there a way to do this in OSGi ?
This can be achieved by using the pax-web-extender support in Fuse, Camel.
However the packaging will need to be WAR.
Here's the reference from Karaf:
https://ops4j1.jira.com/wiki/display/ops4j/Pax+Web+Extender+-+War+-+Examples
Here's a reference implementation from the Camel Committers:
https://github.com/apache/camel/tree/master/examples/camel-example-reportincident
Hope it helps.
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.