use of org.onosproject.net.group.StoredGroupEntry in project onos by opennetworkinglab.
the class DistributedGroupStore method activate.
@Activate
public void activate(ComponentContext context) {
cfgService.registerProperties(getClass());
modified(context);
KryoNamespace.Builder kryoBuilder = new KryoNamespace.Builder().register(KryoNamespaces.API).nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID).register(GroupStoreMessage.class, GroupStoreMessage.Type.class, UpdateType.class, GroupStoreMessageSubjects.class, MultiValuedTimestamp.class, GroupStoreKeyMapKey.class, GroupStoreIdMapKey.class, GroupStoreMapKey.class);
clusterMsgSerializer = kryoBuilder.build("GroupStore");
Serializer serializer = Serializer.using(clusterMsgSerializer);
messageHandlingExecutor = Executors.newFixedThreadPool(MESSAGE_HANDLER_THREAD_POOL_SIZE, groupedThreads("onos/store/group", "message-handlers", log));
clusterCommunicator.addSubscriber(GroupStoreMessageSubjects.REMOTE_GROUP_OP_REQUEST, clusterMsgSerializer::deserialize, this::process, messageHandlingExecutor);
log.debug("Creating Consistent map onos-group-store-keymap");
groupStoreEntriesByKey = storageService.<GroupStoreKeyMapKey, StoredGroupEntry>consistentMapBuilder().withName("onos-group-store-keymap").withSerializer(serializer).build();
groupStoreEntriesByKey.addListener(mapListener);
log.debug("Current size of groupstorekeymap:{}", groupStoreEntriesByKey.size());
synchronizeGroupStoreEntries();
log.debug("Creating GroupStoreId Map From GroupStoreKey Map");
matchGroupEntries();
executor = newSingleThreadScheduledExecutor(groupedThreads("onos/group", "store", log));
statusChangeListener = status -> {
if (status == Status.ACTIVE) {
executor.execute(this::matchGroupEntries);
}
};
groupStoreEntriesByKey.addStatusChangeListener(statusChangeListener);
log.debug("Creating Consistent map pendinggroupkeymap");
auditPendingReqQueue = storageService.<GroupStoreKeyMapKey, StoredGroupEntry>consistentMapBuilder().withName("onos-pending-group-keymap").withSerializer(serializer).build();
log.debug("Current size of pendinggroupkeymap:{}", auditPendingReqQueue.size());
groupTopic = getOrCreateGroupTopic(serializer);
groupTopic.subscribe(this::processGroupMessage);
local = clusterService.getLocalNode().id();
log.info("Started");
}
use of org.onosproject.net.group.StoredGroupEntry in project onos by opennetworkinglab.
the class DistributedGroupStore method getStoredGroups.
private Iterable<StoredGroupEntry> getStoredGroups(DeviceId deviceId) {
NodeId master = mastershipService.getMasterFor(deviceId);
if (master == null && deviceService.isAvailable(deviceId)) {
log.debug("Failed to getGroups: No master for {}", deviceId);
return Collections.emptySet();
}
Set<StoredGroupEntry> storedGroups = getGroupStoreKeyMap().values().stream().filter(input -> input.deviceId().equals(deviceId)).collect(Collectors.toSet());
return ImmutableSet.copyOf(storedGroups);
}
use of org.onosproject.net.group.StoredGroupEntry in project onos by opennetworkinglab.
the class DistributedGroupStore method garbageCollect.
private void garbageCollect(DeviceId deviceId, Set<Group> southboundGroupEntries, Set<StoredGroupEntry> storedGroupEntries) {
if (!garbageCollect) {
return;
}
NodeId master;
Iterator<StoredGroupEntry> it = storedGroupEntries.iterator();
while (it.hasNext()) {
// Mastership change can occur during this iteration
master = mastershipService.getMasterFor(deviceId);
if (!Objects.equals(local, master)) {
log.warn("Tried to run garbage collector while the node was not the master");
return;
}
StoredGroupEntry group = it.next();
if (group.state() != GroupState.PENDING_DELETE && checkGroupRefCount(group)) {
log.debug("Garbage collecting group {} on {}", group, deviceId);
deleteGroupDescription(deviceId, group.appCookie());
southboundGroupEntries.remove(group);
it.remove();
}
}
}
use of org.onosproject.net.group.StoredGroupEntry in project onos by opennetworkinglab.
the class DistributedGroupStore method deviceInitialAuditCompleted.
@Override
public void deviceInitialAuditCompleted(DeviceId deviceId, boolean completed) {
synchronized (deviceAuditStatus) {
if (completed) {
log.debug("AUDIT completed for device {}", deviceId);
deviceAuditStatus.put(deviceId, true);
// Execute all pending group requests
List<StoredGroupEntry> pendingGroupRequests = getPendingGroupKeyTable().values().stream().filter(g -> g.deviceId().equals(deviceId)).collect(Collectors.toList());
if (log.isDebugEnabled()) {
List<String> pendingIds = pendingGroupRequests.stream().map(GroupDescription::givenGroupId).map(id -> id != null ? "0x" + Integer.toHexString(id) : "N/A").collect(Collectors.toList());
log.debug("processing pending group add requests for device {}: {}", deviceId, pendingIds);
}
NodeId master;
for (Group group : pendingGroupRequests) {
// Mastership change can occur during this iteration
if (!shouldHandle(deviceId)) {
log.warn("Tried to process pending groups while the node was not the master" + " or the device {} was not available", deviceId);
return;
}
GroupDescription tmp = new DefaultGroupDescription(group.deviceId(), group.type(), group.buckets(), group.appCookie(), group.givenGroupId(), group.appId());
storeGroupDescriptionInternal(tmp);
getPendingGroupKeyTable().remove(new GroupStoreKeyMapKey(deviceId, group.appCookie()));
}
} else {
Boolean audited = deviceAuditStatus.get(deviceId);
if (audited != null && audited) {
log.debug("Clearing AUDIT status for device {}", deviceId);
deviceAuditStatus.put(deviceId, false);
}
}
}
}
use of org.onosproject.net.group.StoredGroupEntry in project onos by opennetworkinglab.
the class DistributedGroupStore method groupOperationFailed.
@Override
public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
StoredGroupEntry existing = getStoredGroupEntry(deviceId, operation.groupId());
if (existing == null) {
log.warn("No group entry with ID {} found ", operation.groupId());
return;
}
log.warn("groupOperationFailed: group operation {} failed in state {} " + "for group {} in device {} with code {}", operation.opType(), existing.state(), existing.id(), existing.deviceId(), operation.failureCode());
if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.GROUP_EXISTS) {
if (operation.buckets().equals(existing.buckets())) {
if (existing.state() == GroupState.PENDING_ADD || existing.state() == GroupState.PENDING_ADD_RETRY) {
log.info("GROUP_EXISTS: GroupID and Buckets match for group in pending " + "add state - moving to ADDED for group {} in device {}", existing.id(), deviceId);
addOrUpdateGroupEntry(existing);
return;
} else {
log.warn("GROUP_EXISTS: GroupId and Buckets match but existing" + "group in state: {}", existing.state());
}
} else {
log.warn("GROUP EXISTS: Group ID matched but buckets did not. " + "Operation: {} Existing: {}", operation.buckets(), existing.buckets());
}
}
if (operation.failureCode() == GroupOperation.GroupMsgErrorCode.INVALID_GROUP) {
existing.incrFailedRetryCount();
if (existing.failedRetryCount() < MAX_FAILED_ATTEMPTS) {
log.warn("Group {} programming failed {} of {} times in dev {}, " + "retrying ..", existing.id(), existing.failedRetryCount(), MAX_FAILED_ATTEMPTS, deviceId);
return;
}
log.warn("Group {} programming failed {} of {} times in dev {}, " + "removing group from store", existing.id(), existing.failedRetryCount(), MAX_FAILED_ATTEMPTS, deviceId);
// fall through to case
}
switch(operation.opType()) {
case ADD:
if (existing.state() == GroupState.PENDING_ADD || existing.state() == GroupState.PENDING_ADD_RETRY) {
notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing));
log.warn("groupOperationFailed: cleaning up " + "group {} from store in device {}....", existing.id(), existing.deviceId());
// Removal from groupid based map will happen in the
// map update listener
getGroupStoreKeyMap().remove(new GroupStoreKeyMapKey(existing.deviceId(), existing.appCookie()));
}
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());
}
}
Aggregations