use of org.onosproject.net.pi.runtime.PiHandle in project onos by opennetworkinglab.
the class P4RuntimeFlowRuleProgrammable method processFlowRules.
private Collection<FlowRule> processFlowRules(Collection<FlowRule> rules, Operation driverOperation) {
if (!setupBehaviour("processFlowRules()") || rules.isEmpty()) {
return Collections.emptyList();
}
// Created batched write request.
final WriteRequest request = client.write(p4DeviceId, pipeconf);
// For each rule, translate to PI and append to write request.
final Map<PiHandle, FlowRule> handleToRuleMap = Maps.newHashMap();
final List<FlowRule> skippedRules = Lists.newArrayList();
final CompletableFuture<WriteResponse> futureResponse;
WRITE_LOCKS.get(deviceId).lock();
try {
for (FlowRule rule : rules) {
// Translate.
final PiTableEntry entry;
try {
entry = translator.translate(rule, pipeconf);
} catch (PiTranslationException e) {
log.warn("Unable to translate flow rule for pipeconf '{}': {} [{}]", pipeconf.id(), e.getMessage(), rule);
// Next rule.
continue;
}
final PiTableEntryHandle handle = entry.handle(deviceId);
handleToRuleMap.put(handle, rule);
// Update translation store.
if (driverOperation.equals(APPLY)) {
translator.learn(handle, new PiTranslatedEntity<>(rule, entry, handle));
} else {
translator.forget(handle);
}
// Append entry to batched write request (returns false), or skip (true)
if (appendEntryToWriteRequestOrSkip(request, handle, entry, driverOperation)) {
skippedRules.add(rule);
}
}
if (request.pendingUpdates().isEmpty()) {
// All good. No need to write on device.
return rules;
}
// Update mirror.
tableMirror.applyWriteRequest(request);
// Async submit request to server.
futureResponse = request.submit();
} finally {
WRITE_LOCKS.get(deviceId).unlock();
}
// Wait for response.
final WriteResponse response = Futures.getUnchecked(futureResponse);
// Derive successfully applied flow rule from response.
final List<FlowRule> appliedRules = getAppliedFlowRules(response, handleToRuleMap, driverOperation);
// Return skipped and applied rules.
return ImmutableList.<FlowRule>builder().addAll(skippedRules).addAll(appliedRules).build();
}
use of org.onosproject.net.pi.runtime.PiHandle in project onos by opennetworkinglab.
the class AbstractDistributedP4RuntimeMirror method sync.
@Override
@SuppressWarnings("unchecked")
public void sync(DeviceId deviceId, Collection<E> entities) {
checkNotNull(deviceId);
final Map<PiHandle, E> deviceState = entities.stream().collect(Collectors.toMap(e -> e.handle(deviceId), e -> e));
final Map<PiHandle, E> localState = deviceHandleMap(deviceId);
final AtomicInteger removeCount = new AtomicInteger(0);
final AtomicInteger updateCount = new AtomicInteger(0);
final AtomicInteger addCount = new AtomicInteger(0);
// Add missing entries.
deviceState.keySet().stream().filter(deviceHandle -> !localState.containsKey(deviceHandle)).forEach(deviceHandle -> {
final E entryToAdd = deviceState.get(deviceHandle);
log.debug("Adding mirror entry for {}: {}", deviceId, entryToAdd);
put((H) deviceHandle, entryToAdd);
addCount.incrementAndGet();
});
// Update or remove local entries.
localState.keySet().forEach(localHandle -> {
final E localEntry = localState.get(localHandle);
final E deviceEntry = deviceState.get(localHandle);
if (deviceEntry == null) {
log.debug("Removing mirror entry for {}: {}", deviceId, localEntry);
remove((H) localHandle);
removeCount.incrementAndGet();
} else if (!deviceEntry.equals(localEntry)) {
log.debug("Updating mirror entry for {}: {}-->{}", deviceId, localEntry, deviceEntry);
put((H) localHandle, deviceEntry);
updateCount.incrementAndGet();
}
});
if (removeCount.get() + updateCount.get() + addCount.get() > 0) {
log.info("Synchronized {} mirror for {}: {} removed, {} updated, {} added", entityType, deviceId, removeCount, updateCount, addCount);
}
}
Aggregations