How to remove all route definitions in camel context ...something like below
context.removeRouteDefinitions(context.getRouteDefinitions());
context.removeRouteDefinitions(new ArrayList(context.getRouteDefinitions()));
Please try to call this as bean method from your route:
public void removeRoutes(Exchange exchange) {
new Thread(() -> {
try {
exchange.getContext().stopRoute("currentRoute");
exchange.getContext().removeRouteDefinitions(context.getRouteDefinitions());
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
Related
I have a Camel route which is waiting on a lock. Let's simulate it as following:
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("timer://foo?period=100")
.to("direct:bar");
from("direct:bar")
.routeId("test")
.to("log:receive")
.process(new Processor() {
#Override
public void process(final Exchange exchange) throws Exception {
System.out.println("sleeping indefinitely");
try {
Thread.sleep(Long.MAX_VALUE);
} catch (final InterruptedException exception) {
exception.printStackTrace();
}
System.out.println("not sleeping indefinitely");
}
});
}
});
At a certain point in time, I want to stop this test route as soon as possible. Is there a way to stop this route while interrupting the thread currently processing this route? I tried stopRoute as below, but this does not seem to interrupt the thread.
context.getRouteController().stopRoute("test", 1, TimeUnit.NANOSECONDS);
I am using Camel version 3.4.x.
I am trying to hit a REST endpoint on Camel and convert that data into a class (and for simplicity and testing convert that class into a JSON string) and make a POST to a local server. I can get it to do all but make that final post and just seems to hang.
App:
#SpringBootApplication
public class App {
/**
* A main method to start this application.
*/
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
#Component
public class RestTest extends RouteBuilder {
#Override
public void configure() throws Exception {
restConfiguration().component("restlet").host("localhost").port(8000).bindingMode(RestBindingMode.json);
rest("/test").enableCORS(true)
.post("/post").type(User.class).to("direct:transform");
from("direct:transform")
.transform().method("Test", "alter")
.to("http4:/localhost:8088/ws/v1/camel");
}
}
}
Bean:
#Component("Test")
public class Test {
public void alter (Exchange exchange) {
ObjectMapper mapper = new ObjectMapper();
User body = exchange.getIn().getBody(User.class);
try {
String jsonInString = mapper.writeValueAsString(body);
exchange.getOut().setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST));
exchange.getOut().setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
exchange.getOut().setBody(jsonInString);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
User:
public class User {
#JsonProperty
private String firstName;
#JsonProperty
private String lastName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
}
UPDATE
Able to get it to work with process instead of transform but errors when a response is sent back to Camel from the POST:
from("direct:transform")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
ObjectMapper mapper = new ObjectMapper();
User body = exchange.getIn().getBody(User.class);
try {
String jsonInString = mapper.writeValueAsString(body);
exchange.getOut().setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.POST));
exchange.getOut().setHeader(Exchange.CONTENT_TYPE, MediaType.APPLICATION_JSON);
exchange.getOut().setBody(jsonInString);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
})
.to("http4://0.0.0.0:8088/ws/v1/camel");
Error
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.apache.camel.converter.stream.CachedOutputStream$WrappedInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:284)
at com.fasterxml.jackson.databind.SerializerProvider.mappingException(SerializerProvider.java:1110)
at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1135)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:69)
at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:32)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1429)
at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1158)
at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:988)
at org.apache.camel.component.jackson.JacksonDataFormat.marshal(JacksonDataFormat.java:155)
at org.apache.camel.processor.MarshalProcessor.process(MarshalProcessor.java:69)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
at org.apache.camel.processor.MarshalProcessor.process(MarshalProcessor.java:50)
at org.apache.camel.component.rest.RestConsumerBindingProcessor$RestConsumerBindingMarshalOnCompletion.onAfterRoute(RestConsumerBindingProcessor.java:363)
at org.apache.camel.util.UnitOfWorkHelper.afterRouteSynchronizations(UnitOfWorkHelper.java:154)
at org.apache.camel.impl.DefaultUnitOfWork.afterRoute(DefaultUnitOfWork.java:278)
at org.apache.camel.processor.CamelInternalProcessor$RouteLifecycleAdvice.after(CamelInternalProcessor.java:317)
at org.apache.camel.processor.CamelInternalProcessor$InternalCallback.done(CamelInternalProcessor.java:246)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:109)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
at org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)
at org.apache.camel.component.restlet.RestletConsumer$1.handle(RestletConsumer.java:68)
at org.apache.camel.component.restlet.MethodBasedRouter.handle(MethodBasedRouter.java:54)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.routing.Router.doHandle(Router.java:422)
at org.restlet.routing.Router.handle(Router.java:639)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.routing.Router.doHandle(Router.java:422)
at org.restlet.routing.Router.handle(Router.java:639)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:140)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.routing.Filter.doHandle(Filter.java:150)
at org.restlet.routing.Filter.handle(Filter.java:197)
at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)
at org.restlet.Component.handle(Component.java:408)
at org.restlet.Server.handle(Server.java:507)
at org.restlet.engine.connector.ServerHelper.handle(ServerHelper.java:63)
at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:143)
at org.restlet.engine.connector.HttpServerHelper$1.handle(HttpServerHelper.java:64)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:83)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:82)
at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:675)
at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:79)
at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:647)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Leading to the question of what is the fundamental difference between process and transform?
A "Processor" in camel is the lowest level message processing primitive. Under the covers a transform definition is executed as a org.apache.camel.processor.TransformProcessor which is itself a processor. In fact mostly everything is a Processor under the hood so strictly anything you can accomplish with transform you can accomplish with a pure processor:
Your last error is because you need to unmarshal the output of your HTTP call to an object, before it can be marshalled back to JSON using Jackson. Something like that:
from("direct:transform")
.transform().method("Test", "alter")
.to("http4:/localhost:8088/ws/v1/camel")
.unmarshal().json(JsonLibrary.Jackson, User.class);
I am building an app using codename one
So the thing is, I need to access a URL using the app. THe URL brings back some result which I show on the screen.
SO I use these lines to do that :
ConnectionRequest c = new ConnectionRequest() {
protected void readResponse(InputStream input) throws IOException {
ByteArrayOutputStream bs = new ByteArrayOutputStream();
int ch;
while ((ch = input.read()) != -1) {
bs.write(ch);
}
serverOutput = new String(bs.toByteArray());
bs.close();
}
};
c.setUrl("My URL HERE");
c.setPost(false);
NetworkManager.getInstance().addToQueueAndWait(c);
So, now , if the gprs is active, this code works fine.
BUT , if the GPRS is inactive, it throws an Unknow Host Exception
SO to catch this error, i TRIED to use a try catch block like this:
try{
NetworkManager.getInstance().addToQueueAndWait(c);
}
catch(Exception e)
{
Sys.out.pln(e.troString());
}
But, i still get the error in the form of a dialog in the app. How do i catch this error and put my own handling for it?
UPDATE 1:
Am not sure this is necessarily a codename one specific questions, or related to java ...so just help me out with this.
Try this to handle generic errors for all connections:
NetworkManager.getInstance().addErrorListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//handle your error here consume the event
evt.consume();
}
});
Or override:
protected void handleErrorResponseCode(int code, String message) {
}
And:
protected void handleException(Exception err) {
}
In your connection request code to do this for just one class.
Try it...
public void init(Object context) {
Display.getInstance().addEdtErrorHandler(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
evt.consume();
Throwable exception = (Throwable) evt.getSource();
}
});
}
During the processing of an Exchange received from JMS I'm creating dynamically a route that fetches a file from FTP to the file system and when the batch is done I need to remove that same route. The following code fragment shows how I do this:
public void execute() {
try {
context.addRoutes(createFetchIndexRoute(routeId()));
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
private RouteBuilder createFetchIndexRoute(final String routeId) {
return new RouteBuilder() {
#Override
public void configure() throws Exception {
from("ftp://" + getRemoteQuarterDirectory() +
"?fileName=" + location.getFileName() +
"&binary=true" +
"&localWorkDirectory=" + localWorkDirectory)
.to("file://" + getLocalQuarterDirectory())
.process(new Processor() {
RouteTerminator terminator;
#Override
public void process(Exchange exchange) throws Exception {
if (camelBatchComplete(exchange)) {
terminator = new RouteTerminator(routeId,
exchange.getContext());
terminator.start();
}
}
})
.routeId(routeId);
}
};
}
I'm Using a thread to stop a route from a route, which is an approach recommended in the Camel Documentation - How can I stop a route from a route
public class RouteTerminator extends Thread {
private String routeId;
private CamelContext camelContext;
public RouteTerminator(String routeId, CamelContext camelContext) {
this.routeId = routeId;
this.camelContext = camelContext;
}
#Override
public void run() {
try {
camelContext.stopRoute(routeId);
camelContext.removeRoute(routeId);
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
}
In result the route does stop. But what I see in the jconsole is that the thread that corresponds to the route isn't removed. Thus in time these abandoned threads just keep accumulating.
Is there a way to properly stop/remove a route dynamically/programmatically and also to release the route's thread, so that they don't accumulate through time?
This is fixed in the next Camel release 2.9.2 and 2.10. Fixed by this ticket:
https://issues.apache.org/jira/browse/CAMEL-5072
i'm newbie with apache camel (I'm using 2.8.1 version). I'm working with this framework and i understand (i hope) concept like route. Now i have this route definition
try {
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
from("vm:internal").
split().method(DefaultSplitLogic.class, "split").
dynamicRouter(bean(router, "route"));
}
});
}catch (DefaultSplitLogicException e) {
// TODO: handle exception
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This is the DefaultSpliLogic.class
public class DefaultSplitLogic {
public Object[] split(Object o) throws DefaultSplitLogicException{
if(o instanceof Collection<?>){
Collection c = (Collection) o;
return c.toArray();
}
else {
throw new DefaultSplitLogicException("Default Splitting Logic not correct");
}
}
}
This is DefaultSplitLogicException.class
public class DefaultSplitLogicException extends Exception{
/**
*
*/
private static final long serialVersionUID = 1L;
public DefaultSplitLogicException(String msg) {
// TODO Auto-generated constructor stub
super(msg);
System.err.println(msg);
}
public DefaultSplitLogicException(Throwable cause) {
super(cause);
}
}
I leaved router definition.
Now i want to capture my exception (i'm sure that my exception is thrown).
I'm using the onException clause into the route definition
try {
context.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
// TODO Auto-generated method stub
onException(DefaultSplitLogicException.class).handled(false);
from("vm:internal").
split().method(DefaultSplitLogic.class, "split").
dynamicRouter(bean(router, "route"));
}
});
}catch (DefaultSplitLogicException e) {
// TODO: handle exception
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but i cannot manage my exception. I tried to use differently this clause without success. Why?
Thank you all
I think i found the answer. It should be a bug of 2.8.1. version, fixed with 2.8.2+
http://camel.465427.n5.nabble.com/Cannot-handle-Exception-thrown-from-Splitter-Expression-td3286043.html