private Set<Identifier<?>> getCandidates(LinkKey link, EncapsulationType type) { // Available ids on src port Set<Identifier<?>> availableIDsatSrc = getAvailableIDs(link.src(), type); // Available ids on dst port Set<Identifier<?>> availableIDsatDst = getAvailableIDs(link.dst(), type); // Create the candidate set doing an intersection of the previous sets return Sets.intersection(availableIDsatSrc, availableIDsatDst); }
@Override public Link getLink(ConnectPoint src, ConnectPoint dst) { return links.get(linkKey(src, dst)); }
@Override protected void doExecute() { LinkService service = get(LinkService.class); Iterable<Link> links = uri != null ? service.getDeviceLinks(deviceId(uri)) : service.getLinks(); if (outputJson()) { print("%s", json(this, links)); } else { Tools.stream(links) .sorted(Comparator.comparing(link -> linkKey(link).toString())) .forEach(link -> { print(linkString(link)); }); } }
@Override public Set<Link> getEgressLinks(ConnectPoint src) { Set<Link> egress = new HashSet<>(); synchronized (srcLinks) { for (LinkKey linkKey : srcLinks.get(src.deviceId())) { if (linkKey.src().equals(src)) { egress.add(links.get(linkKey)); } } } return egress; }
@Override public Set<Link> getIngressLinks(ConnectPoint dst) { Set<Link> ingress = new HashSet<>(); synchronized (dstLinks) { for (LinkKey linkKey : dstLinks.get(dst.deviceId())) { if (linkKey.dst().equals(dst)) { ingress.add(links.get(linkKey)); } } } return ingress; }
@Override public void addTrackedResources(Key intentKey, Collection<NetworkResource> resources) { for (NetworkResource resource : resources) { if (resource instanceof Link) { intentsByLink.put(linkKey((Link) resource), intentKey); } else if (resource instanceof ElementId) { intentsByDevice.put((ElementId) resource, intentKey); } } }
@Override public void event(NetworkConfigEvent event) { LinkKey lk = (LinkKey) event.subject(); BasicLinkConfig cfg = (BasicLinkConfig) event.config().get(); log.debug("Detected link network config event {}", event.type()); if (!isAllowed(cfg)) { log.info("Kicking out links between {} and {}", lk.src(), lk.dst()); removeLink(lk.src(), lk.dst()); if (cfg.isBidirectional()) { removeLink(lk.dst(), lk.src()); } return; } doUpdate(lk.src(), lk.dst(), cfg); if (cfg.isBidirectional()) { doUpdate(lk.dst(), lk.src(), cfg); } }
@Override public LinkKey read(Kryo kryo, Input input, Class<LinkKey> type) { ConnectPoint src = (ConnectPoint) kryo.readClassAndObject(input); ConnectPoint dst = (ConnectPoint) kryo.readClassAndObject(input); return LinkKey.linkKey(src, dst); } }
/** * Allocates labels and associates them to source * and destination ports of a link. * * @param links the links on which labels will be reserved * @param resourceConsumer the resource consumer * @param type the encapsulation type * @return the list of ports and associated labels */ public Map<ConnectPoint, Identifier<?>> assignLabelToPorts(Set<Link> links, ResourceConsumer resourceConsumer, EncapsulationType type) { Map<LinkKey, Identifier<?>> allocation = this.assignLabelToLinks(links, resourceConsumer, type); if (allocation.isEmpty()) { return Collections.emptyMap(); } Map<ConnectPoint, Identifier<?>> finalAllocation = Maps.newHashMap(); allocation.forEach((link, value) -> { finalAllocation.putIfAbsent(link.src(), value); finalAllocation.putIfAbsent(link.dst(), value); }); return ImmutableMap.copyOf(finalAllocation); }
@Override public void removeTrackedResources(Key intentKey, Collection<NetworkResource> resources) { for (NetworkResource resource : resources) { if (resource instanceof Link) { intentsByLink.remove(linkKey((Link) resource), intentKey); } else if (resource instanceof ElementId) { intentsByDevice.remove(resource, intentKey); } } }
private void printInstallable(Intent installable) { print(" installable: %s %s", installable.getClass().getSimpleName(), installable.id()); print(" resources: %s", installable.resources().stream() .filter(r -> !(r instanceof Link)) .map(this::s) .collect(Collectors.joining(", "))); print(" links: %s", installable.resources().stream() .filter(Link.class::isInstance) .map(Link.class::cast) .map(LinkKey::linkKey) .map(l -> String.format("%s -> %s", l.src(), l.dst())) .collect(Collectors.joining(", "))); }
/** * Find available TributarySlots across path. * * @param intent * @param path path in OTU topology * @return Map of Linkey and Set of available TributarySlots on its ports */ private Map<LinkKey, Set<TributarySlot>> findAvailableTributarySlots(OpticalOduIntent intent, Path path) { Set<LinkKey> linkRequest = Sets.newHashSetWithExpectedSize(path.links().size()); for (int i = 0; i < path.links().size(); i++) { LinkKey link = linkKey(path.links().get(i)); linkRequest.add(link); } return findTributarySlots(intent, linkRequest); }
private Map<LinkKey, Set<TributarySlot>> findTributarySlots(OpticalOduIntent intent, Set<LinkKey> links) { OduSignalType oduSignalType = OduSignalUtils.mappingCltSignalTypeToOduSignalType(intent.getSignalType()); int requestedTsNum = oduSignalType.tributarySlots(); Map<LinkKey, Set<TributarySlot>> slotsMap = new HashMap<>(); for (LinkKey link : links) { Set<TributarySlot> common = findCommonTributarySlotsOnCps(link.src(), link.dst()); if (common.isEmpty() || (common.size() < requestedTsNum)) { log.debug("Failed to find TributarySlots on link {} requestedTsNum={}", link, requestedTsNum); return Collections.emptyMap(); // failed to find enough available TributarySlots on a link } slotsMap.put(link, common.stream() .limit(requestedTsNum) .collect(Collectors.toSet())); } return slotsMap; }
private void checkIntentsByLink(FlowRuleIntent installable, ServiceRefs svcRefs) { Set<Map.Entry<LinkKey, Key>> intentsByLink = getIntentsByLinkSet(svcRefs); installable.resources().forEach( rsrc -> { if (rsrc instanceof Link) { Link link = (Link) rsrc; LinkKey linkKey = LinkKey.linkKey(link); intentsByLink.stream() .filter(entry -> Objects.equals(entry.getKey(), linkKey) && Objects.equals(entry.getValue(), installable.key())) .findAny() .orElseGet(() -> { error("FAILED TO FIND LINK(" + link + ") for intents: " + installable.key()); return null; }); } } ); }
private List<Resource> convertToResources(Map<LinkKey, Set<TributarySlot>> slotsMap) { // Same TributarySlots are used for both directions Set<Resource> resources = slotsMap.entrySet().stream() .flatMap(x -> x.getValue() .stream() .flatMap(ts -> Stream.of( Resources.discrete(x.getKey().src().deviceId(), x.getKey().src().port()) .resource().child(ts), Resources.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port()) .resource().child(ts)))) .collect(Collectors.toSet()); return (ImmutableList.copyOf(resources)); }
@Override public LinkEvent removeLink(ConnectPoint src, ConnectPoint dst) { final LinkKey key = linkKey(src, dst); Map<ProviderId, LinkDescription> descs = getOrCreateLinkDescriptions(key); synchronized (descs) { Link link = links.remove(key); descs.clear(); if (link != null) { srcLinks.remove(link.src().deviceId(), key); dstLinks.remove(link.dst().deviceId(), key); return new LinkEvent(LINK_REMOVED, link); } return null; } }
if (reason instanceof LinkEvent) { LinkEvent linkEvent = (LinkEvent) reason; final LinkKey linkKey = linkKey(linkEvent.subject()); synchronized (intentsByLink) { Set<Key> intentKeys = intentsByLink.get(linkKey);