diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java index 62c027a32e..cb57aeeb51 100644 --- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java +++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/ConnectivityIntentCompiler.java @@ -94,6 +94,25 @@ public abstract class ConnectivityIntentCompiler * @return Path between the two * @throws PathNotFoundException if a path cannot be found */ + @Deprecated + protected Path getPathOrException(ConnectivityIntent intent, + ElementId one, ElementId two) { + Path path = getPath(intent, one, two); + if (path == null) { + throw new PathNotFoundException(one, two); + } + // TODO: let's be more intelligent about this eventually + return path; + } + + /** + * Computes a path between two ConnectPoints. + * + * @param intent intent on which behalf path is being computed + * @param one start of the path + * @param two end of the path + * @return Path between the two, or null if no path can be found + */ protected Path getPath(ConnectivityIntent intent, ElementId one, ElementId two) { Set paths = pathService.getPaths(one, two, weight(intent.constraints())); @@ -102,7 +121,7 @@ public abstract class ConnectivityIntentCompiler .filter(path -> checkPath(path, constraints)) .toList(); if (filtered.isEmpty()) { - throw new PathNotFoundException(one, two); + return null; } // TODO: let's be more intelligent about this eventually return filtered.iterator().next(); diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java index dad8e3bd90..f0f0046713 100644 --- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java +++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompiler.java @@ -82,9 +82,9 @@ public class HostToHostIntentCompiler } boolean isAsymmetric = intent.constraints().contains(new AsymmetricPathConstraint()); - Path pathOne = getPath(intent, intent.one(), intent.two()); + Path pathOne = getPathOrException(intent, intent.one(), intent.two()); Path pathTwo = isAsymmetric ? - getPath(intent, intent.two(), intent.one()) : invertPath(pathOne); + getPathOrException(intent, intent.two(), intent.one()) : invertPath(pathOne); Host one = hostService.getHost(intent.one()); Host two = hostService.getHost(intent.two()); diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsIntentCompiler.java index c8ccf6801a..4f466de160 100644 --- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsIntentCompiler.java +++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsIntentCompiler.java @@ -70,8 +70,8 @@ public class MplsIntentCompiler extends ConnectivityIntentCompiler } List links = new ArrayList<>(); - Path path = getPath(intent, ingressPoint.deviceId(), - egressPoint.deviceId()); + Path path = getPathOrException(intent, ingressPoint.deviceId(), + egressPoint.deviceId()); links.add(createEdgeLink(ingressPoint, true)); links.addAll(path.links()); diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompiler.java index cac5d6899b..758c21b5f7 100644 --- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompiler.java +++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompiler.java @@ -28,19 +28,16 @@ import org.onosproject.net.Link; import org.onosproject.net.Path; import org.onosproject.net.device.DeviceService; import org.onosproject.net.intent.Intent; -import org.onosproject.net.intent.IntentCompiler; import org.onosproject.net.intent.IntentException; import org.onosproject.net.intent.IntentExtensionService; import org.onosproject.net.intent.LinkCollectionIntent; import org.onosproject.net.intent.MultiPointToSinglePointIntent; import org.onosproject.net.intent.PointToPointIntent; -import org.onosproject.net.topology.PathService; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import static org.onosproject.net.intent.constraint.PartialFailureConstraint.intentAllowsPartialFailure; @@ -51,14 +48,11 @@ import static org.onosproject.net.intent.constraint.PartialFailureConstraint.int */ @Component(immediate = true) public class MultiPointToSinglePointIntentCompiler - implements IntentCompiler { + extends ConnectivityIntentCompiler { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected IntentExtensionService intentManager; - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) - protected PathService pathService; - @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected DeviceService deviceService; @@ -78,22 +72,23 @@ public class MultiPointToSinglePointIntentCompiler ConnectPoint egressPoint = intent.egressPoint(); final boolean allowMissingPaths = intentAllowsPartialFailure(intent); - boolean partialTree = false; - boolean anyMissingPaths = false; + boolean hasPaths = false; + boolean missingSomePaths = false; + for (ConnectPoint ingressPoint : intent.ingressPoints()) { if (ingressPoint.deviceId().equals(egressPoint.deviceId())) { if (deviceService.isAvailable(ingressPoint.deviceId())) { - partialTree = true; + hasPaths = true; } else { - anyMissingPaths = true; + missingSomePaths = true; } - continue; } - Path path = getPath(ingressPoint, intent.egressPoint()); + Path path = getPath(intent, ingressPoint.deviceId(), intent.egressPoint().deviceId()); + if (path != null) { - partialTree = true; + hasPaths = true; for (Link link : path.links()) { if (links.containsKey(link.dst().deviceId())) { @@ -107,14 +102,14 @@ public class MultiPointToSinglePointIntentCompiler links.put(link.src().deviceId(), link); } } else { - anyMissingPaths = true; + missingSomePaths = true; } } - if (!partialTree) { - throw new IntentException("Could not find any paths between ingress and egress points."); - } else if (!allowMissingPaths && anyMissingPaths) { - throw new IntentException("Missing some paths between ingress and egress ports."); + if (!hasPaths) { + throw new IntentException("Cannot find any path between ingress and egress points."); + } else if (!allowMissingPaths && missingSomePaths) { + throw new IntentException("Missing some paths between ingress and egress points."); } Intent result = LinkCollectionIntent.builder() @@ -131,20 +126,4 @@ public class MultiPointToSinglePointIntentCompiler return Collections.singletonList(result); } - - /** - * Computes a path between two ConnectPoints. - * - * @param one start of the path - * @param two end of the path - * @return Path between the two - */ - private Path getPath(ConnectPoint one, ConnectPoint two) { - Set paths = pathService.getPaths(one.deviceId(), two.deviceId()); - if (paths.isEmpty()) { - return null; - } - // TODO: let's be more intelligent about this eventually - return paths.iterator().next(); - } } diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java index a6fac6fa78..c3fc34878d 100644 --- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java +++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PointToPointIntentCompiler.java @@ -161,8 +161,8 @@ public class PointToPointIntentCompiler ConnectPoint egressPoint, PointToPointIntent intent) { List links = new ArrayList<>(); - Path path = getPath(intent, ingressPoint.deviceId(), - egressPoint.deviceId()); + Path path = getPathOrException(intent, ingressPoint.deviceId(), + egressPoint.deviceId()); links.add(createEdgeLink(ingressPoint, true)); links.addAll(path.links()); @@ -174,8 +174,8 @@ public class PointToPointIntentCompiler } private List createUnprotectedLinkCollectionIntent(PointToPointIntent intent) { - Path path = getPath(intent, intent.filteredIngressPoint().connectPoint().deviceId(), - intent.filteredEgressPoint().connectPoint().deviceId()); + Path path = getPathOrException(intent, intent.filteredIngressPoint().connectPoint().deviceId(), + intent.filteredEgressPoint().connectPoint().deviceId()); return asList(createLinkCollectionIntent(ImmutableSet.copyOf(path.links()), path.cost(), @@ -274,8 +274,8 @@ public class PointToPointIntentCompiler PointToPointIntent intent, List installable) { List links = new ArrayList<>(); - Path onlyPath = getPath(intent, ingressPoint.deviceId(), - egressPoint.deviceId()); + Path onlyPath = getPathOrException(intent, ingressPoint.deviceId(), + egressPoint.deviceId()); List reusableIntents = null; if (installable != null) { diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java index 22c4e89ac4..a3f7c49343 100644 --- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java +++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/SinglePointToMultiPointIntentCompiler.java @@ -19,31 +19,34 @@ import com.google.common.collect.ImmutableSet; 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.onosproject.net.ConnectPoint; import org.onosproject.net.Link; import org.onosproject.net.Path; +import org.onosproject.net.device.DeviceService; import org.onosproject.net.intent.Intent; +import org.onosproject.net.intent.IntentException; import org.onosproject.net.intent.LinkCollectionIntent; import org.onosproject.net.intent.SinglePointToMultiPointIntent; -import org.onosproject.net.provider.ProviderId; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import static org.onosproject.net.intent.constraint.PartialFailureConstraint.intentAllowsPartialFailure; + @Component(immediate = true) public class SinglePointToMultiPointIntentCompiler extends ConnectivityIntentCompiler { - // TODO: use off-the-shell core provider ID - private static final ProviderId PID = - new ProviderId("core", "org.onosproject.core", true); + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DeviceService deviceService; @Activate public void activate() { - intentManager.registerCompiler(SinglePointToMultiPointIntent.class, - this); + intentManager.registerCompiler(SinglePointToMultiPointIntent.class, this); } @Deactivate @@ -51,19 +54,40 @@ public class SinglePointToMultiPointIntentCompiler intentManager.unregisterCompiler(SinglePointToMultiPointIntent.class); } - @Override public List compile(SinglePointToMultiPointIntent intent, List installable) { Set links = new HashSet<>(); + final boolean allowMissingPaths = intentAllowsPartialFailure(intent); + boolean hasPaths = false; + boolean missingSomePaths = false; + for (ConnectPoint egressPoint : intent.egressPoints()) { if (egressPoint.deviceId().equals(intent.ingressPoint().deviceId())) { + // Do not need to look for paths, since ingress and egress + // devices are the same. + if (deviceService.isAvailable(egressPoint.deviceId())) { + hasPaths = true; + } else { + missingSomePaths = true; + } continue; } Path path = getPath(intent, intent.ingressPoint().deviceId(), egressPoint.deviceId()); - links.addAll(path.links()); + if (path != null) { + hasPaths = true; + links.addAll(path.links()); + } else { + missingSomePaths = true; + } + } + + if (!hasPaths) { + throw new IntentException("Cannot find any path between ingress and egress points."); + } else if (!allowMissingPaths && missingSomePaths) { + throw new IntentException("Missing some paths between ingress and egress points."); } Intent result = LinkCollectionIntent.builder() diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java index ce5f3b7021..2eb4d9f6d4 100644 --- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java +++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MultiPointToSinglePointIntentCompilerTest.java @@ -293,7 +293,6 @@ public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTes */ @Test public void testNonTrivialSelectorsIntent() { - Set ingress = ImmutableSet.of( new FilteredConnectPoint(connectPoint("of1", 1), DefaultTrafficSelector.builder().matchVlanId(VlanId.vlanId("100")).build()),