Camel Route from Jetty to Absolute URL - java

I have an OSGi bundle deployed on Apache Karaf. I have a simple camel route:
<camelContext trace="true" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="jetty:http://0.0.0.0:8282/services?handlers=securityHandler&matchOnUriPrefix=true"/>
<setHeader headerName="CamelHttpQuery">
<constant>wt=xml&rows=1000000&fl=nid,title&fq=sm_vid_Third_parties_with_which_this_organisation_s_content_can_be_shared:%22Indeed%22</constant>
</setHeader>
<to uri="http://172.28.128.158:8983/solr/targetjobs.co.uk.gtimedia.test/select/?"/>
<!-- <split>
<xpath>//int[#name='nid']</xpath>
</split>-->
<convertBodyTo type="java.lang.String" />
</route>
</camelContext>
I can not get it working. When I invoke http://localhost:8282/services it should route to the uri specified in below the setHeader. Instead I am getting this exception:
java.lang.IllegalArgumentException: Invalid uri: /services.
If you are forwarding/bridging http endpoints, then enable the bridgeEndpoint
option on the endpoint:
Endpoint[http://172.28.128.158:8983/solr/targetjobs.co.uk.gtimedia.test/select/]
It says that I need to enable bridge endpoint, but this is not an endpoint, it is an absolute URL to which I am trying to point my route.
I have tried to set up Spring as shown here but this did not work either.I have also tried to change this:
<to uri="http://172.28.128.158:8983/solr/targetjobs.co.uk.gtimedia.test/select/?"/>
to this:
<to uri="jetty//http://172.28.128.158:8983/solr/targetjobs.co.uk.gtimedia.test/select/?"/>
No success as well. Maybe someone knows how to route from jetty uri to absolute url?

Have you tried bridgeEndpoint? As described below:
http://camel.apache.org/how-to-use-camel-as-a-http-proxy-between-a-client-and-server.html
Your target url will look like:
<to uri="jetty//http://172.28.128.158:8983/solr/targetjobs.co.uk.gtimedia.test/select?bridgeEndpoint=true&throwExceptionOnFailure=false"/>

Worked for me:
#Override
public void configure() throws Exception {
restConfiguration()
.host("localhost")
.component("jetty")
.port("8085");
rest("/api")
//NEW ROUTE
.get("/getResidences")
.produces("application/json")
//OLD ROUTE
.to("http://localhost:3000/api/residences?bridgeEndpoint=true&throwExceptionOnFailure=false");
}
Note the .componet("jetty") in rest configuration

Related

Apache Camel Cannot modify json response

I'm bothered with returning an updated JSON, in fact, I receive a JSON defined as an opportunity (it's a business term, we don't need to explain it) from the cxfrs endpoint, convert it to String, then check the method invoked in jax-rs controller, if the we want make an update of Affair json, we publish the message as string in queue q.gestioncougar.cl.creation as described below:
<route id="serviceToCustomerLinksInboundRouting">
<from uri="cxfrs:bean:oab_serviceToObsIT?loggingFeatureEnabled={{gestioncougar.wscall.log.enable}}&loggingSizeLimit={{gestioncougar.wscall.log.size}}" />
<to uri="bean:log?method=info(*,'Body : ${body}')"/>
<convertBodyTo type="java.lang.String" />
<choice>
<when>
<simple>${header.operationName} == 'updateAffair'</simple>
<to uri="activemq:queue:q.gestioncougar.cl.creation?disableReplyTo=true" />
</when>
</choice>
</route>
The config of cxfrs service that is bonded to jax-rs controller:
<cxf:rsServer address="{{gestioncougar.service.in.obsit.url}}" id="oab_serviceToObsIT"
serviceClass="fr.oab.sie.esb.gestioncougar.customerLink.controller.CougarToCL" />
The JAX-RS controller:
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public interface CougarToCL {
#PUT
#Path("/updateAffair")
void updateAffair(String request);
}
Then we create a route that read from the queue q.gestioncougar.cl.creation, next unmarshal the body to POJO format (Java Model), moreover, read it by the method convertToCLFormat defined in the bean traiterCallFromCougar:
<route id="serviceToCustomerLinksCreationOutboundRoute">
<from uri="activemq:queue:q.gestioncougar.cl.creation" />
<!-- Sauvegarde du body initial -->
<unmarshal ref="formatJsonOpportunity" />
<!-- Sauvegarde du body -->
<setProperty propertyName="savedBody">
<simple>${body}</simple>
</setProperty>
<bean ref="traiterCallFromCougar" method="convertToCLFormat"/>
<to uri="bean:log?method=info(*,'CustomerLinks Body Format: ${body}')"/>
</route>
The method convertToCLFormat:
public void convertToCLFormat(Exchange exchange){
Opportunity opportunity = exchange.getProperty("savedBody",Opportunity.class);
EsbLogger.info(exchange, "opportunity {}", opportunity.toString());
exchange.getIn().setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
Affair affair = opportunityAffairMapper.toDealCL(opportunity.getDealCL());
String clBody = affairJsonParser.parsePojoToJson(affair);
EsbLogger.info(exchange, "affair {}", clBody);
exchange.getOut().setHeaders(exchange.getIn().getHeaders());
exchange.getOut().setBody(clBody);
}
and here is the problem !, even if I set the body with the newly mapped JSON defined as Affair, I don't see any change in postman response, but the body is changed when I check the log.
Take a look at the postman request:
Thanks a lot for your time and your help.
Do not put the converted JSON into the "out" message, but rather in the "in" one.
This was so confusing that they now recommend to simply use exchange.getMessage() (without any distinction whether in or out)
See more here:
https://camel.apache.org/manual/latest/camel-3-migration-guide.html#_getout_on_exchange
So this should work:
exchange.getMessage().setBody(clBody);

How to handle exception in blueprint route in camel project

I am working on camel project using JbossFuse. Here I am using blueprint. Now what I want is that when any exception comes in any of the route then that will be handled by some processor and a valid response will be returned to the client.
You can cover any of the route in blueprint file with try catch and process the final response to the client. The logic will be something like:
<route id="route_1">
<from id="_from_1" uri="direct:processDemo1"/>
<doTry id="_doTryDemo1">
<process id="_process_processDemo1" ref="processorBean"/>
<doCatch id="_doCatchDemo1">
<exception>java.lang.Exception</exception>
<to id="_handleExceptionDemo1" uri="direct:HandleException_demo1"/>
</doCatch>
<doFinally id="_doFinallyDemo1">
<log id="_log_Demo1Process_finally" message="Demo1 operation completed"/>
</doFinally>
</doTry>
</route>
Here processorBean is the Bean class to process Demo1 route and uri="direct:HandleException_demo1" is an another route which will be called if there is exception comes in Demo1 route. So the exception route will be for this route will be
<route id="routeDemo1Exception">
<from id="_fromdemo1Exception" uri="direct:HandleException_demo1"/>
<log id="log_demo1Exception" message="Demo1 Exception called"/>
<process id="_process_exception_Demo1" ref="processDemo1ExceptionBean"/>
</route>

Camel - Body becomes empty after logging

Looks like a weird issue or the docs are missing
Case 1
from("direct:ROUTE1").to("someAPI").to("direct:ROUTE2");
from("direct:ROUTE2").log("${body}"); // BODY is printing
Case 2
from("direct:ROUTE1").to("someAPI").to("direct:ROUTE2").log("${body}");
from("direct:ROUTE2").log("${body}"); // BODY is empty
Does adding log clear the exchange body??
As #Spara and #Claus suggested and to save the hassle on how to enable Stream caching.
Below is the sample code:
Using Java DSL for Single route
from("direct:ROUTER1")
.streamCaching()
.to("direct:ROUTER2");
Using Spring DSL for Single route
<route streamCache="true">
<from uri="direct:ROUTER1"/>
<to uri="direct:ROUTER2"/>
</route>
For global and per route scope using JAVA DSL
context.setStreamCache(true);
from("direct:ROUTER1")
.to("direct:ROUTER2");
For global and per route scope using Spring DSL
<route streamCache="true">
<from uri="direct:ROUTER1"/>
<to uri="direct:ROUTER2"/>
</route>
Note link: Camel Stream Caching
why stream caching

Multipart form-data file upload with Camel

I'm trying to setup an Apache Camel route in a Java application where the consumer endpoint is a restlet component that handles an HTTP file upload as a POST of multipart form data and then the producer endpoint forwards the request to a rest service that also accepts multipart form data. I'm new to Camel and can't quite figure out how to wire it up properly. Below is how my route looks so far. Do I need to do any conversion on the body or will the multipart form data be forwarded as is? Can someone provide me some guidance on the proper way to do this or point me to the correct documentation?
<route id="createentityattachment">
<from uri="restlet:/EntityAttachments?restletMethod=POST&restletBinding=#queryStringToHeadersRestletBinding"/>
<camel:recipientList>
<camel:simple>
${header.apigateway}/entityattachments/1.0.0.0/api/v1/EntityAttachments
</camel:simple>
</camel:recipientList>
</route>
I was able to get this working with the below route definition. Note the streamCache="true" attribute on the route. This setting is required for the InputStream to be properly handled in the Exchange. See the Camel docs for more information.
<route id="createentityattachment" streamCache="true">
<from uri="restlet:/EntityAttachments?restletMethod=POST&restletBinding=#queryStringToHeadersRestletBinding"/>
<removeHeaders excludePattern="X-eviCore-EntityAttachments*" pattern="^(Camel|Backbase|User-|Accept|Cache|Cookie|breadcrumbId|Host|Connection|DNT|Upgrade-Insecure-Requests|org.restlet.startTime).*$"/>
<setHeader headerName="CamelHttpMethod">
<constant>POST</constant>
</setHeader>
<to uri="http4://api.innovate.lan:8280/entityattachments/1.0.0.0/api/v1/EntityAttachments"/>
</route>

Failed to parse server's response: Unknown type: nil

Im trying to make a camel route that would get a xml-rpc data from a 3rd party web site. Problem is that some values are NIL. Is there some way to configure route to accept such values?
site: https://i.ifne.eu/om3-dev/ca/xml-rpc/get-upcoming-events-compact
In a worst case scenario i could pre-process it and replace all NIL`s, but i would like to know if there is not some simple solution
EDIT: adding example route
<route>
<from uri="timer://mainTimer?period=5000"/>
<to uri="xmlrpc:https://i.ifne.eu/om3-dev/ca/xml-rpc/get-upcoming-events-compact?defaultMethodName=test" />
<to uri="mock:result" />
</route>
Also I tried to play with XmlRpcClientConfigurer but had no luck there - im a java noob so no idea if im doing it right
public class xmlrpcConfigurer implements XmlRpcClientConfigurer {
#Override
public void configureXmlRpcClient(XmlRpcClient client) {
XmlRpcClientConfigImpl clientConfig = (XmlRpcClientConfigImpl)client.getClientConfig();
clientConfig.setEnabledForExtensions(true);
}
}
Idea behind that was that acording to http://en.wikipedia.org/wiki/XML-RPC nil tag is an extension I dont really know if it does what i think it does...
Well i was not able to find a solution so i have to solve it another way - im removing the nil elements
<dataFormats>
<xmlrpc id="xmlrpcResponse" request="false"/>
</dataFormats>
<route>
<from uri="timer://mainTimer?period=60000"/>
<to uri="https://i.ifne.eu/om3-dev/ca/xml-rpc/get-upcoming-events-compact?defaultMethodName=test" />
<process ref="removeNilFromXml"/>
<unmarshal ref="xmlrpcResponse"/>
<to uri="mock:result" />
</route>
removeNilFromXml.java:
public class removeNilFromXml implements Processor {
public void process(Exchange exchange) throws Exception {
String data = exchange.getIn().getBody(String.class);
String nonildata = data.replace("<nil/>", "");
exchange.getIn().setBody(nonildata);
}
}
Not the best solution but it works...

Categories