ONOS-944: Implemented a Group operation failure handler in GroupManger and SimpleGroupStore.
Change-Id: Ib3be4d534ceff04af2dad0c062fd4cd63d49ee82
diff --git a/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java b/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
index 8c7de08..9258dcc 100644
--- a/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
+++ b/core/store/trivial/src/main/java/org/onosproject/store/trivial/impl/SimpleGroupStore.java
@@ -43,6 +43,7 @@
import org.onosproject.net.group.GroupEvent;
import org.onosproject.net.group.GroupEvent.Type;
import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupOperation;
import org.onosproject.net.group.GroupStore;
import org.onosproject.net.group.GroupStoreDelegate;
import org.onosproject.net.group.StoredGroupEntry;
@@ -474,6 +475,41 @@
}
@Override
+ public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
+
+ StoredGroupEntry existing = (groupEntriesById.get(
+ deviceId) != null) ?
+ groupEntriesById.get(deviceId).get(operation.groupId()) :
+ null;
+
+ if (existing == null) {
+ log.warn("No group entry with ID {} found ", operation.groupId());
+ return;
+ }
+
+ switch (operation.opType()) {
+ case ADD:
+ notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing));
+ break;
+ case MODIFY:
+ notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing));
+ break;
+ case DELETE:
+ notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing));
+ break;
+ default:
+ log.warn("Unknown group operation type {}", operation.opType());
+ }
+
+ ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
+ getGroupKeyTable(existing.deviceId());
+ ConcurrentMap<GroupId, StoredGroupEntry> idTable =
+ getGroupIdTable(existing.deviceId());
+ idTable.remove(existing.id());
+ keyTable.remove(existing.appCookie());
+ }
+
+ @Override
public void addOrUpdateExtraneousGroupEntry(Group group) {
ConcurrentMap<GroupId, Group> extraneousIdTable =
getExtraneousGroupIdTable(group.deviceId());
@@ -497,4 +533,6 @@
return FluentIterable.from(
getExtraneousGroupIdTable(deviceId).values());
}
+
+
}
diff --git a/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java b/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
index 277e1ca..33d7118 100644
--- a/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
+++ b/core/store/trivial/src/test/java/org/onosproject/store/trivial/impl/SimpleGroupStoreTest.java
@@ -40,6 +40,7 @@
import org.onosproject.net.group.GroupDescription;
import org.onosproject.net.group.GroupEvent;
import org.onosproject.net.group.GroupKey;
+import org.onosproject.net.group.GroupOperation;
import org.onosproject.net.group.GroupStore.UpdateType;
import org.onosproject.net.group.GroupStoreDelegate;
@@ -129,6 +130,18 @@
createdGroupId = event.subject().id();
assertEquals(Group.GroupState.PENDING_DELETE,
event.subject().state());
+ } else if (expectedEvent == GroupEvent.Type.GROUP_ADD_FAILED) {
+ createdGroupId = event.subject().id();
+ assertEquals(Group.GroupState.PENDING_ADD,
+ event.subject().state());
+ } else if (expectedEvent == GroupEvent.Type.GROUP_UPDATE_FAILED) {
+ createdGroupId = event.subject().id();
+ assertEquals(Group.GroupState.PENDING_UPDATE,
+ event.subject().state());
+ } else if (expectedEvent == GroupEvent.Type.GROUP_REMOVE_FAILED) {
+ createdGroupId = event.subject().id();
+ assertEquals(Group.GroupState.PENDING_DELETE,
+ event.subject().state());
}
}
@@ -310,6 +323,92 @@
simpleGroupStore.unsetDelegate(removeGroupEntryDelegate);
+
+ }
+
+ @Test
+ public void testGroupOperationFailure() {
+
+ simpleGroupStore.deviceInitialAuditCompleted(D1);
+
+ ApplicationId appId =
+ new DefaultApplicationId(2, "org.groupstore.test");
+ TestGroupKey key = new TestGroupKey("group1");
+ PortNumber[] ports = {PortNumber.portNumber(31),
+ PortNumber.portNumber(32)};
+ List<PortNumber> outPorts = new ArrayList<PortNumber>();
+ outPorts.add(ports[0]);
+ outPorts.add(ports[1]);
+
+ List<GroupBucket> buckets = new ArrayList<GroupBucket>();
+ for (PortNumber portNumber: outPorts) {
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ tBuilder.setOutput(portNumber)
+ .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"))
+ .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
+ .pushMpls()
+ .setMpls(106);
+ buckets.add(DefaultGroupBucket.createSelectGroupBucket(
+ tBuilder.build()));
+ }
+ GroupBuckets groupBuckets = new GroupBuckets(buckets);
+ GroupDescription groupDesc = new DefaultGroupDescription(
+ D1,
+ Group.Type.SELECT,
+ groupBuckets,
+ key,
+ appId);
+ InternalGroupStoreDelegate checkStoreGroupDelegate =
+ new InternalGroupStoreDelegate(key,
+ groupBuckets,
+ GroupEvent.Type.GROUP_ADD_REQUESTED);
+ simpleGroupStore.setDelegate(checkStoreGroupDelegate);
+ // Testing storeGroup operation
+ simpleGroupStore.storeGroupDescription(groupDesc);
+ simpleGroupStore.unsetDelegate(checkStoreGroupDelegate);
+
+ // Testing Group add operation failure
+ Group createdGroup = simpleGroupStore.getGroup(D1, key);
+ checkStoreGroupDelegate.verifyGroupId(createdGroup.id());
+
+ GroupOperation groupAddOp = GroupOperation.
+ createAddGroupOperation(createdGroup.id(),
+ createdGroup.type(),
+ createdGroup.buckets());
+ InternalGroupStoreDelegate checkGroupAddFailureDelegate =
+ new InternalGroupStoreDelegate(key,
+ groupBuckets,
+ GroupEvent.Type.GROUP_ADD_FAILED);
+ simpleGroupStore.setDelegate(checkGroupAddFailureDelegate);
+ simpleGroupStore.groupOperationFailed(D1, groupAddOp);
+
+
+ // Testing Group modify operation failure
+ simpleGroupStore.unsetDelegate(checkGroupAddFailureDelegate);
+ GroupOperation groupModOp = GroupOperation.
+ createModifyGroupOperation(createdGroup.id(),
+ createdGroup.type(),
+ createdGroup.buckets());
+ InternalGroupStoreDelegate checkGroupModFailureDelegate =
+ new InternalGroupStoreDelegate(key,
+ groupBuckets,
+ GroupEvent.Type.GROUP_UPDATE_FAILED);
+ simpleGroupStore.setDelegate(checkGroupModFailureDelegate);
+ simpleGroupStore.groupOperationFailed(D1, groupModOp);
+
+ // Testing Group modify operation failure
+ simpleGroupStore.unsetDelegate(checkGroupModFailureDelegate);
+ GroupOperation groupDelOp = GroupOperation.
+ createDeleteGroupOperation(createdGroup.id(),
+ createdGroup.type());
+ InternalGroupStoreDelegate checkGroupDelFailureDelegate =
+ new InternalGroupStoreDelegate(key,
+ groupBuckets,
+ GroupEvent.Type.GROUP_REMOVE_FAILED);
+ simpleGroupStore.setDelegate(checkGroupDelFailureDelegate);
+ simpleGroupStore.groupOperationFailed(D1, groupDelOp);
+
+
}
}