Committed by
Gerrit Code Review
Distribute failover event with topic
Change-Id: I8629e7e19ebd4a18f95b32ad3ce1eba7ddf4ecc6
Showing
4 changed files
with
108 additions
and
4 deletions
| ... | @@ -47,4 +47,9 @@ public class TestStorageService extends StorageServiceAdapter { | ... | @@ -47,4 +47,9 @@ public class TestStorageService extends StorageServiceAdapter { |
| 47 | public TransactionContextBuilder transactionContextBuilder() { | 47 | public TransactionContextBuilder transactionContextBuilder() { |
| 48 | throw new UnsupportedOperationException("transactionContextBuilder"); | 48 | throw new UnsupportedOperationException("transactionContextBuilder"); |
| 49 | } | 49 | } |
| 50 | + | ||
| 51 | + @Override | ||
| 52 | + public <T> Topic<T> getTopic(String name, Serializer serializer) { | ||
| 53 | + return new TestTopic(name); | ||
| 54 | + } | ||
| 50 | } | 55 | } | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2016-present Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.store.service; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.Sets; | ||
| 20 | + | ||
| 21 | +import java.util.Set; | ||
| 22 | +import java.util.concurrent.CompletableFuture; | ||
| 23 | +import java.util.function.Consumer; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * Test implementation of topic. | ||
| 27 | + */ | ||
| 28 | +public class TestTopic<T> implements Topic<T> { | ||
| 29 | + private final String name; | ||
| 30 | + private final Set<Consumer<T>> callbacks = Sets.newConcurrentHashSet(); | ||
| 31 | + | ||
| 32 | + public TestTopic(String name) { | ||
| 33 | + this.name = name; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + @Override | ||
| 37 | + public CompletableFuture<Void> publish(T message) { | ||
| 38 | + callbacks.forEach(c -> c.accept(message)); | ||
| 39 | + return CompletableFuture.completedFuture(null); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public CompletableFuture<Void> subscribe(Consumer<T> callback) { | ||
| 44 | + callbacks.add(callback); | ||
| 45 | + return CompletableFuture.completedFuture(null); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public CompletableFuture<Void> unsubscribe(Consumer<T> callback) { | ||
| 50 | + callbacks.remove(callback); | ||
| 51 | + return CompletableFuture.completedFuture(null); | ||
| 52 | + } | ||
| 53 | + | ||
| 54 | + @Override | ||
| 55 | + public String name() { | ||
| 56 | + return name; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + @Override | ||
| 60 | + public Type primitiveType() { | ||
| 61 | + return Type.TOPIC; | ||
| 62 | + } | ||
| 63 | +} |
| ... | @@ -62,6 +62,7 @@ import org.onosproject.store.service.MapEventListener; | ... | @@ -62,6 +62,7 @@ import org.onosproject.store.service.MapEventListener; |
| 62 | import org.onosproject.store.service.MultiValuedTimestamp; | 62 | import org.onosproject.store.service.MultiValuedTimestamp; |
| 63 | import org.onosproject.store.service.Serializer; | 63 | import org.onosproject.store.service.Serializer; |
| 64 | import org.onosproject.store.service.StorageService; | 64 | import org.onosproject.store.service.StorageService; |
| 65 | +import org.onosproject.store.service.Topic; | ||
| 65 | import org.onosproject.store.service.Versioned; | 66 | import org.onosproject.store.service.Versioned; |
| 66 | import org.osgi.service.component.ComponentContext; | 67 | import org.osgi.service.component.ComponentContext; |
| 67 | import org.slf4j.Logger; | 68 | import org.slf4j.Logger; |
| ... | @@ -145,6 +146,8 @@ public class DistributedGroupStore | ... | @@ -145,6 +146,8 @@ public class DistributedGroupStore |
| 145 | 146 | ||
| 146 | private KryoNamespace clusterMsgSerializer; | 147 | private KryoNamespace clusterMsgSerializer; |
| 147 | 148 | ||
| 149 | + private static Topic<GroupStoreMessage> groupTopic; | ||
| 150 | + | ||
| 148 | @Property(name = "garbageCollect", boolValue = GARBAGE_COLLECT, | 151 | @Property(name = "garbageCollect", boolValue = GARBAGE_COLLECT, |
| 149 | label = "Enable group garbage collection") | 152 | label = "Enable group garbage collection") |
| 150 | private boolean garbageCollect = GARBAGE_COLLECT; | 153 | private boolean garbageCollect = GARBAGE_COLLECT; |
| ... | @@ -210,6 +213,9 @@ public class DistributedGroupStore | ... | @@ -210,6 +213,9 @@ public class DistributedGroupStore |
| 210 | log.debug("Current size of pendinggroupkeymap:{}", | 213 | log.debug("Current size of pendinggroupkeymap:{}", |
| 211 | auditPendingReqQueue.size()); | 214 | auditPendingReqQueue.size()); |
| 212 | 215 | ||
| 216 | + groupTopic = getOrCreateGroupTopic(serializer); | ||
| 217 | + groupTopic.subscribe(this::processGroupMessage); | ||
| 218 | + | ||
| 213 | log.info("Started"); | 219 | log.info("Started"); |
| 214 | } | 220 | } |
| 215 | 221 | ||
| ... | @@ -237,6 +243,14 @@ public class DistributedGroupStore | ... | @@ -237,6 +243,14 @@ public class DistributedGroupStore |
| 237 | } | 243 | } |
| 238 | } | 244 | } |
| 239 | 245 | ||
| 246 | + private Topic<GroupStoreMessage> getOrCreateGroupTopic(Serializer serializer) { | ||
| 247 | + if (groupTopic == null) { | ||
| 248 | + return storageService.getTopic("group-failover-notif", serializer); | ||
| 249 | + } else { | ||
| 250 | + return groupTopic; | ||
| 251 | + } | ||
| 252 | + }; | ||
| 253 | + | ||
| 240 | /** | 254 | /** |
| 241 | * Returns the group store eventual consistent key map. | 255 | * Returns the group store eventual consistent key map. |
| 242 | * | 256 | * |
| ... | @@ -1109,6 +1123,16 @@ public class DistributedGroupStore | ... | @@ -1109,6 +1123,16 @@ public class DistributedGroupStore |
| 1109 | } | 1123 | } |
| 1110 | } | 1124 | } |
| 1111 | 1125 | ||
| 1126 | + private void processGroupMessage(GroupStoreMessage message) { | ||
| 1127 | + if (message.type() == GroupStoreMessage.Type.FAILOVER) { | ||
| 1128 | + // FIXME: groupStoreEntriesByKey inaccessible here | ||
| 1129 | + getGroupIdTable(message.deviceId()).values() | ||
| 1130 | + .stream() | ||
| 1131 | + .filter((storedGroup) -> (storedGroup.appCookie().equals(message.appCookie()))) | ||
| 1132 | + .findFirst().ifPresent(group -> notifyDelegate(new GroupEvent(Type.GROUP_BUCKET_FAILOVER, group))); | ||
| 1133 | + } | ||
| 1134 | + } | ||
| 1135 | + | ||
| 1112 | private void process(GroupStoreMessage groupOp) { | 1136 | private void process(GroupStoreMessage groupOp) { |
| 1113 | log.debug("Received remote group operation {} request for device {}", | 1137 | log.debug("Received remote group operation {} request for device {}", |
| 1114 | groupOp.type(), | 1138 | groupOp.type(), |
| ... | @@ -1314,13 +1338,12 @@ public class DistributedGroupStore | ... | @@ -1314,13 +1338,12 @@ public class DistributedGroupStore |
| 1314 | 1338 | ||
| 1315 | @Override | 1339 | @Override |
| 1316 | public void notifyOfFailovers(Collection<Group> failoverGroups) { | 1340 | public void notifyOfFailovers(Collection<Group> failoverGroups) { |
| 1317 | - List<GroupEvent> failoverEvents = new ArrayList<>(); | ||
| 1318 | failoverGroups.forEach(group -> { | 1341 | failoverGroups.forEach(group -> { |
| 1319 | if (group.type() == Group.Type.FAILOVER) { | 1342 | if (group.type() == Group.Type.FAILOVER) { |
| 1320 | - failoverEvents.add(new GroupEvent(GroupEvent.Type.GROUP_BUCKET_FAILOVER, group)); | 1343 | + groupTopic.publish(GroupStoreMessage.createGroupFailoverMsg( |
| 1344 | + group.deviceId(), group)); | ||
| 1321 | } | 1345 | } |
| 1322 | }); | 1346 | }); |
| 1323 | - notifyDelegate(failoverEvents); | ||
| 1324 | } | 1347 | } |
| 1325 | 1348 | ||
| 1326 | private void garbageCollect(DeviceId deviceId, | 1349 | private void garbageCollect(DeviceId deviceId, | ... | ... |
| ... | @@ -40,7 +40,8 @@ public final class GroupStoreMessage { | ... | @@ -40,7 +40,8 @@ public final class GroupStoreMessage { |
| 40 | public enum Type { | 40 | public enum Type { |
| 41 | ADD, | 41 | ADD, |
| 42 | UPDATE, | 42 | UPDATE, |
| 43 | - DELETE | 43 | + DELETE, |
| 44 | + FAILOVER | ||
| 44 | } | 45 | } |
| 45 | 46 | ||
| 46 | private GroupStoreMessage(Type type, | 47 | private GroupStoreMessage(Type type, |
| ... | @@ -119,6 +120,18 @@ public final class GroupStoreMessage { | ... | @@ -119,6 +120,18 @@ public final class GroupStoreMessage { |
| 119 | null); | 120 | null); |
| 120 | } | 121 | } |
| 121 | 122 | ||
| 123 | + public static GroupStoreMessage createGroupFailoverMsg(DeviceId deviceId, | ||
| 124 | + GroupDescription desc) { | ||
| 125 | + return new GroupStoreMessage(Type.FAILOVER, | ||
| 126 | + deviceId, | ||
| 127 | + desc.appCookie(), | ||
| 128 | + desc, | ||
| 129 | + null, | ||
| 130 | + null, | ||
| 131 | + desc.appCookie()); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | + | ||
| 122 | /** | 135 | /** |
| 123 | * Returns the device identifier of this group request. | 136 | * Returns the device identifier of this group request. |
| 124 | * | 137 | * | ... | ... |
-
Please register or login to post a comment