Author: davsclaus Date: Mon Aug 2 08:05:07 2010 New Revision: 981401 URL: http://svn.apache.org/viewvc?rev=981401&view=rev Log: CAMEL-3016: Lifecycle operations in JMX not check state before use.
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteRemoveTest.java - copied, changed from r981382, camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteSedaSuspendResumeTest.java camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteRemoveTest.java - copied, changed from r981382, camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteStopAndStartTest.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedService.java camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedSuspendableRoute.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java Mon Aug 2 08:05:07 2010 @@ -370,7 +370,9 @@ public interface CamelContext extends Su * * @param routeId the route id * @throws Exception is thrown if the route could not be shutdown for whatever reason + * @deprecated use {...@link #stopRoute(String)} */ + @Deprecated void shutdownRoute(String routeId) throws Exception; /** @@ -380,10 +382,26 @@ public interface CamelContext extends Su * @param timeout timeout * @param timeUnit the unit to use * @throws Exception is thrown if the route could not be shutdown for whatever reason + * @deprecated use {...@link #stopRoute(String, long, java.util.concurrent.TimeUnit)} */ + @Deprecated void shutdownRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception; /** + * Removes the given route (the route <b>must</b> be stopped before it can be removed). + * <p/> + * <br/>A route which is removed will be unregistered from JMX, have its services stopped/shutdown and the route + * definition etc. will also be removed. All the resources related to the route will be stopped and cleared. + * <p/> + * <br/>End users can use this method to remove unwanted routes or temporary routes which no longer is in demand. + * + * @param routeId the route id + * @return <tt>true</tt> if the route was removed, <tt>false</tt> if the route could not be removed because its not stopped + * @throws Exception is thrown if the route could not be shutdown for whatever reason + */ + boolean removeRoute(String routeId) throws Exception; + + /** * Resumes the given route if it has been previously suspended * <p/> * If the route does <b>not</b> support suspension the route will be started instead Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java Mon Aug 2 08:05:07 2010 @@ -676,6 +676,23 @@ public class DefaultCamelContext extends } } + public synchronized boolean removeRoute(String routeId) throws Exception { + RouteService routeService = routeServices.get(routeId); + if (routeService != null) { + if (getRouteStatus(routeId).isStopped()) { + routeService.setRemovingRoutes(true); + shutdownRouteService(routeService); + removeRouteDefinition(routeId); + ServiceHelper.stopAndShutdownServices(routeService); + routeServices.remove(routeId); + return true; + } else { + return false; + } + } + return false; + } + public synchronized void suspendRoute(String routeId) throws Exception { if (!routeSupportsSuspension(routeId)) { // stop if we suspend is not supported @@ -1530,6 +1547,15 @@ public class DefaultCamelContext extends } } + protected synchronized void shutdownRouteService(RouteService routeService) throws Exception { + routeService.shutdown(); + for (Route route : routeService.getRoutes()) { + if (LOG.isInfoEnabled()) { + LOG.info("Route: " + route.getId() + " shutdown and removed, was consuming from: " + route.getConsumer().getEndpoint()); + } + } + } + protected synchronized void suspendRouteService(RouteService routeService) throws Exception { routeService.suspend(); for (Route route : routeService.getRoutes()) { Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java Mon Aug 2 08:05:07 2010 @@ -94,10 +94,12 @@ public class RouteService extends Servic return inputs; } + @Deprecated public boolean isRemovingRoutes() { return removingRoutes; } - + + @Deprecated public void setRemovingRoutes(boolean removingRoutes) { this.removingRoutes = removingRoutes; } @@ -201,6 +203,11 @@ public class RouteService extends Servic @Override protected void doShutdown() throws Exception { + // need to call onRoutesRemove when the CamelContext is shutting down or Route is shutdown + for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) { + strategy.onRoutesRemove(routes); + } + // clear inputs on shutdown inputs.clear(); warmUpDone.set(false); Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java Mon Aug 2 08:05:07 2010 @@ -128,7 +128,11 @@ public class ManagedCamelContext { @ManagedOperation(description = "Start Camel") public void start() throws Exception { - context.start(); + if (context.isSuspended()) { + context.resume(); + } else { + context.start(); + } } @ManagedOperation(description = "Stop Camel (shutdown)") @@ -143,7 +147,11 @@ public class ManagedCamelContext { @ManagedOperation(description = "Resume Camel") public void resume() throws Exception { - context.resume(); + if (context.isSuspended()) { + context.resume(); + } else { + throw new IllegalStateException("CamelContext is not suspended"); + } } @ManagedOperation(description = "Send body (in only)") Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedProcessor.java Mon Aug 2 08:05:07 2010 @@ -106,11 +106,17 @@ public class ManagedProcessor extends Ma @ManagedOperation(description = "Start Processor") public void start() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } ServiceHelper.startService(getProcessor()); } @ManagedOperation(description = "Stop Processor") public void stop() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } ServiceHelper.stopService(getProcessor()); } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java Mon Aug 2 08:05:07 2010 @@ -122,26 +122,51 @@ public class ManagedRoute extends Manage @ManagedOperation(description = "Start route") public void start() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.startRoute(getRouteId()); } @ManagedOperation(description = "Stop route") public void stop() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.stopRoute(getRouteId()); } @ManagedOperation(description = "Stop route (using timeout in seconds)") public void stop(long timeout) throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.stopRoute(getRouteId(), timeout, TimeUnit.SECONDS); } @ManagedOperation(description = "Shutdown and remove route") + @Deprecated public void shutdown() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.shutdownRoute(getRouteId()); } @ManagedOperation(description = "Shutdown and remove route (using timeout in seconds)") + @Deprecated public void shutdown(long timeout) throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.shutdownRoute(getRouteId(), timeout, TimeUnit.SECONDS); } + + @ManagedOperation(description = "Remove route (must be stopped)") + public boolean remove() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } + return context.removeRoute(getRouteId()); + } } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedService.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedService.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedService.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedService.java Mon Aug 2 08:05:07 2010 @@ -90,11 +90,17 @@ public class ManagedService { @ManagedOperation(description = "Start Service") public void start() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } service.start(); } @ManagedOperation(description = "Stop Service") public void stop() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } service.stop(); } @@ -115,6 +121,9 @@ public class ManagedService { @ManagedOperation(description = "Suspend Service") public void suspend() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } if (service instanceof SuspendableService) { SuspendableService ss = (SuspendableService) service; ss.suspend(); @@ -125,6 +134,9 @@ public class ManagedService { @ManagedOperation(description = "Resume Service") public void resume() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } if (service instanceof SuspendableService) { SuspendableService ss = (SuspendableService) service; ss.resume(); Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedSuspendableRoute.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedSuspendableRoute.java?rev=981401&r1=981400&r2=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedSuspendableRoute.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedSuspendableRoute.java Mon Aug 2 08:05:07 2010 @@ -32,16 +32,25 @@ public class ManagedSuspendableRoute ext @ManagedOperation(description = "Suspend route") public void suspend() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.suspendRoute(getRouteId()); } @ManagedOperation(description = "Suspend route (using timeout in seconds)") public void suspend(long timeout) throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.suspendRoute(getRouteId(), timeout, TimeUnit.SECONDS); } @ManagedOperation(description = "Resume Route") public void resume() throws Exception { + if (!context.getStatus().isStarted()) { + throw new IllegalArgumentException("CamelContext is not started"); + } context.resumeRoute(getRouteId()); } Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteRemoveTest.java (from r981382, camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteSedaSuspendResumeTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteRemoveTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteRemoveTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteSedaSuspendResumeTest.java&r1=981382&r2=981401&rev=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteSedaSuspendResumeTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/RouteRemoveTest.java Mon Aug 2 08:05:07 2010 @@ -23,9 +23,9 @@ import org.apache.camel.component.mock.M /** * @version $Revision$ */ -public class RouteSedaSuspendResumeTest extends ContextTestSupport { +public class RouteRemoveTest extends ContextTestSupport { - public void testSuspendResume() throws Exception { + public void testRemove() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedBodiesReceived("A"); @@ -33,28 +33,22 @@ public class RouteSedaSuspendResumeTest assertMockEndpointsSatisfied(); - log.info("Suspending"); - - // now suspend and dont expect a message to be routed - resetMocks(); - mock.expectedMessageCount(0); - context.suspendRoute("foo"); - - // seda consumer doesnt support suspension so it will stop instead - assertEquals("Stopped", context.getRouteStatus("foo").name()); - - template.sendBody("seda:foo", "B"); - mock.assertIsSatisfied(1000); - - log.info("Resuming"); + assertEquals("Started", context.getRouteStatus("foo").name()); + assertEquals(1, context.getRoutes().size()); - // now resume and expect the previous message to be routed - resetMocks(); - mock.expectedBodiesReceived("B"); - context.resumeRoute("foo"); - assertMockEndpointsSatisfied(); + // must be stopped so we cant remove + boolean removed = context.removeRoute("foo"); + assertFalse(removed); + assertEquals(1, context.getRoutes().size()); assertEquals("Started", context.getRouteStatus("foo").name()); + + // remove route then + context.stopRoute("foo"); + removed = context.removeRoute("foo"); + assertTrue(removed); + assertEquals(0, context.getRoutes().size()); + assertNull(context.getRouteStatus("foo")); } @Override Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteRemoveTest.java (from r981382, camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteStopAndStartTest.java) URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteRemoveTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteRemoveTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteStopAndStartTest.java&r1=981382&r2=981401&rev=981401&view=diff ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteStopAndStartTest.java (original) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteRemoveTest.java Mon Aug 2 08:05:07 2010 @@ -29,7 +29,7 @@ import org.apache.camel.component.mock.M /** * @version $Revision$ */ -public class ManagedRouteStopAndStartTest extends ContextTestSupport { +public class ManagedRouteRemoveTest extends ContextTestSupport { @Override protected boolean useJmx() { @@ -42,7 +42,7 @@ public class ManagedRouteStopAndStartTes super.setUp(); } - public void testStopAndStartRoute() throws Exception { + public void testRemove() throws Exception { MBeanServer mbeanServer = context.getManagementStrategy().getManagementAgent().getMBeanServer(); ObjectName on = getRouteObjectName(mbeanServer); @@ -63,28 +63,16 @@ public class ManagedRouteStopAndStartTes state = (String) mbeanServer.getAttribute(on, "State"); assertEquals("Should be stopped", ServiceStatus.Stopped.name(), state); - mock.reset(); - mock.expectedBodiesReceived("Bye World"); - // wait 3 seconds while route is stopped to verify that file was not consumed - mock.setResultWaitTime(3000); - - template.sendBodyAndHeader("file://target/managed", "Bye World", Exchange.FILE_NAME, "bye.txt"); - - // route is stopped so we do not get the file - mock.assertIsNotSatisfied(); - - // prepare mock for starting route - mock.reset(); - mock.expectedBodiesReceived("Bye World"); + // remove + mbeanServer.invoke(on, "remove", null, null); - // start - mbeanServer.invoke(on, "start", null, null); + // should not be registered anymore + boolean registered = mbeanServer.isRegistered(on); + assertFalse("Route mbean should have been unregistered", registered); - state = (String) mbeanServer.getAttribute(on, "State"); - assertEquals("Should be started", ServiceStatus.Started.name(), state); - - // this time the file is consumed - mock.assertIsSatisfied(); + // and no more routes + Set<ObjectName> set = mbeanServer.queryNames(new ObjectName("*:type=routes,*"), null); + assertEquals(0, set.size()); } static ObjectName getRouteObjectName(MBeanServer mbeanServer) throws Exception {