I made an instance of Camel Context and added the routes in the context as follows:
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
System.out.println("in add route method");
from("direct:start").routeId("contextRoute")
.setHeader("client_id", constant("abc"))
.setHeader("client_secret", constant("clk"))
.setHeader(Exchange.HTTP_METHOD, constant("POST"))
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
.setHeader(Exchange.HTTP_URI, constant(url))
.marshal(gsonDataFormat)
.log("trying to send message")
.to(url)
.log("response is ${body}");
}
});
camelContext.start();
However I am not able to get a log of my messages and debug the route. Is there an issue with the route or is there an issue with the log files or anything?
Related
I'm using Camel to route http requests. A client reaches my Camel router at a servlet endpoint providing the information required to route the request, then I lookup into the database to resolve the endpoint. The requests are routed correctly but the response I get seems to be corrupted (I'm making the call from a Rest client), here the corrupted response:
If I call the destination endpoint without passing from camel it returns the right response:
I also checked that the response leaves the destination endpoint not corrupted.
Here my Camel configuration classes:
#Singleton
#Startup
public class CamelStartupBean {
#PostConstruct
public void init() {
CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new CamelRouteConfiguration());
camelContext.start();
}
static class CamelRouteConfiguration extends RouteBuilder {
#Override
public void configure() {
from("servlet:callService?matchOnUriPrefix=true")
.routeId("callService")
.recipientList(method(CallServiceConfiguration.class, "resolveServiceRoute"));
}
}
static class CallServiceConfiguration {
public String resolveServiceRoute(Exchange exchange) {
String route;
// lookup the database to find a route ...
route = "http://demo.apps.closhlab.osh.local/rest/DemoService?bridgeEndpoint=true";
return route;
}
}
}
I'm using Camel 3.9.0 and my app is deployed on the Docker image jboss/wildfly:15.0.0.Final.
Any idea? Thank you.
Upgrading to Camel 3.11.0 solved the issue.
I have example code below, why is the process method in MockEndpoint.whenAnyExchangeReceived NOT executed?
I expect the response is "Expected Body from mock remote http call", but the actual response is what passed in request("Camel rocks").
public class CamelMockRemoteHttpCallTest extends CamelTestSupport {
#Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("direct:start")
.to("http://abc/bcd")
;
}
};
}
#Override
public String isMockEndpointsAndSkip() {
return "http://abc/bcd";
}
#Test
public void testSimulateErrorUsingMock() throws Exception {
MockEndpoint http = getMockEndpoint("mock:http://abc/bcd");
http.whenAnyExchangeReceived(new Processor() {
public void process(Exchange exchange) throws Exception {
exchange.getOut().setBody("Expected Body from mock remote http call"); //why this line doesn't execute
}
});
String response = template.requestBody("direct:start", "Camel rocks", String.class);
assertEquals("Expected Body from mock remote http call", response); //failed, the actual response is "Camel rocks"
}
}
I have added some breakpoints to your test and it seems, that automatically created mock endpoint is mock://http:abc/bcd, not mock:http://abc/bcd.
To find, why is this happening, you can look to method org.apache.camel.impl.InterceptSendToMockEndpointStrategy#registerEndpoint, which is called as part of mock endpoint auto registration. There is // removed from http URI. And then to org.apache.camel.util.URISupport#normalizeUri method, where is // added for mock uri prefix.
There is also nice comment in implementation of InterceptSendToMockEndpointStrategy, but I couldn't find it mentioned in documentation.
// create mock endpoint which we will use as interceptor
// replace :// from scheme to make it easy to lookup the mock endpoint without having double :// in uri
When you change it to getMockEndpoint("mock://http:abc/bcd"), the test passes.
The best way to avoid these issues, is pass false as second parameter of getMockEndpoint() method, if you expect already created endpoint. This will throw exception, if mock endpoint does not exists. Otherwise is new mock endpoint created on demand.
I'm testing exception handling in Camel, and noticed an odd behaviour. I have an http component with deliberately throws a 404 Error. Camel would then throw a HttpOperationFailedException created by org.apache.camel.component.http.HttpProducer.populateHttpOperationFailedException I'm using onWhen to distinguish between different status codes:
This is a sample of the approach for a 404:
onException(HttpOperationFailedException.class)
.onWhen(new Predicate() {
public boolean matches(Exchange exchange) {
HttpOperationFailedException ex = exchange.getProperty(
Exchange.EXCEPTION_CAUGHT,
HttpOperationFailedException.class);
logger.warn("*** 404 Error ***");
return (ex.getStatusCode() == 404);
}
}).handled(true).maximumRedeliveries(0);
But it never gets executed.
So then I tried this:
onException(Exception.class)
.onWhen(new Predicate() {
public boolean matches(Exchange exchange) {
Object ex = exchange.getProperty(Exchange.EXCEPTION_CAUGHT);
logger.error(ex.getClass());
return (true);
}
}).handled(true).maximumRedeliveries(0);
And the logger always shows class org.apache.camel.http.common.HttpOperationFailedException
Any help would be great! I'm using Camel 2.17.1.
I need camel restlet from another restlet to a class object . But i am getting
org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream#12a7889
in producerTemplate .
Invoking camel :
Future<Object> responseFuture = producer.asyncRequestBody("direct:fablertcatalogredirect", k1);
try {
Object obj = (Object)responseFuture.get(500, TimeUnit.SECONDS);
System.out.println("Future Output Value"+obj.toString());
System.out.println("Bytes : "+obj.getClass().getDeclaredMethods());
System.out.println(obj.getClass());
} catch (Exception e) {
e.printStackTrace();
}
My RouteBuilder:
from("direct:fablertcatalogredirect").to("http://localhost:8093/FablertsCatalog/getresults");
If I ran this using postman rest client I can get the JSON . But here I am getting org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream as response.
i had to something like this in the route after the http call
.convertBodyTo(String.class)
I try to define a CXF endpoint, but the it doesn't work.
When I want to address the endpoint then I'v got the "bean not found" exception.
CXF definition:
#Override
public void configure() throws Exception
{
errorHandler(deadLetterChannel(systemInfo.getQueuName())
.allowRedeliveryWhileStopping(true)
.maximumRedeliveries(-1)
);
onException(Exception.class).process(routeHandlingBean);
CamelContext camelContext = getContext();
CxfEndpoint partnerTestService = new CxfEndpoint();
partnerTestService.setEndpointNameString("partnerTestService");
partnerTestService.setAddress("http://localhost:9081/MockPartnerService");
partnerTestService.setWsdlURL("http://localhost:9081/MockPartnerService?wsdl");
partnerTestService.setServiceClass(aaa.bbb.ccc.service.PartnerService.class);
partnerTestService.setServiceNameString("partnerTestService");
partnerTestService.setDataFormat(DataFormat.CXF_MESSAGE);
partnerTestService.setCamelContext(camelContext);
try {
camelContext.addEndpoint("partnerTestService", partnerTestService);
} catch (Exception e) {
e.printStackTrace();
}
When I try to call the endpoint:
cxf:bean:partnerTestService
Then I have got this error message:
org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: cxf://bean:partnerTestService due to: No bean could be found in the registry for: partnerTestService of type: org.apache.camel.component.cxf.CxfEndpoint
I don't know what else I have to set up.
Thx!
Feri
The solution is the usage of CxfEndpoint class. I wrote a function what gives back a needed object (instead of string endpoint), and so it is work.
The route definition:
ValueBuilder dynRouterMethod = method(esbDynRouter, "endpointRoute");
from(queueName).id(systemInfo.getRouteId()).routeId(systemInfo.getRouteId()).autoStartup(false)
.transacted()
.log(LoggingLevel.INFO, systemInfo.getRouteId() + " route usage.")
.beanRef("statusUpdaterBean", "updateSendingStatus")
.dynamicRouter(dynRouterMethod)
.beanRef("statusUpdaterBean", "updateSentStatus")
;
The procedure (it called in dynamic router procedure):
private CxfEndpoint getCxfEndpoint(DispConfView target) throws Exception
{
CxfEndpoint cxfEndpoint = (CxfEndpoint) camelContext.getEndpoint(<Something>);
if (cxfEndpoint == null)
{
String serviceClassNme = <class name what represent the POJO class>;
String methodName = <WS methode name>;
cxfEndpoint = new CxfEndpoint();
cxfEndpoint.setAddress(methodName);
cxfEndpoint.setDataFormat(DataFormat.POJO);
cxfEndpoint.setServiceClass(serviceClassNme);
cxfEndpoint.setCamelContext(camelContext);
camelContext.addEndpoint(<Something>, cxfEndpoint);
}
return cxfEndpoint;
}
This solution work if the message is POJO-type.