[CAMEL-8948] CamelBlueprintTestSupport detects if BP container will be reloaded and syncs with the reload
(cherry picked from commit 9b6737bd904bc2ec893060d8fe50494f0713fa27) Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9eb4b81a Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9eb4b81a Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9eb4b81a Branch: refs/heads/camel-2.15.x Commit: 9eb4b81a10004f85fdfd813f8e505f234dc6c52c Parents: d0586a2 Author: Grzegorz Grzybek <gr.grzy...@gmail.com> Authored: Mon Jul 20 09:43:09 2015 +0200 Committer: Grzegorz Grzybek <gr.grzy...@gmail.com> Committed: Tue Jul 21 09:45:50 2015 +0200 ---------------------------------------------------------------------- .../test/blueprint/CamelBlueprintHelper.java | 27 ++++--- .../blueprint/CamelBlueprintTestSupport.java | 75 +++++++++++++++++--- .../org/apache/camel/test/blueprint/Main.java | 7 +- 3 files changed, 87 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/9eb4b81a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintHelper.java b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintHelper.java index b920f9f..497b065 100644 --- a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintHelper.java +++ b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintHelper.java @@ -179,7 +179,8 @@ public final class CamelBlueprintHelper { @SuppressWarnings({"unchecked", "rawtypes"}) public static void setPersistentFileForConfigAdmin(BundleContext bundleContext, String pid, String fileName, final Dictionary props, - String symbolicName, Set<Long> bpEvents) throws IOException, InterruptedException { + String symbolicName, Set<Long> bpEvents, + boolean expectReload) throws IOException, InterruptedException { if (pid != null) { if (fileName == null) { throw new IllegalArgumentException("The persistent file should not be null"); @@ -198,18 +199,22 @@ public final class CamelBlueprintHelper { // we *have to* use "null" as 2nd arg to have correct bundle location for Configuration object final Configuration config = configAdmin.getConfiguration(pid, null); LOG.info("Updating ConfigAdmin {} by overriding properties {}", config, props); - // we will have update and in consequence, BP container reload, let's wait for it to + // we may have update and in consequence, BP container reload, let's wait for it to // be CREATED again - CamelBlueprintHelper.waitForBlueprintContainer(bpEvents, bundleContext, symbolicName, BlueprintEvent.CREATED, new Runnable() { - @Override - public void run() { - try { - config.update(props); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + if (expectReload) { + CamelBlueprintHelper.waitForBlueprintContainer(bpEvents, bundleContext, symbolicName, BlueprintEvent.CREATED, new Runnable() { + @Override + public void run() { + try { + config.update(props); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } } - } - }); + }); + } else { + config.update(props); + } } } http://git-wip-us.apache.org/repos/asf/camel/blob/9eb4b81a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java ---------------------------------------------------------------------- diff --git a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java index 030f99e..be721e4 100644 --- a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java +++ b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/CamelBlueprintTestSupport.java @@ -18,6 +18,8 @@ package org.apache.camel.test.blueprint; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Dictionary; import java.util.HashSet; import java.util.LinkedHashMap; @@ -26,6 +28,10 @@ import java.util.Map; import java.util.Properties; import java.util.Set; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.aries.blueprint.compendium.cm.CmNamespaceHandler; import org.apache.camel.CamelContext; import org.apache.camel.component.properties.PropertiesComponent; import org.apache.camel.model.ModelCamelContext; @@ -39,6 +45,10 @@ import org.osgi.framework.ServiceRegistration; import org.osgi.service.blueprint.container.BlueprintEvent; import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * Base class for OSGi Blueprint unit tests with Camel. @@ -69,6 +79,8 @@ public abstract class CamelBlueprintTestSupport extends CamelTestSupport { final BundleContext answer = CamelBlueprintHelper.createBundleContext(symbolicName, getBlueprintDescriptor(), includeTestBundle(), getBundleFilter(), getBundleVersion(), getBundleDirectives()); + boolean expectReload = expectBlueprintContainerReloadOnConfigAdminUpdate(); + // must register override properties early in OSGi containers Properties extra = useOverridePropertiesWithPropertiesComponent(); if (extra != null) { @@ -119,7 +131,7 @@ public abstract class CamelBlueprintTestSupport extends CamelTestSupport { if (!new File(file[0]).exists()) { throw new IllegalArgumentException("The provided file \"" + file[0] + "\" from loadConfigAdminConfigurationFile doesn't exist"); } - CamelBlueprintHelper.setPersistentFileForConfigAdmin(answer, file[1], file[0], props, symbolicName, bpEvents); + CamelBlueprintHelper.setPersistentFileForConfigAdmin(answer, file[1], file[0], props, symbolicName, bpEvents, expectReload); } // allow end user to override properties @@ -135,16 +147,20 @@ public abstract class CamelBlueprintTestSupport extends CamelTestSupport { throw new IllegalArgumentException("Cannot find configuration with pid " + pid + " in OSGi ConfigurationAdmin service."); } log.info("Updating ConfigAdmin {} by overriding properties {}", config, props); - CamelBlueprintHelper.waitForBlueprintContainer(bpEvents, answer, symbolicName, BlueprintEvent.CREATED, new Runnable() { - @Override - public void run() { - try { - config.update(props); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); + if (expectReload) { + CamelBlueprintHelper.waitForBlueprintContainer(bpEvents, answer, symbolicName, BlueprintEvent.CREATED, new Runnable() { + @Override + public void run() { + try { + config.update(props); + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } } - } - }); + }); + } else { + config.update(props); + } } return answer; @@ -189,6 +205,45 @@ public abstract class CamelBlueprintTestSupport extends CamelTestSupport { } /** + * This method may be overriden to instruct BP test support that BP container will reloaded when + * Config Admin configuration is updated. By default, this is expected, when blueprint XML definition + * contains <code><cm:property-placeholder persistent-id="PID" update-strategy="reload"></code> + */ + protected boolean expectBlueprintContainerReloadOnConfigAdminUpdate() { + boolean expectedReload = false; + String descriptor = getBlueprintDescriptor(); + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + try { + // cm-1.0 doesn't define update-strategy attribute + Set<String> cmNamesaces = new HashSet<>(Arrays.asList( + CmNamespaceHandler.BLUEPRINT_CM_NAMESPACE_1_1, + CmNamespaceHandler.BLUEPRINT_CM_NAMESPACE_1_2, + CmNamespaceHandler.BLUEPRINT_CM_NAMESPACE_1_3 + )); + DocumentBuilder db = dbf.newDocumentBuilder(); + Document doc = db.parse(getClass().getClassLoader().getResourceAsStream(descriptor)); + NodeList nl = doc.getDocumentElement().getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + Node node = nl.item(i); + if (node instanceof Element) { + Element pp = (Element) node; + if (cmNamesaces.contains(pp.getNamespaceURI())) { + String us = pp.getAttribute("update-strategy"); + if (us != null && us.equals("reload")) { + expectedReload = true; + break; + } + } + } + } + } catch (Exception e) { + throw new RuntimeException(e.getMessage(), e); + } + return expectedReload; + } + + /** * Creates a holder for the given service, which make it easier to use {@link #addServicesOnStartup(java.util.Map)} */ protected KeyValueHolder<Object, Dictionary> asService(Object service, Dictionary dict) { http://git-wip-us.apache.org/repos/asf/camel/blob/9eb4b81a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/Main.java ---------------------------------------------------------------------- diff --git a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/Main.java b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/Main.java index cadc063..404844f 100644 --- a/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/Main.java +++ b/components/camel-test-blueprint/src/main/java/org/apache/camel/test/blueprint/Main.java @@ -17,9 +17,11 @@ package org.apache.camel.test.blueprint; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Properties; +import java.util.Set; import javax.xml.bind.JAXBException; @@ -28,6 +30,7 @@ import org.apache.camel.ProducerTemplate; import org.apache.camel.main.MainSupport; import org.apache.camel.view.ModelFileGenerator; import org.osgi.framework.BundleContext; +import org.osgi.service.blueprint.container.BlueprintEvent; /** * A command line tool for booting up a CamelContext using an OSGi Blueprint XML file @@ -100,8 +103,10 @@ public class Main extends MainSupport { } LOG.debug("Starting Blueprint XML file: " + descriptors); bundleContext = createBundleContext(bundleName); + Set<Long> eventHistory = new HashSet<>(); + CamelBlueprintHelper.waitForBlueprintContainer(eventHistory, bundleContext, bundleName, BlueprintEvent.CREATED, null); CamelBlueprintHelper.setPersistentFileForConfigAdmin(bundleContext, configAdminPid, configAdminFileName, new Properties(), - bundleName, null); + bundleName, eventHistory, true); camelContext = CamelBlueprintHelper.getOsgiService(bundleContext, CamelContext.class); if (camelContext == null) { throw new IllegalArgumentException("Cannot find CamelContext in blueprint XML file: " + descriptors);