From: Tom Pantelis Date: Fri, 22 Jul 2016 04:11:44 +0000 (-0400) Subject: Restart BP container after dependency wait time out X-Git-Tag: release/boron~46 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=e6b9c7e282a526aeb1469b6f7aa9b61f69d01743 Restart BP container after dependency wait time out The blueprint container first waits for all dependencies (ie OSGi services, clustered app config etc). By default it waits 5 min after which it fails the container. For a missing OSGi service this is probably OK but it could take longer for a clustered-app-config if the data store isn't available. Ideally we would use an infinite timeout but unfortunately the timeout can't be configured globally - it can only be set at the bundle level in the manifest and we don't want to have to configure it in every bundle (although it may be possible with some maven magic in odlparent). Therefore I added code in BlueprintBundleTracker to listen for container FAILURE events and restart the container if it's due to missing dependencies. Change-Id: Ib8ebb1a02dfd601e48722f9fc3011df7391432cb Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java index 6781b6514d..218f1d1ff8 100644 --- a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java +++ b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintBundleTracker.java @@ -121,7 +121,8 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus private void registerBlueprintEventHandler(BundleContext context) { Dictionary props = new Hashtable<>(); - props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC, EventConstants.TOPIC_CREATED); + props.put(org.osgi.service.event.EventConstants.EVENT_TOPIC, + new String[]{EventConstants.TOPIC_CREATED, EventConstants.TOPIC_FAILURE}); eventHandlerReg = context.registerService(EventHandler.class.getName(), this, props); } @@ -197,6 +198,22 @@ public class BlueprintBundleTracker implements BundleActivator, BundleTrackerCus if(EventConstants.TOPIC_CREATED.equals(event.getTopic())) { LOG.info("Blueprint container for bundle {} was successfully created", event.getProperty(EventConstants.BUNDLE)); + } else if(EventConstants.TOPIC_FAILURE.equals(event.getTopic())) { + // If the container timed out waiting for dependencies, we'll destroy it and start it again. This + // is indicated via a non-null DEPENDENCIES property containing the missing dependencies. The + // default timeout is 5 min and ideally we would set this to infinite but the timeout can only + // be set at the bundle level in the manifest - there's no way to set it globally. + if(event.getProperty(EventConstants.DEPENDENCIES) != null) { + Bundle bundle = (Bundle) event.getProperty(EventConstants.BUNDLE); + + List paths = findBlueprintPaths(bundle); + if(!paths.isEmpty()) { + LOG.warn("Blueprint container for bundle {} timed out waiting for dependencies - restarting it", + event.getProperty(EventConstants.BUNDLE)); + + restartService.restartContainer(bundle, paths); + } + } } } diff --git a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintContainerRestartServiceImpl.java b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintContainerRestartServiceImpl.java index e70fc372b7..02b7bac1b7 100644 --- a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintContainerRestartServiceImpl.java +++ b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/BlueprintContainerRestartServiceImpl.java @@ -75,6 +75,22 @@ class BlueprintContainerRestartServiceImpl implements AutoCloseable, BlueprintCo this.blueprintExtenderService = blueprintExtenderService; } + public void restartContainer(final Bundle bundle, final List paths) { + if(restartExecutor.isShutdown()) { + return; + } + + LOG.debug("restartContainer for bundle {}", bundle); + + restartExecutor.execute(new Runnable() { + @Override + public void run() { + blueprintExtenderService.destroyContainer(bundle, blueprintExtenderService.getContainer(bundle)); + blueprintExtenderService.createContainer(bundle, paths); + } + }); + } + @Override public void restartContainerAndDependents(final Bundle bundle) { if(restartExecutor.isShutdown()) {