import java.util.Arrays;
import java.util.Collections;
import java.util.Deque;
-import java.util.Dictionary;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.List;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.blueprint.container.EventConstants;
-import org.osgi.service.event.EventHandler;
+import org.osgi.service.blueprint.container.BlueprintEvent;
+import org.osgi.service.blueprint.container.BlueprintListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
}
public void restartContainer(final Bundle bundle, final List<Object> paths) {
+ LOG.debug("restartContainer for bundle {}", bundle);
+
if (restartExecutor.isShutdown()) {
+ LOG.debug("Already closed - returning");
return;
}
- LOG.debug("restartContainer for bundle {}", bundle);
-
restartExecutor.execute(() -> {
blueprintExtenderService.destroyContainer(bundle, blueprintExtenderService.getContainer(bundle));
blueprintExtenderService.createContainer(bundle, paths);
restartExecutor.execute(() -> restartContainerAndDependentsInternal(bundle));
}
- private void restartContainerAndDependentsInternal(Bundle forBundle) {
+ private void restartContainerAndDependentsInternal(final Bundle forBundle) {
Preconditions.checkNotNull(blueprintExtenderService);
Preconditions.checkNotNull(quiesceParticipant);
// restart config modules.
final CountDownLatch containerCreationComplete = new CountDownLatch(containerBundles.size());
ServiceRegistration<?> eventHandlerReg = registerEventHandler(forBundle.getBundleContext(), event -> {
- LOG.debug("handleEvent {} for bundle {}", event.getTopic(), event.getProperty(EventConstants.BUNDLE));
- if (containerBundles.contains(event.getProperty(EventConstants.BUNDLE))) {
+ final Bundle bundle = event.getBundle();
+ if (event.isReplay()) {
+ LOG.trace("Got replay BlueprintEvent {} for bundle {}", event.getType(), bundle);
+ return;
+ }
+
+ LOG.debug("Got BlueprintEvent {} for bundle {}", event.getType(), bundle);
+ if (containerBundles.contains(bundle)
+ && (event.getType() == BlueprintEvent.CREATED || event.getType() == BlueprintEvent.FAILURE)) {
containerCreationComplete.countDown();
+ LOG.debug("containerCreationComplete is now {}", containerCreationComplete.getCount());
}
});
containerBundles, containerBundles.size() - containerCreationComplete.getCount());
return;
}
- } catch (InterruptedException e) {
+ } catch (final InterruptedException e) {
LOG.debug("CountDownLatch await was interrupted - returning");
return;
}
// Now restart any associated config system Modules.
restartConfigModules(forBundle.getBundleContext(), configModules);
+
+ LOG.info("Finished restarting blueprint containers for bundle {} and its dependent bundles", forBundle);
}
/**
}, Collections.singletonList(nextBundle));
}
- private void createContainers(List<Bundle> containerBundles) {
+ private void createContainers(final List<Bundle> containerBundles) {
containerBundles.forEach(bundle -> {
List<Object> paths = BlueprintBundleTracker.findBlueprintPaths(bundle);
});
}
- private void restartConfigModules(BundleContext bundleContext, List<Entry<String,
+ private void restartConfigModules(final BundleContext bundleContext, final List<Entry<String,
ModuleIdentifier>> configModules) {
if (configModules.isEmpty()) {
return;
}
- private void restartConfigModules(List<Entry<String, ModuleIdentifier>> configModules,
- ConfigSubsystemFacade configFacade) throws ParserConfigurationException, DocumentedException,
+ private void restartConfigModules(final List<Entry<String, ModuleIdentifier>> configModules,
+ final ConfigSubsystemFacade configFacade) throws ParserConfigurationException, DocumentedException,
ValidationException, ConflictingVersionException {
Document document = XmlUtil.newDocument();
Element moduleElement = configMapping.moduleToXml(moduleNamespace, moduleId.getFactoryName(),
moduleId.getInstanceName(), instanceON, document);
modulesElement.appendChild(moduleElement);
- } catch (InstanceNotFoundException e) {
+ } catch (final InstanceNotFoundException e) {
LOG.warn("Error looking up config module: namespace {}, module name {}, instance {}",
moduleNamespace, moduleId.getFactoryName(), moduleId.getInstanceName(), e);
}
* @param containerBundles the current set of bundles containing blueprint containers
* @param configModules the current set of bundles containing config modules
*/
- private void findDependentContainersRecursively(Bundle bundle, Set<Bundle> containerBundles,
- List<Entry<String, ModuleIdentifier>> configModules) {
+ private void findDependentContainersRecursively(final Bundle bundle, final Set<Bundle> containerBundles,
+ final List<Entry<String, ModuleIdentifier>> configModules) {
if (!containerBundles.add(bundle)) {
// Already seen this bundle...
return;
}
}
- private void possiblyAddConfigModuleIdentifier(ServiceReference<?> reference,
- List<Entry<String, ModuleIdentifier>> configModules) {
+ private void possiblyAddConfigModuleIdentifier(final ServiceReference<?> reference,
+ final List<Entry<String, ModuleIdentifier>> configModules) {
Object moduleNamespace = reference.getProperty(CONFIG_MODULE_NAMESPACE_PROP);
if (moduleNamespace == null) {
return;
}
@Nullable
- private String getRequiredConfigModuleProperty(String propName, Object moduleNamespace,
- ServiceReference<?> reference) {
+ private String getRequiredConfigModuleProperty(final String propName, final Object moduleNamespace,
+ final ServiceReference<?> reference) {
Object value = reference.getProperty(propName);
if (value == null) {
LOG.warn(
return value.toString();
}
- private ServiceRegistration<?> registerEventHandler(BundleContext bundleContext, EventHandler handler) {
- Dictionary<String, Object> props = new Hashtable<>();
- props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC,
- new String[]{EventConstants.TOPIC_CREATED, EventConstants.TOPIC_FAILURE});
- return bundleContext.registerService(EventHandler.class.getName(), handler, props);
+ private ServiceRegistration<?> registerEventHandler(final BundleContext bundleContext,
+ final BlueprintListener listener) {
+ return bundleContext.registerService(BlueprintListener.class.getName(), listener, new Hashtable<>());
}
@Override
public void close() {
+ LOG.debug("Closing");
+
restartExecutor.shutdownNow();
}
}