ONOS-1786: Updates group buckets when link status is changed.
- Add null check for port map when creating new groups
Change-Id: I92b494d91e908011f2c08be850ccde648e647a09
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java b/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java
index 4e8d326..8e91a99 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/SpringOpenTTP.java
@@ -73,6 +73,7 @@
import org.slf4j.Logger;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@@ -207,63 +208,140 @@
@Override
public void next(NextObjective nextObjective) {
- switch (nextObjective.type()) {
- case SIMPLE:
- log.debug("processing SIMPLE next objective");
- Collection<TrafficTreatment> treatments = nextObjective.next();
- if (treatments.size() == 1) {
- TrafficTreatment treatment = treatments.iterator().next();
- GroupBucket bucket = DefaultGroupBucket
- .createIndirectGroupBucket(treatment);
- final GroupKey key = new DefaultGroupKey(
- appKryo.serialize(nextObjective
- .id()));
- GroupDescription groupDescription = new DefaultGroupDescription(
- deviceId,
- GroupDescription.Type.INDIRECT,
- new GroupBuckets(
- Collections.singletonList(bucket)),
- key,
- nextObjective.appId());
- groupService.addGroup(groupDescription);
- pendingGroups.put(key, nextObjective);
+
+ if (nextObjective.op() == Objective.Operation.REMOVE) {
+ if (nextObjective.next() == null) {
+ removeGroup(nextObjective);
+ } else {
+ removeBucketFromGroup(nextObjective);
}
- break;
- case HASHED:
- log.debug("processing HASHED next objective");
- List<GroupBucket> buckets = nextObjective
- .next()
- .stream()
- .map((treatment) -> DefaultGroupBucket
- .createSelectGroupBucket(treatment))
- .collect(Collectors.toList());
- if (!buckets.isEmpty()) {
- final GroupKey key = new DefaultGroupKey(
- appKryo.serialize(nextObjective
- .id()));
- GroupDescription groupDescription = new DefaultGroupDescription(
- deviceId,
- GroupDescription.Type.SELECT,
- new GroupBuckets(buckets),
- key,
- nextObjective.appId());
- groupService.addGroup(groupDescription);
- pendingGroups.put(key, nextObjective);
+ } else if (nextObjective.op() == Objective.Operation.ADD) {
+ NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id());
+ if (nextGroup != null) {
+ addBucketToGroup(nextObjective);
+ } else {
+ addGroup(nextObjective);
}
- break;
- case BROADCAST:
- case FAILOVER:
- log.debug("BROADCAST and FAILOVER next objectives not supported");
- fail(nextObjective, ObjectiveError.UNSUPPORTED);
- log.warn("Unsupported next objective type {}", nextObjective.type());
- break;
- default:
- fail(nextObjective, ObjectiveError.UNKNOWN);
- log.warn("Unknown next objective type {}", nextObjective.type());
+ } else {
+ log.warn("Unsupported operation {}", nextObjective.op());
}
}
+ private void removeGroup(NextObjective nextObjective) {
+ final GroupKey key = new DefaultGroupKey(
+ appKryo.serialize(nextObjective.id()));
+ groupService.removeGroup(deviceId, key, appId);
+ }
+
+ private void addGroup(NextObjective nextObjective) {
+ switch (nextObjective.type()) {
+ case SIMPLE:
+ log.debug("processing SIMPLE next objective");
+ Collection<TrafficTreatment> treatments = nextObjective.next();
+ if (treatments.size() == 1) {
+ TrafficTreatment treatment = treatments.iterator().next();
+ GroupBucket bucket = DefaultGroupBucket
+ .createIndirectGroupBucket(treatment);
+ final GroupKey key = new DefaultGroupKey(
+ appKryo.serialize(nextObjective
+ .id()));
+ GroupDescription groupDescription = new DefaultGroupDescription(
+ deviceId,
+ GroupDescription.Type.INDIRECT,
+ new GroupBuckets(
+ Collections.singletonList(bucket)),
+ key,
+ nextObjective.appId());
+ groupService.addGroup(groupDescription);
+ pendingGroups.put(key, nextObjective);
+ }
+ break;
+ case HASHED:
+ log.debug("processing HASHED next objective");
+ List<GroupBucket> buckets = nextObjective
+ .next()
+ .stream()
+ .map((treatment) -> DefaultGroupBucket
+ .createSelectGroupBucket(treatment))
+ .collect(Collectors.toList());
+ if (!buckets.isEmpty()) {
+ final GroupKey key = new DefaultGroupKey(
+ appKryo.serialize(nextObjective
+ .id()));
+ GroupDescription groupDescription = new DefaultGroupDescription(
+ deviceId,
+ GroupDescription.Type.SELECT,
+ new GroupBuckets(buckets),
+ key,
+ nextObjective.appId());
+ groupService.addGroup(groupDescription);
+ pendingGroups.put(key, nextObjective);
+ }
+ break;
+ case BROADCAST:
+ case FAILOVER:
+ log.debug("BROADCAST and FAILOVER next objectives not supported");
+ fail(nextObjective, ObjectiveError.UNSUPPORTED);
+ log.warn("Unsupported next objective type {}", nextObjective.type());
+ break;
+ default:
+ fail(nextObjective, ObjectiveError.UNKNOWN);
+ log.warn("Unknown next objective type {}", nextObjective.type());
+ }
+ }
+
+ private void addBucketToGroup(NextObjective nextObjective) {
+ Collection<TrafficTreatment> treatments = nextObjective.next();
+ TrafficTreatment treatment = treatments.iterator().next();
+ final GroupKey key = new DefaultGroupKey(
+ appKryo.serialize(nextObjective
+ .id()));
+ Group group = groupService.getGroup(deviceId, key);
+ if (group == null) {
+ log.warn("Group is not found in {} for {}", deviceId, key);
+ return;
+ }
+ GroupBucket bucket;
+ if (group.type() == GroupDescription.Type.INDIRECT) {
+ bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
+ } else if (group.type() == GroupDescription.Type.SELECT) {
+ bucket = DefaultGroupBucket.createSelectGroupBucket(treatment);
+ } else {
+ log.warn("Unsupported Group type {}", group.type());
+ return;
+ }
+ GroupBuckets bucketsToAdd = new GroupBuckets(Arrays.asList(bucket));
+ groupService.addBucketsToGroup(deviceId, key, bucketsToAdd, key, appId);
+ }
+
+ private void removeBucketFromGroup(NextObjective nextObjective) {
+ NextGroup nextGroup = flowObjectiveStore.getNextGroup(nextObjective.id());
+ if (nextGroup != null) {
+ Collection<TrafficTreatment> treatments = nextObjective.next();
+ TrafficTreatment treatment = treatments.iterator().next();
+ final GroupKey key = new DefaultGroupKey(
+ appKryo.serialize(nextObjective
+ .id()));
+ Group group = groupService.getGroup(deviceId, key);
+ if (group == null) {
+ log.warn("Group is not found in {} for {}", deviceId, key);
+ return;
+ }
+ GroupBucket bucket;
+ if (group.type() == GroupDescription.Type.INDIRECT) {
+ bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
+ } else if (group.type() == GroupDescription.Type.SELECT) {
+ bucket = DefaultGroupBucket.createSelectGroupBucket(treatment);
+ } else {
+ log.warn("Unsupported Group type {}", group.type());
+ return;
+ }
+ GroupBuckets removeBuckets = new GroupBuckets(Arrays.asList(bucket));
+ groupService.removeBucketsFromGroup(deviceId, key, removeBuckets, key, appId);
+ }
+ }
+
private Collection<FlowRule> processForward(ForwardingObjective fwd) {
switch (fwd.flag()) {
case SPECIFIC: