ActiveMQ Splitter / aggregator using jms transport - jboss

I have a problem with the activemq *aggregator*, would be very thankfull if someone would help me out somehow. Marshaling into a xml.
So i have my route configured like this:
<route id="myRoute">
<from uri="timer:someScheduler?period=5000" />
<bean ref="someBean" method="someMethod" />
<marshal>
<jaxb contextPath="some package" />
</marshal>
<split streaming="true">
<tokenize token="#id" group="1000" />
<to uri="activemq:topic:some_topic" />
</split>
</route>
This works and it splits my xml messages composed by 1k rows, tho dunno how to configure the aggregator in order to put together all the messages before proceding with their processing.
This is it(doesn't work):
<route id="myRoute">
<from uri="activemq:topic:some_Topic" />
<aggregate completionSize="5">
<correlationExpression>
<constant>true</constant>
</correlationExpression>
<to uri="mock:aggregated"/>
</aggregate>
<unmarshal>
<jaxb contextPath="some_package" />
</unmarshal>
<bean ref="someBean" method="someMethod" />
</route>
Thanks in advance!

What you need to do is to provide the aggregator with an implementation of an AggregationStrategy - this is a class that tells the pattern how to assemble two objects that match the correllationExpression. See Camel Aggregator for an example as to how to do this.

Related

Apache camel set mongodb collection dynamically

I'm trying to create a route where the endpoint depents on the incoming message. The aim is to write into a mongodb in different databases and collection.
I'm looking for an easy way to get the information from the message header and write it in to the <to uri=""/>
<route>
<from uri="jms:topic:BUS_IN" />
<to uri="mongodb:myDb?database=${header.someValue}&collection=storyTeaser&operation=save" />
</route>
Thanks a lot
You could add a second route that sets the header variables:
<route>
<from uri="jms:topic:BUS_IN" />
<camel:setHeader headerName="CamelMongoDbDatabase">
<camel:simple>testmydb</camel:simple>
</camel:setHeader>
<camel:setHeader headerName="CamelMongoDbCollection">
<camel:simple>mycollection</camel:simple>
</camel:setHeader>
<to uri="jms:queue:mongodb.out"/>
</route>
And then add the parameter "dynamicity" in the uri of your first route:
<route>
<from uri="jms:queue:mongodb.out" />
<to uri="mongodb:myDb?database=new_test&collection=old&dynamicity=true&operation=save"/>
</route>
Using Apache Camels toD function https://camel.apache.org/message-endpoint.html will allow you to dynamically set the URI as messages are passed through. The URI allows for simple language https://camel.apache.org/simple.html where we can for instance use the filename to generate a collection.
Heres an example Route:
from(input).routeId("SampleRoute")
.toD("mongodb3://mongoBean?database=myDB&collection=${file:onlyname.noext}&" +
"operation=insert&createCollection=true")

cxf jax-ws no complexType for subclasses while using generic method

I am not quite familiar with CXF configuration. Here I am encountering a situation that a object (subclass) is going to be used for client but it does not declare in Endpoint.
For example, there is a super class "SuperClass" and two subclasses "SubClassA" and "SubClassB". The following method is declared in Endpoint:
public <T extends SuperClass> T search(Criteria criteria, ClassType type);
Therefore, those subclasses do not appear in Endpoint and it causes that their complexType is missing in wsdl. Error saying no read type is prompted when the object of subclass is called from client.
org.apache.cxf.interceptor.Fault:
Could not determine how to read type: {http://model.fmchan.com}SubClassA
So here I would like to seek for a solution to add those subclasses into wsdl so as to be called properly on client side.
If it is properly configured, the following should be shown on wsdl:
<xsd:complexType name="SubClassA">
<xsd:sequence>
<xsd:element minOccurs="0" name="date" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>
Enclosed is the configuration on server side for your reference.
<import resource="classpath:META-INF/cxf/cxf.xml" />
<bean id="aegisContext" class="org.apache.cxf.aegis.AegisContext"
p:writeXsiTypes="true" scope="prototype" />
<bean id="aegisBean" p:aegisContext-ref="aegisContext"
class="org.apache.cxf.aegis.databinding.AegisDatabinding"
scope="prototype" />
<bean id="genericServiceImpl" class="com.fmchan.service.SomeEndpointImpl"/>
<jaxws:endpoint implementor="#genericServiceImpl"
address="${service.address}">
<jaxws:serviceFactory>
<ref bean="jaxws-and-aegis-service-factory" />
</jaxws:serviceFactory>
</jaxws:endpoint>
<bean id="jaxws-and-aegis-service-factory"
class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean"
scope="prototype">
<property name="dataBinding">
<bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
</property>
</bean>
Thank you for any help in advance.
The simplest solution I come up with is to create a dummy method including those subclasses A and B as parameters for endpoint. It probably isn't the best solution and I still seek for better one.

URI to Spring DSL How do I pass in REST Get Parameters

An example URI for my rest service is as follows:
http://xx.xx.xxx.xx:8080/myservice/service/encode?encrypt=true&payload=11/11/2013%207:59:15%20AM&ttl=10h
The service route I am using on the node with my service on it is as follows. This works fine. The route should bridge whatever we give it through to the service.
<route id="my-server">
<from uri="fabric-camel:myClusterId:jetty:http://xx.xx.xxx.xx:8484/myservice/service?matchOnUriPrefix=true" />
<to uri="jetty:http://xx.xx.xxx.xx:8080/myservice/service?bridgeEndpoint=true&throwExceptionOnFailure=false" />
</route>
My trouble is with the client route. The time component is working fine but my efforts to append anything to the GET have failed. If I can figure out how to do this I can create any number of client examples.
<route id="fabric-client" errorHandlerRef="errorHandler">
<from uri="timer://foo?fixedRate=true&period=1000"/>
<to uri="fabric-camel:myClusterId"/>
</route>
Can someone give me a leg up by converting the URI example above to Sprint DSL? I am hoping you can show me how to do it. From that I can figure out how to pass in variables.
Here is the answer to my syntax question.
<route id="fabric-client" errorHandlerRef="errorHandler">
<from uri="timer://foo?fixedRate=true&period=1000"/>
<setHeader headerName="CamelHttpPath">
<simple>/encode?encrypt=true&payload=11/11/2013%207:59:15%20AM&ttl=10h</simple>
</setHeader>
<to uri="fabric-camel:myClusterId"/>
<log message=">>> ${body}"/>
</route>
This post was the key. http://camel.465427.n5.nabble.com/Setting-url-params-in-REST-call-with-Camel-td2257861.html Took a lot of Googling.
This reference might help other people it helped me; especially the side by side Java and Spring DSL.
http://people.apache.org/~dkulp/camel/http.html I actually can't remember how I figured out how to map Exchange.HTTP_PATH to CamelHttpPath. I think I had to guess - getting late.

wso2esb enrich mediator deletes node soap:Header

I have 2 child wsse:Security in soap:Header and trying to delete one. I tried to do this with Enrich Mediator, but instead of replace soap:Header it deletes. Here is simple example that reproduces it:
<inSequence>
<enrich>
<source type="inline" clone="true">
<soapenv:Header xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<foo/>
</soapenv:Header>
</source>
<target xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xpath="//soapenv:Header"/>
</enrich>
<log level="full"/>
</inSequence>
Log mediator logs message without Header. If I add to target action="child", everything work just as expected. So i have 2 questions:
1. Why enrich mediator act like that?
2. How can i change header with other way?
You should use header mediator to change SOAP Headers
Have a look there : https://docs.wso2.com/display/ESB481/Header+Mediator
Sample to add a custom header :
<header xmlns:myns="http://com/header" name="myns:MyHeader" value="0"/>
Sample to remove it :
<header xmlns:myns="http://com/header" name="myns:MyHeader" action="remove"/>
You can use this mediator to change http headers : just add a scope attribute with a value equals to 'transport'

Default route is matched instead specific route

<routes>
<www type="Zend_Controller_Router_Route_Hostname">
<route>www.domain.com</route>
<chains>
<index type="Zend_Controller_Router_Route">
<route></route>
<defaults module="default" controller="index" action="index" />
</index>
<community>
<route>community</route>
<defaults module="community" />
<chains>
<index type="Zend_Controller_Router_Route">
<route>:action/*</route>
<defaults controller="index" action="index" />
</index>
<member type="Zend_Controller_Router_Route_Regex">
<route>member/profile-(\d+)-(.+)</route>
<reverse>member/profile-%d-%s</reverse>
<map>
<id>1</id>
<nom>2</nom>
</map>
<defaults action="viewmember" />
</member>
</chains>
</community>
</chains>
</www>
As you can see, I use a route with :action/* in to cover the homepages and the basics actions on index controller.
domain.com/community/random_action => works good.
domain.com/community/ doesn't work. The whole homepage is displayed.
I checked, and the default route is matched.
I tried assemble() on route "www-community-index" and it gives well www.domain.com/community
I don't see from where comes the problem :(
The first thing you should check is if you deleted the default route.
The second one is....remember that the routes are checked in reverse order. This means that the most specific should be the first and the default the last one.