Implement path protection for point to point intents
Change-Id: I3f3627e7c2a7e3ab017e46655692ab70fdeae413
diff --git a/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java b/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java
index df90c41..921c279 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/FlowRuleIntent.java
@@ -35,6 +35,7 @@
public class FlowRuleIntent extends Intent {
private final Collection<FlowRule> flowRules;
+ private PathIntent.ProtectionType type;
/**
* Creates a flow rule intent with the specified flow rules and resources.
@@ -48,7 +49,19 @@
}
/**
- * Creates an flow rule intent with the specified key, flow rules to be set, and
+ * Creates a flow rule intent with the specified flow rules, resources, and type.
+ *
+ * @param appId application id
+ * @param flowRules flow rules to be set
+ * @param resources network resource to be set
+ */
+ public FlowRuleIntent(ApplicationId appId, List<FlowRule> flowRules, Collection<NetworkResource> resources,
+ PathIntent.ProtectionType type) {
+ this(appId, null, flowRules, resources, type);
+ }
+
+ /**
+ * Creates a flow rule intent with the specified key, flow rules to be set, and
* required network resources.
*
* @param appId application id
@@ -58,8 +71,32 @@
*/
public FlowRuleIntent(ApplicationId appId, Key key, Collection<FlowRule> flowRules,
Collection<NetworkResource> resources) {
+ this(appId, key, flowRules, resources, PathIntent.ProtectionType.PRIMARY);
+ }
+
+ /**
+ * Creates a flow rule intent with the specified key, flow rules to be set, and
+ * required network resources.
+ *
+ * @param appId application id
+ * @param key key
+ * @param flowRules flow rules
+ * @param resources network resources
+ */
+ public FlowRuleIntent(ApplicationId appId, Key key, Collection<FlowRule> flowRules,
+ Collection<NetworkResource> resources, PathIntent.ProtectionType primary) {
super(appId, key, resources, DEFAULT_INTENT_PRIORITY);
this.flowRules = ImmutableList.copyOf(checkNotNull(flowRules));
+ this.type = primary;
+ }
+
+ /**
+ * Creates a flow rule intent with all the same characteristics as the given
+ * one except for the flow rule type.
+ */
+ public FlowRuleIntent(FlowRuleIntent intent, PathIntent.ProtectionType type) {
+ this(intent.appId(), intent.key(), intent.flowRules(),
+ intent.resources(), type);
}
/**
@@ -68,6 +105,7 @@
protected FlowRuleIntent() {
super();
this.flowRules = null;
+ this.type = PathIntent.ProtectionType.PRIMARY;
}
/**
@@ -84,6 +122,10 @@
return true;
}
+ public PathIntent.ProtectionType type() {
+ return type;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java b/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java
index 63fff1d..f2a0e45 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentCompiler.java
@@ -31,7 +31,7 @@
* Compiles the specified intent into other intents.
*
* @param intent intent to be compiled
- * @param installable previously compilation result; optional
+ * @param installable previous compilation result; optional
* @return list of resulting intents
* @throws IntentException if issues are encountered while compiling the intent
*/
diff --git a/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java b/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
index b674c06..7ac22b3 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
@@ -36,10 +36,11 @@
public class PathIntent extends ConnectivityIntent {
private final Path path;
+ private ProtectionType type;
/**
* Creates a new point-to-point intent with the supplied ingress/egress
- * ports and using the specified explicit path.
+ * ports and using the specified explicit path. Path is primary by default.
*
* @param appId application identifier
* @param key intent key
@@ -57,10 +58,38 @@
Path path,
List<Constraint> constraints,
int priority) {
+ this(appId, key, selector, treatment, path, constraints, priority,
+ ProtectionType.PRIMARY);
+ }
+
+ /**
+ * Creates a new point-to-point intent with the supplied ingress/egress
+ * ports and using the specified explicit path, which can be classified
+ * as PRIMARY or BACKUP.
+ *
+ * @param appId application identifier
+ * @param key intent key
+ * @param selector traffic selector
+ * @param treatment treatment
+ * @param path traversed links
+ * @param constraints optional list of constraints
+ * @param priority priority to use for the generated flows
+ * @param type PRIMARY or BACKUP
+ * @throws NullPointerException {@code path} is null
+ */
+ protected PathIntent(ApplicationId appId,
+ Key key,
+ TrafficSelector selector,
+ TrafficTreatment treatment,
+ Path path,
+ List<Constraint> constraints,
+ int priority,
+ ProtectionType type) {
super(appId, key, resources(path.links()), selector, treatment, constraints,
- priority);
+ priority);
PathIntent.validate(path.links());
this.path = path;
+ this.type = type;
}
/**
@@ -69,6 +98,7 @@
protected PathIntent() {
super();
this.path = null;
+ this.type = ProtectionType.PRIMARY;
}
/**
@@ -85,6 +115,7 @@
*/
public static class Builder extends ConnectivityIntent.Builder {
Path path;
+ ProtectionType type;
protected Builder() {
// Hide default constructor
@@ -131,6 +162,11 @@
return this;
}
+ public Builder setType(ProtectionType type) {
+ this.type = type;
+ return this;
+ }
+
/**
* Builds a path intent from the accumulated parameters.
*
@@ -145,7 +181,8 @@
treatment,
path,
constraints,
- priority
+ priority,
+ type == null ? ProtectionType.PRIMARY : type
);
}
}
@@ -183,6 +220,10 @@
return path;
}
+ public ProtectionType type() {
+ return type;
+ }
+
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
@@ -195,7 +236,25 @@
.add("treatment", treatment())
.add("constraints", constraints())
.add("path", path)
+ .add("type", type)
.toString();
}
+ // for path protection purposes
+ public enum ProtectionType {
+ /**
+ * Intent within primary path.
+ */
+ PRIMARY,
+ /**
+ * Intent within backup path.
+ */
+ BACKUP,
+ /**
+ * Intent whose flow rule serves as the fast failover
+ * between primary and backup paths.
+ */
+ FAILOVER
+ }
+
}
diff --git a/core/api/src/main/java/org/onosproject/net/intent/constraint/ProtectionConstraint.java b/core/api/src/main/java/org/onosproject/net/intent/constraint/ProtectionConstraint.java
new file mode 100644
index 0000000..d4d2c74
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/intent/constraint/ProtectionConstraint.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.constraint;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.ResourceContext;
+
+/**
+ * Constraint that determines whether to employ path protection.
+ */
+@Beta
+public class ProtectionConstraint implements Constraint {
+ // doesn't use LinkResourceService
+ @Override
+ public double cost(Link link, ResourceContext context) {
+ return 1;
+ }
+
+ // doesn't use LinkResourceService
+ @Override
+ public boolean validate(Path path, ResourceContext context) {
+ return true;
+ }
+
+ /**
+ * Determines whether to utilize path protection for the given intent.
+ *
+ * @param intent intent to be inspected
+ * @return whether the intent has a ProtectionConstraint
+ */
+ public static boolean requireProtectedPath(Intent intent) {
+ if (intent instanceof PointToPointIntent) {
+ PointToPointIntent pointToPointIntent = (PointToPointIntent) intent;
+ return pointToPointIntent.constraints().stream()
+ .anyMatch(p -> p instanceof ProtectionConstraint);
+ }
+ return false;
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java
index a87263a..d3db258 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/PointToPointIntentTest.java
@@ -26,7 +26,7 @@
public class PointToPointIntentTest extends ConnectivityIntentTest {
/**
- * Checks that the MultiPointToSinglePointIntent class is immutable.
+ * Checks that the PointToPointIntent class is immutable.
*/
@Test
public void checkImmutability() {