@Override protected CamelContext createCamelContext() throws Exception { CamelContext answer = null; Long timeout = getCamelContextCreationTimeout(); if (timeout == null) { answer = CamelBlueprintHelper.getOsgiService(bundleContext, CamelContext.class); } else if (timeout >= 0) { answer = CamelBlueprintHelper.getOsgiService(bundleContext, CamelContext.class, timeout); } else { throw new IllegalArgumentException( "getCamelContextCreationTimeout cannot return a negative value."); } // must override context so we use the correct one in testing context = (ModelCamelContext) answer; return answer; }
@AfterClass public static void tearDownAfterClass() throws Exception { if (threadLocalBundleContext.get() != null) { CamelBlueprintHelper.disposeBundleContext(threadLocalBundleContext.get()); threadLocalBundleContext.remove(); } CamelTestSupport.tearDownAfterClass(); }
@After @Override public void tearDown() throws Exception { System.clearProperty("skipStartingCamelContext"); System.clearProperty("registerBlueprintCamelContextEager"); super.tearDown(); if (isCreateCamelContextPerClass()) { // we tear down in after class return; } // unregister services if (bundleContext != null) { for (ServiceRegistration<?> reg : services) { bundleContext.ungetService(reg.getReference()); } } CamelBlueprintHelper.disposeBundleContext(bundleContext); }
@SuppressWarnings({"rawtypes", "unchecked"}) protected BundleContext createBundleContext() throws Exception { final String symbolicName = getClass().getSimpleName(); final BundleContext answer = CamelBlueprintHelper.createBundleContext( symbolicName, getBlueprintDescriptor(), includeTestBundle(), getBundleFilter(), getBundleVersion(), getBundleDirectives()); // must register override properties early in OSGi containers Properties extra = useOverridePropertiesWithPropertiesComponent(); if (extra != null) { answer.registerService(PropertiesComponent.OVERRIDE_PROPERTIES, extra, null); } Map<String, KeyValueHolder<Object, Dictionary>> map = new LinkedHashMap<String, KeyValueHolder<Object, Dictionary>>(); addServicesOnStartup(map); for (Map.Entry<String, KeyValueHolder<Object, Dictionary>> entry : map.entrySet()) { String clazz = entry.getKey(); Object service = entry.getValue().getKey(); Dictionary dict = entry.getValue().getValue(); log.debug("Registering service {} -> {}", clazz, service); ServiceRegistration<?> reg = answer.registerService(clazz, service, dict); if (reg != null) { services.add(reg); } } // must reuse props as we can do both load from .cfg file and override afterwards Dictionary props = new Properties(); // load configuration file String[] file = loadConfigAdminConfigurationFile(); if (file != null && file.length != 2) { throw new IllegalArgumentException( "The returned String[] from loadConfigAdminConfigurationFile must be of length 2, was " + file.length); } if (file != null) { CamelBlueprintHelper.setPersistentFileForConfigAdmin(answer, file[1], file[0], props); } // allow end user to override properties String pid = useOverridePropertiesWithConfigAdmin(props); if (pid != null) { // we will update the configuration now. As OSGi is highly asynchronous, we need to make the // tests as repeatable as possible // the problem is when blueprint container defines cm:property-placeholder with // update-strategy="reload" // updating the configuration leads to (felix framework + aries blueprint): // 1. schedule org.apache.felix.cm.impl.ConfigurationManager.UpdateConfiguration object to run // in config admin thread // 2. this thread calls org.apache.felix.cm.impl.ConfigurationImpl#tryBindLocation() // 3. org.osgi.service.cm.ConfigurationEvent#CM_LOCATION_CHANGED is send // 4. // org.apache.aries.blueprint.compendium.cm.ManagedObjectManager.ConfigurationWatcher#updated() is invoked // 5. new Thread().start() is called // 6. org.apache.aries.blueprint.compendium.cm.ManagedObject#updated() is called // 7. org.apache.aries.blueprint.compendium.cm.CmPropertyPlaceholder#updated() is called // 8. new Thread().start() is called // 9. org.apache.aries.blueprint.services.ExtendedBlueprintContainer#reload() is called which // destroys everything in BP container // 10. finally reload of BP container is scheduled (in yet another thread) // // if we start/use camel context between point 9 and 10 we may get many different errors // described in https://issues.apache.org/jira/browse/ARIES-961 // to synchronize this (main) thread of execution with the asynchronous series of events, we // can register the following listener. // this way be sure that we got to point 3 final CountDownLatch latch = new CountDownLatch(2); answer.registerService( ConfigurationListener.class, new ConfigurationListener() { @Override public void configurationEvent(ConfigurationEvent event) { if (event.getType() == ConfigurationEvent.CM_LOCATION_CHANGED) { latch.countDown(); } // when we update the configuration, BP container will be reloaded as well // hoping that we get the event after *second* restart, let's register the listener answer.registerService( BlueprintListener.class, new BlueprintListener() { @Override public void blueprintEvent(BlueprintEvent event) { if (event.getType() == BlueprintEvent.CREATED && event.getBundle().getSymbolicName().equals(symbolicName)) { latch.countDown(); } } }, null); } }, null); ConfigurationAdmin configAdmin = CamelBlueprintHelper.getOsgiService(answer, ConfigurationAdmin.class); // passing null as second argument ties the configuration to correct bundle. // using single-arg method causes: // *ERROR* Cannot use configuration xxx.properties for [org.osgi.service.cm.ManagedService, // id=N, bundle=N/jar:file:xyz.jar!/]: No visibility to configuration bound to file:pojosr Configuration config = configAdmin.getConfiguration(pid, null); if (config == null) { throw new IllegalArgumentException( "Cannot find configuration with pid " + pid + " in OSGi ConfigurationAdmin service."); } log.info("Updating ConfigAdmin {} by overriding properties {}", config, props); config.update(props); latch.await(CamelBlueprintHelper.DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); } return answer; }
protected <T> T getOsgiService(Class<T> type, String filter, long timeout) { return CamelBlueprintHelper.getOsgiService(bundleContext, type, filter, timeout); }
protected <T> T getOsgiService(Class<T> type) { return CamelBlueprintHelper.getOsgiService(bundleContext, type); }