Madan Jampani

SecurityMode: Ensure store event handling happens in a background thread to avoid deadlocks

Change-Id: Id32b8ab0cf040cf2ed255f3527426f39bc58476c
(cherry picked from commit 67fd1e62)
...@@ -28,8 +28,8 @@ import org.apache.felix.scr.annotations.Service; ...@@ -28,8 +28,8 @@ import org.apache.felix.scr.annotations.Service;
28 import org.apache.karaf.features.BundleInfo; 28 import org.apache.karaf.features.BundleInfo;
29 import org.apache.karaf.features.Feature; 29 import org.apache.karaf.features.Feature;
30 import org.apache.karaf.features.FeaturesService; 30 import org.apache.karaf.features.FeaturesService;
31 -
32 import org.onlab.util.KryoNamespace; 31 import org.onlab.util.KryoNamespace;
32 +import org.onlab.util.Tools;
33 import org.onosproject.app.ApplicationAdminService; 33 import org.onosproject.app.ApplicationAdminService;
34 import org.onosproject.core.Application; 34 import org.onosproject.core.Application;
35 import org.onosproject.core.ApplicationId; 35 import org.onosproject.core.ApplicationId;
...@@ -49,6 +49,8 @@ import java.util.HashSet; ...@@ -49,6 +49,8 @@ import java.util.HashSet;
49 import java.util.Objects; 49 import java.util.Objects;
50 import java.util.Set; 50 import java.util.Set;
51 import java.util.concurrent.ConcurrentHashMap; 51 import java.util.concurrent.ConcurrentHashMap;
52 +import java.util.concurrent.ExecutorService;
53 +import java.util.concurrent.Executors;
52 import java.util.stream.Collectors; 54 import java.util.stream.Collectors;
53 55
54 import static org.onosproject.security.store.SecurityModeState.*; 56 import static org.onosproject.security.store.SecurityModeState.*;
...@@ -84,6 +86,9 @@ public class DistributedSecurityModeStore ...@@ -84,6 +86,9 @@ public class DistributedSecurityModeStore
84 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 86 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
85 protected FeaturesService featuresService; 87 protected FeaturesService featuresService;
86 88
89 + private ExecutorService eventHandler;
90 + private final SecurityStateListener statesListener = new SecurityStateListener();
91 +
87 private static final Serializer STATE_SERIALIZER = Serializer.using(new KryoNamespace.Builder() 92 private static final Serializer STATE_SERIALIZER = Serializer.using(new KryoNamespace.Builder()
88 .register(KryoNamespaces.API) 93 .register(KryoNamespaces.API)
89 .register(SecurityModeState.class) 94 .register(SecurityModeState.class)
...@@ -97,12 +102,13 @@ public class DistributedSecurityModeStore ...@@ -97,12 +102,13 @@ public class DistributedSecurityModeStore
97 102
98 @Activate 103 @Activate
99 public void activate() { 104 public void activate() {
105 + eventHandler = Executors.newSingleThreadExecutor(Tools.groupedThreads("onos/security/store", "event-handler"));
100 states = storageService.<ApplicationId, SecurityInfo>consistentMapBuilder() 106 states = storageService.<ApplicationId, SecurityInfo>consistentMapBuilder()
101 .withName("smonos-sdata") 107 .withName("smonos-sdata")
102 .withSerializer(STATE_SERIALIZER) 108 .withSerializer(STATE_SERIALIZER)
103 .build(); 109 .build();
104 110
105 - states.addListener(new SecurityStateListener()); 111 + states.addListener(statesListener, eventHandler);
106 112
107 violations = storageService.<ApplicationId, Set<Permission>>eventuallyConsistentMapBuilder() 113 violations = storageService.<ApplicationId, Set<Permission>>eventuallyConsistentMapBuilder()
108 .withName("smonos-rperms") 114 .withName("smonos-rperms")
...@@ -119,6 +125,8 @@ public class DistributedSecurityModeStore ...@@ -119,6 +125,8 @@ public class DistributedSecurityModeStore
119 125
120 @Deactivate 126 @Deactivate
121 public void deactivate() { 127 public void deactivate() {
128 + states.removeListener(statesListener);
129 + eventHandler.shutdown();
122 violations.destroy(); 130 violations.destroy();
123 log.info("Stopped"); 131 log.info("Stopped");
124 } 132 }
......