use of org.onosproject.net.pi.runtime.PiActionProfileMemberHandle in project onos by opennetworkinglab.
the class P4RuntimeActionGroupProgrammable method getGroups.
@Override
public Collection<Group> getGroups() {
if (!setupBehaviour("getGroups()")) {
return Collections.emptyList();
}
if (driverBoolProperty(READ_ACTION_GROUPS_FROM_MIRROR, DEFAULT_READ_ACTION_GROUPS_FROM_MIRROR)) {
return getGroupsFromMirror();
}
// Dump groups and members from device for all action profiles.
final P4RuntimeReadClient.ReadRequest request = client.read(p4DeviceId, pipeconf);
pipeconf.pipelineModel().actionProfiles().stream().filter(piActionProfileModel -> piActionProfileModel.tables().stream().map(tableId -> pipeconf.pipelineModel().table(tableId)).allMatch(piTableModel -> piTableModel.isPresent() && !piTableModel.get().oneShotOnly())).map(PiActionProfileModel::id).forEach(id -> request.actionProfileGroups(id).actionProfileMembers(id));
final P4RuntimeReadClient.ReadResponse response = request.submitSync();
if (!response.isSuccess()) {
// Error at client level.
return Collections.emptyList();
}
final Collection<PiActionProfileGroup> groupsOnDevice = response.all(PiActionProfileGroup.class);
final Map<PiActionProfileMemberHandle, PiActionProfileMember> membersOnDevice = response.all(PiActionProfileMember.class).stream().collect(toMap(m -> m.handle(deviceId), m -> m));
// Sync mirrors.
groupMirror.sync(deviceId, groupsOnDevice);
memberMirror.sync(deviceId, membersOnDevice.values());
// Retrieve the original PD group before translation.
final List<Group> result = Lists.newArrayList();
final List<PiActionProfileGroup> groupsToRemove = Lists.newArrayList();
final Set<PiActionProfileMemberHandle> memberHandlesToKeep = Sets.newHashSet();
for (PiActionProfileGroup piGroup : groupsOnDevice) {
final Group pdGroup = checkAndForgeGroupEntry(piGroup, membersOnDevice);
if (pdGroup == null) {
// Entry is on device but is inconsistent with controller state.
// Mark for removal.
groupsToRemove.add(piGroup);
} else {
result.add(pdGroup);
// Keep track of member handles used in groups.
piGroup.members().stream().map(m -> PiActionProfileMemberHandle.of(deviceId, piGroup.actionProfile(), m.id())).forEach(memberHandlesToKeep::add);
}
}
// Trigger clean up of inconsistent groups and members (if any). Also
// take care of removing any orphan member, e.g. from a
// partial/unsuccessful group insertion.
final Set<PiActionProfileMemberHandle> memberHandlesToRemove = Sets.difference(membersOnDevice.keySet(), memberHandlesToKeep);
final Set<PiActionProfileGroupHandle> groupHandlesToRemove = groupsToRemove.stream().map(g -> g.handle(deviceId)).collect(toSet());
if (groupHandlesToRemove.size() + memberHandlesToRemove.size() > 0) {
log.warn("Cleaning up {} action profile groups and " + "{} members on {}...", groupHandlesToRemove.size(), memberHandlesToRemove.size(), deviceId);
client.write(p4DeviceId, pipeconf).delete(groupHandlesToRemove).delete(memberHandlesToRemove).submit().whenComplete((r, ex) -> {
if (ex != null) {
log.error("Exception removing inconsistent group/members", ex);
} else {
log.debug("Completed removal of inconsistent " + "groups/members ({} of {} updates succeeded)", r.success().size(), r.all().size());
groupMirror.applyWriteResponse(r);
memberMirror.applyWriteResponse(r);
}
});
}
// Done.
return result;
}
Aggregations