Committed by
Gerrit Code Review
adding group garbage collection functionality
If a group has a reference count of zero for more than a configurable timeout, it is garbage collected. This feature can be deactivated by component config. Change-Id: I254d62a90ef7ac8d2ce2f406b67957455a5bf4d0
Showing
5 changed files
with
299 additions
and
203 deletions
... | @@ -35,6 +35,7 @@ public class DefaultGroup extends DefaultGroupDescription | ... | @@ -35,6 +35,7 @@ public class DefaultGroup extends DefaultGroupDescription |
35 | private long bytes; | 35 | private long bytes; |
36 | private long referenceCount; | 36 | private long referenceCount; |
37 | private GroupId id; | 37 | private GroupId id; |
38 | + private int age; | ||
38 | 39 | ||
39 | /** | 40 | /** |
40 | * Initializes default values. | 41 | * Initializes default values. |
... | @@ -48,6 +49,7 @@ public class DefaultGroup extends DefaultGroupDescription | ... | @@ -48,6 +49,7 @@ public class DefaultGroup extends DefaultGroupDescription |
48 | packets = 0; | 49 | packets = 0; |
49 | bytes = 0; | 50 | bytes = 0; |
50 | referenceCount = 0; | 51 | referenceCount = 0; |
52 | + age = 0; | ||
51 | } | 53 | } |
52 | 54 | ||
53 | /** | 55 | /** |
... | @@ -128,6 +130,11 @@ public class DefaultGroup extends DefaultGroupDescription | ... | @@ -128,6 +130,11 @@ public class DefaultGroup extends DefaultGroupDescription |
128 | return this.bytes; | 130 | return this.bytes; |
129 | } | 131 | } |
130 | 132 | ||
133 | + @Override | ||
134 | + public int age() { | ||
135 | + return age; | ||
136 | + } | ||
137 | + | ||
131 | /** | 138 | /** |
132 | * Sets the new state for this entry. | 139 | * Sets the new state for this entry. |
133 | * | 140 | * |
... | @@ -171,6 +178,11 @@ public class DefaultGroup extends DefaultGroupDescription | ... | @@ -171,6 +178,11 @@ public class DefaultGroup extends DefaultGroupDescription |
171 | @Override | 178 | @Override |
172 | public void setReferenceCount(long referenceCount) { | 179 | public void setReferenceCount(long referenceCount) { |
173 | this.referenceCount = referenceCount; | 180 | this.referenceCount = referenceCount; |
181 | + if (referenceCount == 0) { | ||
182 | + age++; | ||
183 | + } else { | ||
184 | + age = 0; | ||
185 | + } | ||
174 | } | 186 | } |
175 | 187 | ||
176 | @Override | 188 | @Override |
... | @@ -214,6 +226,7 @@ public class DefaultGroup extends DefaultGroupDescription | ... | @@ -214,6 +226,7 @@ public class DefaultGroup extends DefaultGroupDescription |
214 | .add("description", super.toString()) | 226 | .add("description", super.toString()) |
215 | .add("groupid", id) | 227 | .add("groupid", id) |
216 | .add("state", state) | 228 | .add("state", state) |
229 | + .add("age", age) | ||
217 | .toString(); | 230 | .toString(); |
218 | } | 231 | } |
219 | 232 | ... | ... |
... | @@ -96,4 +96,12 @@ public interface Group extends GroupDescription { | ... | @@ -96,4 +96,12 @@ public interface Group extends GroupDescription { |
96 | * @return number of flow rules or other groups pointing to this group | 96 | * @return number of flow rules or other groups pointing to this group |
97 | */ | 97 | */ |
98 | long referenceCount(); | 98 | long referenceCount(); |
99 | + | ||
100 | + /** | ||
101 | + * Obtains the age of a group. The age reflects the number of polling rounds | ||
102 | + * the group has had a reference count of zero. | ||
103 | + * | ||
104 | + * @return the age of the group as an integer | ||
105 | + */ | ||
106 | + int age(); | ||
99 | } | 107 | } | ... | ... |
... | @@ -19,15 +19,17 @@ import com.google.common.collect.FluentIterable; | ... | @@ -19,15 +19,17 @@ import com.google.common.collect.FluentIterable; |
19 | import com.google.common.collect.ImmutableSet; | 19 | import com.google.common.collect.ImmutableSet; |
20 | import com.google.common.collect.Iterables; | 20 | import com.google.common.collect.Iterables; |
21 | import com.google.common.collect.Sets; | 21 | import com.google.common.collect.Sets; |
22 | - | ||
23 | import org.apache.felix.scr.annotations.Activate; | 22 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 23 | import org.apache.felix.scr.annotations.Component; |
25 | import org.apache.felix.scr.annotations.Deactivate; | 24 | import org.apache.felix.scr.annotations.Deactivate; |
25 | +import org.apache.felix.scr.annotations.Modified; | ||
26 | +import org.apache.felix.scr.annotations.Property; | ||
26 | import org.apache.felix.scr.annotations.Reference; | 27 | import org.apache.felix.scr.annotations.Reference; |
27 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 28 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
28 | import org.apache.felix.scr.annotations.Service; | 29 | import org.apache.felix.scr.annotations.Service; |
29 | import org.onlab.util.KryoNamespace; | 30 | import org.onlab.util.KryoNamespace; |
30 | import org.onlab.util.NewConcurrentHashMap; | 31 | import org.onlab.util.NewConcurrentHashMap; |
32 | +import org.onosproject.cfg.ComponentConfigService; | ||
31 | import org.onosproject.cluster.ClusterService; | 33 | import org.onosproject.cluster.ClusterService; |
32 | import org.onosproject.cluster.NodeId; | 34 | import org.onosproject.cluster.NodeId; |
33 | import org.onosproject.core.DefaultGroupId; | 35 | import org.onosproject.core.DefaultGroupId; |
... | @@ -54,19 +56,21 @@ import org.onosproject.net.group.StoredGroupBucketEntry; | ... | @@ -54,19 +56,21 @@ import org.onosproject.net.group.StoredGroupBucketEntry; |
54 | import org.onosproject.net.group.StoredGroupEntry; | 56 | import org.onosproject.net.group.StoredGroupEntry; |
55 | import org.onosproject.store.AbstractStore; | 57 | import org.onosproject.store.AbstractStore; |
56 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; | 58 | import org.onosproject.store.cluster.messaging.ClusterCommunicationService; |
57 | -import org.onosproject.store.service.MultiValuedTimestamp; | ||
58 | import org.onosproject.store.serializers.KryoNamespaces; | 59 | import org.onosproject.store.serializers.KryoNamespaces; |
59 | import org.onosproject.store.service.ConsistentMap; | 60 | import org.onosproject.store.service.ConsistentMap; |
60 | import org.onosproject.store.service.MapEvent; | 61 | import org.onosproject.store.service.MapEvent; |
61 | import org.onosproject.store.service.MapEventListener; | 62 | import org.onosproject.store.service.MapEventListener; |
63 | +import org.onosproject.store.service.MultiValuedTimestamp; | ||
62 | import org.onosproject.store.service.Serializer; | 64 | import org.onosproject.store.service.Serializer; |
63 | import org.onosproject.store.service.StorageService; | 65 | import org.onosproject.store.service.StorageService; |
64 | import org.onosproject.store.service.Versioned; | 66 | import org.onosproject.store.service.Versioned; |
67 | +import org.osgi.service.component.ComponentContext; | ||
65 | import org.slf4j.Logger; | 68 | import org.slf4j.Logger; |
66 | 69 | ||
67 | import java.util.ArrayList; | 70 | import java.util.ArrayList; |
68 | import java.util.Collection; | 71 | import java.util.Collection; |
69 | import java.util.Collections; | 72 | import java.util.Collections; |
73 | +import java.util.Dictionary; | ||
70 | import java.util.HashMap; | 74 | import java.util.HashMap; |
71 | import java.util.HashSet; | 75 | import java.util.HashSet; |
72 | import java.util.Iterator; | 76 | import java.util.Iterator; |
... | @@ -75,6 +79,7 @@ import java.util.Map; | ... | @@ -75,6 +79,7 @@ import java.util.Map; |
75 | import java.util.Map.Entry; | 79 | import java.util.Map.Entry; |
76 | import java.util.Objects; | 80 | import java.util.Objects; |
77 | import java.util.Optional; | 81 | import java.util.Optional; |
82 | +import java.util.Properties; | ||
78 | import java.util.Set; | 83 | import java.util.Set; |
79 | import java.util.concurrent.ConcurrentHashMap; | 84 | import java.util.concurrent.ConcurrentHashMap; |
80 | import java.util.concurrent.ConcurrentMap; | 85 | import java.util.concurrent.ConcurrentMap; |
... | @@ -83,7 +88,9 @@ import java.util.concurrent.Executors; | ... | @@ -83,7 +88,9 @@ import java.util.concurrent.Executors; |
83 | import java.util.concurrent.atomic.AtomicInteger; | 88 | import java.util.concurrent.atomic.AtomicInteger; |
84 | import java.util.stream.Collectors; | 89 | import java.util.stream.Collectors; |
85 | 90 | ||
91 | +import static com.google.common.base.Strings.isNullOrEmpty; | ||
86 | import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; | 92 | import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; |
93 | +import static org.onlab.util.Tools.get; | ||
87 | import static org.onlab.util.Tools.groupedThreads; | 94 | import static org.onlab.util.Tools.groupedThreads; |
88 | import static org.slf4j.LoggerFactory.getLogger; | 95 | import static org.slf4j.LoggerFactory.getLogger; |
89 | 96 | ||
... | @@ -99,6 +106,9 @@ public class DistributedGroupStore | ... | @@ -99,6 +106,9 @@ public class DistributedGroupStore |
99 | 106 | ||
100 | private final Logger log = getLogger(getClass()); | 107 | private final Logger log = getLogger(getClass()); |
101 | 108 | ||
109 | + private static final boolean GARBAGE_COLLECT = false; | ||
110 | + private static final int GC_THRESH = 6; | ||
111 | + | ||
102 | private final int dummyId = 0xffffffff; | 112 | private final int dummyId = 0xffffffff; |
103 | private final GroupId dummyGroupId = new DefaultGroupId(dummyId); | 113 | private final GroupId dummyGroupId = new DefaultGroupId(dummyId); |
104 | 114 | ||
... | @@ -114,14 +124,17 @@ public class DistributedGroupStore | ... | @@ -114,14 +124,17 @@ public class DistributedGroupStore |
114 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 124 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
115 | protected MastershipService mastershipService; | 125 | protected MastershipService mastershipService; |
116 | 126 | ||
127 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
128 | + protected ComponentConfigService cfgService; | ||
129 | + | ||
117 | // Per device group table with (device id + app cookie) as key | 130 | // Per device group table with (device id + app cookie) as key |
118 | private ConsistentMap<GroupStoreKeyMapKey, | 131 | private ConsistentMap<GroupStoreKeyMapKey, |
119 | - StoredGroupEntry> groupStoreEntriesByKey = null; | 132 | + StoredGroupEntry> groupStoreEntriesByKey = null; |
120 | // Per device group table with (device id + group id) as key | 133 | // Per device group table with (device id + group id) as key |
121 | private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, StoredGroupEntry>> | 134 | private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, StoredGroupEntry>> |
122 | - groupEntriesById = new ConcurrentHashMap<>(); | 135 | + groupEntriesById = new ConcurrentHashMap<>(); |
123 | private ConsistentMap<GroupStoreKeyMapKey, | 136 | private ConsistentMap<GroupStoreKeyMapKey, |
124 | - StoredGroupEntry> auditPendingReqQueue = null; | 137 | + StoredGroupEntry> auditPendingReqQueue = null; |
125 | private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, Group>> | 138 | private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, Group>> |
126 | extraneousGroupEntriesById = new ConcurrentHashMap<>(); | 139 | extraneousGroupEntriesById = new ConcurrentHashMap<>(); |
127 | private ExecutorService messageHandlingExecutor; | 140 | private ExecutorService messageHandlingExecutor; |
... | @@ -135,27 +148,37 @@ public class DistributedGroupStore | ... | @@ -135,27 +148,37 @@ public class DistributedGroupStore |
135 | 148 | ||
136 | private KryoNamespace clusterMsgSerializer; | 149 | private KryoNamespace clusterMsgSerializer; |
137 | 150 | ||
151 | + @Property(name = "garbageCollect", boolValue = GARBAGE_COLLECT, | ||
152 | + label = "Enable group garbage collection") | ||
153 | + private boolean garbageCollect = GARBAGE_COLLECT; | ||
154 | + | ||
155 | + @Property(name = "gcThresh", intValue = GC_THRESH, | ||
156 | + label = "Number of rounds for group garbage collection") | ||
157 | + private int gcThresh = GC_THRESH; | ||
158 | + | ||
159 | + | ||
138 | @Activate | 160 | @Activate |
139 | public void activate() { | 161 | public void activate() { |
162 | + cfgService.registerProperties(getClass()); | ||
140 | kryoBuilder = new KryoNamespace.Builder() | 163 | kryoBuilder = new KryoNamespace.Builder() |
141 | - .register(KryoNamespaces.API) | 164 | + .register(KryoNamespaces.API) |
142 | - .register(DefaultGroup.class, | 165 | + .register(DefaultGroup.class, |
143 | - DefaultGroupBucket.class, | 166 | + DefaultGroupBucket.class, |
144 | - DefaultGroupDescription.class, | 167 | + DefaultGroupDescription.class, |
145 | - DefaultGroupKey.class, | 168 | + DefaultGroupKey.class, |
146 | - GroupDescription.Type.class, | 169 | + GroupDescription.Type.class, |
147 | - Group.GroupState.class, | 170 | + Group.GroupState.class, |
148 | - GroupBuckets.class, | 171 | + GroupBuckets.class, |
149 | - DefaultGroupId.class, | 172 | + DefaultGroupId.class, |
150 | - GroupStoreMessage.class, | 173 | + GroupStoreMessage.class, |
151 | - GroupStoreMessage.Type.class, | 174 | + GroupStoreMessage.Type.class, |
152 | - UpdateType.class, | 175 | + UpdateType.class, |
153 | - GroupStoreMessageSubjects.class, | 176 | + GroupStoreMessageSubjects.class, |
154 | - MultiValuedTimestamp.class, | 177 | + MultiValuedTimestamp.class, |
155 | - GroupStoreKeyMapKey.class, | 178 | + GroupStoreKeyMapKey.class, |
156 | - GroupStoreIdMapKey.class, | 179 | + GroupStoreIdMapKey.class, |
157 | - GroupStoreMapKey.class | 180 | + GroupStoreMapKey.class |
158 | - ); | 181 | + ); |
159 | 182 | ||
160 | clusterMsgSerializer = kryoBuilder.build(); | 183 | clusterMsgSerializer = kryoBuilder.build(); |
161 | 184 | ||
... | @@ -165,9 +188,9 @@ public class DistributedGroupStore | ... | @@ -165,9 +188,9 @@ public class DistributedGroupStore |
165 | "message-handlers")); | 188 | "message-handlers")); |
166 | 189 | ||
167 | clusterCommunicator.addSubscriber(GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, | 190 | clusterCommunicator.addSubscriber(GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, |
168 | - clusterMsgSerializer::deserialize, | 191 | + clusterMsgSerializer::deserialize, |
169 | - this::process, | 192 | + this::process, |
170 | - messageHandlingExecutor); | 193 | + messageHandlingExecutor); |
171 | 194 | ||
172 | log.debug("Creating Consistent map onos-group-store-keymap"); | 195 | log.debug("Creating Consistent map onos-group-store-keymap"); |
173 | 196 | ||
... | @@ -193,19 +216,36 @@ public class DistributedGroupStore | ... | @@ -193,19 +216,36 @@ public class DistributedGroupStore |
193 | 216 | ||
194 | @Deactivate | 217 | @Deactivate |
195 | public void deactivate() { | 218 | public void deactivate() { |
219 | + cfgService.unregisterProperties(getClass(), false); | ||
196 | clusterCommunicator.removeSubscriber(GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST); | 220 | clusterCommunicator.removeSubscriber(GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST); |
197 | groupStoreEntriesByKey.destroy(); | 221 | groupStoreEntriesByKey.destroy(); |
198 | auditPendingReqQueue.destroy(); | 222 | auditPendingReqQueue.destroy(); |
199 | log.info("Stopped"); | 223 | log.info("Stopped"); |
200 | } | 224 | } |
201 | 225 | ||
226 | + @Modified | ||
227 | + public void modified(ComponentContext context) { | ||
228 | + Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties(); | ||
229 | + | ||
230 | + try { | ||
231 | + String s = get(properties, "garbageCollect"); | ||
232 | + garbageCollect = isNullOrEmpty(s) ? GARBAGE_COLLECT : Boolean.parseBoolean(s.trim()); | ||
233 | + | ||
234 | + s = get(properties, "gcThresh"); | ||
235 | + gcThresh = isNullOrEmpty(s) ? GC_THRESH : Integer.parseInt(s.trim()); | ||
236 | + } catch (Exception e) { | ||
237 | + gcThresh = GC_THRESH; | ||
238 | + garbageCollect = GARBAGE_COLLECT; | ||
239 | + } | ||
240 | + } | ||
241 | + | ||
202 | private static NewConcurrentHashMap<GroupId, Group> | 242 | private static NewConcurrentHashMap<GroupId, Group> |
203 | - lazyEmptyExtraneousGroupIdTable() { | 243 | + lazyEmptyExtraneousGroupIdTable() { |
204 | return NewConcurrentHashMap.<GroupId, Group>ifNeeded(); | 244 | return NewConcurrentHashMap.<GroupId, Group>ifNeeded(); |
205 | } | 245 | } |
206 | 246 | ||
207 | private static NewConcurrentHashMap<GroupId, StoredGroupEntry> | 247 | private static NewConcurrentHashMap<GroupId, StoredGroupEntry> |
208 | - lazyEmptyGroupIdTable() { | 248 | + lazyEmptyGroupIdTable() { |
209 | return NewConcurrentHashMap.<GroupId, StoredGroupEntry>ifNeeded(); | 249 | return NewConcurrentHashMap.<GroupId, StoredGroupEntry>ifNeeded(); |
210 | } | 250 | } |
211 | 251 | ||
... | @@ -215,7 +255,7 @@ public class DistributedGroupStore | ... | @@ -215,7 +255,7 @@ public class DistributedGroupStore |
215 | * @return Map representing group key table. | 255 | * @return Map representing group key table. |
216 | */ | 256 | */ |
217 | private Map<GroupStoreKeyMapKey, StoredGroupEntry> | 257 | private Map<GroupStoreKeyMapKey, StoredGroupEntry> |
218 | - getGroupStoreKeyMap() { | 258 | + getGroupStoreKeyMap() { |
219 | return groupStoreEntriesByKey.asJavaMap(); | 259 | return groupStoreEntriesByKey.asJavaMap(); |
220 | } | 260 | } |
221 | 261 | ||
... | @@ -236,7 +276,7 @@ public class DistributedGroupStore | ... | @@ -236,7 +276,7 @@ public class DistributedGroupStore |
236 | * @return Map representing group key table. | 276 | * @return Map representing group key table. |
237 | */ | 277 | */ |
238 | private Map<GroupStoreKeyMapKey, StoredGroupEntry> | 278 | private Map<GroupStoreKeyMapKey, StoredGroupEntry> |
239 | - getPendingGroupKeyTable() { | 279 | + getPendingGroupKeyTable() { |
240 | return auditPendingReqQueue.asJavaMap(); | 280 | return auditPendingReqQueue.asJavaMap(); |
241 | } | 281 | } |
242 | 282 | ||
... | @@ -261,14 +301,13 @@ public class DistributedGroupStore | ... | @@ -261,14 +301,13 @@ public class DistributedGroupStore |
261 | @Override | 301 | @Override |
262 | public int getGroupCount(DeviceId deviceId) { | 302 | public int getGroupCount(DeviceId deviceId) { |
263 | return (getGroups(deviceId) != null) ? | 303 | return (getGroups(deviceId) != null) ? |
264 | - Iterables.size(getGroups(deviceId)) : 0; | 304 | + Iterables.size(getGroups(deviceId)) : 0; |
265 | } | 305 | } |
266 | 306 | ||
267 | /** | 307 | /** |
268 | * Returns the groups associated with a device. | 308 | * Returns the groups associated with a device. |
269 | * | 309 | * |
270 | * @param deviceId the device ID | 310 | * @param deviceId the device ID |
271 | - * | ||
272 | * @return the group entries | 311 | * @return the group entries |
273 | */ | 312 | */ |
274 | @Override | 313 | @Override |
... | @@ -294,9 +333,8 @@ public class DistributedGroupStore | ... | @@ -294,9 +333,8 @@ public class DistributedGroupStore |
294 | /** | 333 | /** |
295 | * Returns the stored group entry. | 334 | * Returns the stored group entry. |
296 | * | 335 | * |
297 | - * @param deviceId the device ID | 336 | + * @param deviceId the device ID |
298 | * @param appCookie the group key | 337 | * @param appCookie the group key |
299 | - * | ||
300 | * @return a group associated with the key | 338 | * @return a group associated with the key |
301 | */ | 339 | */ |
302 | @Override | 340 | @Override |
... | @@ -365,8 +403,8 @@ public class DistributedGroupStore | ... | @@ -365,8 +403,8 @@ public class DistributedGroupStore |
365 | groupDesc.deviceId()); | 403 | groupDesc.deviceId()); |
366 | if (mastershipService.getMasterFor(groupDesc.deviceId()) == null) { | 404 | if (mastershipService.getMasterFor(groupDesc.deviceId()) == null) { |
367 | log.error("No Master for device {}..." | 405 | log.error("No Master for device {}..." |
368 | - + "Can not perform add group operation", | 406 | + + "Can not perform add group operation", |
369 | - groupDesc.deviceId()); | 407 | + groupDesc.deviceId()); |
370 | //TODO: Send Group operation failure event | 408 | //TODO: Send Group operation failure event |
371 | return; | 409 | return; |
372 | } | 410 | } |
... | @@ -375,19 +413,20 @@ public class DistributedGroupStore | ... | @@ -375,19 +413,20 @@ public class DistributedGroupStore |
375 | groupDesc); | 413 | groupDesc); |
376 | 414 | ||
377 | clusterCommunicator.unicast(groupOp, | 415 | clusterCommunicator.unicast(groupOp, |
378 | - GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, | 416 | + GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, |
379 | - clusterMsgSerializer::serialize, | 417 | + clusterMsgSerializer::serialize, |
380 | - mastershipService.getMasterFor(groupDesc.deviceId())).whenComplete((result, error) -> { | 418 | + mastershipService.getMasterFor(groupDesc.deviceId())) |
419 | + .whenComplete((result, error) -> { | ||
381 | if (error != null) { | 420 | if (error != null) { |
382 | log.warn("Failed to send request to master: {} to {}", | 421 | log.warn("Failed to send request to master: {} to {}", |
383 | - groupOp, | 422 | + groupOp, |
384 | - mastershipService.getMasterFor(groupDesc.deviceId())); | 423 | + mastershipService.getMasterFor(groupDesc.deviceId())); |
385 | //TODO: Send Group operation failure event | 424 | //TODO: Send Group operation failure event |
386 | } else { | 425 | } else { |
387 | log.debug("Sent Group operation request for device {} " | 426 | log.debug("Sent Group operation request for device {} " |
388 | - + "to remote MASTER {}", | 427 | + + "to remote MASTER {}", |
389 | - groupDesc.deviceId(), | 428 | + groupDesc.deviceId(), |
390 | - mastershipService.getMasterFor(groupDesc.deviceId())); | 429 | + mastershipService.getMasterFor(groupDesc.deviceId())); |
391 | } | 430 | } |
392 | }); | 431 | }); |
393 | return; | 432 | return; |
... | @@ -415,7 +454,7 @@ public class DistributedGroupStore | ... | @@ -415,7 +454,7 @@ public class DistributedGroupStore |
415 | return null; | 454 | return null; |
416 | } | 455 | } |
417 | 456 | ||
418 | - for (Group extraneousGroup:extraneousMap.values()) { | 457 | + for (Group extraneousGroup : extraneousMap.values()) { |
419 | if (extraneousGroup.buckets().equals(buckets)) { | 458 | if (extraneousGroup.buckets().equals(buckets)) { |
420 | return extraneousGroup; | 459 | return extraneousGroup; |
421 | } | 460 | } |
... | @@ -434,7 +473,7 @@ public class DistributedGroupStore | ... | @@ -434,7 +473,7 @@ public class DistributedGroupStore |
434 | // Add this group description to pending group key table | 473 | // Add this group description to pending group key table |
435 | // Create a group entry object with Dummy Group ID | 474 | // Create a group entry object with Dummy Group ID |
436 | log.debug("storeGroupDescriptionInternal: Device {} AUDIT pending...Queuing Group ADD request", | 475 | log.debug("storeGroupDescriptionInternal: Device {} AUDIT pending...Queuing Group ADD request", |
437 | - groupDesc.deviceId()); | 476 | + groupDesc.deviceId()); |
438 | StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc); | 477 | StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc); |
439 | group.setState(GroupState.WAITING_AUDIT_COMPLETE); | 478 | group.setState(GroupState.WAITING_AUDIT_COMPLETE); |
440 | Map<GroupStoreKeyMapKey, StoredGroupEntry> pendingKeyTable = | 479 | Map<GroupStoreKeyMapKey, StoredGroupEntry> pendingKeyTable = |
... | @@ -449,10 +488,10 @@ public class DistributedGroupStore | ... | @@ -449,10 +488,10 @@ public class DistributedGroupStore |
449 | if (groupDesc.givenGroupId() != null) { | 488 | if (groupDesc.givenGroupId() != null) { |
450 | //Check if there is a extraneous group existing with the same Id | 489 | //Check if there is a extraneous group existing with the same Id |
451 | matchingExtraneousGroup = getMatchingExtraneousGroupbyId( | 490 | matchingExtraneousGroup = getMatchingExtraneousGroupbyId( |
452 | - groupDesc.deviceId(), groupDesc.givenGroupId()); | 491 | + groupDesc.deviceId(), groupDesc.givenGroupId()); |
453 | if (matchingExtraneousGroup != null) { | 492 | if (matchingExtraneousGroup != null) { |
454 | log.debug("storeGroupDescriptionInternal: Matching extraneous group " | 493 | log.debug("storeGroupDescriptionInternal: Matching extraneous group " |
455 | - + "found in Device {} for group id 0x{}", | 494 | + + "found in Device {} for group id 0x{}", |
456 | groupDesc.deviceId(), | 495 | groupDesc.deviceId(), |
457 | Integer.toHexString(groupDesc.givenGroupId())); | 496 | Integer.toHexString(groupDesc.givenGroupId())); |
458 | //Check if the group buckets matches with user provided buckets | 497 | //Check if the group buckets matches with user provided buckets |
... | @@ -460,19 +499,19 @@ public class DistributedGroupStore | ... | @@ -460,19 +499,19 @@ public class DistributedGroupStore |
460 | //Group is already existing with the same buckets and Id | 499 | //Group is already existing with the same buckets and Id |
461 | // Create a group entry object | 500 | // Create a group entry object |
462 | log.debug("storeGroupDescriptionInternal: Buckets also matching " | 501 | log.debug("storeGroupDescriptionInternal: Buckets also matching " |
463 | - + "in Device {} for group id 0x{}", | 502 | + + "in Device {} for group id 0x{}", |
464 | groupDesc.deviceId(), | 503 | groupDesc.deviceId(), |
465 | Integer.toHexString(groupDesc.givenGroupId())); | 504 | Integer.toHexString(groupDesc.givenGroupId())); |
466 | StoredGroupEntry group = new DefaultGroup( | 505 | StoredGroupEntry group = new DefaultGroup( |
467 | - matchingExtraneousGroup.id(), groupDesc); | 506 | + matchingExtraneousGroup.id(), groupDesc); |
468 | // Insert the newly created group entry into key and id maps | 507 | // Insert the newly created group entry into key and id maps |
469 | getGroupStoreKeyMap(). | 508 | getGroupStoreKeyMap(). |
470 | - put(new GroupStoreKeyMapKey(groupDesc.deviceId(), | 509 | + put(new GroupStoreKeyMapKey(groupDesc.deviceId(), |
471 | - groupDesc.appCookie()), group); | 510 | + groupDesc.appCookie()), group); |
472 | // Ensure it also inserted into group id based table to | 511 | // Ensure it also inserted into group id based table to |
473 | // avoid any chances of duplication in group id generation | 512 | // avoid any chances of duplication in group id generation |
474 | getGroupIdTable(groupDesc.deviceId()). | 513 | getGroupIdTable(groupDesc.deviceId()). |
475 | - put(matchingExtraneousGroup.id(), group); | 514 | + put(matchingExtraneousGroup.id(), group); |
476 | addOrUpdateGroupEntry(matchingExtraneousGroup); | 515 | addOrUpdateGroupEntry(matchingExtraneousGroup); |
477 | removeExtraneousGroupEntry(matchingExtraneousGroup); | 516 | removeExtraneousGroupEntry(matchingExtraneousGroup); |
478 | return; | 517 | return; |
... | @@ -480,22 +519,22 @@ public class DistributedGroupStore | ... | @@ -480,22 +519,22 @@ public class DistributedGroupStore |
480 | //Group buckets are not matching. Update group | 519 | //Group buckets are not matching. Update group |
481 | //with user provided buckets. | 520 | //with user provided buckets. |
482 | log.debug("storeGroupDescriptionInternal: Buckets are not " | 521 | log.debug("storeGroupDescriptionInternal: Buckets are not " |
483 | - + "matching in Device {} for group id 0x{}", | 522 | + + "matching in Device {} for group id 0x{}", |
484 | groupDesc.deviceId(), | 523 | groupDesc.deviceId(), |
485 | Integer.toHexString(groupDesc.givenGroupId())); | 524 | Integer.toHexString(groupDesc.givenGroupId())); |
486 | StoredGroupEntry modifiedGroup = new DefaultGroup( | 525 | StoredGroupEntry modifiedGroup = new DefaultGroup( |
487 | - matchingExtraneousGroup.id(), groupDesc); | 526 | + matchingExtraneousGroup.id(), groupDesc); |
488 | modifiedGroup.setState(GroupState.PENDING_UPDATE); | 527 | modifiedGroup.setState(GroupState.PENDING_UPDATE); |
489 | getGroupStoreKeyMap(). | 528 | getGroupStoreKeyMap(). |
490 | - put(new GroupStoreKeyMapKey(groupDesc.deviceId(), | 529 | + put(new GroupStoreKeyMapKey(groupDesc.deviceId(), |
491 | - groupDesc.appCookie()), modifiedGroup); | 530 | + groupDesc.appCookie()), modifiedGroup); |
492 | // Ensure it also inserted into group id based table to | 531 | // Ensure it also inserted into group id based table to |
493 | // avoid any chances of duplication in group id generation | 532 | // avoid any chances of duplication in group id generation |
494 | getGroupIdTable(groupDesc.deviceId()). | 533 | getGroupIdTable(groupDesc.deviceId()). |
495 | - put(matchingExtraneousGroup.id(), modifiedGroup); | 534 | + put(matchingExtraneousGroup.id(), modifiedGroup); |
496 | removeExtraneousGroupEntry(matchingExtraneousGroup); | 535 | removeExtraneousGroupEntry(matchingExtraneousGroup); |
497 | log.debug("storeGroupDescriptionInternal: Triggering Group " | 536 | log.debug("storeGroupDescriptionInternal: Triggering Group " |
498 | - + "UPDATE request for {} in device {}", | 537 | + + "UPDATE request for {} in device {}", |
499 | matchingExtraneousGroup.id(), | 538 | matchingExtraneousGroup.id(), |
500 | groupDesc.deviceId()); | 539 | groupDesc.deviceId()); |
501 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, modifiedGroup)); | 540 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, modifiedGroup)); |
... | @@ -505,7 +544,7 @@ public class DistributedGroupStore | ... | @@ -505,7 +544,7 @@ public class DistributedGroupStore |
505 | } else { | 544 | } else { |
506 | //Check if there is an extraneous group with user provided buckets | 545 | //Check if there is an extraneous group with user provided buckets |
507 | matchingExtraneousGroup = getMatchingExtraneousGroupbyBuckets( | 546 | matchingExtraneousGroup = getMatchingExtraneousGroupbyBuckets( |
508 | - groupDesc.deviceId(), groupDesc.buckets()); | 547 | + groupDesc.deviceId(), groupDesc.buckets()); |
509 | if (matchingExtraneousGroup != null) { | 548 | if (matchingExtraneousGroup != null) { |
510 | //Group is already existing with the same buckets. | 549 | //Group is already existing with the same buckets. |
511 | //So reuse this group. | 550 | //So reuse this group. |
... | @@ -513,15 +552,15 @@ public class DistributedGroupStore | ... | @@ -513,15 +552,15 @@ public class DistributedGroupStore |
513 | groupDesc.deviceId()); | 552 | groupDesc.deviceId()); |
514 | //Create a group entry object | 553 | //Create a group entry object |
515 | StoredGroupEntry group = new DefaultGroup( | 554 | StoredGroupEntry group = new DefaultGroup( |
516 | - matchingExtraneousGroup.id(), groupDesc); | 555 | + matchingExtraneousGroup.id(), groupDesc); |
517 | // Insert the newly created group entry into key and id maps | 556 | // Insert the newly created group entry into key and id maps |
518 | getGroupStoreKeyMap(). | 557 | getGroupStoreKeyMap(). |
519 | - put(new GroupStoreKeyMapKey(groupDesc.deviceId(), | 558 | + put(new GroupStoreKeyMapKey(groupDesc.deviceId(), |
520 | - groupDesc.appCookie()), group); | 559 | + groupDesc.appCookie()), group); |
521 | // Ensure it also inserted into group id based table to | 560 | // Ensure it also inserted into group id based table to |
522 | // avoid any chances of duplication in group id generation | 561 | // avoid any chances of duplication in group id generation |
523 | getGroupIdTable(groupDesc.deviceId()). | 562 | getGroupIdTable(groupDesc.deviceId()). |
524 | - put(matchingExtraneousGroup.id(), group); | 563 | + put(matchingExtraneousGroup.id(), group); |
525 | addOrUpdateGroupEntry(matchingExtraneousGroup); | 564 | addOrUpdateGroupEntry(matchingExtraneousGroup); |
526 | removeExtraneousGroupEntry(matchingExtraneousGroup); | 565 | removeExtraneousGroupEntry(matchingExtraneousGroup); |
527 | return; | 566 | return; |
... | @@ -543,11 +582,11 @@ public class DistributedGroupStore | ... | @@ -543,11 +582,11 @@ public class DistributedGroupStore |
543 | new DefaultGroupId(groupDesc.givenGroupId())); | 582 | new DefaultGroupId(groupDesc.givenGroupId())); |
544 | if (existing != null) { | 583 | if (existing != null) { |
545 | log.warn("Group already exists with the same id: 0x{} in dev:{} " | 584 | log.warn("Group already exists with the same id: 0x{} in dev:{} " |
546 | - + "but with different key: {} (request gkey: {})", | 585 | + + "but with different key: {} (request gkey: {})", |
547 | - Integer.toHexString(groupDesc.givenGroupId()), | 586 | + Integer.toHexString(groupDesc.givenGroupId()), |
548 | - groupDesc.deviceId(), | 587 | + groupDesc.deviceId(), |
549 | - existing.appCookie(), | 588 | + existing.appCookie(), |
550 | - groupDesc.appCookie()); | 589 | + groupDesc.appCookie()); |
551 | return; | 590 | return; |
552 | } | 591 | } |
553 | id = new DefaultGroupId(groupDesc.givenGroupId()); | 592 | id = new DefaultGroupId(groupDesc.givenGroupId()); |
... | @@ -556,15 +595,15 @@ public class DistributedGroupStore | ... | @@ -556,15 +595,15 @@ public class DistributedGroupStore |
556 | StoredGroupEntry group = new DefaultGroup(id, groupDesc); | 595 | StoredGroupEntry group = new DefaultGroup(id, groupDesc); |
557 | // Insert the newly created group entry into key and id maps | 596 | // Insert the newly created group entry into key and id maps |
558 | getGroupStoreKeyMap(). | 597 | getGroupStoreKeyMap(). |
559 | - put(new GroupStoreKeyMapKey(groupDesc.deviceId(), | 598 | + put(new GroupStoreKeyMapKey(groupDesc.deviceId(), |
560 | - groupDesc.appCookie()), group); | 599 | + groupDesc.appCookie()), group); |
561 | // Ensure it also inserted into group id based table to | 600 | // Ensure it also inserted into group id based table to |
562 | // avoid any chances of duplication in group id generation | 601 | // avoid any chances of duplication in group id generation |
563 | getGroupIdTable(groupDesc.deviceId()). | 602 | getGroupIdTable(groupDesc.deviceId()). |
564 | - put(id, group); | 603 | + put(id, group); |
565 | log.debug("storeGroupDescriptionInternal: Processing Group ADD request for Id {} in device {}", | 604 | log.debug("storeGroupDescriptionInternal: Processing Group ADD request for Id {} in device {}", |
566 | - id, | 605 | + id, |
567 | - groupDesc.deviceId()); | 606 | + groupDesc.deviceId()); |
568 | notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, | 607 | notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, |
569 | group)); | 608 | group)); |
570 | } | 609 | } |
... | @@ -573,10 +612,10 @@ public class DistributedGroupStore | ... | @@ -573,10 +612,10 @@ public class DistributedGroupStore |
573 | * Updates the existing group entry with the information | 612 | * Updates the existing group entry with the information |
574 | * from group description. | 613 | * from group description. |
575 | * | 614 | * |
576 | - * @param deviceId the device ID | 615 | + * @param deviceId the device ID |
577 | * @param oldAppCookie the current group key | 616 | * @param oldAppCookie the current group key |
578 | - * @param type update type | 617 | + * @param type update type |
579 | - * @param newBuckets group buckets for updates | 618 | + * @param newBuckets group buckets for updates |
580 | * @param newAppCookie optional new group key | 619 | * @param newAppCookie optional new group key |
581 | */ | 620 | */ |
582 | @Override | 621 | @Override |
... | @@ -592,8 +631,8 @@ public class DistributedGroupStore | ... | @@ -592,8 +631,8 @@ public class DistributedGroupStore |
592 | deviceId); | 631 | deviceId); |
593 | if (mastershipService.getMasterFor(deviceId) == null) { | 632 | if (mastershipService.getMasterFor(deviceId) == null) { |
594 | log.error("No Master for device {}..." | 633 | log.error("No Master for device {}..." |
595 | - + "Can not perform update group operation", | 634 | + + "Can not perform update group operation", |
596 | - deviceId); | 635 | + deviceId); |
597 | //TODO: Send Group operation failure event | 636 | //TODO: Send Group operation failure event |
598 | return; | 637 | return; |
599 | } | 638 | } |
... | @@ -605,16 +644,16 @@ public class DistributedGroupStore | ... | @@ -605,16 +644,16 @@ public class DistributedGroupStore |
605 | newAppCookie); | 644 | newAppCookie); |
606 | 645 | ||
607 | clusterCommunicator.unicast(groupOp, | 646 | clusterCommunicator.unicast(groupOp, |
608 | - GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, | 647 | + GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, |
609 | - clusterMsgSerializer::serialize, | 648 | + clusterMsgSerializer::serialize, |
610 | - mastershipService.getMasterFor(deviceId)).whenComplete((result, error) -> { | 649 | + mastershipService.getMasterFor(deviceId)).whenComplete((result, error) -> { |
611 | - if (error != null) { | 650 | + if (error != null) { |
612 | - log.warn("Failed to send request to master: {} to {}", | 651 | + log.warn("Failed to send request to master: {} to {}", |
613 | - groupOp, | 652 | + groupOp, |
614 | - mastershipService.getMasterFor(deviceId), error); | 653 | + mastershipService.getMasterFor(deviceId), error); |
615 | - } | 654 | + } |
616 | - //TODO: Send Group operation failure event | 655 | + //TODO: Send Group operation failure event |
617 | - }); | 656 | + }); |
618 | return; | 657 | return; |
619 | } | 658 | } |
620 | log.debug("updateGroupDescription for device {} is getting handled locally", | 659 | log.debug("updateGroupDescription for device {} is getting handled locally", |
... | @@ -627,15 +666,15 @@ public class DistributedGroupStore | ... | @@ -627,15 +666,15 @@ public class DistributedGroupStore |
627 | } | 666 | } |
628 | 667 | ||
629 | private void updateGroupDescriptionInternal(DeviceId deviceId, | 668 | private void updateGroupDescriptionInternal(DeviceId deviceId, |
630 | - GroupKey oldAppCookie, | 669 | + GroupKey oldAppCookie, |
631 | - UpdateType type, | 670 | + UpdateType type, |
632 | - GroupBuckets newBuckets, | 671 | + GroupBuckets newBuckets, |
633 | - GroupKey newAppCookie) { | 672 | + GroupKey newAppCookie) { |
634 | // Check if a group is existing with the provided key | 673 | // Check if a group is existing with the provided key |
635 | Group oldGroup = getGroup(deviceId, oldAppCookie); | 674 | Group oldGroup = getGroup(deviceId, oldAppCookie); |
636 | if (oldGroup == null) { | 675 | if (oldGroup == null) { |
637 | log.warn("updateGroupDescriptionInternal: Group not found...strange. " | 676 | log.warn("updateGroupDescriptionInternal: Group not found...strange. " |
638 | - + "GroupKey:{} DeviceId:{}", oldAppCookie, deviceId); | 677 | + + "GroupKey:{} DeviceId:{}", oldAppCookie, deviceId); |
639 | return; | 678 | return; |
640 | } | 679 | } |
641 | 680 | ||
... | @@ -656,9 +695,9 @@ public class DistributedGroupStore | ... | @@ -656,9 +695,9 @@ public class DistributedGroupStore |
656 | StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), | 695 | StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), |
657 | updatedGroupDesc); | 696 | updatedGroupDesc); |
658 | log.debug("updateGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_UPDATE", | 697 | log.debug("updateGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_UPDATE", |
659 | - oldGroup.id(), | 698 | + oldGroup.id(), |
660 | - oldGroup.deviceId(), | 699 | + oldGroup.deviceId(), |
661 | - oldGroup.state()); | 700 | + oldGroup.state()); |
662 | newGroup.setState(GroupState.PENDING_UPDATE); | 701 | newGroup.setState(GroupState.PENDING_UPDATE); |
663 | newGroup.setLife(oldGroup.life()); | 702 | newGroup.setLife(oldGroup.life()); |
664 | newGroup.setPackets(oldGroup.packets()); | 703 | newGroup.setPackets(oldGroup.packets()); |
... | @@ -669,12 +708,12 @@ public class DistributedGroupStore | ... | @@ -669,12 +708,12 @@ public class DistributedGroupStore |
669 | log.debug("updateGroupDescriptionInternal with type {}: Group updated with buckets", | 708 | log.debug("updateGroupDescriptionInternal with type {}: Group updated with buckets", |
670 | type); | 709 | type); |
671 | getGroupStoreKeyMap(). | 710 | getGroupStoreKeyMap(). |
672 | - put(new GroupStoreKeyMapKey(newGroup.deviceId(), | 711 | + put(new GroupStoreKeyMapKey(newGroup.deviceId(), |
673 | - newGroup.appCookie()), newGroup); | 712 | + newGroup.appCookie()), newGroup); |
674 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup)); | 713 | notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup)); |
675 | } else { | 714 | } else { |
676 | log.warn("updateGroupDescriptionInternal with type {}: No " | 715 | log.warn("updateGroupDescriptionInternal with type {}: No " |
677 | - + "change in the buckets in update", type); | 716 | + + "change in the buckets in update", type); |
678 | } | 717 | } |
679 | } | 718 | } |
680 | 719 | ||
... | @@ -688,7 +727,7 @@ public class DistributedGroupStore | ... | @@ -688,7 +727,7 @@ public class DistributedGroupStore |
688 | if (type == UpdateType.ADD) { | 727 | if (type == UpdateType.ADD) { |
689 | // Check if the any of the new buckets are part of | 728 | // Check if the any of the new buckets are part of |
690 | // the old bucket list | 729 | // the old bucket list |
691 | - for (GroupBucket addBucket:buckets.buckets()) { | 730 | + for (GroupBucket addBucket : buckets.buckets()) { |
692 | if (!newBucketList.contains(addBucket)) { | 731 | if (!newBucketList.contains(addBucket)) { |
693 | newBucketList.add(addBucket); | 732 | newBucketList.add(addBucket); |
694 | groupDescUpdated = true; | 733 | groupDescUpdated = true; |
... | @@ -697,7 +736,7 @@ public class DistributedGroupStore | ... | @@ -697,7 +736,7 @@ public class DistributedGroupStore |
697 | } else if (type == UpdateType.REMOVE) { | 736 | } else if (type == UpdateType.REMOVE) { |
698 | // Check if the to be removed buckets are part of the | 737 | // Check if the to be removed buckets are part of the |
699 | // old bucket list | 738 | // old bucket list |
700 | - for (GroupBucket removeBucket:buckets.buckets()) { | 739 | + for (GroupBucket removeBucket : buckets.buckets()) { |
701 | if (newBucketList.contains(removeBucket)) { | 740 | if (newBucketList.contains(removeBucket)) { |
702 | newBucketList.remove(removeBucket); | 741 | newBucketList.remove(removeBucket); |
703 | groupDescUpdated = true; | 742 | groupDescUpdated = true; |
... | @@ -715,7 +754,7 @@ public class DistributedGroupStore | ... | @@ -715,7 +754,7 @@ public class DistributedGroupStore |
715 | /** | 754 | /** |
716 | * Triggers deleting the existing group entry. | 755 | * Triggers deleting the existing group entry. |
717 | * | 756 | * |
718 | - * @param deviceId the device ID | 757 | + * @param deviceId the device ID |
719 | * @param appCookie the group key | 758 | * @param appCookie the group key |
720 | */ | 759 | */ |
721 | @Override | 760 | @Override |
... | @@ -728,8 +767,8 @@ public class DistributedGroupStore | ... | @@ -728,8 +767,8 @@ public class DistributedGroupStore |
728 | deviceId); | 767 | deviceId); |
729 | if (mastershipService.getMasterFor(deviceId) == null) { | 768 | if (mastershipService.getMasterFor(deviceId) == null) { |
730 | log.error("No Master for device {}..." | 769 | log.error("No Master for device {}..." |
731 | - + "Can not perform delete group operation", | 770 | + + "Can not perform delete group operation", |
732 | - deviceId); | 771 | + deviceId); |
733 | //TODO: Send Group operation failure event | 772 | //TODO: Send Group operation failure event |
734 | return; | 773 | return; |
735 | } | 774 | } |
... | @@ -738,16 +777,16 @@ public class DistributedGroupStore | ... | @@ -738,16 +777,16 @@ public class DistributedGroupStore |
738 | appCookie); | 777 | appCookie); |
739 | 778 | ||
740 | clusterCommunicator.unicast(groupOp, | 779 | clusterCommunicator.unicast(groupOp, |
741 | - GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, | 780 | + GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, |
742 | - clusterMsgSerializer::serialize, | 781 | + clusterMsgSerializer::serialize, |
743 | - mastershipService.getMasterFor(deviceId)).whenComplete((result, error) -> { | 782 | + mastershipService.getMasterFor(deviceId)).whenComplete((result, error) -> { |
744 | - if (error != null) { | 783 | + if (error != null) { |
745 | - log.warn("Failed to send request to master: {} to {}", | 784 | + log.warn("Failed to send request to master: {} to {}", |
746 | - groupOp, | 785 | + groupOp, |
747 | - mastershipService.getMasterFor(deviceId), error); | 786 | + mastershipService.getMasterFor(deviceId), error); |
748 | - } | 787 | + } |
749 | - //TODO: Send Group operation failure event | 788 | + //TODO: Send Group operation failure event |
750 | - }); | 789 | + }); |
751 | return; | 790 | return; |
752 | } | 791 | } |
753 | log.debug("deleteGroupDescription in device {} is getting handled locally", | 792 | log.debug("deleteGroupDescription in device {} is getting handled locally", |
... | @@ -764,14 +803,14 @@ public class DistributedGroupStore | ... | @@ -764,14 +803,14 @@ public class DistributedGroupStore |
764 | } | 803 | } |
765 | 804 | ||
766 | log.debug("deleteGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_DELETE", | 805 | log.debug("deleteGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_DELETE", |
767 | - existing.id(), | 806 | + existing.id(), |
768 | - existing.deviceId(), | 807 | + existing.deviceId(), |
769 | - existing.state()); | 808 | + existing.state()); |
770 | synchronized (existing) { | 809 | synchronized (existing) { |
771 | existing.setState(GroupState.PENDING_DELETE); | 810 | existing.setState(GroupState.PENDING_DELETE); |
772 | getGroupStoreKeyMap(). | 811 | getGroupStoreKeyMap(). |
773 | - put(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie()), | 812 | + put(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie()), |
774 | - existing); | 813 | + existing); |
775 | } | 814 | } |
776 | log.debug("deleteGroupDescriptionInternal: in device {} issuing GROUP_REMOVE_REQUESTED", | 815 | log.debug("deleteGroupDescriptionInternal: in device {} issuing GROUP_REMOVE_REQUESTED", |
777 | deviceId); | 816 | deviceId); |
... | @@ -792,15 +831,15 @@ public class DistributedGroupStore | ... | @@ -792,15 +831,15 @@ public class DistributedGroupStore |
792 | 831 | ||
793 | if (existing != null) { | 832 | if (existing != null) { |
794 | log.trace("addOrUpdateGroupEntry: updating group entry {} in device {}", | 833 | log.trace("addOrUpdateGroupEntry: updating group entry {} in device {}", |
795 | - group.id(), | 834 | + group.id(), |
796 | - group.deviceId()); | 835 | + group.deviceId()); |
797 | synchronized (existing) { | 836 | synchronized (existing) { |
798 | - for (GroupBucket bucket:group.buckets().buckets()) { | 837 | + for (GroupBucket bucket : group.buckets().buckets()) { |
799 | Optional<GroupBucket> matchingBucket = | 838 | Optional<GroupBucket> matchingBucket = |
800 | existing.buckets().buckets() | 839 | existing.buckets().buckets() |
801 | - .stream() | 840 | + .stream() |
802 | - .filter((existingBucket)->(existingBucket.equals(bucket))) | 841 | + .filter((existingBucket) -> (existingBucket.equals(bucket))) |
803 | - .findFirst(); | 842 | + .findFirst(); |
804 | if (matchingBucket.isPresent()) { | 843 | if (matchingBucket.isPresent()) { |
805 | ((StoredGroupBucketEntry) matchingBucket. | 844 | ((StoredGroupBucketEntry) matchingBucket. |
806 | get()).setPackets(bucket.packets()); | 845 | get()).setPackets(bucket.packets()); |
... | @@ -808,38 +847,39 @@ public class DistributedGroupStore | ... | @@ -808,38 +847,39 @@ public class DistributedGroupStore |
808 | get()).setBytes(bucket.bytes()); | 847 | get()).setBytes(bucket.bytes()); |
809 | } else { | 848 | } else { |
810 | log.warn("addOrUpdateGroupEntry: No matching " | 849 | log.warn("addOrUpdateGroupEntry: No matching " |
811 | - + "buckets to update stats"); | 850 | + + "buckets to update stats"); |
812 | } | 851 | } |
813 | } | 852 | } |
814 | existing.setLife(group.life()); | 853 | existing.setLife(group.life()); |
815 | existing.setPackets(group.packets()); | 854 | existing.setPackets(group.packets()); |
816 | existing.setBytes(group.bytes()); | 855 | existing.setBytes(group.bytes()); |
856 | + existing.setReferenceCount(group.referenceCount()); | ||
817 | if ((existing.state() == GroupState.PENDING_ADD) || | 857 | if ((existing.state() == GroupState.PENDING_ADD) || |
818 | - (existing.state() == GroupState.PENDING_ADD_RETRY)) { | 858 | + (existing.state() == GroupState.PENDING_ADD_RETRY)) { |
819 | log.trace("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", | 859 | log.trace("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", |
820 | - existing.id(), | 860 | + existing.id(), |
821 | - existing.deviceId(), | 861 | + existing.deviceId(), |
822 | - existing.state()); | 862 | + existing.state()); |
823 | existing.setState(GroupState.ADDED); | 863 | existing.setState(GroupState.ADDED); |
824 | existing.setIsGroupStateAddedFirstTime(true); | 864 | existing.setIsGroupStateAddedFirstTime(true); |
825 | event = new GroupEvent(Type.GROUP_ADDED, existing); | 865 | event = new GroupEvent(Type.GROUP_ADDED, existing); |
826 | } else { | 866 | } else { |
827 | log.trace("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", | 867 | log.trace("addOrUpdateGroupEntry: group entry {} in device {} moving from {} to ADDED", |
828 | - existing.id(), | 868 | + existing.id(), |
829 | - existing.deviceId(), | 869 | + existing.deviceId(), |
830 | - GroupState.PENDING_UPDATE); | 870 | + GroupState.PENDING_UPDATE); |
831 | existing.setState(GroupState.ADDED); | 871 | existing.setState(GroupState.ADDED); |
832 | existing.setIsGroupStateAddedFirstTime(false); | 872 | existing.setIsGroupStateAddedFirstTime(false); |
833 | event = new GroupEvent(Type.GROUP_UPDATED, existing); | 873 | event = new GroupEvent(Type.GROUP_UPDATED, existing); |
834 | } | 874 | } |
835 | //Re-PUT map entries to trigger map update events | 875 | //Re-PUT map entries to trigger map update events |
836 | getGroupStoreKeyMap(). | 876 | getGroupStoreKeyMap(). |
837 | - put(new GroupStoreKeyMapKey(existing.deviceId(), | 877 | + put(new GroupStoreKeyMapKey(existing.deviceId(), |
838 | - existing.appCookie()), existing); | 878 | + existing.appCookie()), existing); |
839 | } | 879 | } |
840 | } else { | 880 | } else { |
841 | log.warn("addOrUpdateGroupEntry: Group update " | 881 | log.warn("addOrUpdateGroupEntry: Group update " |
842 | - + "happening for a non-existing entry in the map"); | 882 | + + "happening for a non-existing entry in the map"); |
843 | } | 883 | } |
844 | 884 | ||
845 | if (event != null) { | 885 | if (event != null) { |
... | @@ -859,8 +899,8 @@ public class DistributedGroupStore | ... | @@ -859,8 +899,8 @@ public class DistributedGroupStore |
859 | 899 | ||
860 | if (existing != null) { | 900 | if (existing != null) { |
861 | log.debug("removeGroupEntry: removing group entry {} in device {}", | 901 | log.debug("removeGroupEntry: removing group entry {} in device {}", |
862 | - group.id(), | 902 | + group.id(), |
863 | - group.deviceId()); | 903 | + group.deviceId()); |
864 | //Removal from groupid based map will happen in the | 904 | //Removal from groupid based map will happen in the |
865 | //map update listener | 905 | //map update listener |
866 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), | 906 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), |
... | @@ -868,9 +908,9 @@ public class DistributedGroupStore | ... | @@ -868,9 +908,9 @@ public class DistributedGroupStore |
868 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing)); | 908 | notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing)); |
869 | } else { | 909 | } else { |
870 | log.warn("removeGroupEntry for {} in device{} is " | 910 | log.warn("removeGroupEntry for {} in device{} is " |
871 | - + "not existing in our maps", | 911 | + + "not existing in our maps", |
872 | - group.id(), | 912 | + group.id(), |
873 | - group.deviceId()); | 913 | + group.deviceId()); |
874 | } | 914 | } |
875 | } | 915 | } |
876 | 916 | ||
... | @@ -900,13 +940,13 @@ public class DistributedGroupStore | ... | @@ -900,13 +940,13 @@ public class DistributedGroupStore |
900 | // Execute all pending group requests | 940 | // Execute all pending group requests |
901 | List<StoredGroupEntry> pendingGroupRequests = | 941 | List<StoredGroupEntry> pendingGroupRequests = |
902 | getPendingGroupKeyTable().values() | 942 | getPendingGroupKeyTable().values() |
903 | - .stream() | 943 | + .stream() |
904 | - .filter(g-> g.deviceId().equals(deviceId)) | 944 | + .filter(g -> g.deviceId().equals(deviceId)) |
905 | - .collect(Collectors.toList()); | 945 | + .collect(Collectors.toList()); |
906 | log.debug("processing pending group add requests for device {} and number of pending requests {}", | 946 | log.debug("processing pending group add requests for device {} and number of pending requests {}", |
907 | - deviceId, | 947 | + deviceId, |
908 | - pendingGroupRequests.size()); | 948 | + pendingGroupRequests.size()); |
909 | - for (Group group:pendingGroupRequests) { | 949 | + for (Group group : pendingGroupRequests) { |
910 | GroupDescription tmp = new DefaultGroupDescription( | 950 | GroupDescription tmp = new DefaultGroupDescription( |
911 | group.deviceId(), | 951 | group.deviceId(), |
912 | group.type(), | 952 | group.type(), |
... | @@ -916,7 +956,7 @@ public class DistributedGroupStore | ... | @@ -916,7 +956,7 @@ public class DistributedGroupStore |
916 | group.appId()); | 956 | group.appId()); |
917 | storeGroupDescriptionInternal(tmp); | 957 | storeGroupDescriptionInternal(tmp); |
918 | getPendingGroupKeyTable(). | 958 | getPendingGroupKeyTable(). |
919 | - remove(new GroupStoreKeyMapKey(deviceId, group.appCookie())); | 959 | + remove(new GroupStoreKeyMapKey(deviceId, group.appCookie())); |
920 | } | 960 | } |
921 | } else { | 961 | } else { |
922 | Boolean audited = deviceAuditStatus.get(deviceId); | 962 | Boolean audited = deviceAuditStatus.get(deviceId); |
... | @@ -948,11 +988,11 @@ public class DistributedGroupStore | ... | @@ -948,11 +988,11 @@ public class DistributedGroupStore |
948 | } | 988 | } |
949 | 989 | ||
950 | log.warn("groupOperationFailed: group operation {} failed" | 990 | log.warn("groupOperationFailed: group operation {} failed" |
951 | - + "for group {} in device {} with code {}", | 991 | + + "for group {} in device {} with code {}", |
952 | - operation.opType(), | 992 | + operation.opType(), |
953 | - existing.id(), | 993 | + existing.id(), |
954 | - existing.deviceId(), | 994 | + existing.deviceId(), |
955 | - operation.failureCode()); | 995 | + operation.failureCode()); |
956 | if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { | 996 | if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) { |
957 | log.warn("Current extraneous groups in device:{} are: {}", | 997 | log.warn("Current extraneous groups in device:{} are: {}", |
958 | deviceId, | 998 | deviceId, |
... | @@ -960,14 +1000,14 @@ public class DistributedGroupStore | ... | @@ -960,14 +1000,14 @@ public class DistributedGroupStore |
960 | if (operation.buckets().equals(existing.buckets())) { | 1000 | if (operation.buckets().equals(existing.buckets())) { |
961 | if (existing.state() == GroupState.PENDING_ADD) { | 1001 | if (existing.state() == GroupState.PENDING_ADD) { |
962 | log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " | 1002 | log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " |
963 | - + "add state - moving to ADDED for group {} in device {}", | 1003 | + + "add state - moving to ADDED for group {} in device {}", |
964 | - existing.id(), deviceId); | 1004 | + existing.id(), deviceId); |
965 | addOrUpdateGroupEntry(existing); | 1005 | addOrUpdateGroupEntry(existing); |
966 | return; | 1006 | return; |
967 | } else { | 1007 | } else { |
968 | log.warn("GROUP EXISTS: Group ID matched but buckets did not. " | 1008 | log.warn("GROUP EXISTS: Group ID matched but buckets did not. " |
969 | - + "Operation: {} Existing: {}", operation.buckets(), | 1009 | + + "Operation: {} Existing: {}", operation.buckets(), |
970 | - existing.buckets()); | 1010 | + existing.buckets()); |
971 | } | 1011 | } |
972 | } | 1012 | } |
973 | } | 1013 | } |
... | @@ -976,9 +1016,9 @@ public class DistributedGroupStore | ... | @@ -976,9 +1016,9 @@ public class DistributedGroupStore |
976 | if (existing.state() == GroupState.PENDING_ADD) { | 1016 | if (existing.state() == GroupState.PENDING_ADD) { |
977 | notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); | 1017 | notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing)); |
978 | log.warn("groupOperationFailed: cleaningup " | 1018 | log.warn("groupOperationFailed: cleaningup " |
979 | - + "group {} from store in device {}....", | 1019 | + + "group {} from store in device {}....", |
980 | - existing.id(), | 1020 | + existing.id(), |
981 | - existing.deviceId()); | 1021 | + existing.deviceId()); |
982 | //Removal from groupid based map will happen in the | 1022 | //Removal from groupid based map will happen in the |
983 | //map update listener | 1023 | //map update listener |
984 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), | 1024 | getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), |
... | @@ -999,8 +1039,8 @@ public class DistributedGroupStore | ... | @@ -999,8 +1039,8 @@ public class DistributedGroupStore |
999 | @Override | 1039 | @Override |
1000 | public void addOrUpdateExtraneousGroupEntry(Group group) { | 1040 | public void addOrUpdateExtraneousGroupEntry(Group group) { |
1001 | log.debug("add/update extraneous group entry {} in device {}", | 1041 | log.debug("add/update extraneous group entry {} in device {}", |
1002 | - group.id(), | 1042 | + group.id(), |
1003 | - group.deviceId()); | 1043 | + group.deviceId()); |
1004 | ConcurrentMap<GroupId, Group> extraneousIdTable = | 1044 | ConcurrentMap<GroupId, Group> extraneousIdTable = |
1005 | getExtraneousGroupIdTable(group.deviceId()); | 1045 | getExtraneousGroupIdTable(group.deviceId()); |
1006 | extraneousIdTable.put(group.id(), group); | 1046 | extraneousIdTable.put(group.id(), group); |
... | @@ -1011,8 +1051,8 @@ public class DistributedGroupStore | ... | @@ -1011,8 +1051,8 @@ public class DistributedGroupStore |
1011 | @Override | 1051 | @Override |
1012 | public void removeExtraneousGroupEntry(Group group) { | 1052 | public void removeExtraneousGroupEntry(Group group) { |
1013 | log.debug("remove extraneous group entry {} of device {} from store", | 1053 | log.debug("remove extraneous group entry {} of device {} from store", |
1014 | - group.id(), | 1054 | + group.id(), |
1015 | - group.deviceId()); | 1055 | + group.deviceId()); |
1016 | ConcurrentMap<GroupId, Group> extraneousIdTable = | 1056 | ConcurrentMap<GroupId, Group> extraneousIdTable = |
1017 | getExtraneousGroupIdTable(group.deviceId()); | 1057 | getExtraneousGroupIdTable(group.deviceId()); |
1018 | extraneousIdTable.remove(group.id()); | 1058 | extraneousIdTable.remove(group.id()); |
... | @@ -1038,7 +1078,7 @@ public class DistributedGroupStore | ... | @@ -1038,7 +1078,7 @@ public class DistributedGroupStore |
1038 | StoredGroupEntry group = Versioned.valueOrNull(mapEvent.newValue()); | 1078 | StoredGroupEntry group = Versioned.valueOrNull(mapEvent.newValue()); |
1039 | if ((key == null) && (group == null)) { | 1079 | if ((key == null) && (group == null)) { |
1040 | log.error("GroupStoreKeyMapListener: Received " | 1080 | log.error("GroupStoreKeyMapListener: Received " |
1041 | - + "event {} with null entry", mapEvent.type()); | 1081 | + + "event {} with null entry", mapEvent.type()); |
1042 | return; | 1082 | return; |
1043 | } else if (group == null) { | 1083 | } else if (group == null) { |
1044 | group = getGroupIdTable(key.deviceId()).values() | 1084 | group = getGroupIdTable(key.deviceId()).values() |
... | @@ -1047,7 +1087,7 @@ public class DistributedGroupStore | ... | @@ -1047,7 +1087,7 @@ public class DistributedGroupStore |
1047 | .findFirst().get(); | 1087 | .findFirst().get(); |
1048 | if (group == null) { | 1088 | if (group == null) { |
1049 | log.error("GroupStoreKeyMapListener: Received " | 1089 | log.error("GroupStoreKeyMapListener: Received " |
1050 | - + "event {} with null entry... can not process", mapEvent.type()); | 1090 | + + "event {} with null entry... can not process", mapEvent.type()); |
1051 | return; | 1091 | return; |
1052 | } | 1092 | } |
1053 | } | 1093 | } |
... | @@ -1063,13 +1103,13 @@ public class DistributedGroupStore | ... | @@ -1063,13 +1103,13 @@ public class DistributedGroupStore |
1063 | if (value.isGroupStateAddedFirstTime()) { | 1103 | if (value.isGroupStateAddedFirstTime()) { |
1064 | groupEvent = new GroupEvent(Type.GROUP_ADDED, value); | 1104 | groupEvent = new GroupEvent(Type.GROUP_ADDED, value); |
1065 | log.trace("Received first time GROUP_ADDED state update for id {} in device {}", | 1105 | log.trace("Received first time GROUP_ADDED state update for id {} in device {}", |
1066 | - group.id(), | 1106 | + group.id(), |
1067 | - group.deviceId()); | 1107 | + group.deviceId()); |
1068 | } else { | 1108 | } else { |
1069 | groupEvent = new GroupEvent(Type.GROUP_UPDATED, value); | 1109 | groupEvent = new GroupEvent(Type.GROUP_UPDATED, value); |
1070 | log.trace("Received following GROUP_ADDED state update for id {} in device {}", | 1110 | log.trace("Received following GROUP_ADDED state update for id {} in device {}", |
1071 | - group.id(), | 1111 | + group.id(), |
1072 | - group.deviceId()); | 1112 | + group.deviceId()); |
1073 | } | 1113 | } |
1074 | } | 1114 | } |
1075 | } else if (mapEvent.type() == MapEvent.Type.REMOVE) { | 1115 | } else if (mapEvent.type() == MapEvent.Type.REMOVE) { |
... | @@ -1086,24 +1126,24 @@ public class DistributedGroupStore | ... | @@ -1086,24 +1126,24 @@ public class DistributedGroupStore |
1086 | 1126 | ||
1087 | private void process(GroupStoreMessage groupOp) { | 1127 | private void process(GroupStoreMessage groupOp) { |
1088 | log.debug("Received remote group operation {} request for device {}", | 1128 | log.debug("Received remote group operation {} request for device {}", |
1089 | - groupOp.type(), | 1129 | + groupOp.type(), |
1090 | - groupOp.deviceId()); | 1130 | + groupOp.deviceId()); |
1091 | - if (!mastershipService.isLocalMaster(groupOp.deviceId())) { | 1131 | + if (!mastershipService.isLocalMaster(groupOp.deviceId())) { |
1092 | - log.warn("This node is not MASTER for device {}", groupOp.deviceId()); | 1132 | + log.warn("This node is not MASTER for device {}", groupOp.deviceId()); |
1093 | - return; | 1133 | + return; |
1094 | - } | 1134 | + } |
1095 | - if (groupOp.type() == GroupStoreMessage.Type.ADD) { | 1135 | + if (groupOp.type() == GroupStoreMessage.Type.ADD) { |
1096 | - storeGroupDescriptionInternal(groupOp.groupDesc()); | 1136 | + storeGroupDescriptionInternal(groupOp.groupDesc()); |
1097 | - } else if (groupOp.type() == GroupStoreMessage.Type.UPDATE) { | 1137 | + } else if (groupOp.type() == GroupStoreMessage.Type.UPDATE) { |
1098 | - updateGroupDescriptionInternal(groupOp.deviceId(), | 1138 | + updateGroupDescriptionInternal(groupOp.deviceId(), |
1099 | - groupOp.appCookie(), | 1139 | + groupOp.appCookie(), |
1100 | - groupOp.updateType(), | 1140 | + groupOp.updateType(), |
1101 | - groupOp.updateBuckets(), | 1141 | + groupOp.updateBuckets(), |
1102 | - groupOp.newAppCookie()); | 1142 | + groupOp.newAppCookie()); |
1103 | - } else if (groupOp.type() == GroupStoreMessage.Type.DELETE) { | 1143 | + } else if (groupOp.type() == GroupStoreMessage.Type.DELETE) { |
1104 | - deleteGroupDescriptionInternal(groupOp.deviceId(), | 1144 | + deleteGroupDescriptionInternal(groupOp.deviceId(), |
1105 | - groupOp.appCookie()); | 1145 | + groupOp.appCookie()); |
1106 | - } | 1146 | + } |
1107 | } | 1147 | } |
1108 | 1148 | ||
1109 | /** | 1149 | /** |
... | @@ -1144,6 +1184,7 @@ public class DistributedGroupStore | ... | @@ -1144,6 +1184,7 @@ public class DistributedGroupStore |
1144 | 1184 | ||
1145 | protected static class GroupStoreKeyMapKey extends GroupStoreMapKey { | 1185 | protected static class GroupStoreKeyMapKey extends GroupStoreMapKey { |
1146 | private final GroupKey appCookie; | 1186 | private final GroupKey appCookie; |
1187 | + | ||
1147 | public GroupStoreKeyMapKey(DeviceId deviceId, | 1188 | public GroupStoreKeyMapKey(DeviceId deviceId, |
1148 | GroupKey appCookie) { | 1189 | GroupKey appCookie) { |
1149 | super(deviceId); | 1190 | super(deviceId); |
... | @@ -1175,6 +1216,7 @@ public class DistributedGroupStore | ... | @@ -1175,6 +1216,7 @@ public class DistributedGroupStore |
1175 | 1216 | ||
1176 | protected static class GroupStoreIdMapKey extends GroupStoreMapKey { | 1217 | protected static class GroupStoreIdMapKey extends GroupStoreMapKey { |
1177 | private final GroupId groupId; | 1218 | private final GroupId groupId; |
1219 | + | ||
1178 | public GroupStoreIdMapKey(DeviceId deviceId, | 1220 | public GroupStoreIdMapKey(DeviceId deviceId, |
1179 | GroupId groupId) { | 1221 | GroupId groupId) { |
1180 | super(deviceId); | 1222 | super(deviceId); |
... | @@ -1228,17 +1270,20 @@ public class DistributedGroupStore | ... | @@ -1228,17 +1270,20 @@ public class DistributedGroupStore |
1228 | storedGroupEntries.size(), | 1270 | storedGroupEntries.size(), |
1229 | deviceId); | 1271 | deviceId); |
1230 | for (Iterator<StoredGroupEntry> it1 = storedGroupEntries.iterator(); | 1272 | for (Iterator<StoredGroupEntry> it1 = storedGroupEntries.iterator(); |
1231 | - it1.hasNext();) { | 1273 | + it1.hasNext();) { |
1232 | Group group = it1.next(); | 1274 | Group group = it1.next(); |
1233 | log.trace("Stored Group {} for device {}", group, deviceId); | 1275 | log.trace("Stored Group {} for device {}", group, deviceId); |
1234 | } | 1276 | } |
1235 | 1277 | ||
1278 | + garbageCollect(deviceId, southboundGroupEntries, storedGroupEntries); | ||
1279 | + | ||
1236 | for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) { | 1280 | for (Iterator<Group> it2 = southboundGroupEntries.iterator(); it2.hasNext();) { |
1237 | Group group = it2.next(); | 1281 | Group group = it2.next(); |
1238 | if (storedGroupEntries.remove(group)) { | 1282 | if (storedGroupEntries.remove(group)) { |
1239 | // we both have the group, let's update some info then. | 1283 | // we both have the group, let's update some info then. |
1240 | log.trace("Group AUDIT: group {} exists in both planes for device {}", | 1284 | log.trace("Group AUDIT: group {} exists in both planes for device {}", |
1241 | - group.id(), deviceId); | 1285 | + group.id(), deviceId); |
1286 | + | ||
1242 | groupAdded(group); | 1287 | groupAdded(group); |
1243 | it2.remove(); | 1288 | it2.remove(); |
1244 | } | 1289 | } |
... | @@ -1249,15 +1294,15 @@ public class DistributedGroupStore | ... | @@ -1249,15 +1294,15 @@ public class DistributedGroupStore |
1249 | // It is possible that group update is | 1294 | // It is possible that group update is |
1250 | // in progress while we got a stale info from switch | 1295 | // in progress while we got a stale info from switch |
1251 | if (!storedGroupEntries.remove(getGroup( | 1296 | if (!storedGroupEntries.remove(getGroup( |
1252 | - group.deviceId(), group.id()))) { | 1297 | + group.deviceId(), group.id()))) { |
1253 | log.warn("Group AUDIT: Inconsistent state:" | 1298 | log.warn("Group AUDIT: Inconsistent state:" |
1254 | - + "Group exists in ID based table while " | 1299 | + + "Group exists in ID based table while " |
1255 | - + "not present in key based table"); | 1300 | + + "not present in key based table"); |
1256 | } | 1301 | } |
1257 | } else { | 1302 | } else { |
1258 | // there are groups in the switch that aren't in the store | 1303 | // there are groups in the switch that aren't in the store |
1259 | log.debug("Group AUDIT: extraneous group {} exists in data plane for device {}", | 1304 | log.debug("Group AUDIT: extraneous group {} exists in data plane for device {}", |
1260 | - group.id(), deviceId); | 1305 | + group.id(), deviceId); |
1261 | extraneousStoredEntries.remove(group); | 1306 | extraneousStoredEntries.remove(group); |
1262 | extraneousGroup(group); | 1307 | extraneousGroup(group); |
1263 | } | 1308 | } |
... | @@ -1265,24 +1310,47 @@ public class DistributedGroupStore | ... | @@ -1265,24 +1310,47 @@ public class DistributedGroupStore |
1265 | for (Group group : storedGroupEntries) { | 1310 | for (Group group : storedGroupEntries) { |
1266 | // there are groups in the store that aren't in the switch | 1311 | // there are groups in the store that aren't in the switch |
1267 | log.debug("Group AUDIT: group {} missing in data plane for device {}", | 1312 | log.debug("Group AUDIT: group {} missing in data plane for device {}", |
1268 | - group.id(), deviceId); | 1313 | + group.id(), deviceId); |
1269 | groupMissing(group); | 1314 | groupMissing(group); |
1270 | } | 1315 | } |
1271 | for (Group group : extraneousStoredEntries) { | 1316 | for (Group group : extraneousStoredEntries) { |
1272 | // there are groups in the extraneous store that | 1317 | // there are groups in the extraneous store that |
1273 | // aren't in the switch | 1318 | // aren't in the switch |
1274 | log.debug("Group AUDIT: clearing extraneous group {} from store for device {}", | 1319 | log.debug("Group AUDIT: clearing extraneous group {} from store for device {}", |
1275 | - group.id(), deviceId); | 1320 | + group.id(), deviceId); |
1276 | removeExtraneousGroupEntry(group); | 1321 | removeExtraneousGroupEntry(group); |
1277 | } | 1322 | } |
1278 | 1323 | ||
1279 | if (!deviceInitialAuditStatus) { | 1324 | if (!deviceInitialAuditStatus) { |
1280 | log.info("Group AUDIT: Setting device {} initial AUDIT completed", | 1325 | log.info("Group AUDIT: Setting device {} initial AUDIT completed", |
1281 | - deviceId); | 1326 | + deviceId); |
1282 | deviceInitialAuditCompleted(deviceId, true); | 1327 | deviceInitialAuditCompleted(deviceId, true); |
1283 | } | 1328 | } |
1284 | } | 1329 | } |
1285 | 1330 | ||
1331 | + private void garbageCollect(DeviceId deviceId, | ||
1332 | + Set<Group> southboundGroupEntries, | ||
1333 | + Set<StoredGroupEntry> storedGroupEntries) { | ||
1334 | + if (!garbageCollect) { | ||
1335 | + return; | ||
1336 | + } | ||
1337 | + | ||
1338 | + Iterator<StoredGroupEntry> it = storedGroupEntries.iterator(); | ||
1339 | + while (it.hasNext()) { | ||
1340 | + StoredGroupEntry group = it.next(); | ||
1341 | + if (group.state() != GroupState.PENDING_DELETE && checkGroupRefCount(group)) { | ||
1342 | + log.debug("Garbage collecting group {} on {}", group, deviceId); | ||
1343 | + deleteGroupDescription(deviceId, group.appCookie()); | ||
1344 | + southboundGroupEntries.remove(group); | ||
1345 | + it.remove(); | ||
1346 | + } | ||
1347 | + } | ||
1348 | + } | ||
1349 | + | ||
1350 | + private boolean checkGroupRefCount(Group group) { | ||
1351 | + return (group.referenceCount() == 0 && group.age() >= gcThresh); | ||
1352 | + } | ||
1353 | + | ||
1286 | private void groupMissing(Group group) { | 1354 | private void groupMissing(Group group) { |
1287 | switch (group.state()) { | 1355 | switch (group.state()) { |
1288 | case PENDING_DELETE: | 1356 | case PENDING_DELETE: |
... | @@ -1299,14 +1367,14 @@ public class DistributedGroupStore | ... | @@ -1299,14 +1367,14 @@ public class DistributedGroupStore |
1299 | StoredGroupEntry existing = | 1367 | StoredGroupEntry existing = |
1300 | getStoredGroupEntry(group.deviceId(), group.id()); | 1368 | getStoredGroupEntry(group.deviceId(), group.id()); |
1301 | log.debug("groupMissing: group entry {} in device {} moving from {} to PENDING_ADD_RETRY", | 1369 | log.debug("groupMissing: group entry {} in device {} moving from {} to PENDING_ADD_RETRY", |
1302 | - existing.id(), | 1370 | + existing.id(), |
1303 | - existing.deviceId(), | 1371 | + existing.deviceId(), |
1304 | - existing.state()); | 1372 | + existing.state()); |
1305 | existing.setState(Group.GroupState.PENDING_ADD_RETRY); | 1373 | existing.setState(Group.GroupState.PENDING_ADD_RETRY); |
1306 | //Re-PUT map entries to trigger map update events | 1374 | //Re-PUT map entries to trigger map update events |
1307 | getGroupStoreKeyMap(). | 1375 | getGroupStoreKeyMap(). |
1308 | - put(new GroupStoreKeyMapKey(existing.deviceId(), | 1376 | + put(new GroupStoreKeyMapKey(existing.deviceId(), |
1309 | - existing.appCookie()), existing); | 1377 | + existing.appCookie()), existing); |
1310 | notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, | 1378 | notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, |
1311 | group)); | 1379 | group)); |
1312 | break; | 1380 | break; | ... | ... |
... | @@ -23,6 +23,7 @@ import org.junit.After; | ... | @@ -23,6 +23,7 @@ import org.junit.After; |
23 | import org.junit.Before; | 23 | import org.junit.Before; |
24 | import org.junit.Test; | 24 | import org.junit.Test; |
25 | import org.onlab.junit.TestUtils; | 25 | import org.onlab.junit.TestUtils; |
26 | +import org.onosproject.cfg.ComponentConfigAdapter; | ||
26 | import org.onosproject.cluster.NodeId; | 27 | import org.onosproject.cluster.NodeId; |
27 | import org.onosproject.core.DefaultGroupId; | 28 | import org.onosproject.core.DefaultGroupId; |
28 | import org.onosproject.core.GroupId; | 29 | import org.onosproject.core.GroupId; |
... | @@ -129,6 +130,7 @@ public class DistributedGroupStoreTest { | ... | @@ -129,6 +130,7 @@ public class DistributedGroupStoreTest { |
129 | groupStoreImpl.storageService = new TestStorageService(); | 130 | groupStoreImpl.storageService = new TestStorageService(); |
130 | groupStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter(); | 131 | groupStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter(); |
131 | groupStoreImpl.mastershipService = new MasterOfAll(); | 132 | groupStoreImpl.mastershipService = new MasterOfAll(); |
133 | + groupStoreImpl.cfgService = new ComponentConfigAdapter(); | ||
132 | groupStoreImpl.activate(); | 134 | groupStoreImpl.activate(); |
133 | groupStore = groupStoreImpl; | 135 | groupStore = groupStoreImpl; |
134 | auditPendingReqQueue = | 136 | auditPendingReqQueue = | ... | ... |
... | @@ -156,6 +156,11 @@ public class GroupsResourceTest extends ResourceTest { | ... | @@ -156,6 +156,11 @@ public class GroupsResourceTest extends ResourceTest { |
156 | } | 156 | } |
157 | 157 | ||
158 | @Override | 158 | @Override |
159 | + public int age() { | ||
160 | + return 0; | ||
161 | + } | ||
162 | + | ||
163 | + @Override | ||
159 | public Type type() { | 164 | public Type type() { |
160 | return GroupDescription.Type.ALL; | 165 | return GroupDescription.Type.ALL; |
161 | } | 166 | } | ... | ... |
-
Please register or login to post a comment