protected NextGroup getGroupForNextObjective(Integer nextId) { NextGroup next = flowObjectiveStore.getNextGroup(nextId); if (next != null) { List<Deque<GroupKey>> gkeys = appKryo.deserialize(next.data()); if (gkeys != null && !gkeys.isEmpty()) { return next; } else { log.warn("Empty next group found in FlowObjective store for " + "next-id:{} in dev:{}", nextId, deviceId); } } else { log.warn("next-id {} not found in Flow objective store for dev:{}", nextId, deviceId); } return null; }
@Override public int allocateNextId() { checkPermission(FLOWRULE_WRITE); return flowObjectiveStore.allocateNextId(); }
@Override public List<String> getNextMappings() { List<String> mappings = new ArrayList<>(); Map<Integer, NextGroup> allnexts = flowObjectiveStore.getAllGroups(); // XXX if the NextGroup after de-serialization actually stored info of the deviceId // then info on any nextObj could be retrieved from one controller instance. // Right now the drivers on one instance can only fetch for next-ids that came // to them. // Also, we still need to send the right next-id to the right driver as potentially // there can be different drivers for different devices. But on that account, // no instance should be decoding for another instance's nextIds. for (Map.Entry<Integer, NextGroup> e : allnexts.entrySet()) { // get the device this next Objective was sent to DeviceId deviceId = nextToDevice.get(e.getKey()); mappings.add("NextId " + e.getKey() + ": " + ((deviceId != null) ? deviceId : "nextId not in this onos instance")); if (deviceId != null) { // this instance of the controller sent the nextObj to a driver Pipeliner pipeliner = getDevicePipeliner(deviceId); List<String> nextMappings = pipeliner.getNextMappings(e.getValue()); if (nextMappings != null) { mappings.addAll(nextMappings); } } } return mappings; }
@Override public void run() { Set<GroupKey> keys = pendingGroups.asMap().keySet().stream() .filter(key -> groupService.getGroup(deviceId, key) != null) .collect(Collectors.toSet()); keys.stream().forEach(key -> { NextObjective obj = pendingGroups.getIfPresent(key); if (obj == null) { return; } pass(obj); pendingGroups.invalidate(key); log.info("Heard back from group service for group {}. " + "Applying pending forwarding objectives", obj.id()); flowObjectiveStore.putNextGroup(obj.id(), new CentecV350Group(key)); }); } }
flowObjectiveStore.unsetDelegate(super.delegate); flowObjectiveStore.setDelegate(delegate);
@Activate protected void activate() { cfgService.registerProperties(getClass()); executorService = newFixedThreadPool(numThreads, groupedThreads(GROUP_THREAD_NAME, WORKER_PATTERN, log)); flowObjectiveStore.setDelegate(delegate); deviceService.addListener(deviceListener); driverService.addListener(driverListener); log.info("Started"); }
@Deactivate protected void deactivate() { flowObjectiveStore.unsetDelegate(delegate); mastershipService.removeListener(mastershipListener); deviceService.removeListener(deviceListener); executorService.shutdown(); pipeliners.clear(); driverHandlers.clear(); deviceCompositionTreeMap.clear(); log.info("Stopped"); }
/** * Removes all groups in multiple possible group-chains that represent the next * objective. * * @param nextObjective the next objective to remove * @param next the NextGroup that represents the existing group-chain for * this next objective */ protected void removeGroup(NextObjective nextObjective, NextGroup next) { List<Deque<GroupKey>> allgkeys = Ofdpa2Pipeline.appKryo.deserialize(next.data()); List<GroupKey> groupKeys = allgkeys.stream() .map(Deque::getFirst).collect(Collectors.toList()); pendingRemoveNextObjectives.put(nextObjective, groupKeys); allgkeys.forEach(groupChain -> groupChain.forEach(groupKey -> groupService.removeGroup(deviceId, groupKey, nextObjective.appId()))); flowObjectiveStore.removeNextGroup(nextObjective.id()); }
@Override public void run() { Set<GroupKey> keys = pendingGroups .asMap() .keySet() .stream() .filter(key -> groupService.getGroup(deviceId, key) != null) .collect(Collectors.toSet()); keys.stream() .forEach(key -> { NextObjective obj = pendingGroups .getIfPresent(key); if (obj == null) { return; } log.debug("Group verified: dev:{} gid:{} <<->> nextId:{}", deviceId, groupService.getGroup(deviceId, key).id(), obj.id()); pass(obj); pendingGroups.invalidate(key); flowObjectiveStore.putNextGroup( obj.id(), new SpringOpenGroup(key, null)); }); } }
@Activate protected void activate() { executorService = newFixedThreadPool(4, groupedThreads("onos/objective-installer", "%d", log)); flowObjectiveStore.setDelegate(delegate); mastershipService.addListener(mastershipListener); deviceService.addListener(deviceListener); deviceService.getDevices().forEach(device -> setupPipelineHandler(device.id())); deviceCompositionTreeMap = Maps.newConcurrentMap(); log.info("Started"); }
@Deactivate protected void deactivate() { cfgService.unregisterProperties(getClass(), false); flowObjectiveStore.unsetDelegate(delegate); deviceService.removeListener(deviceListener); driverService.removeListener(driverListener); executorService.shutdown(); pipeliners.clear(); driverHandlers.clear(); nextToDevice.clear(); log.info("Stopped"); }
private GroupKey getGroupForNextObjective(Integer nextId) { NextGroup next = flowObjectiveStore.getNextGroup(nextId); return appKryo.deserialize(next.data()); }
@Override public void event(GroupEvent event) { if (event.type() == GroupEvent.Type.GROUP_ADDED) { GroupKey key = event.subject().appCookie(); NextObjective obj = pendingGroups.getIfPresent(key); if (obj != null) { flowObjectiveStore.putNextGroup(obj.id(), new OLTPipelineGroup(key)); pass(obj); pendingGroups.invalidate(key); } } } }
@Override public int allocateNextId() { checkPermission(FLOWRULE_WRITE); return flowObjectiveStore.allocateNextId(); }
private boolean queueObjective(DeviceId deviceId, ForwardingObjective fwd) { if (fwd.nextId() != null && flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { log.trace("Queuing forwarding objective for nextId {}", fwd.nextId()); if (pendingForwards.putIfAbsent(fwd.nextId(), Sets.newHashSet(new PendingNext(deviceId, fwd))) != null) { Set<PendingNext> pending = pendingForwards.get(fwd.nextId()); pending.add(new PendingNext(deviceId, fwd)); } return true; } return false; }
@Override public void event(GroupEvent event) { if (event.type() == GroupEvent.Type.GROUP_ADDED) { GroupKey key = event.subject().appCookie(); NextObjective obj = pendingGroups.getIfPresent(key); if (obj != null) { flowObjectiveStore.putNextGroup(obj.id(), new CentecV350Group(key)); pass(obj); pendingGroups.invalidate(key); } } } }
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; }
/** * Next Objectives are stored as dummy groups for retrieval later * when Forwarding Objectives reference the next objective id. At that point * the dummy group is fetched from the distributed store and the enclosed * treatment is applied as a flow rule action. * * @param nextObj the next objective of type simple */ private void processSimpleNextObjective(NextObjective nextObj) { // Simple next objective has a single treatment (not a collection) log.debug("Received nextObj {}", nextObj.id()); // delay processing to emulate group creation delay(50); TrafficTreatment treatment = nextObj.next().iterator().next(); flowObjectiveStore.putNextGroup(nextObj.id(), new DummyGroup(treatment)); }
boolean queueFwdObjective(DeviceId deviceId, ForwardingObjective fwd) { boolean queued = false; synchronized (pendingForwards) { // double check the flow objective store, because this block could run // after a notification arrives if (flowObjectiveStore.getNextGroup(fwd.nextId()) == null) { pendingForwards.compute(fwd.nextId(), (id, pending) -> { PendingFlowObjective pendfo = new PendingFlowObjective(deviceId, fwd); if (pending == null) { return Sets.newLinkedHashSet(ImmutableSet.of(pendfo)); } else { pending.add(pendfo); return pending; } }); queued = true; } } if (queued) { log.debug("Queued forwarding objective {} for nextId {} meant for device {}", fwd.id(), fwd.nextId(), deviceId); } return queued; }
@Override public void next(NextObjective nextObjective) { pendingNext.put(nextObjective.id(), nextObjective); flowObjectiveStore.putNextGroup(nextObjective.id(), new SingleGroup(new DefaultGroupKey(appKryo.serialize(nextObjective.id())))); nextObjective.context().ifPresent(context -> context.onSuccess(nextObjective)); }