public List<NextObjective> updateNext(NextObjective nextObjective) { List<NextObjective> updates = new ArrayList<>(); switch (nextObjective.op()) { case ADD: this.nextMap.put(nextObjective.id(), nextObjective); updates.add(nextObjective); break; case REMOVE: this.nextMap.remove(nextObjective.id()); updates.add(nextObjective); break; default: break; } return updates; }
@Override public void next(DeviceId deviceId, NextObjective nextObjective) { checkPermission(FLOWRULE_WRITE); if (nextObjective.op() == Operation.ADD || nextObjective.op() == Operation.VERIFY || flowObjectiveStore.getNextGroup(nextObjective.id()) != null || !queueNextObjective(deviceId, nextObjective)) { // either group exists or we are trying to create it - let it through executorService.execute(new ObjectiveInstaller(deviceId, nextObjective)); } }
boolean queueNextObjective(DeviceId deviceId, NextObjective next) { // we need to hold off on other operations till we get notified that the // initial group creation has succeeded boolean queued = false; synchronized (pendingNexts) { // double check the flow objective store, because this block could run // after a notification arrives if (flowObjectiveStore.getNextGroup(next.id()) == null) { pendingNexts.compute(next.id(), (id, pending) -> { PendingFlowObjective pendfo = new PendingFlowObjective(deviceId, next); if (pending == null) { return Lists.newArrayList(pendfo); } else { pending.add(pendfo); return pending; } }); queued = true; } } if (queued) { log.debug("Queued next objective {} with operation {} meant for device {}", next.id(), next.op(), deviceId); } return queued; }
@Override public ObjectNode encode(NextObjective nextObjective, CodecContext context) { checkNotNull(nextObjective, NOT_NULL_MESSAGE); final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class); final JsonCodec<TrafficSelector> trafficSelectorCodec = context.codec(TrafficSelector.class); // encode common properties ObjectiveCodecHelper och = new ObjectiveCodecHelper(); ObjectNode result = och.encode(nextObjective, context); // encode id result.put(ID, nextObjective.id()); // encode type result.put(TYPE, nextObjective.type().toString()); // encode operation result.put(OPERATION, nextObjective.op().toString()); // encode treatments ArrayNode treatments = context.mapper().createArrayNode(); nextObjective.next().forEach(t -> { ObjectNode treatmentJson = trafficTreatmentCodec.encode(t, context); treatments.add(treatmentJson); }); result.set(TREATMENTS, treatments); // encode meta if (nextObjective.meta() != null) { ObjectNode trafficSelectorNode = trafficSelectorCodec.encode(nextObjective.meta(), context); result.set(META, trafficSelectorNode); } return result; }