ONOS-3321 Added ability for applications to register a deactivation hook.
Change-Id: I284321474dbf9e39e8b61f7b907f637ba6b80aaf
diff --git a/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java b/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
index 161659f..a9e928e 100644
--- a/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
+++ b/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.app.impl;
+import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -30,20 +31,21 @@
import org.onosproject.app.ApplicationState;
import org.onosproject.app.ApplicationStore;
import org.onosproject.app.ApplicationStoreDelegate;
-import org.onosproject.event.AbstractListenerManager;
import org.onosproject.core.Application;
import org.onosproject.core.ApplicationId;
+import org.onosproject.event.AbstractListenerManager;
import org.onosproject.security.Permission;
import org.onosproject.security.SecurityUtil;
import org.slf4j.Logger;
import java.io.InputStream;
+import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.app.ApplicationEvent.Type.*;
-import static org.onosproject.security.AppPermission.Type.*;
import static org.onosproject.security.AppGuard.checkPermission;
+import static org.onosproject.security.AppPermission.Type.APP_READ;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -69,6 +71,9 @@
private boolean initializing;
+ // Application supplied hooks for pre-activation processing.
+ private final Map<String, Runnable> deactivateHooks = Maps.newConcurrentMap();
+
@Activate
public void activate() {
eventDispatcher.addSink(ApplicationEvent.class, listenerRegistry);
@@ -122,6 +127,14 @@
}
@Override
+ public void registerDeactivateHook(ApplicationId appId, Runnable hook) {
+ checkPermission(APP_READ);
+ checkNotNull(appId, APP_ID_NULL);
+ checkNotNull(hook, "Hook cannot be null");
+ deactivateHooks.put(appId.name(), hook);
+ }
+
+ @Override
public Application install(InputStream appDescStream) {
checkNotNull(appDescStream, "Application archive stream cannot be null");
Application app = store.create(appDescStream);
@@ -235,6 +248,7 @@
private synchronized boolean uninstallAppFeatures(Application app) throws Exception {
boolean changed = false;
+ invokeHook(deactivateHooks.get(app.id().name()), app.id());
for (String name : app.features()) {
Feature feature = featuresService.getFeature(name);
if (feature != null && featuresService.isInstalled(feature)) {
@@ -247,4 +261,16 @@
return changed;
}
+ // Invokes the specified function, if not null.
+ private void invokeHook(Runnable hook, ApplicationId appId) {
+ if (hook != null) {
+ try {
+ hook.run();
+ } catch (Exception e) {
+ log.warn("Deactivate hook for application {} encountered an error",
+ appId.name(), e);
+ }
+ }
+ }
+
}
diff --git a/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java b/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
index f4d560a..ec99c18 100644
--- a/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
+++ b/core/net/src/main/java/org/onosproject/core/impl/CoreManager.java
@@ -24,6 +24,7 @@
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.SharedExecutors;
+import org.onosproject.app.ApplicationService;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.ApplicationIdStore;
@@ -48,7 +49,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onosproject.security.AppGuard.checkPermission;
-import static org.onosproject.security.AppPermission.Type.*;
+import static org.onosproject.security.AppPermission.Type.APP_READ;
@@ -71,6 +72,9 @@
protected IdBlockStore idBlockStore;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ApplicationService appService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ComponentConfigService cfgService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -111,28 +115,24 @@
@Override
public Version version() {
checkPermission(APP_READ);
-
return version;
}
@Override
public Set<ApplicationId> getAppIds() {
checkPermission(APP_READ);
-
return applicationIdStore.getAppIds();
}
@Override
public ApplicationId getAppId(Short id) {
checkPermission(APP_READ);
-
return applicationIdStore.getAppId(id);
}
@Override
public ApplicationId getAppId(String name) {
checkPermission(APP_READ);
-
return applicationIdStore.getAppId(name);
}
@@ -144,6 +144,13 @@
}
@Override
+ public ApplicationId registerApplication(String name, Runnable preDeactivate) {
+ ApplicationId id = registerApplication(name);
+ appService.registerDeactivateHook(id, preDeactivate);
+ return id;
+ }
+
+ @Override
public IdGenerator getIdGenerator(String topic) {
IdBlockAllocator allocator = new StoreBasedIdBlockAllocator(topic, idBlockStore);
return new BlockAllocatorBasedIdGenerator(allocator);
@@ -185,10 +192,10 @@
*/
private static Integer getIntegerProperty(Dictionary<?, ?> properties,
String propertyName) {
- Integer value = null;
+ Integer value;
try {
String s = (String) properties.get(propertyName);
- value = isNullOrEmpty(s) ? value : Integer.parseInt(s.trim());
+ value = isNullOrEmpty(s) ? null : Integer.parseInt(s.trim());
} catch (NumberFormatException | ClassCastException e) {
value = null;
}