[VOL-3016] OLTPipeline removes empty next group if the last group was removed because of empty buckets
Change-Id: Ife4973a1bdd4137fd43fa4d2a49b94a5f3280aeb
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
index 841e444..2ef01d2 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OltPipeline.java
@@ -301,28 +301,34 @@
if (nextObjective.type() != NextObjective.Type.BROADCAST) {
log.error("OLT only supports broadcast groups.");
fail(nextObjective, ObjectiveError.BADPARAMS);
+ return;
}
- if (nextObjective.next().size() != 1) {
+ if (nextObjective.next().size() != 1 && !nextObjective.op().equals(Objective.Operation.REMOVE)) {
log.error("OLT only supports singleton broadcast groups.");
fail(nextObjective, ObjectiveError.BADPARAMS);
+ return;
}
- TrafficTreatment treatment = nextObjective.next().stream().findFirst().get();
+ Optional<TrafficTreatment> treatmentOpt = nextObjective.next().stream().findFirst();
+ if (treatmentOpt.isEmpty() && !nextObjective.op().equals(Objective.Operation.REMOVE)) {
+ log.error("Next objective {} does not have a treatment", nextObjective);
+ fail(nextObjective, ObjectiveError.BADPARAMS);
+ return;
+ }
-
- GroupBucket bucket = DefaultGroupBucket.createAllGroupBucket(treatment);
GroupKey key = new DefaultGroupKey(appKryo.serialize(nextObjective.id()));
-
pendingGroups.put(key, nextObjective);
-
+ log.trace("NextObjective Operation {}", nextObjective.op());
switch (nextObjective.op()) {
case ADD:
GroupDescription groupDesc =
new DefaultGroupDescription(deviceId,
GroupDescription.Type.ALL,
- new GroupBuckets(Collections.singletonList(bucket)),
+ new GroupBuckets(
+ Collections.singletonList(
+ buildBucket(treatmentOpt.get()))),
key,
null,
nextObjective.appId());
@@ -333,12 +339,16 @@
break;
case ADD_TO_EXISTING:
groupService.addBucketsToGroup(deviceId, key,
- new GroupBuckets(Collections.singletonList(bucket)),
+ new GroupBuckets(
+ Collections.singletonList(
+ buildBucket(treatmentOpt.get()))),
key, nextObjective.appId());
break;
case REMOVE_FROM_EXISTING:
groupService.removeBucketsFromGroup(deviceId, key,
- new GroupBuckets(Collections.singletonList(bucket)),
+ new GroupBuckets(
+ Collections.singletonList(
+ buildBucket(treatmentOpt.get()))),
key, nextObjective.appId());
break;
default:
@@ -348,6 +358,10 @@
}
+ private GroupBucket buildBucket(TrafficTreatment treatment) {
+ return DefaultGroupBucket.createAllGroupBucket(treatment);
+ }
+
private void processMulticastRule(ForwardingObjective fwd) {
if (fwd.nextId() == null) {
log.error("Multicast objective does not have a next id");
@@ -1015,16 +1029,23 @@
private class InnerGroupListener implements GroupListener {
@Override
public void event(GroupEvent event) {
+ GroupKey key = event.subject().appCookie();
+ NextObjective obj = pendingGroups.getIfPresent(key);
+ if (obj == null) {
+ log.debug("No pending group for {}, moving on", key);
+ return;
+ }
+ log.trace("Event {} for group {}, handling pending" +
+ "NextGroup {}", event.type(), key, obj.id());
if (event.type() == GroupEvent.Type.GROUP_ADDED ||
event.type() == GroupEvent.Type.GROUP_UPDATED) {
- GroupKey key = event.subject().appCookie();
-
- NextObjective obj = pendingGroups.getIfPresent(key);
- if (obj != null) {
flowObjectiveStore.putNextGroup(obj.id(), new OLTPipelineGroup(key));
pass(obj);
pendingGroups.invalidate(key);
- }
+ } else if (event.type() == GroupEvent.Type.GROUP_REMOVED) {
+ flowObjectiveStore.removeNextGroup(obj.id());
+ pass(obj);
+ pendingGroups.invalidate(key);
}
}
}