Repository: camel Updated Branches: refs/heads/camel-2.13.x 7afc9b4b6 -> da30a0d69
CAMEL-7327: Container SPI should keep camel context before container has been set so when setting container the existing camel contexts can be managed too. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/da30a0d6 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/da30a0d6 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/da30a0d6 Branch: refs/heads/camel-2.13.x Commit: da30a0d693f6d7c1e425672ad56536248c3e3dd4 Parents: 7afc9b4 Author: Claus Ibsen <davscl...@apache.org> Authored: Fri Mar 28 11:33:07 2014 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Mar 28 11:33:31 2014 +0100 ---------------------------------------------------------------------- .../apache/camel/impl/DefaultCamelContext.java | 2 + .../java/org/apache/camel/spi/Container.java | 45 +++++++++++- .../org/apache/camel/spi/ContainerTest.java | 77 ++++++++++++++++++++ 3 files changed, 120 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/da30a0d6/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java index 801c991..0baac81 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java @@ -1912,6 +1912,8 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon // and clear start date startDate = null; + + Container.Instance.unmanage(this); } /** http://git-wip-us.apache.org/repos/asf/camel/blob/da30a0d6/camel-core/src/main/java/org/apache/camel/spi/Container.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/spi/Container.java b/camel-core/src/main/java/org/apache/camel/spi/Container.java index b43cc36..68e7558 100644 --- a/camel-core/src/main/java/org/apache/camel/spi/Container.java +++ b/camel-core/src/main/java/org/apache/camel/spi/Container.java @@ -16,13 +16,18 @@ */ package org.apache.camel.spi; +import java.util.LinkedHashSet; +import java.util.Set; + import org.apache.camel.CamelContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The <code>Container</code> interface defines an object that can be used - * to customize all Camel contexts created. - * - * A container can be used to globally intercept and customize Camel contexts, + * to customize all Camel CONTEXTS created. + * <p/> + * A container can be used to globally intercept and customize Camel CONTEXTS, * by registering a <code>LifecycleStrategy</code>, a <code>ProcessorFactory</code>, * or any other SPI object. */ @@ -33,7 +38,9 @@ public interface Container { */ public static final class Instance { + private static final Logger LOG = LoggerFactory.getLogger(Container.class); private static Container container; + private static final Set<CamelContext> CONTEXTS = new LinkedHashSet<CamelContext>(); private Instance() { } @@ -54,6 +61,16 @@ public interface Container { */ public static void set(Container container) { Instance.container = container; + + if (container == null) { + CONTEXTS.clear(); + } else if (!CONTEXTS.isEmpty()) { + // manage any pending CamelContext which was started before a Container was set + for (CamelContext context : CONTEXTS) { + manageCamelContext(container, context); + } + CONTEXTS.clear(); + } } /** @@ -64,9 +81,29 @@ public interface Container { public static void manage(CamelContext camelContext) { Container cnt = container; if (cnt != null) { - cnt.manage(camelContext); + manageCamelContext(cnt, camelContext); + } else { + // Container not yet set so need to remember this CamelContext + CONTEXTS.add(camelContext); + } + } + + private static void manageCamelContext(Container container, CamelContext context) { + try { + container.manage(context); + } catch (Throwable t) { + LOG.warn("Error during manage CamelContext " + context.getName() + ". This exception is ignored.", t); } } + + /** + * Called by Camel when a <code>CamelContext</code> has been destroyed. + * + * @param camelContext the CamelContext which has been destroyed + */ + public static void unmanage(CamelContext camelContext) { + CONTEXTS.remove(camelContext); + } } /** http://git-wip-us.apache.org/repos/asf/camel/blob/da30a0d6/camel-core/src/test/java/org/apache/camel/spi/ContainerTest.java ---------------------------------------------------------------------- diff --git a/camel-core/src/test/java/org/apache/camel/spi/ContainerTest.java b/camel-core/src/test/java/org/apache/camel/spi/ContainerTest.java new file mode 100644 index 0000000..94cd8fd --- /dev/null +++ b/camel-core/src/test/java/org/apache/camel/spi/ContainerTest.java @@ -0,0 +1,77 @@ +/** + * 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.spi; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; + +public class ContainerTest extends TestCase { + + private final class MyContainer implements Container { + + private List<String> names = new ArrayList<String>(); + + @Override + public void manage(CamelContext camelContext) { + names.add(camelContext.getName()); + } + } + + @Override + protected void tearDown() throws Exception { + Container.Instance.set(null); + super.tearDown(); + } + + public void testContainerSet() throws Exception { + MyContainer myContainer = new MyContainer(); + + CamelContext camel1 = new DefaultCamelContext(); + CamelContext camel2 = new DefaultCamelContext(); + + assertEquals(0, myContainer.names.size()); + Container.Instance.set(myContainer); + // after we set, then we should manage the 2 pending contexts + assertEquals(2, myContainer.names.size()); + + CamelContext camel3 = new DefaultCamelContext(); + assertEquals(3, myContainer.names.size()); + assertEquals(camel1.getName(), myContainer.names.get(0)); + assertEquals(camel2.getName(), myContainer.names.get(1)); + assertEquals(camel3.getName(), myContainer.names.get(2)); + + camel1.stop(); + camel2.stop(); + camel3.stop(); + } + + public void testNoContainerSet() throws Exception { + MyContainer myContainer = new MyContainer(); + + CamelContext camel1 = new DefaultCamelContext(); + CamelContext camel2 = new DefaultCamelContext(); + + assertEquals(0, myContainer.names.size()); + + camel1.stop(); + camel2.stop(); + } +}