diff options
Diffstat (limited to 'framework/src/onos/core/net/src/main/java/org/onosproject')
9 files changed, 313 insertions, 209 deletions
diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java index 04d1dfdf..7ddac0ce 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterManager.java @@ -25,17 +25,26 @@ import org.apache.karaf.system.SystemService; import org.joda.time.DateTime; import org.onlab.packet.IpAddress; import org.onosproject.cluster.ClusterAdminService; -import org.onosproject.cluster.ClusterDefinitionService; import org.onosproject.cluster.ClusterEvent; import org.onosproject.cluster.ClusterEventListener; +import org.onosproject.cluster.ClusterMetadata; +import org.onosproject.cluster.ClusterMetadataService; import org.onosproject.cluster.ClusterService; import org.onosproject.cluster.ClusterStore; import org.onosproject.cluster.ClusterStoreDelegate; import org.onosproject.cluster.ControllerNode; import org.onosproject.cluster.NodeId; +import org.onosproject.cluster.Partition; import org.onosproject.event.AbstractListenerManager; import org.slf4j.Logger; +import com.google.common.collect.Lists; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; import java.util.Set; import static com.google.common.base.Preconditions.checkArgument; @@ -44,8 +53,6 @@ import static org.onosproject.security.AppGuard.checkPermission; import static org.slf4j.LoggerFactory.getLogger; import static org.onosproject.security.AppPermission.Type.*; - - /** * Implementation of the cluster service. */ @@ -61,7 +68,7 @@ public class ClusterManager private ClusterStoreDelegate delegate = new InternalStoreDelegate(); @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected ClusterDefinitionService clusterDefinitionService; + protected ClusterMetadataService clusterMetadataService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected ClusterStore store; @@ -73,8 +80,9 @@ public class ClusterManager public void activate() { store.setDelegate(delegate); eventDispatcher.addSink(ClusterEvent.class, listenerRegistry); - clusterDefinitionService.seedNodes() - .forEach(node -> store.addNode(node.id(), node.ip(), node.tcpPort())); + clusterMetadataService.getClusterMetadata() + .getNodes() + .forEach(node -> store.addNode(node.id(), node.ip(), node.tcpPort())); log.info("Started"); } @@ -119,11 +127,16 @@ public class ClusterManager } @Override - public void formCluster(Set<ControllerNode> nodes, String ipPrefix) { + public void formCluster(Set<ControllerNode> nodes) { checkNotNull(nodes, "Nodes cannot be null"); checkArgument(!nodes.isEmpty(), "Nodes cannot be empty"); - checkNotNull(ipPrefix, "IP prefix cannot be null"); - clusterDefinitionService.formCluster(nodes, ipPrefix); + + ClusterMetadata metadata = ClusterMetadata.builder() + .withName("default") + .withControllerNodes(nodes) + .withPartitions(buildDefaultPartitions(nodes)) + .build(); + clusterMetadataService.setClusterMetadata(metadata); try { log.warn("Shutting down container for cluster reconfiguration!"); systemService.reboot("now", SystemService.Swipe.NONE); @@ -153,4 +166,21 @@ public class ClusterManager post(event); } } + + private static Collection<Partition> buildDefaultPartitions(Collection<ControllerNode> nodes) { + List<ControllerNode> sorted = new ArrayList<>(nodes); + Collections.sort(sorted, (o1, o2) -> o1.id().toString().compareTo(o2.id().toString())); + Collection<Partition> partitions = Lists.newArrayList(); + + int length = nodes.size(); + int count = 3; + for (int i = 0; i < length; i++) { + Set<NodeId> set = new HashSet<>(count); + for (int j = 0; j < count; j++) { + set.add(sorted.get((i + j) % length).id()); + } + partitions.add(new Partition("p" + (i + 1), set)); + } + return partitions; + } } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java new file mode 100644 index 00000000..a0f7a833 --- /dev/null +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/cluster/impl/ClusterMetadataManager.java @@ -0,0 +1,116 @@ +package org.onosproject.cluster.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Collection; +import java.util.Enumeration; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.IpAddress; +import org.onosproject.cluster.ClusterMetadata; +import org.onosproject.cluster.ClusterMetadataEvent; +import org.onosproject.cluster.ClusterMetadataEventListener; +import org.onosproject.cluster.ClusterMetadataService; +import org.onosproject.cluster.ClusterMetadataStore; +import org.onosproject.cluster.ClusterMetadataStoreDelegate; +import org.onosproject.cluster.ControllerNode; +import org.onosproject.event.AbstractListenerManager; +import org.onosproject.store.service.Versioned; +import org.slf4j.Logger; + +/** + * Implementation of ClusterMetadataService. + */ +@Component(immediate = true) +@Service +public class ClusterMetadataManager + extends AbstractListenerManager<ClusterMetadataEvent, ClusterMetadataEventListener> + implements ClusterMetadataService { + + private ControllerNode localNode; + private final Logger log = getLogger(getClass()); + + private ClusterMetadataStoreDelegate delegate = new InternalStoreDelegate(); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ClusterMetadataStore store; + + @Activate + public void activate() { + store.setDelegate(delegate); + eventDispatcher.addSink(ClusterMetadataEvent.class, listenerRegistry); + establishSelfIdentity(); + log.info("Started"); + } + + @Deactivate + public void deactivate() { + store.unsetDelegate(delegate); + eventDispatcher.removeSink(ClusterMetadataEvent.class); + log.info("Stopped"); + } + + @Override + public ClusterMetadata getClusterMetadata() { + return Versioned.valueOrElse(store.getClusterMetadata(), null); + } + + @Override + public ControllerNode getLocalNode() { + return localNode; + } + + @Override + public void setClusterMetadata(ClusterMetadata metadata) { + checkNotNull(metadata, "Cluster metadata cannot be null"); + store.setClusterMetadata(metadata); + } + + // Store delegate to re-post events emitted from the store. + private class InternalStoreDelegate implements ClusterMetadataStoreDelegate { + @Override + public void notify(ClusterMetadataEvent event) { + post(event); + } + } + + private IpAddress findLocalIp(Collection<ControllerNode> controllerNodes) throws SocketException { + Enumeration<NetworkInterface> interfaces = + NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface iface = interfaces.nextElement(); + Enumeration<InetAddress> inetAddresses = iface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + IpAddress ip = IpAddress.valueOf(inetAddresses.nextElement()); + if (controllerNodes.stream() + .map(ControllerNode::ip) + .anyMatch(nodeIp -> ip.equals(nodeIp))) { + return ip; + } + } + } + throw new IllegalStateException("Unable to determine local ip"); + } + + private void establishSelfIdentity() { + try { + IpAddress ip = findLocalIp(getClusterMetadata().getNodes()); + localNode = getClusterMetadata().getNodes() + .stream() + .filter(node -> node.ip().equals(ip)) + .findFirst() + .get(); + } catch (SocketException e) { + throw new IllegalStateException("Cannot determine local IP", e); + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java index 19377cf6..8f601497 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/device/impl/OpticalPortOperator.java @@ -112,10 +112,10 @@ public final class OpticalPortOperator implements ConfigOperator { return new OduCltPortDescription(port, odu.isEnabled(), odu.signalType(), sa); case PACKET: case FIBER: + case COPPER: return new DefaultPortDescription(port, descr.isEnabled(), descr.type(), descr.portSpeed(), sa); default: - // this includes copper ports. log.warn("Unsupported optical port type {} - can't update", descr.type()); return descr; } diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java index 137aca1e..0a1af6f5 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java @@ -29,9 +29,11 @@ import org.onosproject.net.flow.criteria.VlanPcpCriterion; import org.onosproject.net.flow.criteria.MplsCriterion; import org.onosproject.net.flow.criteria.IPCriterion; import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion; +import org.onosproject.net.flow.criteria.OduSignalIdCriterion; import org.onosproject.net.flow.criteria.Criteria; import org.onosproject.net.flow.instructions.Instruction; import org.onosproject.net.flow.instructions.L0ModificationInstruction; +import org.onosproject.net.flow.instructions.L1ModificationInstruction; import org.onosproject.net.flow.instructions.L2ModificationInstruction; import org.onosproject.net.flow.instructions.L3ModificationInstruction; import org.onosproject.net.flowobjective.DefaultForwardingObjective; @@ -155,6 +157,7 @@ public final class FlowObjectiveCompositionUtil { return treatmentBuilder.build(); } + //CHECKSTYLE:OFF public static TrafficSelector revertTreatmentSelector(TrafficTreatment trafficTreatment, TrafficSelector trafficSelector) { @@ -195,14 +198,30 @@ public final class FlowObjectiveCompositionUtil { } else { return null; } - } else { - break; } default: break; } break; } + case L1MODIFICATION: { + L1ModificationInstruction l1 = (L1ModificationInstruction) instruction; + switch (l1.subtype()) { + case ODU_SIGID: + if (criterionMap.containsKey(Criterion.Type.ODU_SIGID)) { + if (((OduSignalIdCriterion) criterionMap.get((Criterion.Type.ODU_SIGID))).oduSignalId() + .equals(((L1ModificationInstruction.ModOduSignalIdInstruction) l1) + .oduSignalId())) { + criterionMap.remove(Criterion.Type.ODU_SIGID); + } else { + return null; + } + } + default: + break; + } + break; + } case L2MODIFICATION: { L2ModificationInstruction l2 = (L2ModificationInstruction) instruction; switch (l2.subtype()) { @@ -344,6 +363,7 @@ public final class FlowObjectiveCompositionUtil { return selectorBuilder.build(); } + //CHECKSTYLE:ON public static Set<Criterion.Type> getTypeSet(TrafficSelector trafficSelector) { Set<Criterion.Type> typeSet = new HashSet<>(); diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java index 5fd1c85d..acc5a5d5 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java @@ -24,12 +24,14 @@ import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.onlab.packet.EthType; import org.onlab.packet.Ethernet; +import org.onlab.packet.MplsLabel; import org.onlab.packet.VlanId; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DeviceId; import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; import org.onosproject.net.PortNumber; import org.onosproject.net.flow.DefaultFlowRule; import org.onosproject.net.flow.DefaultTrafficSelector; @@ -46,24 +48,23 @@ import org.onosproject.net.intent.Intent; import org.onosproject.net.intent.IntentCompiler; import org.onosproject.net.intent.IntentExtensionService; import org.onosproject.net.intent.MplsPathIntent; -import org.onosproject.net.link.LinkStore; -import org.onosproject.net.resource.link.DefaultLinkResourceRequest; +import org.onosproject.net.newresource.ResourcePath; +import org.onosproject.net.newresource.ResourceService; import org.onosproject.net.resource.link.LinkResourceAllocations; -import org.onosproject.net.resource.link.LinkResourceRequest; -import org.onosproject.net.resource.link.LinkResourceService; -import org.onosproject.net.resource.link.MplsLabel; -import org.onosproject.net.resource.link.MplsLabelResourceAllocation; -import org.onosproject.net.resource.ResourceAllocation; -import org.onosproject.net.resource.ResourceType; import org.slf4j.Logger; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.net.LinkKey.linkKey; import static org.slf4j.LoggerFactory.getLogger; @Component(immediate = true) @@ -78,18 +79,15 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { protected CoreService coreService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected LinkResourceService resourceService; - - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected LinkStore linkStore; + protected ResourceService resourceService; protected ApplicationId appId; @Override public List<Intent> compile(MplsPathIntent intent, List<Intent> installable, Set<LinkResourceAllocations> resources) { - LinkResourceAllocations allocations = assignMplsLabel(intent); - List<FlowRule> rules = generateRules(intent, allocations); + Map<LinkKey, MplsLabel> labels = assignMplsLabel(intent); + List<FlowRule> rules = generateRules(intent, labels); return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources())); } @@ -105,39 +103,60 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { intentExtensionService.unregisterCompiler(MplsPathIntent.class); } - private LinkResourceAllocations assignMplsLabel(MplsPathIntent intent) { + private Map<LinkKey, MplsLabel> assignMplsLabel(MplsPathIntent intent) { // TODO: do it better... Suggestions? - Set<Link> linkRequest = Sets.newHashSetWithExpectedSize(intent.path() + Set<LinkKey> linkRequest = Sets.newHashSetWithExpectedSize(intent.path() .links().size() - 2); for (int i = 1; i <= intent.path().links().size() - 2; i++) { - Link link = intent.path().links().get(i); + LinkKey link = linkKey(intent.path().links().get(i)); linkRequest.add(link); // add the inverse link. I want that the label is reserved both for // the direct and inverse link - linkRequest.add(linkStore.getLink(link.dst(), link.src())); + linkRequest.add(linkKey(link.dst(), link.src())); } - LinkResourceRequest.Builder request = DefaultLinkResourceRequest - .builder(intent.id(), linkRequest).addMplsRequest(); - LinkResourceAllocations reqMpls = resourceService - .requestResources(request.build()); - return reqMpls; - } + Map<LinkKey, MplsLabel> labels = findMplsLabels(linkRequest); + if (labels.isEmpty()) { + return Collections.emptyMap(); + } + + List<ResourcePath> resources = labels.entrySet().stream() + .map(x -> new ResourcePath(linkKey(x.getKey().src(), x.getKey().src()), x.getValue())) + .collect(Collectors.toList()); + List<org.onosproject.net.newresource.ResourceAllocation> allocations = + resourceService.allocate(intent.id(), resources); + if (allocations.isEmpty()) { + Collections.emptyMap(); + } - private MplsLabel getMplsLabel(LinkResourceAllocations allocations, Link link) { - for (ResourceAllocation allocation : allocations - .getResourceAllocation(link)) { - if (allocation.type() == ResourceType.MPLS_LABEL) { - return ((MplsLabelResourceAllocation) allocation).mplsLabel(); + return labels; + } + private Map<LinkKey, MplsLabel> findMplsLabels(Set<LinkKey> links) { + Map<LinkKey, MplsLabel> labels = new HashMap<>(); + for (LinkKey link : links) { + Optional<MplsLabel> label = findMplsLabel(link); + if (label.isPresent()) { + labels.put(link, label.get()); } } - log.warn("MPLS label was not assigned successfully"); - return null; + + return labels; + } + + private Optional<MplsLabel> findMplsLabel(LinkKey link) { + return resourceService.getAvailableResources(new ResourcePath(link)).stream() + .filter(x -> x.lastComponent() instanceof MplsLabel) + .map(x -> (MplsLabel) x.lastComponent()) + .findFirst(); + } + + private MplsLabel getMplsLabel(Map<LinkKey, MplsLabel> labels, LinkKey link) { + return labels.get(link); } private List<FlowRule> generateRules(MplsPathIntent intent, - LinkResourceAllocations allocations) { + Map<LinkKey, MplsLabel> labels) { Iterator<Link> links = intent.path().links().iterator(); Link srcLink = links.next(); @@ -149,7 +168,7 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { // Ingress traffic // Get the new MPLS label - MplsLabel mpls = getMplsLabel(allocations, link); + MplsLabel mpls = getMplsLabel(labels, linkKey(link)); checkNotNull(mpls); MplsLabel prevLabel = mpls; rules.add(ingressFlow(prev.port(), link, intent, mpls)); @@ -163,7 +182,7 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { if (links.hasNext()) { // Transit traffic // Get the new MPLS label - mpls = getMplsLabel(allocations, link); + mpls = getMplsLabel(labels, linkKey(link)); checkNotNull(mpls); rules.add(transitFlow(prev.port(), link, intent, prevLabel, mpls)); @@ -181,7 +200,8 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { } private FlowRule ingressFlow(PortNumber inPort, Link link, - MplsPathIntent intent, MplsLabel label) { + MplsPathIntent intent, + MplsLabel label) { TrafficSelector.Builder ingressSelector = DefaultTrafficSelector .builder(intent.selector()); @@ -193,10 +213,10 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { .matchMplsLabel(intent.ingressLabel().get()); // Swap the MPLS label - treat.setMpls(label.label()); + treat.setMpls(label); } else { // Push and set the MPLS label - treat.pushMpls().setMpls(label.label()); + treat.pushMpls().setMpls(label); } // Add the output action treat.setOutput(link.src().port()); @@ -205,21 +225,21 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { } private FlowRule transitFlow(PortNumber inPort, Link link, - MplsPathIntent intent, - MplsLabel prevLabel, - MplsLabel outLabel) { + MplsPathIntent intent, + MplsLabel prevLabel, + MplsLabel outLabel) { // Ignore the ingress Traffic Selector and use only the MPLS label // assigned in the previous link TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); selector.matchInPort(inPort).matchEthType(Ethernet.MPLS_UNICAST) - .matchMplsLabel(prevLabel.label()); + .matchMplsLabel(prevLabel); TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(); // Set the new label only if the label on the packet is // different if (!prevLabel.equals(outLabel)) { - treat.setMpls(outLabel.label()); + treat.setMpls(outLabel); } treat.setOutput(link.src().port()); @@ -227,14 +247,14 @@ public class MplsPathIntentCompiler implements IntentCompiler<MplsPathIntent> { } private FlowRule egressFlow(PortNumber inPort, Link link, - MplsPathIntent intent, - MplsLabel prevLabel) { + MplsPathIntent intent, + MplsLabel prevLabel) { // egress point: either set the egress MPLS label or pop the // MPLS label based on the intent annotations TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); selector.matchInPort(inPort).matchEthType(Ethernet.MPLS_UNICAST) - .matchMplsLabel(prevLabel.label()); + .matchMplsLabel(prevLabel); // apply the intent's treatments TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder(intent diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java index c6eb7c5a..fce8498c 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java @@ -17,6 +17,7 @@ package org.onosproject.net.intent.impl.compiler; import org.apache.commons.lang3.tuple.Pair; import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Modified; import org.apache.felix.scr.annotations.Property; @@ -70,7 +71,7 @@ import static com.google.common.base.Preconditions.checkArgument; * An intent compiler for {@link org.onosproject.net.intent.OpticalCircuitIntent}. */ // For now, remove component designation until dependency on the new resource manager is available. -// @Component(immediate = true) +@Component(immediate = true) public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircuitIntent> { private static final Logger log = LoggerFactory.getLogger(OpticalCircuitIntentCompiler.class); diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java index eb5b4af8..d6725b7c 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java @@ -16,7 +16,11 @@ package org.onosproject.net.intent.impl.compiler; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; @@ -24,6 +28,7 @@ import org.onlab.util.Frequency; import org.onosproject.net.AnnotationKeys; import org.onosproject.net.ConnectPoint; import org.onosproject.net.DeviceId; +import org.onosproject.net.IndexedLambda; import org.onosproject.net.Link; import org.onosproject.net.OchPort; import org.onosproject.net.OchSignal; @@ -38,32 +43,29 @@ import org.onosproject.net.intent.IntentExtensionService; import org.onosproject.net.intent.OpticalConnectivityIntent; import org.onosproject.net.intent.OpticalPathIntent; import org.onosproject.net.intent.impl.IntentCompilationException; +import org.onosproject.net.newresource.ResourceAllocation; import org.onosproject.net.newresource.ResourcePath; import org.onosproject.net.newresource.ResourceService; -import org.onosproject.net.resource.ResourceType; -import org.onosproject.net.resource.link.DefaultLinkResourceRequest; -import org.onosproject.net.resource.link.LambdaResource; -import org.onosproject.net.resource.link.LambdaResourceAllocation; import org.onosproject.net.resource.link.LinkResourceAllocations; -import org.onosproject.net.resource.link.LinkResourceRequest; -import org.onosproject.net.resource.link.LinkResourceService; import org.onosproject.net.topology.LinkWeight; import org.onosproject.net.topology.Topology; import org.onosproject.net.topology.TopologyService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkArgument; +import static org.onosproject.net.LinkKey.linkKey; /** * An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}. */ // For now, remove component designation until dependency on the new resource manager is available. -// @Component(immediate = true) +@Component(immediate = true) public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> { protected static final Logger log = LoggerFactory.getLogger(OpticalConnectivityIntentCompiler.class); @@ -80,9 +82,6 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected ResourceService resourceService; - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected LinkResourceService linkResourceService; - @Activate public void activate() { intentManager.registerCompiler(OpticalConnectivityIntent.class, this); @@ -138,13 +137,12 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical ochSignal = srcOchPort.lambda(); } else { // Request and reserve lambda on path - LinkResourceAllocations linkAllocs = assignWavelength(intent, path); - if (linkAllocs == null) { + IndexedLambda lambda = assignWavelength(intent, path); + if (lambda == null) { continue; } - LambdaResourceAllocation lambdaAlloc = getWavelength(path, linkAllocs); OmsPort omsPort = (OmsPort) deviceService.getPort(path.src().deviceId(), path.src().port()); - ochSignal = new OchSignal(lambdaAlloc.lambda().toInt(), omsPort.maxFrequency(), omsPort.grid()); + ochSignal = new OchSignal((int) lambda.index(), omsPort.maxFrequency(), omsPort.grid()); } // Create installable optical path intent @@ -171,72 +169,46 @@ public class OpticalConnectivityIntentCompiler implements IntentCompiler<Optical } /** - * Find the lambda allocated to the path. - * - * @param path the path - * @param linkAllocs the link allocations - * @return lambda allocated to the given path - */ - private LambdaResourceAllocation getWavelength(Path path, LinkResourceAllocations linkAllocs) { - return path.links().stream() - .flatMap(x -> linkAllocs.getResourceAllocation(x).stream()) - .filter(x -> x.type() == ResourceType.LAMBDA) - .findFirst() - .map(x -> (LambdaResourceAllocation) x) - .orElse(null); - } - - /** * Request and reserve first available wavelength across path. * * @param path path in WDM topology - * @return first available lambda resource allocation + * @return first available lambda allocated */ - private LinkResourceAllocations assignWavelength(Intent intent, Path path) { - LinkResourceRequest.Builder request = - DefaultLinkResourceRequest.builder(intent.id(), path.links()) - .addLambdaRequest(); - - LinkResourceAllocations allocations = linkResourceService.requestResources(request.build()); - - if (!checkWavelengthContinuity(allocations, path)) { - linkResourceService.releaseResources(allocations); + private IndexedLambda assignWavelength(Intent intent, Path path) { + Set<IndexedLambda> lambdas = findCommonLambdasOverLinks(path.links()); + if (lambdas.isEmpty()) { return null; } - return allocations; - } + IndexedLambda minLambda = findFirstLambda(lambdas); + List<ResourcePath> lambdaResources = path.links().stream() + .map(x -> new ResourcePath(linkKey(x.src(), x.dst()))) + .map(x -> ResourcePath.child(x, minLambda)) + .collect(Collectors.toList()); - /** - * Checks wavelength continuity constraint across path, i.e., an identical lambda is used on all links. - * @return true if wavelength continuity is met, false otherwise - */ - private boolean checkWavelengthContinuity(LinkResourceAllocations allocations, Path path) { - if (allocations == null) { - return false; + List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), lambdaResources); + if (allocations.isEmpty()) { + log.info("Resource allocation for {} failed (resource request: {})", intent, lambdaResources); } - List<LambdaResource> lambdas = path.links().stream() - .flatMap(x -> allocations.getResourceAllocation(x).stream()) - .filter(x -> x.type() == ResourceType.LAMBDA) - .map(x -> ((LambdaResourceAllocation) x).lambda()) - .collect(Collectors.toList()); + return minLambda; + } - LambdaResource lambda = null; - for (LambdaResource nextLambda: lambdas) { - if (nextLambda == null) { - return false; - } - if (lambda == null) { - lambda = nextLambda; - continue; - } - if (!lambda.equals(nextLambda)) { - return false; - } - } + private Set<IndexedLambda> findCommonLambdasOverLinks(List<Link> links) { + return links.stream() + .map(x -> new ResourcePath(linkKey(x.src(), x.dst()))) + .map(resourceService::getAvailableResources) + .map(x -> Iterables.filter(x, r -> r.lastComponent() instanceof IndexedLambda)) + .map(x -> Iterables.transform(x, r -> (IndexedLambda) r.lastComponent())) + .map(x -> (Set<IndexedLambda>) ImmutableSet.copyOf(x)) + .reduce(Sets::intersection) + .orElse(Collections.emptySet()); + } - return true; + private IndexedLambda findFirstLambda(Set<IndexedLambda> lambdas) { + return lambdas.stream() + .findFirst() + .get(); } private ConnectPoint staticPort(ConnectPoint connectPoint) { diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java index 5226967f..10fe75ea 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/newresource/impl/ResourceManager.java @@ -41,7 +41,7 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * An implementation of ResourceService. */ -@Component(immediate = true, enabled = false) +@Component(immediate = true) @Service @Beta public final class ResourceManager implements ResourceService, ResourceAdminService { @@ -127,6 +127,17 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ } @Override + public Collection<ResourcePath> getAvailableResources(ResourcePath parent) { + checkNotNull(parent); + + Collection<ResourcePath> children = store.getChildResources(parent); + return children.stream() + // We access store twice in this method, then the store may be updated by others + .filter(x -> !store.getConsumer(x).isPresent()) + .collect(Collectors.toList()); + } + + @Override public boolean isAvailable(ResourcePath resource) { checkNotNull(resource); diff --git a/framework/src/onos/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java b/framework/src/onos/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java index 8b9952ed..7eb189e5 100644 --- a/framework/src/onos/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java +++ b/framework/src/onos/core/net/src/main/java/org/onosproject/net/resource/impl/LinkResourceManager.java @@ -31,7 +31,6 @@ import org.onosproject.net.resource.ResourceType; import org.onosproject.net.resource.link.BandwidthResourceAllocation; import org.onosproject.net.resource.link.BandwidthResourceRequest; import org.onosproject.net.resource.link.DefaultLinkResourceAllocations; -import org.onosproject.net.resource.link.LambdaResource; import org.onosproject.net.resource.link.LambdaResourceAllocation; import org.onosproject.net.resource.link.LambdaResourceRequest; import org.onosproject.net.resource.link.LinkResourceAllocations; @@ -46,15 +45,12 @@ import org.onosproject.net.resource.link.MplsLabelResourceAllocation; import org.onosproject.net.resource.link.MplsLabelResourceRequest; import org.slf4j.Logger; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; +import java.util.Optional; import java.util.Set; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; import static org.onosproject.security.AppGuard.checkPermission; import static org.slf4j.LoggerFactory.getLogger; import static org.onosproject.security.AppPermission.Type.*; @@ -86,67 +82,6 @@ public class LinkResourceManager log.info("Stopped"); } - /** - * Returns available lambdas on specified link. - * - * @param link the link - * @return available lambdas on specified link - */ - private Set<LambdaResource> getAvailableLambdas(Link link) { - checkNotNull(link); - Set<ResourceAllocation> resAllocs = store.getFreeResources(link); - if (resAllocs == null) { - return Collections.emptySet(); - } - Set<LambdaResource> lambdas = new HashSet<>(); - for (ResourceAllocation res : resAllocs) { - if (res.type() == ResourceType.LAMBDA) { - lambdas.add(((LambdaResourceAllocation) res).lambda()); - } - } - return lambdas; - } - - - /** - * Returns available lambdas on specified links. - * - * @param links the links - * @return available lambdas on specified links - */ - private Iterable<LambdaResource> getAvailableLambdas(Iterable<Link> links) { - checkNotNull(links); - Iterator<Link> i = links.iterator(); - checkArgument(i.hasNext()); - Set<LambdaResource> lambdas = new HashSet<>(getAvailableLambdas(i.next())); - while (i.hasNext()) { - lambdas.retainAll(getAvailableLambdas(i.next())); - } - return lambdas; - } - - - /** - * Returns available MPLS label on specified link. - * - * @param link the link - * @return available MPLS labels on specified link - */ - private Iterable<MplsLabel> getAvailableMplsLabels(Link link) { - Set<ResourceAllocation> resAllocs = store.getFreeResources(link); - if (resAllocs == null) { - return Collections.emptySet(); - } - Set<MplsLabel> mplsLabels = new HashSet<>(); - for (ResourceAllocation res : resAllocs) { - if (res.type() == ResourceType.MPLS_LABEL) { - - mplsLabels.add(((MplsLabelResourceAllocation) res).mplsLabel()); - } - } - - return mplsLabels; - } @Override public LinkResourceAllocations requestResources(LinkResourceRequest req) { @@ -164,26 +99,23 @@ public class LinkResourceManager allocs.add(new BandwidthResourceAllocation(br.bandwidth())); break; case LAMBDA: - Iterator<LambdaResource> lambdaIterator = - getAvailableLambdas(req.links()).iterator(); - if (lambdaIterator.hasNext()) { - allocs.add(new LambdaResourceAllocation(lambdaIterator.next())); - } else { - log.info("Failed to allocate lambda resource."); - return null; - } + LambdaResourceRequest lr = (LambdaResourceRequest) r; + allocs.add(new LambdaResourceAllocation(lr.lambda())); break; case MPLS_LABEL: for (Link link : req.links()) { if (allocsPerLink.get(link) == null) { allocsPerLink.put(link, new HashSet<>()); } - Iterator<MplsLabel> mplsIter = getAvailableMplsLabels(link) - .iterator(); - if (mplsIter.hasNext()) { - allocsPerLink.get(link) - .add(new MplsLabelResourceAllocation(mplsIter - .next())); + + Optional<MplsLabel> label = req.resources(link).stream() + .filter(x -> x.type() == ResourceType.MPLS_LABEL) + .map(x -> (MplsLabelResourceRequest) x) + .map(MplsLabelResourceRequest::mplsLabel) + .findFirst(); + + if (label.isPresent()) { + allocsPerLink.get(link).add(new MplsLabelResourceAllocation(label.get())); } else { log.info("Failed to allocate MPLS resource."); break; @@ -258,10 +190,12 @@ public class LinkResourceManager ((BandwidthResourceAllocation) alloc).bandwidth())); break; case LAMBDA: - result.add(new LambdaResourceRequest()); + result.add(new LambdaResourceRequest( + ((LambdaResourceAllocation) alloc).lambda())); break; case MPLS_LABEL: - result.add(new MplsLabelResourceRequest()); + result.add(new MplsLabelResourceRequest( + ((MplsLabelResourceAllocation) alloc).mplsLabel())); break; default: break; |