You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2011/12/31 14:31:45 UTC
svn commit: r1226081 - in /camel/trunk/camel-core/src:
main/java/org/apache/camel/ main/java/org/apache/camel/impl/
main/java/org/apache/camel/processor/ test/java/org/apache/camel/impl/
test/java/org/apache/camel/management/ test/java/org/apache/camel...
Author: davsclaus
Date: Sat Dec 31 13:31:45 2011
New Revision: 1226081
URL: http://svn.apache.org/viewvc?rev=1226081&view=rev
Log:
CAMEL-4842: Removing route should remove producer cache from JMX, as well from services to close list on CamelContext, to not eat up memory.
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartStopAndShutdownRouteTest.java
- copied, changed from r1226049, camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartAndStopRoutesTest.java
camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
- copied, changed from r1226049, camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddSecondRouteTest.java
camel/trunk/camel-core/src/test/java/org/apache/camel/util/MyDummyObject.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/CamelContext.java
camel/trunk/camel-core/src/main/java/org/apache/camel/Route.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/DefaultRoute.java
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/RouteService.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientList.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RoutingSlip.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.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=1226081&r1=1226080&r2=1226081&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 Sat Dec 31 13:31:45 2011
@@ -154,6 +154,18 @@ public interface CamelContext extends Su
void addService(Object object) throws Exception;
/**
+ * Removes a service from this context.
+ * <p/>
+ * The service is assumed to have been previously added using {@link #addService(Object)} method.
+ * This method will <b>not</b> change the service lifecycle.
+ *
+ * @param object the service
+ * @throws Exception can be thrown if error removing the service
+ * @return <tt>true</tt> if the service was removed, <tt>false</tt> if no service existed
+ */
+ boolean removeService(Object object) throws Exception;
+
+ /**
* Has the given service already been added to this context?
*
* @param object the service
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Route.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Route.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Route.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Route.java Sat Dec 31 13:31:45 2011
@@ -107,4 +107,9 @@ public interface Route {
*/
Navigate<Processor> navigate();
+ /**
+ * Callback preparing the route to be started, by warming up the route.
+ */
+ void warmUp();
+
}
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=1226081&r1=1226080&r2=1226081&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 Sat Dec 31 13:31:45 2011
@@ -913,6 +913,23 @@ public class DefaultCamelContext extends
}
}
+ public boolean removeService(Object object) throws Exception {
+ if (object instanceof Service) {
+ Service service = (Service) object;
+
+ for (LifecycleStrategy strategy : lifecycleStrategies) {
+ if (service instanceof Endpoint) {
+ // use specialized endpoint remove
+ strategy.onEndpointRemove((Endpoint) service);
+ } else {
+ strategy.onServiceRemove(this, service, null);
+ }
+ }
+ return servicesToClose.remove(service);
+ }
+ return false;
+ }
+
public boolean hasService(Object object) {
if (object instanceof Service) {
Service service = (Service) object;
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRoute.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRoute.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRoute.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultRoute.java Sat Dec 31 13:31:45 2011
@@ -85,7 +85,13 @@ public abstract class DefaultRoute exten
}
public void addService(Service service) {
- getServices().add(service);
+ if (!services.contains(service)) {
+ services.add(service);
+ }
+ }
+
+ public void warmUp() {
+ getServices().clear();
}
/**
@@ -115,7 +121,12 @@ public abstract class DefaultRoute exten
}
protected void doStop() throws Exception {
- // clear services when stopping
+ // noop
+ }
+
+ @Override
+ protected void doShutdown() throws Exception {
+ // clear services when shutting down
services.clear();
}
}
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=1226081&r1=1226080&r2=1226081&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 Sat Dec 31 13:31:45 2011
@@ -118,8 +118,10 @@ public class RouteService extends ChildS
if (warmUpDone.compareAndSet(false, true)) {
for (Route route : routes) {
- LOG.debug("Starting services on route: {}", route.getId());
+ // warm up the route first
+ route.warmUp();
+ LOG.debug("Starting services on route: {}", route.getId());
List<Service> services = route.getServices();
// callback that we are staring these services
@@ -224,6 +226,20 @@ public class RouteService extends ChildS
@Override
protected void doShutdown() throws Exception {
for (Route route : routes) {
+ LOG.debug("Shutting down services on route: {}", route.getId());
+ List<Service> services = route.getServices();
+
+ // gather list of services to stop as we need to start child services as well
+ Set<Service> list = new LinkedHashSet<Service>();
+ for (Service service : services) {
+ doGetChildServices(list, service);
+ }
+ // shutdown services
+ stopChildService(route, list, true);
+
+ // shutdown the route itself
+ ServiceHelper.stopAndShutdownServices(route);
+
// endpoints should only be stopped when Camel is shutting down
// see more details in the warmUp method
ServiceHelper.stopAndShutdownServices(route.getEndpoint());
@@ -239,7 +255,8 @@ public class RouteService extends ChildS
for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) {
strategy.onRoutesRemove(routes);
}
-
+
+ // remove the routes from the collections
camelContext.removeRouteCollection(routes);
// clear inputs on shutdown
@@ -288,7 +305,7 @@ public class RouteService extends ChildS
protected void stopChildService(Route route, Set<Service> services, boolean shutdown) throws Exception {
for (Service service : services) {
- LOG.debug("Stopping child service on route: {} -> {}", route.getId(), service);
+ LOG.debug("{} child service on route: {} -> {}", new Object[]{shutdown ? "Shutting down" : "Stopping", route.getId(), service});
for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) {
strategy.onServiceRemove(camelContext, service, route);
}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientList.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientList.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientList.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientList.java Sat Dec 31 13:31:45 2011
@@ -171,6 +171,12 @@ public class RecipientList extends Servi
ServiceHelper.stopService(producerCache);
}
+ protected void doShutdown() throws Exception {
+ // remove producer cache from service
+ camelContext.removeService(producerCache);
+ ServiceHelper.stopAndShutdownService(producerCache);
+ }
+
public boolean isStreaming() {
return streaming;
}
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientListProcessor.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientListProcessor.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RecipientListProcessor.java Sat Dec 31 13:31:45 2011
@@ -233,6 +233,13 @@ public class RecipientListProcessor exte
super.doStop();
}
+ protected void doShutdown() throws Exception {
+ // remove producer cache from service
+ getCamelContext().removeService(producerCache);
+ ServiceHelper.stopAndShutdownService(producerCache);
+ super.doShutdown();
+ }
+
@Override
public String toString() {
return "RecipientList";
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RoutingSlip.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RoutingSlip.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RoutingSlip.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/RoutingSlip.java Sat Dec 31 13:31:45 2011
@@ -368,6 +368,12 @@ public class RoutingSlip extends Service
ServiceHelper.stopService(producerCache);
}
+ protected void doShutdown() throws Exception {
+ // remove producer cache from service
+ camelContext.removeService(producerCache);
+ ServiceHelper.stopAndShutdownService(producerCache);
+ }
+
/**
* Returns the outbound message if available. Otherwise return the inbound message.
*/
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java Sat Dec 31 13:31:45 2011
@@ -168,4 +168,9 @@ public class SendProcessor extends Servi
ServiceHelper.stopService(producerCache);
}
+ protected void doShutdown() throws Exception {
+ // remove producer cache from service
+ camelContext.removeService(producerCache);
+ ServiceHelper.stopAndShutdownService(producerCache);
+ }
}
Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartStopAndShutdownRouteTest.java (from r1226049, camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartAndStopRoutesTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartStopAndShutdownRouteTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartStopAndShutdownRouteTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartAndStopRoutesTest.java&r1=1226049&r2=1226081&rev=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartAndStopRoutesTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/StartStopAndShutdownRouteTest.java Sat Dec 31 13:31:45 2011
@@ -16,60 +16,36 @@
*/
package org.apache.camel.impl;
-import java.util.List;
-
import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Route;
import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.component.seda.SedaEndpoint;
-import org.apache.camel.model.FromDefinition;
-import org.apache.camel.model.RouteDefinition;
/**
* This test stops a route, mutates it then restarts it
*
* @version
*/
-public class StartAndStopRoutesTest extends ContextTestSupport {
- protected SedaEndpoint endpointA;
- protected SedaEndpoint endpointB;
- protected SedaEndpoint endpointC;
- protected Object expectedBody = "<hello>world!</hello>";
-
- public void testStartRouteThenStopMutateAndStartRouteAgain() throws Exception {
- List<RouteDefinition> routes = context.getRouteDefinitions();
- assertCollectionSize("Route", routes, 1);
- RouteDefinition route = routes.get(0);
-
- endpointA = getMandatoryEndpoint("seda:test.a", SedaEndpoint.class);
- endpointB = getMandatoryEndpoint("seda:test.b", SedaEndpoint.class);
- endpointC = getMandatoryEndpoint("seda:test.C", SedaEndpoint.class);
-
- // send from A over B to results
- MockEndpoint results = getMockEndpoint("mock:results");
- results.expectedBodiesReceived(expectedBody);
+public class StartStopAndShutdownRouteTest extends ContextTestSupport {
- template.sendBody(endpointA, expectedBody);
+ public void testStartStopAndShutdownRoute() throws Exception {
- assertMockEndpointsSatisfied();
+ // there should still be 2 services on the route
+ Route myRoute = context.getRoute("foo");
+ int services = myRoute.getServices().size();
+ assertTrue(services > 0);
// stop the route
- context.stopRoute(route);
+ context.stopRoute("foo");
- // lets mutate the route...
- FromDefinition fromType = assertOneElement(route.getInputs());
- fromType.setUri("seda:test.C");
- context.startRoute(route);
-
- // now lets check it works
- // send from C over B to results
- results.reset();
- results = getMockEndpoint("mock:results");
- results.expectedBodiesReceived(expectedBody);
+ // there should still be the same number of services on the route
+ assertEquals(services, myRoute.getServices().size());
- template.sendBody(endpointC, expectedBody);
+ // shutting down the route, by stop and remove
+ context.stopRoute("foo");
+ context.removeRoute("foo");
- assertMockEndpointsSatisfied();
+ // and now no more services as the route is shutdown
+ assertEquals(0, myRoute.getServices().size());
}
@Override
@@ -77,9 +53,7 @@ public class StartAndStopRoutesTest exte
return new RouteBuilder() {
@Override
public void configure() throws Exception {
- from("seda:test.a").
- to("seda:test.b").
- to("mock:results");
+ from("direct:start").routeId("foo").to("mock:foo");
}
};
Copied: camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java (from r1226049, camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddSecondRouteTest.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java?p2=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java&p1=camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddSecondRouteTest.java&r1=1226049&r2=1226081&rev=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddSecondRouteTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java Sat Dec 31 13:31:45 2011
@@ -16,18 +16,19 @@
*/
package org.apache.camel.management;
+import java.util.Set;
import javax.management.MBeanServer;
import javax.management.ObjectName;
-import org.apache.camel.ServiceStatus;
import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
/**
* Tests mbeans is registered when adding a 2nd route after CamelContext has been started.
*
* @version
*/
-public class ManagedRouteAddSecondRouteTest extends ManagementTestSupport {
+public class ManagedRouteAddRemoveTest extends ManagementTestSupport {
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
@@ -39,15 +40,21 @@ public class ManagedRouteAddSecondRouteT
};
}
- public void testRouteAddSecondRoute() throws Exception {
+ public void testRouteAddRemoteRoute() throws Exception {
+ MockEndpoint result = getMockEndpoint("mock:result");
+ result.expectedMessageCount(1);
+ template.sendBody("direct:start", "Hello World");
+ result.assertIsSatisfied();
+
MBeanServer mbeanServer = getMBeanServer();
- ObjectName route1 = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=routes,name=\"foo\"");
+ ObjectName on = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=services,name=ProducerCache*");
- // should be started
- String state = (String) mbeanServer.getAttribute(route1, "State");
- assertEquals("Should be started", ServiceStatus.Started.name(), state);
+ // number of producer caches
+ Set<ObjectName> names = mbeanServer.queryNames(on, null);
+ assertEquals(1, names.size());
+
+ log.info("Adding 2nd route");
- log.info(">>>>>>>>>>>>>>>>> adding 2nd route <<<<<<<<<<<<<<");
// add a 2nd route
context.addRoutes(new RouteBuilder() {
@Override
@@ -55,14 +62,30 @@ public class ManagedRouteAddSecondRouteT
from("direct:bar").routeId("bar").to("mock:bar");
}
});
- log.info(">>>>>>>>>>>>>>>>> adding 2nd route DONE <<<<<<<<<<<<<<");
- // find the 2nd route
- ObjectName route2 = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=routes,name=\"bar\"");
+ // and send a message to it
+ MockEndpoint bar = getMockEndpoint("mock:bar");
+ bar.expectedMessageCount(1);
+ template.sendBody("direct:bar", "Hello World");
+ bar.assertIsSatisfied();
+
+ // there should be one more producer cache
+ names = mbeanServer.queryNames(on, null);
+ assertEquals(2, names.size());
+
+ log.info("Removing 2nd route");
+
+ // now remove the 2nd route
+ context.stopRoute("bar");
+ boolean removed = context.removeRoute("bar");
+ assertTrue(removed);
+
+ // the producer cache should have been removed
+ on = ObjectName.getInstance("org.apache.camel:context=localhost/camel-1,type=services,name=ProducerCache*");
+ names = mbeanServer.queryNames(on, null);
+ assertEquals(1, names.size());
- // should be started
- state = (String) mbeanServer.getAttribute(route2, "State");
- assertEquals("Should be started", ServiceStatus.Started.name(), state);
+ log.info("Shutting down...");
}
}
\ No newline at end of file
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/util/MyDummyObject.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/MyDummyObject.java?rev=1226081&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/util/MyDummyObject.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/MyDummyObject.java Sat Dec 31 13:31:45 2011
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.util;
+
+/**
+ *
+ */
+public class MyDummyObject {
+
+ private String name;
+
+ public MyDummyObject(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java?rev=1226081&r1=1226080&r2=1226081&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/util/ObjectHelperTest.java Sat Dec 31 13:31:45 2011
@@ -317,5 +317,18 @@ public class ObjectHelperTest extends Te
assertTrue(ObjectHelper.hasDefaultPublicNoArgConstructor(ObjectHelperTest.class));
assertFalse(ObjectHelper.hasDefaultPublicNoArgConstructor(MyStaticClass.class));
}
+
+ public void testIdentityHashCode() {
+ MyDummyObject dummy = new MyDummyObject("Camel");
+
+ String code = ObjectHelper.getIdentityHashCode(dummy);
+ String code2 = ObjectHelper.getIdentityHashCode(dummy);
+
+ assertEquals(code, code2);
+
+ MyDummyObject dummyB = new MyDummyObject("Camel");
+ String code3 = ObjectHelper.getIdentityHashCode(dummyB);
+ assertNotSame(code, code3);
+ }
}