Committed by
Helen Wu
Group event indicating failover of previously used live port
Change-Id: I32749b38d5e4fab93fa97bbf6587bd0dc91db88c
Showing
8 changed files
with
121 additions
and
3 deletions
... | @@ -56,6 +56,13 @@ public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { | ... | @@ -56,6 +56,13 @@ public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> { |
56 | */ | 56 | */ |
57 | GROUP_UPDATE_FAILED, | 57 | GROUP_UPDATE_FAILED, |
58 | 58 | ||
59 | + /** | ||
60 | + * Signifies change in the first live bucket in failover group | ||
61 | + * (i.e. change in which bucket is in use). | ||
62 | + * Only to be used with failover Group. | ||
63 | + */ | ||
64 | + GROUP_BUCKET_FAILOVER, | ||
65 | + | ||
59 | // internal event between Manager <-> Store | 66 | // internal event between Manager <-> Store |
60 | 67 | ||
61 | /* | 68 | /* | ... | ... |
... | @@ -41,7 +41,12 @@ public interface GroupProviderService extends ProviderService<GroupProvider> { | ... | @@ -41,7 +41,12 @@ public interface GroupProviderService extends ProviderService<GroupProvider> { |
41 | * @param deviceId device identifier | 41 | * @param deviceId device identifier |
42 | * @param groupEntries collection of group entries as seen in data plane | 42 | * @param groupEntries collection of group entries as seen in data plane |
43 | */ | 43 | */ |
44 | - void pushGroupMetrics(DeviceId deviceId, | 44 | + void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries); |
45 | - Collection<Group> groupEntries); | ||
46 | 45 | ||
46 | + /** | ||
47 | + * Notifies store of group failovers. | ||
48 | + * | ||
49 | + * @param failoverGroups failover groups in which a failover has occurred | ||
50 | + */ | ||
51 | + void notifyOfFailovers(Collection<Group> failoverGroups); | ||
47 | } | 52 | } | ... | ... |
... | @@ -179,4 +179,9 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { | ... | @@ -179,4 +179,9 @@ public interface GroupStore extends Store<GroupEvent, GroupStoreDelegate> { |
179 | * @param groupEntries the group entries as received from southbound | 179 | * @param groupEntries the group entries as received from southbound |
180 | */ | 180 | */ |
181 | void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries); | 181 | void pushGroupMetrics(DeviceId deviceId, Collection<Group> groupEntries); |
182 | + | ||
183 | + /** | ||
184 | + * Indicates failover within a failover group. | ||
185 | + */ | ||
186 | + void notifyOfFailovers(Collection<Group> failoverGroups); | ||
182 | } | 187 | } | ... | ... |
... | @@ -646,6 +646,17 @@ public class SimpleGroupStore | ... | @@ -646,6 +646,17 @@ public class SimpleGroupStore |
646 | } | 646 | } |
647 | } | 647 | } |
648 | 648 | ||
649 | + @Override | ||
650 | + public void notifyOfFailovers(Collection<Group> failoverGroups) { | ||
651 | + List<GroupEvent> failoverEvents = new ArrayList<>(); | ||
652 | + failoverGroups.forEach(group -> { | ||
653 | + if (group.type() == Group.Type.FAILOVER) { | ||
654 | + failoverEvents.add(new GroupEvent(GroupEvent.Type.GROUP_BUCKET_FAILOVER, group)); | ||
655 | + } | ||
656 | + }); | ||
657 | + notifyDelegate(failoverEvents); | ||
658 | + } | ||
659 | + | ||
649 | private void groupMissing(Group group) { | 660 | private void groupMissing(Group group) { |
650 | switch (group.state()) { | 661 | switch (group.state()) { |
651 | case PENDING_DELETE: | 662 | case PENDING_DELETE: | ... | ... |
... | @@ -324,9 +324,9 @@ public class GroupManager | ... | @@ -324,9 +324,9 @@ public class GroupManager |
324 | case GROUP_ADD_FAILED: | 324 | case GROUP_ADD_FAILED: |
325 | case GROUP_UPDATE_FAILED: | 325 | case GROUP_UPDATE_FAILED: |
326 | case GROUP_REMOVE_FAILED: | 326 | case GROUP_REMOVE_FAILED: |
327 | + case GROUP_BUCKET_FAILOVER: | ||
327 | post(event); | 328 | post(event); |
328 | break; | 329 | break; |
329 | - | ||
330 | default: | 330 | default: |
331 | break; | 331 | break; |
332 | } | 332 | } |
... | @@ -353,6 +353,11 @@ public class GroupManager | ... | @@ -353,6 +353,11 @@ public class GroupManager |
353 | checkValidity(); | 353 | checkValidity(); |
354 | store.pushGroupMetrics(deviceId, groupEntries); | 354 | store.pushGroupMetrics(deviceId, groupEntries); |
355 | } | 355 | } |
356 | + | ||
357 | + @Override | ||
358 | + public void notifyOfFailovers(Collection<Group> failoverGroups) { | ||
359 | + store.notifyOfFailovers(failoverGroups); | ||
360 | + } | ||
356 | } | 361 | } |
357 | 362 | ||
358 | private class InternalDeviceListener implements DeviceListener { | 363 | private class InternalDeviceListener implements DeviceListener { |
... | @@ -378,4 +383,5 @@ public class GroupManager | ... | @@ -378,4 +383,5 @@ public class GroupManager |
378 | } | 383 | } |
379 | } | 384 | } |
380 | } | 385 | } |
386 | + | ||
381 | } | 387 | } | ... | ... |
... | @@ -1312,6 +1312,17 @@ public class DistributedGroupStore | ... | @@ -1312,6 +1312,17 @@ public class DistributedGroupStore |
1312 | } | 1312 | } |
1313 | } | 1313 | } |
1314 | 1314 | ||
1315 | + @Override | ||
1316 | + public void notifyOfFailovers(Collection<Group> failoverGroups) { | ||
1317 | + List<GroupEvent> failoverEvents = new ArrayList<>(); | ||
1318 | + failoverGroups.forEach(group -> { | ||
1319 | + if (group.type() == Group.Type.FAILOVER) { | ||
1320 | + failoverEvents.add(new GroupEvent(GroupEvent.Type.GROUP_BUCKET_FAILOVER, group)); | ||
1321 | + } | ||
1322 | + }); | ||
1323 | + notifyDelegate(failoverEvents); | ||
1324 | + } | ||
1325 | + | ||
1315 | private void garbageCollect(DeviceId deviceId, | 1326 | private void garbageCollect(DeviceId deviceId, |
1316 | Set<Group> southboundGroupEntries, | 1327 | Set<Group> southboundGroupEntries, |
1317 | Set<StoredGroupEntry> storedGroupEntries) { | 1328 | Set<StoredGroupEntry> storedGroupEntries) { | ... | ... |
... | @@ -18,7 +18,10 @@ package org.onosproject.provider.of.group.impl; | ... | @@ -18,7 +18,10 @@ package org.onosproject.provider.of.group.impl; |
18 | 18 | ||
19 | import static org.slf4j.LoggerFactory.getLogger; | 19 | import static org.slf4j.LoggerFactory.getLogger; |
20 | 20 | ||
21 | +import java.util.ArrayList; | ||
21 | import java.util.Collection; | 22 | import java.util.Collection; |
23 | +import java.util.Iterator; | ||
24 | +import java.util.List; | ||
22 | import java.util.Map; | 25 | import java.util.Map; |
23 | import java.util.Optional; | 26 | import java.util.Optional; |
24 | import java.util.concurrent.atomic.AtomicLong; | 27 | import java.util.concurrent.atomic.AtomicLong; |
... | @@ -31,9 +34,12 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -31,9 +34,12 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
31 | import org.onosproject.core.DefaultGroupId; | 34 | import org.onosproject.core.DefaultGroupId; |
32 | import org.onosproject.core.GroupId; | 35 | import org.onosproject.core.GroupId; |
33 | import org.onosproject.net.DeviceId; | 36 | import org.onosproject.net.DeviceId; |
37 | +import org.onosproject.net.PortNumber; | ||
38 | +import org.onosproject.net.device.DeviceService; | ||
34 | import org.onosproject.net.driver.DriverService; | 39 | import org.onosproject.net.driver.DriverService; |
35 | import org.onosproject.net.group.DefaultGroup; | 40 | import org.onosproject.net.group.DefaultGroup; |
36 | import org.onosproject.net.group.Group; | 41 | import org.onosproject.net.group.Group; |
42 | +import org.onosproject.net.group.GroupBucket; | ||
37 | import org.onosproject.net.group.GroupBuckets; | 43 | import org.onosproject.net.group.GroupBuckets; |
38 | import org.onosproject.net.group.GroupDescription; | 44 | import org.onosproject.net.group.GroupDescription; |
39 | import org.onosproject.net.group.GroupOperation; | 45 | import org.onosproject.net.group.GroupOperation; |
... | @@ -42,6 +48,7 @@ import org.onosproject.net.group.GroupOperations; | ... | @@ -42,6 +48,7 @@ import org.onosproject.net.group.GroupOperations; |
42 | import org.onosproject.net.group.GroupProvider; | 48 | import org.onosproject.net.group.GroupProvider; |
43 | import org.onosproject.net.group.GroupProviderRegistry; | 49 | import org.onosproject.net.group.GroupProviderRegistry; |
44 | import org.onosproject.net.group.GroupProviderService; | 50 | import org.onosproject.net.group.GroupProviderService; |
51 | +import org.onosproject.net.group.GroupService; | ||
45 | import org.onosproject.net.group.StoredGroupBucketEntry; | 52 | import org.onosproject.net.group.StoredGroupBucketEntry; |
46 | import org.onosproject.net.provider.AbstractProvider; | 53 | import org.onosproject.net.provider.AbstractProvider; |
47 | import org.onosproject.net.provider.ProviderId; | 54 | import org.onosproject.net.provider.ProviderId; |
... | @@ -62,6 +69,7 @@ import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry; | ... | @@ -62,6 +69,7 @@ import org.projectfloodlight.openflow.protocol.OFGroupStatsEntry; |
62 | import org.projectfloodlight.openflow.protocol.OFGroupStatsReply; | 69 | import org.projectfloodlight.openflow.protocol.OFGroupStatsReply; |
63 | import org.projectfloodlight.openflow.protocol.OFGroupType; | 70 | import org.projectfloodlight.openflow.protocol.OFGroupType; |
64 | import org.projectfloodlight.openflow.protocol.OFMessage; | 71 | import org.projectfloodlight.openflow.protocol.OFMessage; |
72 | +import org.projectfloodlight.openflow.protocol.OFPortDesc; | ||
65 | import org.projectfloodlight.openflow.protocol.OFPortStatus; | 73 | import org.projectfloodlight.openflow.protocol.OFPortStatus; |
66 | import org.projectfloodlight.openflow.protocol.OFStatsReply; | 74 | import org.projectfloodlight.openflow.protocol.OFStatsReply; |
67 | import org.projectfloodlight.openflow.protocol.OFStatsType; | 75 | import org.projectfloodlight.openflow.protocol.OFStatsType; |
... | @@ -88,6 +96,12 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv | ... | @@ -88,6 +96,12 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv |
88 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 96 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
89 | protected DriverService driverService; | 97 | protected DriverService driverService; |
90 | 98 | ||
99 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
100 | + protected DeviceService deviceService; | ||
101 | + | ||
102 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
103 | + protected GroupService groupService; | ||
104 | + | ||
91 | private GroupProviderService providerService; | 105 | private GroupProviderService providerService; |
92 | 106 | ||
93 | static final int POLL_INTERVAL = 10; | 107 | static final int POLL_INTERVAL = 10; |
... | @@ -389,6 +403,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv | ... | @@ -389,6 +403,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv |
389 | 403 | ||
390 | @Override | 404 | @Override |
391 | public void portChanged(Dpid dpid, OFPortStatus status) { | 405 | public void portChanged(Dpid dpid, OFPortStatus status) { |
406 | + providerService.notifyOfFailovers(checkFailoverGroups(dpid, status)); | ||
392 | } | 407 | } |
393 | 408 | ||
394 | @Override | 409 | @Override |
... | @@ -396,4 +411,58 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv | ... | @@ -396,4 +411,58 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv |
396 | } | 411 | } |
397 | } | 412 | } |
398 | 413 | ||
414 | + /** | ||
415 | + * Builds a list of failover Groups whose primary live bucket failed over | ||
416 | + * (i.e. bucket in use has changed). | ||
417 | + * | ||
418 | + * @param dpid DPID of switch whose port's status changed | ||
419 | + * @param status new status of port | ||
420 | + * @return list of groups whose primary live bucket failed over | ||
421 | + */ | ||
422 | + private List<Group> checkFailoverGroups(Dpid dpid, OFPortStatus status) { | ||
423 | + List<Group> groupList = new ArrayList<>(); | ||
424 | + OFPortDesc desc = status.getDesc(); | ||
425 | + PortNumber portNumber = PortNumber.portNumber(desc.getPortNo().getPortNumber()); | ||
426 | + DeviceId id = DeviceId.deviceId(Dpid.uri(dpid)); | ||
427 | + if (desc.isEnabled()) { | ||
428 | + return groupList; | ||
429 | + } | ||
430 | + Iterator<Group> iterator = groupService.getGroups(id).iterator(); | ||
431 | + while (iterator.hasNext()) { | ||
432 | + Group group = iterator.next(); | ||
433 | + if (group.type() == GroupDescription.Type.FAILOVER && | ||
434 | + checkFailoverGroup(group, id, portNumber)) { | ||
435 | + groupList.add(group); | ||
436 | + } | ||
437 | + } | ||
438 | + return groupList; | ||
439 | + } | ||
440 | + | ||
441 | + /** | ||
442 | + * Checks whether the first live port in the failover group's bucket | ||
443 | + * has failed over. | ||
444 | + * | ||
445 | + * @param group failover group to be checked for failover | ||
446 | + * @param id device ID of switch whose port's status changed | ||
447 | + * @param portNumber port number of port that was disabled | ||
448 | + * @return whether the failover group experienced failover | ||
449 | + */ | ||
450 | + private boolean checkFailoverGroup(Group group, DeviceId id, | ||
451 | + PortNumber portNumber) { | ||
452 | + boolean portReached = false; | ||
453 | + boolean portEnabled = false; | ||
454 | + Iterator<GroupBucket> bIterator = group.buckets().buckets().iterator(); | ||
455 | + GroupBucket bucket; | ||
456 | + while (bIterator.hasNext() && !portReached) { | ||
457 | + bucket = bIterator.next(); | ||
458 | + if (deviceService.getPort(id, bucket.watchPort()).isEnabled()) { | ||
459 | + portEnabled = true; | ||
460 | + } | ||
461 | + if (bucket.watchPort().equals(portNumber)) { | ||
462 | + portReached = true; | ||
463 | + } | ||
464 | + } | ||
465 | + return portReached && !portEnabled; | ||
466 | + } | ||
467 | + | ||
399 | } | 468 | } | ... | ... |
... | @@ -201,6 +201,10 @@ public class OpenFlowGroupProviderTest { | ... | @@ -201,6 +201,10 @@ public class OpenFlowGroupProviderTest { |
201 | this.groups = groupEntries; | 201 | this.groups = groupEntries; |
202 | } | 202 | } |
203 | 203 | ||
204 | + @Override | ||
205 | + public void notifyOfFailovers(Collection<Group> groups) { | ||
206 | + } | ||
207 | + | ||
204 | public Collection<Group> getGroupEntries() { | 208 | public Collection<Group> getGroupEntries() { |
205 | return groups; | 209 | return groups; |
206 | } | 210 | } | ... | ... |
-
Please register or login to post a comment