use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStore method storeGroupDescriptionInternal.
private void storeGroupDescriptionInternal(GroupDescription groupDesc) {
// Check if a group is existing with the same key
if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) {
return;
}
synchronized (deviceAuditStatus) {
if (deviceAuditStatus.get(groupDesc.deviceId()) == null) {
// Device group audit has not completed yet
// Add this group description to pending group key table
// Create a group entry object with Dummy Group ID
log.debug("storeGroupDescriptionInternal: Device {} AUDIT pending...Queuing Group id {} ADD request", groupDesc.deviceId(), groupDesc.givenGroupId() != null ? "0x" + Integer.toHexString(groupDesc.givenGroupId()) : "N/A");
StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc);
group.setState(GroupState.WAITING_AUDIT_COMPLETE);
Map<GroupStoreKeyMapKey, StoredGroupEntry> pendingKeyTable = getPendingGroupKeyTable();
pendingKeyTable.put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
return;
}
}
Group matchingExtraneousGroup = null;
if (groupDesc.givenGroupId() != null) {
// Check if there is a extraneous group existing with the same Id
matchingExtraneousGroup = getMatchingExtraneousGroupbyId(groupDesc.deviceId(), groupDesc.givenGroupId());
if (matchingExtraneousGroup != null) {
log.debug("storeGroupDescriptionInternal: Matching extraneous group " + "found in Device {} for group id 0x{}", groupDesc.deviceId(), Integer.toHexString(groupDesc.givenGroupId()));
// Check if the group buckets matches with user provided buckets
if (matchingExtraneousGroup.buckets().equals(groupDesc.buckets())) {
// Group is already existing with the same buckets and Id
// Create a group entry object
log.debug("storeGroupDescriptionInternal: Buckets also matching " + "in Device {} for group id 0x{}", groupDesc.deviceId(), Integer.toHexString(groupDesc.givenGroupId()));
StoredGroupEntry group = new DefaultGroup(matchingExtraneousGroup.id(), groupDesc);
// Insert the newly created group entry into key and id maps
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(matchingExtraneousGroup.id(), group);
addOrUpdateGroupEntry(matchingExtraneousGroup);
removeExtraneousGroupEntry(matchingExtraneousGroup);
return;
} else {
// Group buckets are not matching. Update group
// with user provided buckets.
log.debug("storeGroupDescriptionInternal: Buckets are not " + "matching in Device {} for group id 0x{}", groupDesc.deviceId(), Integer.toHexString(groupDesc.givenGroupId()));
StoredGroupEntry modifiedGroup = new DefaultGroup(matchingExtraneousGroup.id(), groupDesc);
modifiedGroup.setState(GroupState.PENDING_UPDATE);
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), modifiedGroup);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(matchingExtraneousGroup.id(), modifiedGroup);
removeExtraneousGroupEntry(matchingExtraneousGroup);
log.debug("storeGroupDescriptionInternal: Triggering Group " + "UPDATE request for {} in device {}", matchingExtraneousGroup.id(), groupDesc.deviceId());
notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, modifiedGroup));
return;
}
}
} else {
// Check if there is an extraneous group with user provided buckets
matchingExtraneousGroup = getMatchingExtraneousGroupbyBuckets(groupDesc.deviceId(), groupDesc.buckets());
if (matchingExtraneousGroup != null) {
// Group is already existing with the same buckets.
// So reuse this group.
log.debug("storeGroupDescriptionInternal: Matching extraneous group found in Device {}", groupDesc.deviceId());
// Create a group entry object
StoredGroupEntry group = new DefaultGroup(matchingExtraneousGroup.id(), groupDesc);
// Insert the newly created group entry into key and id maps
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(matchingExtraneousGroup.id(), group);
addOrUpdateGroupEntry(matchingExtraneousGroup);
removeExtraneousGroupEntry(matchingExtraneousGroup);
return;
} else {
// TODO: Check if there are any empty groups that can be used here
log.debug("storeGroupDescriptionInternal: No matching extraneous groups found in Device {}", groupDesc.deviceId());
}
}
GroupId id = null;
if (groupDesc.givenGroupId() == null) {
// Get a new group identifier
id = new GroupId(getFreeGroupIdValue(groupDesc.deviceId()));
} else {
// we need to use the identifier passed in by caller, but check if
// already used
Group existing = getGroup(groupDesc.deviceId(), new GroupId(groupDesc.givenGroupId()));
if (existing != null) {
log.warn("Group already exists with the same id: 0x{} in dev:{} " + "but with different key: {} (request gkey: {})", Integer.toHexString(groupDesc.givenGroupId()), groupDesc.deviceId(), existing.appCookie(), groupDesc.appCookie());
return;
}
id = new GroupId(groupDesc.givenGroupId());
}
// Create a group entry object
StoredGroupEntry group = new DefaultGroup(id, groupDesc);
// Insert the newly created group entry into key and id maps
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(groupDesc.deviceId(), groupDesc.appCookie()), group);
// Ensure it also inserted into group id based table to
// avoid any chances of duplication in group id generation
getGroupIdTable(groupDesc.deviceId()).put(id, group);
log.debug("storeGroupDescriptionInternal: Processing Group ADD request for Id {} in device {}", id, groupDesc.deviceId());
notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED, group));
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStore method updateGroupEntryStatsInternal.
/**
* Updates the stats of an existing group entry.
*
* @param group the new stats
* @param existing the existing group
*/
private void updateGroupEntryStatsInternal(Group group, StoredGroupEntry existing) {
for (GroupBucket bucket : group.buckets().buckets()) {
Optional<GroupBucket> matchingBucket = existing.buckets().buckets().stream().filter((existingBucket) -> (existingBucket.equals(bucket))).findFirst();
if (matchingBucket.isPresent()) {
((StoredGroupBucketEntry) matchingBucket.get()).setPackets(bucket.packets());
((StoredGroupBucketEntry) matchingBucket.get()).setBytes(bucket.bytes());
} else {
log.warn("updateGroupEntryStatsInternal: No matching bucket {}" + " to update stats for group {}", bucket, group.id());
}
}
existing.setLife(group.life());
existing.setPackets(group.packets());
existing.setBytes(group.bytes());
existing.setReferenceCount(group.referenceCount());
existing.setFailedRetryCount(0);
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStore method updateGroupDescriptionInternal.
private void updateGroupDescriptionInternal(DeviceId deviceId, GroupKey oldAppCookie, UpdateType type, GroupBuckets newBuckets, GroupKey newAppCookie) {
// Check if a group is existing with the provided key
Group oldGroup = getGroup(deviceId, oldAppCookie);
if (oldGroup == null) {
log.warn("updateGroupDescriptionInternal: Group not found...strange. " + "GroupKey:{} DeviceId:{} newGroupKey:{}", oldAppCookie, deviceId, newAppCookie);
return;
}
List<GroupBucket> newBucketList = getUpdatedBucketList(oldGroup, type, newBuckets);
if (newBucketList != null) {
// Create a new group object from the old group
GroupBuckets updatedBuckets = new GroupBuckets(newBucketList);
GroupKey newCookie = (newAppCookie != null) ? newAppCookie : oldAppCookie;
GroupDescription updatedGroupDesc = new DefaultGroupDescription(oldGroup.deviceId(), oldGroup.type(), updatedBuckets, newCookie, oldGroup.givenGroupId(), oldGroup.appId());
StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(), updatedGroupDesc);
log.debug("updateGroupDescriptionInternal: group entry {} in device {} moving from {} to PENDING_UPDATE", oldGroup.id(), oldGroup.deviceId(), oldGroup.state());
newGroup.setState(GroupState.PENDING_UPDATE);
newGroup.setLife(oldGroup.life());
newGroup.setPackets(oldGroup.packets());
newGroup.setBytes(oldGroup.bytes());
// Update the group entry in groupkey based map.
// Update to groupid based map will happen in the
// groupkey based map update listener
log.debug("updateGroupDescriptionInternal with type {}: Group {} updated with buckets", type, newGroup.id());
getGroupStoreKeyMap().put(new GroupStoreKeyMapKey(newGroup.deviceId(), newGroup.appCookie()), newGroup);
notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup));
} else {
log.warn("updateGroupDescriptionInternal with type {}: Group {} No " + "change in the buckets in update", type, oldGroup.id());
}
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStoreTest method testRemoveGroupDescription.
/**
* Tests adding and removing a group.
*/
@Test
public void testRemoveGroupDescription() throws Exception {
groupStore.deviceInitialAuditCompleted(deviceId1, true);
groupStore.storeGroupDescription(groupDescription1);
groupStore.deleteGroupDescription(deviceId1, groupKey1);
// Group should still be there, marked for removal
assertThat(groupStore.getGroupCount(deviceId1), is(1));
Group queriedGroup = groupStore.getGroup(deviceId1, groupId1);
assertThat(queriedGroup.state(), is(Group.GroupState.PENDING_DELETE));
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class DistributedGroupStoreTest method testGroupOperationFailedWithErrorCode.
/**
* Tests group operation failed interface, with error codes for failures.
*/
@Test
public void testGroupOperationFailedWithErrorCode() {
TestDelegate delegate = new TestDelegate();
groupStore.setDelegate(delegate);
groupStore.deviceInitialAuditCompleted(deviceId1, true);
groupStore.storeGroupDescription(groupDescription1);
groupStore.deviceInitialAuditCompleted(deviceId2, true);
groupStore.storeGroupDescription(groupDescription2);
List<GroupEvent> eventsAfterAdds = delegate.eventsSeen();
assertThat(eventsAfterAdds, hasSize(2));
eventsAfterAdds.forEach(event -> assertThat(event.type(), is(GroupEvent.Type.GROUP_ADD_REQUESTED)));
delegate.resetEvents();
// test group exists
GroupOperation opAdd = GroupOperation.createAddGroupOperation(groupId1, ALL, allGroupBuckets);
GroupOperation addFailedExists = GroupOperation.createFailedGroupOperation(opAdd, GroupMsgErrorCode.GROUP_EXISTS);
groupStore.groupOperationFailed(deviceId1, addFailedExists);
List<GroupEvent> eventsAfterAddFailed = delegate.eventsSeen();
assertThat(eventsAfterAddFailed, hasSize(2));
assertThat(eventsAfterAddFailed.get(0).type(), is(GroupEvent.Type.GROUP_ADDED));
assertThat(eventsAfterAddFailed.get(1).type(), is(GroupEvent.Type.GROUP_ADDED));
Group g1 = groupStore.getGroup(deviceId1, groupId1);
assertEquals(0, g1.failedRetryCount());
delegate.resetEvents();
// test invalid group
Group g2 = groupStore.getGroup(deviceId2, groupId2);
assertEquals(0, g2.failedRetryCount());
assertEquals(GroupState.PENDING_ADD, g2.state());
GroupOperation opAdd1 = GroupOperation.createAddGroupOperation(groupId2, INDIRECT, indirectGroupBuckets);
GroupOperation addFailedInvalid = GroupOperation.createFailedGroupOperation(opAdd1, GroupMsgErrorCode.INVALID_GROUP);
groupStore.groupOperationFailed(deviceId2, addFailedInvalid);
groupStore.pushGroupMetrics(deviceId2, ImmutableList.of());
List<GroupEvent> eventsAfterAddFailed1 = delegate.eventsSeen();
assertThat(eventsAfterAddFailed1, hasSize(1));
assertThat(eventsAfterAddFailed.get(0).type(), is(GroupEvent.Type.GROUP_ADD_REQUESTED));
g2 = groupStore.getGroup(deviceId2, groupId2);
assertEquals(1, g2.failedRetryCount());
assertEquals(GroupState.PENDING_ADD_RETRY, g2.state());
delegate.resetEvents();
groupStore.groupOperationFailed(deviceId2, addFailedInvalid);
groupStore.pushGroupMetrics(deviceId2, ImmutableList.of());
List<GroupEvent> eventsAfterAddFailed2 = delegate.eventsSeen();
assertThat(eventsAfterAddFailed2, hasSize(1));
assertThat(eventsAfterAddFailed.get(0).type(), is(GroupEvent.Type.GROUP_ADD_REQUESTED));
g2 = groupStore.getGroup(deviceId2, groupId2);
assertEquals(2, g2.failedRetryCount());
assertEquals(GroupState.PENDING_ADD_RETRY, g2.state());
delegate.resetEvents();
groupStore.groupOperationFailed(deviceId2, addFailedInvalid);
groupStore.pushGroupMetrics(deviceId2, ImmutableList.of());
List<GroupEvent> eventsAfterAddFailed3 = delegate.eventsSeen();
assertThat(eventsAfterAddFailed3, hasSize(2));
assertThat(eventsAfterAddFailed.get(0).type(), is(GroupEvent.Type.GROUP_ADD_FAILED));
assertThat(eventsAfterAddFailed.get(1).type(), is(GroupEvent.Type.GROUP_REMOVED));
g2 = groupStore.getGroup(deviceId2, groupId2);
assertEquals(null, g2);
delegate.resetEvents();
}
Aggregations