use of org.apache.camel.StatefulService in project camel by apache.
the class DefaultCamelContext method doStartOrResumeRoutes.
/**
* Starts or resumes the routes
*
* @param routeServices the routes to start (will only start a route if its not already started)
* @param checkClash whether to check for startup ordering clash
* @param startConsumer whether the route consumer should be started. Can be used to warmup the route without starting the consumer.
* @param resumeConsumer whether the route consumer should be resumed.
* @param addingRoutes whether we are adding new routes
* @throws Exception is thrown if error starting routes
*/
protected void doStartOrResumeRoutes(Map<String, RouteService> routeServices, boolean checkClash, boolean startConsumer, boolean resumeConsumer, boolean addingRoutes) throws Exception {
isStartingRoutes.set(true);
try {
// filter out already started routes
Map<String, RouteService> filtered = new LinkedHashMap<String, RouteService>();
for (Map.Entry<String, RouteService> entry : routeServices.entrySet()) {
boolean startable = false;
Consumer consumer = entry.getValue().getRoutes().iterator().next().getConsumer();
if (consumer instanceof SuspendableService) {
// consumer could be suspended, which is not reflected in the RouteService status
startable = ((SuspendableService) consumer).isSuspended();
}
if (!startable && consumer instanceof StatefulService) {
// consumer could be stopped, which is not reflected in the RouteService status
startable = ((StatefulService) consumer).getStatus().isStartable();
} else if (!startable) {
// no consumer so use state from route service
startable = entry.getValue().getStatus().isStartable();
}
if (startable) {
filtered.put(entry.getKey(), entry.getValue());
}
}
// the context is in last phase of staring, so lets start the routes
safelyStartRouteServices(checkClash, startConsumer, resumeConsumer, addingRoutes, filtered.values());
} finally {
isStartingRoutes.remove();
}
}
use of org.apache.camel.StatefulService in project camel by apache.
the class RouteDefinition method adviceWith.
/**
* Advices this route with the route builder.
* <p/>
* <b>Important:</b> It is recommended to only advice a given route once (you can of course advice multiple routes).
* If you do it multiple times, then it may not work as expected, especially when any kind of error handling is involved.
* The Camel team plan for Camel 3.0 to support this as internal refactorings in the routing engine is needed to support this properly.
* <p/>
* You can use a regular {@link RouteBuilder} but the specialized {@link org.apache.camel.builder.AdviceWithRouteBuilder}
* has additional features when using the <a href="http://camel.apache.org/advicewith.html">advice with</a> feature.
* We therefore suggest you to use the {@link org.apache.camel.builder.AdviceWithRouteBuilder}.
* <p/>
* The advice process will add the interceptors, on exceptions, on completions etc. configured
* from the route builder to this route.
* <p/>
* This is mostly used for testing purpose to add interceptors and the likes to an existing route.
* <p/>
* Will stop and remove the old route from camel context and add and start this new advised route.
*
* @param camelContext the camel context
* @param builder the route builder
* @return a new route which is this route merged with the route builder
* @throws Exception can be thrown from the route builder
* @see AdviceWithRouteBuilder
*/
@SuppressWarnings("deprecation")
public RouteDefinition adviceWith(ModelCamelContext camelContext, RouteBuilder builder) throws Exception {
ObjectHelper.notNull(camelContext, "CamelContext");
ObjectHelper.notNull(builder, "RouteBuilder");
log.debug("AdviceWith route before: {}", this);
// and offer features to manipulate the route directly
if (builder instanceof AdviceWithRouteBuilder) {
((AdviceWithRouteBuilder) builder).setOriginalRoute(this);
}
// configure and prepare the routes from the builder
RoutesDefinition routes = builder.configureRoutes(camelContext);
log.debug("AdviceWith routes: {}", routes);
// we can only advice with a route builder without any routes
if (!builder.getRouteCollection().getRoutes().isEmpty()) {
throw new IllegalArgumentException("You can only advice from a RouteBuilder which has no existing routes." + " Remove all routes from the route builder.");
}
// context scoped error handler, in case no error handlers was configured
if (builder.getRouteCollection().getErrorHandlerBuilder() != null && camelContext.getErrorHandlerBuilder() != builder.getRouteCollection().getErrorHandlerBuilder()) {
throw new IllegalArgumentException("You can not advice with error handlers. Remove the error handlers from the route builder.");
}
// stop and remove this existing route
camelContext.removeRouteDefinition(this);
// any advice with tasks we should execute first?
if (builder instanceof AdviceWithRouteBuilder) {
List<AdviceWithTask> tasks = ((AdviceWithRouteBuilder) builder).getAdviceWithTasks();
for (AdviceWithTask task : tasks) {
task.task();
}
}
// now merge which also ensures that interceptors and the likes get mixed in correctly as well
RouteDefinition merged = routes.route(this);
// add the new merged route
camelContext.getRouteDefinitions().add(0, merged);
// log the merged route at info level to make it easier to end users to spot any mistakes they may have made
log.info("AdviceWith route after: " + merged);
// If the camel context is started then we start the route
if (camelContext instanceof StatefulService) {
StatefulService service = (StatefulService) camelContext;
if (service.isStarted()) {
camelContext.startRoute(merged);
}
}
return merged;
}
use of org.apache.camel.StatefulService in project camel by apache.
the class RouteSedaSuspendResumeTest method testSuspendResume.
public void testSuspendResume() throws Exception {
MockEndpoint mock = getMockEndpoint("mock:result");
mock.expectedBodiesReceived("A");
template.sendBody("seda:foo", "A");
assertMockEndpointsSatisfied();
log.info("Suspending");
// now suspend and dont expect a message to be routed
resetMocks();
mock.expectedMessageCount(0);
context.suspendRoute("foo");
assertEquals("Suspended", context.getRouteStatus("foo").name());
Route route = context.getRoute("foo");
if (route instanceof StatefulService) {
assertEquals("Suspended", ((StatefulService) route).getStatus().name());
}
// need to give seda consumer thread time to idle
Thread.sleep(500);
template.sendBody("seda:foo", "B");
mock.assertIsSatisfied(1000);
log.info("Resuming");
// now resume and expect the previous message to be routed
resetMocks();
mock.expectedBodiesReceived("B");
context.resumeRoute("foo");
assertMockEndpointsSatisfied();
assertEquals("Started", context.getRouteStatus("foo").name());
route = context.getRoute("foo");
if (route instanceof StatefulService) {
assertEquals("Started", ((StatefulService) route).getStatus().name());
}
}
use of org.apache.camel.StatefulService in project camel by apache.
the class BackpressurePublisherRoutePolicyTest method testThatRouteRestartsOnUnsubscription.
@Test
public void testThatRouteRestartsOnUnsubscription() throws Exception {
CountDownLatch generationLatch = new CountDownLatch(25);
new RouteBuilder() {
@Override
public void configure() throws Exception {
ThrottlingInflightRoutePolicy policy = new ThrottlingInflightRoutePolicy();
policy.setMaxInflightExchanges(10);
policy.setScope(ThrottlingInflightRoutePolicy.ThrottlingScope.Route);
policy.setResumePercentOfMax(70);
policy.setLoggingLevel(LoggingLevel.INFO);
// unbounded
from("timer:tick?period=50").id("policy-route").routePolicy(policy).process(x -> generationLatch.countDown()).to("reactive-streams:pub");
}
}.addRoutesToCamelContext(context);
CountDownLatch receptionLatch = new CountDownLatch(35);
Publisher<Exchange> pub = CamelReactiveStreams.get(context()).fromStream("pub", Exchange.class);
TestSubscriber<Exchange> subscriber = new TestSubscriber<Exchange>() {
@Override
public void onNext(Exchange o) {
super.onNext(o);
receptionLatch.countDown();
}
};
subscriber.setInitiallyRequested(10);
pub.subscribe(subscriber);
// Add another (fast) subscription that should not affect the backpressure on the route
Observable.fromPublisher(pub).subscribe();
context.start();
// after 25 messages are generated
generationLatch.await(5, TimeUnit.SECONDS);
// The number of exchanges should be 10 (requested by the subscriber), so 35-10=25
assertEquals(25, receptionLatch.getCount());
// fire a delayed request from the subscriber (required by camel core)
subscriber.request(1);
Thread.sleep(250);
StatefulService service = (StatefulService) context().getRoute("policy-route").getConsumer();
// ensure the route is stopped or suspended
assertTrue(service.isStopped() || service.isSuspended());
subscriber.cancel();
// request other exchanges to ensure that the route works
CountDownLatch latch = new CountDownLatch(20);
Observable.fromPublisher(pub).subscribe(n -> {
latch.countDown();
});
assertTrue(latch.await(5, TimeUnit.SECONDS));
}
use of org.apache.camel.StatefulService in project camel by apache.
the class BackpressurePublisherRoutePolicyTest method testThatBackpressureCausesTemporaryRouteStop.
@Test
public void testThatBackpressureCausesTemporaryRouteStop() throws Exception {
CountDownLatch generationLatch = new CountDownLatch(25);
new RouteBuilder() {
@Override
public void configure() throws Exception {
ThrottlingInflightRoutePolicy policy = new ThrottlingInflightRoutePolicy();
policy.setMaxInflightExchanges(10);
policy.setScope(ThrottlingInflightRoutePolicy.ThrottlingScope.Route);
policy.setResumePercentOfMax(70);
policy.setLoggingLevel(LoggingLevel.INFO);
from("timer:tick?period=50&repeatCount=35").id("policy-route").routePolicy(policy).process(x -> generationLatch.countDown()).to("reactive-streams:pub");
}
}.addRoutesToCamelContext(context);
CountDownLatch receptionLatch = new CountDownLatch(35);
Publisher<Exchange> pub = CamelReactiveStreams.get(context()).fromStream("pub", Exchange.class);
TestSubscriber<Exchange> subscriber = new TestSubscriber<Exchange>() {
@Override
public void onNext(Exchange o) {
super.onNext(o);
receptionLatch.countDown();
}
};
subscriber.setInitiallyRequested(10);
pub.subscribe(subscriber);
// Add another (fast) subscription that should not affect the backpressure on the route
Observable.fromPublisher(pub).subscribe();
context.start();
// after 25 messages are generated
generationLatch.await(5, TimeUnit.SECONDS);
// The number of exchanges should be 10 (requested by the subscriber), so 35-10=25
assertEquals(25, receptionLatch.getCount());
// fire a delayed request from the subscriber (required by camel core)
subscriber.request(1);
Thread.sleep(250);
StatefulService service = (StatefulService) context().getRoute("policy-route").getConsumer();
// ensure the route is stopped or suspended
assertTrue(service.isStopped() || service.isSuspended());
// request all the remaining exchanges
subscriber.request(24);
assertTrue(receptionLatch.await(5, TimeUnit.SECONDS));
// The reception latch has gone to 0
}
Aggregations