use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class FabricPipeliner method handleVerify.
private ObjectiveError handleVerify(NextObjective nextObjective) {
Map<GroupBucket, FlowRule> bucketsToFlows = getBucketToFlowMapping(nextObjective);
if (bucketsToFlows.isEmpty() && !nextObjective.nextTreatments().isEmpty()) {
log.warn("VERIFY failed due to translation error, bucketsToFlows is empty");
return ObjectiveError.BADPARAMS;
}
if (log.isTraceEnabled()) {
log.trace("Mapping bucketsToFlows {} has been generated ", bucketsToFlows);
}
GroupKey groupKey = nextTranslator.getGroupKey(nextObjective);
if (groupKey == null) {
log.warn("VERIFY failed due to translation error, unable to determine group key");
return ObjectiveError.BADPARAMS;
}
Group groupFromStore = groupService.getGroup(deviceId, groupKey);
if (groupFromStore == null) {
log.warn("VERIFY failed due to missing group in the store");
return ObjectiveError.GROUPMISSING;
}
// Looking for duplicate buckets - remove them by using a set and comparing size after/before
Set<GroupBucket> bucketsFromStore = Sets.newHashSet(groupFromStore.buckets().buckets());
if (groupFromStore.buckets().buckets().size() > bucketsFromStore.size()) {
log.warn("Duplicated buckets detected in device:{}, nextId:{}, before-size" + ":{} after-size:{} .. correcting", deviceId, nextObjective.id(), groupFromStore.buckets().buckets().size(), bucketsFromStore.size());
final GroupBuckets bucketToSet = new GroupBuckets(Lists.newArrayList(bucketsFromStore));
groupService.setBucketsForGroup(deviceId, groupKey, bucketToSet, groupKey, nextObjective.appId());
// Forge temporary the group to avoid race condition with the store
groupFromStore = new DefaultGroup(groupFromStore.id(), deviceId, groupFromStore.type(), bucketToSet);
}
// Looking for buckets missing in the group but defined in the next
Map<GroupBucket, FlowRule> toAdd = Maps.newHashMap();
for (Map.Entry<GroupBucket, FlowRule> entry : bucketsToFlows.entrySet()) {
if (!groupFromStore.buckets().buckets().contains(entry.getKey())) {
toAdd.put(entry.getKey(), entry.getValue());
}
}
// Looking for buckets missing in the next but defined in the group
// FIXME SDFAB-250 we cannot remove associated egress flows
List<GroupBucket> toRemove = Lists.newArrayList();
groupFromStore.buckets().buckets().forEach(bucket -> {
if (!bucketsToFlows.containsKey(bucket)) {
toRemove.add(bucket);
}
});
if (!toAdd.isEmpty() || !toRemove.isEmpty()) {
log.warn("Mismatch detected in device:{}, nextId:{}, groupFromTranslation-size:{} " + "groupFromStore-size:{} toAdd-size:{} toRemove-size: {} .. correcting", deviceId, nextObjective.id(), bucketsToFlows.size(), groupFromStore.buckets().buckets().size(), toAdd.size(), toRemove.size());
}
if (!toAdd.isEmpty()) {
if (log.isTraceEnabled()) {
log.trace("Adding missing buckets {} and flows {}", toAdd.keySet(), toAdd.values());
}
final FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
final FlowRule dummyFlow = getDummyFlow(nextObjective);
toAdd.values().stream().filter(flowRule -> !flowRule.equals(dummyFlow)).forEach(ops::add);
final GroupBuckets bucketsToAdd = new GroupBuckets(Lists.newArrayList(toAdd.keySet()));
groupService.addBucketsToGroup(deviceId, groupKey, bucketsToAdd, groupKey, nextObjective.appId());
flowRuleService.apply(ops.build());
}
if (!toRemove.isEmpty()) {
if (log.isTraceEnabled()) {
log.trace("Removing stale buckets {}", toRemove);
}
final GroupBuckets bucketsToRemove = new GroupBuckets(toRemove);
groupService.removeBucketsFromGroup(deviceId, groupKey, bucketsToRemove, groupKey, nextObjective.appId());
}
return null;
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method getPrimaryPort.
/**
* Gets primary port number through failover group associated
* with this intent.
*/
private PortNumber getPrimaryPort(PointToPointIntent intent) {
Group group = groupService.getGroup(intent.filteredIngressPoint().connectPoint().deviceId(), makeGroupKey(intent.id()));
PortNumber primaryPort = null;
if (group != null) {
List<GroupBucket> buckets = group.buckets().buckets();
Iterator<GroupBucket> iterator = buckets.iterator();
while (primaryPort == null && iterator.hasNext()) {
GroupBucket bucket = iterator.next();
Instruction individualInstruction = bucket.treatment().allInstructions().get(0);
if (individualInstruction instanceof Instructions.OutputInstruction) {
Instructions.OutputInstruction outInstruction = (Instructions.OutputInstruction) individualInstruction;
PortNumber tempPortNum = outInstruction.port();
Port port = deviceService.getPort(intent.filteredIngressPoint().connectPoint().deviceId(), tempPortNum);
if (port != null && port.isEnabled()) {
primaryPort = tempPortNum;
}
}
}
}
return primaryPort;
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method buildFailoverTreatment.
private TrafficTreatment buildFailoverTreatment(DeviceId srcDevice, GroupKey groupKey) {
Group group = waitForGroup(srcDevice, groupKey);
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
TrafficTreatment trafficTreatment = tBuilder.group(group.id()).build();
return trafficTreatment;
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method waitForGroup.
/**
* Waits for specified group to appear until timeout.
*
* @param deviceId {@link DeviceId}
* @param groupKey {@link GroupKey} to wait for.
* @param timeout timeout
* @param unit unit of timeout
* @return {@link Group}
* @throws IntentCompilationException on any error.
*/
private Group waitForGroup(DeviceId deviceId, GroupKey groupKey, long timeout, TimeUnit unit) {
Group group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
return group;
}
final CompletableFuture<Group> future = new CompletableFuture<>();
final GroupListener listener = event -> {
if (event.subject().deviceId() == deviceId && event.subject().appCookie().equals(groupKey)) {
future.complete(event.subject());
return;
}
};
groupService.addListener(listener);
try {
group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
return group;
}
return future.get(timeout, unit);
} catch (InterruptedException e) {
log.debug("Interrupted", e);
Thread.currentThread().interrupt();
throw new IntentCompilationException("Interrupted", e);
} catch (ExecutionException e) {
log.debug("ExecutionException", e);
throw new IntentCompilationException("ExecutionException caught", e);
} catch (TimeoutException e) {
// one last try
group = groupService.getGroup(deviceId, groupKey);
if (group != null) {
return group;
} else {
log.debug("Timeout", e);
throw new IntentCompilationException("Timeout", e);
}
} finally {
groupService.removeListener(listener);
}
}
use of org.onosproject.net.group.Group in project onos by opennetworkinglab.
the class PointToPointIntentCompiler method removeAndUpdateIntents.
/**
* Removes intents from installables list, depending on the values
* of instance variables erasePrimary and eraseBackup. Flow rule intents
* that contain the manufactured fast failover flow rules are never deleted.
* The contents are simply modified as necessary. If cleanUpIntents size
* is greater than 1 (failover intent), then one whole path from previous
* installables must be still viable.
*
* @param cleanUpIntents list of installable intents
*/
private void removeAndUpdateIntents(List<Intent> cleanUpIntents, PointToPointIntent pointIntent) {
ListIterator<Intent> iterator = cleanUpIntents.listIterator();
while (iterator.hasNext()) {
Intent cIntent = iterator.next();
if (cIntent instanceof FlowRuleIntent) {
FlowRuleIntent fIntent = (FlowRuleIntent) cIntent;
if (fIntent.type() == PathIntent.ProtectionType.PRIMARY && erasePrimary) {
// remove primary path's flow rule intents
iterator.remove();
} else if (fIntent.type() == PathIntent.ProtectionType.BACKUP && eraseBackup) {
// remove backup path's flow rule intents
iterator.remove();
} else if (fIntent.type() == PathIntent.ProtectionType.BACKUP && erasePrimary) {
// promote backup path's flow rule intents to primary
iterator.set(new FlowRuleIntent(fIntent, PathIntent.ProtectionType.PRIMARY));
}
}
}
// remove buckets whose watchports are disabled if the failover group exists
Group group = groupService.getGroup(pointIntent.filteredIngressPoint().connectPoint().deviceId(), makeGroupKey(pointIntent.id()));
if (group != null) {
updateFailoverGroup(pointIntent);
}
}
Aggregations