Merge remote-tracking branch 'origin/master'
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/IntentIdCompleter.java b/cli/src/main/java/org/onlab/onos/cli/net/IntentIdCompleter.java
index 5e217d6..5d2e952 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/IntentIdCompleter.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/IntentIdCompleter.java
@@ -24,7 +24,7 @@
Iterator<Intent> it = service.getIntents().iterator();
SortedSet<String> strings = delegate.getStrings();
while (it.hasNext()) {
- strings.add(it.next().getId().toString());
+ strings.add(it.next().id().toString());
}
// Now let the completer do the work for figuring out what to offer.
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java
index a7d260d..a0c9845 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/IntentsListCommand.java
@@ -17,8 +17,8 @@
protected void execute() {
IntentService service = get(IntentService.class);
for (Intent intent : service.getIntents()) {
- IntentState state = service.getIntentState(intent.getId());
- print("%s %s %s", intent.getId(), state, intent);
+ IntentState state = service.getIntentState(intent.id());
+ print("%s %s %s", intent.id(), state, intent);
}
}
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/WipeOutCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/WipeOutCommand.java
index 3f90f2a..766a849 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/WipeOutCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/WipeOutCommand.java
@@ -34,7 +34,7 @@
IntentService intentService = get(IntentService.class);
for (Intent intent : intentService.getIntents()) {
- if (intentService.getIntentState(intent.getId()) == IntentState.INSTALLED) {
+ if (intentService.getIntentState(intent.id()) == IntentState.INSTALLED) {
intentService.withdraw(intent);
}
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/AbstractIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/AbstractIntent.java
index eefe750..c8a4a05 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/AbstractIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/AbstractIntent.java
@@ -24,7 +24,7 @@
}
@Override
- public IntentId getId() {
+ public IntentId id() {
return id;
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/ConnectivityIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/ConnectivityIntent.java
index 70cec58..ed0c5cc 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/ConnectivityIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/ConnectivityIntent.java
@@ -53,7 +53,7 @@
*
* @return traffic match
*/
- public TrafficSelector getTrafficSelector() {
+ public TrafficSelector selector() {
return selector;
}
@@ -62,7 +62,7 @@
*
* @return applied action
*/
- public TrafficTreatment getTrafficTreatment() {
+ public TrafficTreatment treatment() {
return treatment;
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
index 7cef3da..f420fc2 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
@@ -80,9 +80,9 @@
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
- .add("id", getId())
- .add("selector", getTrafficSelector())
- .add("treatment", getTrafficTreatment())
+ .add("id", id())
+ .add("selector", selector())
+ .add("treatment", treatment())
.add("one", one)
.add("two", two)
.toString();
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java b/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
index d4c630a..3e339d1 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
@@ -11,5 +11,5 @@
*
* @return intent identifier
*/
- IntentId getId();
+ IntentId id();
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentEvent.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentEvent.java
index c98e788..742a590 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentEvent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentEvent.java
@@ -1,106 +1,55 @@
package org.onlab.onos.net.intent;
-import com.google.common.base.MoreObjects;
import org.onlab.onos.event.AbstractEvent;
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
/**
* A class to represent an intent related event.
*/
-public class IntentEvent extends AbstractEvent<IntentState, Intent> {
+public class IntentEvent extends AbstractEvent<IntentEvent.Type, Intent> {
- // TODO: determine a suitable parent class; if one does not exist, consider
- // introducing one
+ public enum Type {
+ /**
+ * Signifies that a new intent has been submitted to the system.
+ */
+ SUBMITTED,
- private final long time;
- private final Intent intent;
- private final IntentState state;
- private final IntentState previous;
+ /**
+ * Signifies that an intent has been successfully installed.
+ */
+ INSTALLED,
- /**
- * Creates an event describing a state change of an intent.
- *
- * @param intent subject intent
- * @param state new intent state
- * @param previous previous intent state
- * @param time time the event created in milliseconds since start of epoch
- * @throws NullPointerException if the intent or state is null
- */
- public IntentEvent(Intent intent, IntentState state, IntentState previous, long time) {
- super(state, intent);
- this.intent = checkNotNull(intent);
- this.state = checkNotNull(state);
- this.previous = previous;
- this.time = time;
+ /**
+ * Signifies that an intent has failed compilation or installation.
+ */
+ FAILED,
+
+ /**
+ * Signifies that an intent has been withdrawn from the system.
+ */
+ WITHDRAWN
}
/**
- * Returns the state of the intent which caused the event.
+ * Creates an event of a given type and for the specified intent and the
+ * current time.
*
- * @return the state of the intent
+ * @param type event type
+ * @param intent subject intent
+ * @param time time the event created in milliseconds since start of epoch
*/
- public IntentState getState() {
- return state;
+ public IntentEvent(Type type, Intent intent, long time) {
+ super(type, intent, time);
}
/**
- * Returns the previous state of the intent which caused the event.
+ * Creates an event of a given type and for the specified intent and the
+ * current time.
*
- * @return the previous state of the intent
+ * @param type event type
+ * @param intent subject intent
*/
- public IntentState getPreviousState() {
- return previous;
+ public IntentEvent(Type type, Intent intent) {
+ super(type, intent);
}
- /**
- * Returns the intent associated with the event.
- *
- * @return the intent
- */
- public Intent getIntent() {
- return intent;
- }
-
- /**
- * Returns the time at which the event was created.
- *
- * @return the time in milliseconds since start of epoch
- */
- public long getTime() {
- return time;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- IntentEvent that = (IntentEvent) o;
- return Objects.equals(this.intent, that.intent)
- && Objects.equals(this.state, that.state)
- && Objects.equals(this.previous, that.previous)
- && Objects.equals(this.time, that.time);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(intent, state, previous, time);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass())
- .add("intent", intent)
- .add("state", state)
- .add("previous", previous)
- .add("time", time)
- .toString();
- }
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentState.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentState.java
index 20476e5..bd140af 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentState.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentState.java
@@ -1,55 +1,70 @@
package org.onlab.onos.net.intent;
/**
- * This class represents the states of an intent.
- *
- * <p>
- * Note: The state is expressed as enum, but there is possibility
- * in the future that we define specific class instead of enum to improve
- * the extensibility of state definition.
- * </p>
+ * Representation of the phases an intent may attain during its lifecycle.
*/
public enum IntentState {
- // FIXME: requires discussion on State vs. EventType and a solid state-transition diagram
- // TODO: consider the impact of conflict detection
- // TODO: consider the impact that external events affect an installed intent
+
/**
- * The beginning state.
- *
+ * Signifies that the intent has been submitted and will start compiling
+ * shortly. However, this compilation may not necessarily occur on the
+ * local controller instance.
+ * <p/>
* All intent in the runtime take this state first.
*/
SUBMITTED,
/**
- * The intent compilation has been completed.
- *
- * An intent translation graph (tree) is completely created.
- * Leaves of the graph are installable intent type.
+ * Signifies that the intent is being compiled into installable intents.
+ * This is a transitional state after which the intent will enter either
+ * {@link #FAILED} state or {@link #INSTALLING} state.
*/
- COMPILED,
+ COMPILING,
/**
- * The intent has been successfully installed.
+ * Signifies that the resulting installable intents are being installed
+ * into the network environment. This is a transitional state after which
+ * the intent will enter either {@link #INSTALLED} state or
+ * {@link #RECOMPILING} state.
+ */
+ INSTALLING,
+
+ /**
+ * The intent has been successfully installed. This is a state where the
+ * intent may remain parked until it is withdrawn by the application or
+ * until the network environment changes in some way to make the original
+ * set of installable intents untenable.
*/
INSTALLED,
/**
- * The intent is being withdrawn.
- *
- * When {@link IntentService#withdraw(Intent)} is called,
- * the intent takes this state first.
+ * Signifies that the intent is being recompiled into installable intents
+ * as an attempt to adapt to an anomaly in the network environment.
+ * This is a transitional state after which the intent will enter either
+ * {@link #FAILED} state or {@link #INSTALLING} state.
+ * <p/>
+ * Exit to the {@link #FAILED} state may be caused by failure to compile
+ * or by compiling into the same set of installable intents which have
+ * previously failed to be installed.
+ */
+ RECOMPILING,
+
+ /**
+ * Indicates that the intent is being withdrawn. This is a transitional
+ * state, triggered by invocation of the
+ * {@link IntentService#withdraw(Intent)} but one with only one outcome,
+ * which is the the intent being placed in the {@link #WITHDRAWN} state.
*/
WITHDRAWING,
/**
- * The intent has been successfully withdrawn.
+ * Indicates that the intent has been successfully withdrawn.
*/
WITHDRAWN,
/**
- * The intent has failed to be compiled, installed, or withdrawn.
- *
- * When the intent failed to be withdrawn, it is still, at least partially installed.
+ * Signifies that the intent has failed compiling, installing or
+ * recompiling states.
*/
- FAILED,
+ FAILED
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentStore.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentStore.java
index 037f179..fc023bb 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentStore.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentStore.java
@@ -10,10 +10,16 @@
public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
/**
- * Creates a new intent.
+ * Submits a new intent into the store. If the returned event is not
+ * null, the manager is expected to dispatch the event and then to kick
+ * off intent compilation process. Otherwise, another node has been elected
+ * to perform the compilation process and the node will learn about
+ * the submittal and results of the intent compilation via the delegate
+ * mechanism.
*
- * @param intent intent
- * @return appropriate event or null if no change resulted
+ * @param intent intent to be submitted
+ * @return event indicating the intent was submitted or null if no
+ * change resulted, e.g. duplicate intent
*/
IntentEvent createIntent(Intent intent);
@@ -68,10 +74,9 @@
*
* @param intentId original intent identifier
* @param installableIntents compiled installable intents
- * @return compiled state transition event
*/
- IntentEvent addInstallableIntents(IntentId intentId,
- List<InstallableIntent> installableIntents);
+ void addInstallableIntents(IntentId intentId,
+ List<InstallableIntent> installableIntents);
/**
* Returns the list of the installable events associated with the specified
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
index af1e84b..be8d309 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
@@ -1,25 +1,24 @@
package org.onlab.onos.net.intent;
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-import java.util.Set;
-
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.Sets;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.Sets;
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
/**
* Abstraction of multiple source to single destination connectivity intent.
*/
public class MultiPointToSinglePointIntent extends ConnectivityIntent {
- private final Set<ConnectPoint> ingressPorts;
- private final ConnectPoint egressPort;
+ private final Set<ConnectPoint> ingressPoints;
+ private final ConnectPoint egressPoint;
/**
* Creates a new multi-to-single point connectivity intent for the specified
@@ -28,25 +27,25 @@
* @param id intent identifier
* @param match traffic match
* @param action action
- * @param ingressPorts set of ports from which ingress traffic originates
- * @param egressPort port to which traffic will egress
- * @throws NullPointerException if {@code ingressPorts} or
- * {@code egressPort} is null.
- * @throws IllegalArgumentException if the size of {@code ingressPorts} is
+ * @param ingressPoints set of ports from which ingress traffic originates
+ * @param egressPoint port to which traffic will egress
+ * @throws NullPointerException if {@code ingressPoints} or
+ * {@code egressPoint} is null.
+ * @throws IllegalArgumentException if the size of {@code ingressPoints} is
* not more than 1
*/
public MultiPointToSinglePointIntent(IntentId id, TrafficSelector match,
TrafficTreatment action,
- Set<ConnectPoint> ingressPorts,
- ConnectPoint egressPort) {
+ Set<ConnectPoint> ingressPoints,
+ ConnectPoint egressPoint) {
super(id, match, action);
- checkNotNull(ingressPorts);
- checkArgument(!ingressPorts.isEmpty(),
+ checkNotNull(ingressPoints);
+ checkArgument(!ingressPoints.isEmpty(),
"there should be at least one ingress port");
- this.ingressPorts = Sets.newHashSet(ingressPorts);
- this.egressPort = checkNotNull(egressPort);
+ this.ingressPoints = Sets.newHashSet(ingressPoints);
+ this.egressPoint = checkNotNull(egressPoint);
}
/**
@@ -54,8 +53,8 @@
*/
protected MultiPointToSinglePointIntent() {
super();
- this.ingressPorts = null;
- this.egressPort = null;
+ this.ingressPoints = null;
+ this.egressPoint = null;
}
/**
@@ -64,8 +63,8 @@
*
* @return set of ingress ports
*/
- public Set<ConnectPoint> getIngressPorts() {
- return ingressPorts;
+ public Set<ConnectPoint> ingressPoints() {
+ return ingressPoints;
}
/**
@@ -73,8 +72,8 @@
*
* @return egress port
*/
- public ConnectPoint getEgressPort() {
- return egressPort;
+ public ConnectPoint egressPoint() {
+ return egressPoint;
}
@Override
@@ -90,23 +89,23 @@
}
MultiPointToSinglePointIntent that = (MultiPointToSinglePointIntent) o;
- return Objects.equals(this.ingressPorts, that.ingressPorts)
- && Objects.equals(this.egressPort, that.egressPort);
+ return Objects.equals(this.ingressPoints, that.ingressPoints)
+ && Objects.equals(this.egressPoint, that.egressPoint);
}
@Override
public int hashCode() {
- return Objects.hash(super.hashCode(), ingressPorts, egressPort);
+ return Objects.hash(super.hashCode(), ingressPoints, egressPoint);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
- .add("id", getId())
- .add("match", getTrafficSelector())
- .add("action", getTrafficTreatment())
- .add("ingressPorts", getIngressPorts())
- .add("egressPort", getEgressPort())
+ .add("id", id())
+ .add("match", selector())
+ .add("action", treatment())
+ .add("ingressPoints", ingressPoints())
+ .add("egressPoint", egressPoint())
.toString();
}
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/PathIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/PathIntent.java
index 4c3486f..ff2e917 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/PathIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/PathIntent.java
@@ -46,7 +46,7 @@
*
* @return traversed links
*/
- public Path getPath() {
+ public Path path() {
return path;
}
@@ -79,11 +79,11 @@
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
- .add("id", getId())
- .add("match", getTrafficSelector())
- .add("action", getTrafficTreatment())
- .add("ingressPort", getIngressPort())
- .add("egressPort", getEgressPort())
+ .add("id", id())
+ .add("match", selector())
+ .add("action", treatment())
+ .add("ingressPort", ingressPoint())
+ .add("egressPort", egressPoint())
.add("path", path)
.toString();
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntent.java
index 4c86bae..7b7c18a 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntent.java
@@ -14,27 +14,27 @@
*/
public class PointToPointIntent extends ConnectivityIntent {
- private final ConnectPoint ingressPort;
- private final ConnectPoint egressPort;
+ private final ConnectPoint ingressPoint;
+ private final ConnectPoint egressPoint;
/**
* Creates a new point-to-point intent with the supplied ingress/egress
* ports.
*
- * @param id intent identifier
- * @param selector traffic selector
- * @param treatment treatment
- * @param ingressPort ingress port
- * @param egressPort egress port
- * @throws NullPointerException if {@code ingressPort} or {@code egressPort} is null.
+ * @param id intent identifier
+ * @param selector traffic selector
+ * @param treatment treatment
+ * @param ingressPoint ingress port
+ * @param egressPoint egress port
+ * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
*/
public PointToPointIntent(IntentId id, TrafficSelector selector,
TrafficTreatment treatment,
- ConnectPoint ingressPort,
- ConnectPoint egressPort) {
+ ConnectPoint ingressPoint,
+ ConnectPoint egressPoint) {
super(id, selector, treatment);
- this.ingressPort = checkNotNull(ingressPort);
- this.egressPort = checkNotNull(egressPort);
+ this.ingressPoint = checkNotNull(ingressPoint);
+ this.egressPoint = checkNotNull(egressPoint);
}
/**
@@ -42,8 +42,8 @@
*/
protected PointToPointIntent() {
super();
- this.ingressPort = null;
- this.egressPort = null;
+ this.ingressPoint = null;
+ this.egressPoint = null;
}
/**
@@ -52,8 +52,8 @@
*
* @return ingress port
*/
- public ConnectPoint getIngressPort() {
- return ingressPort;
+ public ConnectPoint ingressPoint() {
+ return ingressPoint;
}
/**
@@ -61,8 +61,8 @@
*
* @return egress port
*/
- public ConnectPoint getEgressPort() {
- return egressPort;
+ public ConnectPoint egressPoint() {
+ return egressPoint;
}
@Override
@@ -78,23 +78,23 @@
}
PointToPointIntent that = (PointToPointIntent) o;
- return Objects.equals(this.ingressPort, that.ingressPort)
- && Objects.equals(this.egressPort, that.egressPort);
+ return Objects.equals(this.ingressPoint, that.ingressPoint)
+ && Objects.equals(this.egressPoint, that.egressPoint);
}
@Override
public int hashCode() {
- return Objects.hash(super.hashCode(), ingressPort, egressPort);
+ return Objects.hash(super.hashCode(), ingressPoint, egressPoint);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
- .add("id", getId())
- .add("match", getTrafficSelector())
- .add("action", getTrafficTreatment())
- .add("ingressPort", ingressPort)
- .add("egressPort", egressPort)
+ .add("id", id())
+ .add("match", selector())
+ .add("action", treatment())
+ .add("ingressPoint", ingressPoint)
+ .add("egressPoints", egressPoint)
.toString();
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntent.java
index af2616b..2a17bfe 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntent.java
@@ -17,34 +17,34 @@
*/
public class SinglePointToMultiPointIntent extends ConnectivityIntent {
- private final ConnectPoint ingressPort;
- private final Set<ConnectPoint> egressPorts;
+ private final ConnectPoint ingressPoint;
+ private final Set<ConnectPoint> egressPoints;
/**
* Creates a new single-to-multi point connectivity intent.
*
- * @param id intent identifier
- * @param selector traffic selector
- * @param treatment treatment
- * @param ingressPort port on which traffic will ingress
- * @param egressPorts set of ports on which traffic will egress
- * @throws NullPointerException if {@code ingressPort} or
- * {@code egressPorts} is null
- * @throws IllegalArgumentException if the size of {@code egressPorts} is
+ * @param id intent identifier
+ * @param selector traffic selector
+ * @param treatment treatment
+ * @param ingressPoint port on which traffic will ingress
+ * @param egressPoints set of ports on which traffic will egress
+ * @throws NullPointerException if {@code ingressPoint} or
+ * {@code egressPoints} is null
+ * @throws IllegalArgumentException if the size of {@code egressPoints} is
* not more than 1
*/
public SinglePointToMultiPointIntent(IntentId id, TrafficSelector selector,
TrafficTreatment treatment,
- ConnectPoint ingressPort,
- Set<ConnectPoint> egressPorts) {
+ ConnectPoint ingressPoint,
+ Set<ConnectPoint> egressPoints) {
super(id, selector, treatment);
- checkNotNull(egressPorts);
- checkArgument(!egressPorts.isEmpty(),
+ checkNotNull(egressPoints);
+ checkArgument(!egressPoints.isEmpty(),
"there should be at least one egress port");
- this.ingressPort = checkNotNull(ingressPort);
- this.egressPorts = Sets.newHashSet(egressPorts);
+ this.ingressPoint = checkNotNull(ingressPoint);
+ this.egressPoints = Sets.newHashSet(egressPoints);
}
/**
@@ -52,8 +52,8 @@
*/
protected SinglePointToMultiPointIntent() {
super();
- this.ingressPort = null;
- this.egressPorts = null;
+ this.ingressPoint = null;
+ this.egressPoints = null;
}
/**
@@ -61,8 +61,8 @@
*
* @return ingress port
*/
- public ConnectPoint getIngressPort() {
- return ingressPort;
+ public ConnectPoint ingressPoint() {
+ return ingressPoint;
}
/**
@@ -70,8 +70,8 @@
*
* @return set of egress ports
*/
- public Set<ConnectPoint> getEgressPorts() {
- return egressPorts;
+ public Set<ConnectPoint> egressPoints() {
+ return egressPoints;
}
@Override
@@ -87,23 +87,23 @@
}
SinglePointToMultiPointIntent that = (SinglePointToMultiPointIntent) o;
- return Objects.equals(this.ingressPort, that.ingressPort)
- && Objects.equals(this.egressPorts, that.egressPorts);
+ return Objects.equals(this.ingressPoint, that.ingressPoint)
+ && Objects.equals(this.egressPoints, that.egressPoints);
}
@Override
public int hashCode() {
- return Objects.hash(super.hashCode(), ingressPort, egressPorts);
+ return Objects.hash(super.hashCode(), ingressPoint, egressPoints);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
- .add("id", getId())
- .add("match", getTrafficSelector())
- .add("action", getTrafficTreatment())
- .add("ingressPort", ingressPort)
- .add("egressPort", egressPorts)
+ .add("id", id())
+ .add("match", selector())
+ .add("action", treatment())
+ .add("ingressPoint", ingressPoint)
+ .add("egressPort", egressPoints)
.toString();
}
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java b/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
index 349749e..9afccc8 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
@@ -40,8 +40,7 @@
@Override
public void run() {
try {
- List<InstallableIntent> installable = compileIntent(intent);
- installIntents(intent, installable);
+ executeCompilingPhase(intent);
} catch (IntentException e) {
exceptions.add(e);
}
@@ -55,8 +54,8 @@
@Override
public void run() {
try {
- List<InstallableIntent> installable = getInstallable(intent.getId());
- uninstallIntents(intent, installable);
+ List<InstallableIntent> installable = getInstallable(intent.id());
+ executeWithdrawingPhase(intent, installable);
} catch (IntentException e) {
exceptions.add(e);
}
@@ -84,53 +83,60 @@
return installer;
}
- private <T extends Intent> List<InstallableIntent> compileIntent(T intent) {
+ private <T extends Intent> void executeCompilingPhase(T intent) {
+ setState(intent, IntentState.COMPILING);
try {
// For the fake, we compile using a single level pass
List<InstallableIntent> installable = new ArrayList<>();
for (Intent compiled : getCompiler(intent).compile(intent)) {
installable.add((InstallableIntent) compiled);
}
- setState(intent, IntentState.COMPILED);
- return installable;
+ executeInstallingPhase(intent, installable);
+
} catch (IntentException e) {
setState(intent, IntentState.FAILED);
- throw e;
+ dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
}
}
- private void installIntents(Intent intent, List<InstallableIntent> installable) {
+ private void executeInstallingPhase(Intent intent,
+ List<InstallableIntent> installable) {
+ setState(intent, IntentState.INSTALLING);
try {
for (InstallableIntent ii : installable) {
registerSubclassInstallerIfNeeded(ii);
getInstaller(ii).install(ii);
}
setState(intent, IntentState.INSTALLED);
- putInstallable(intent.getId(), installable);
+ putInstallable(intent.id(), installable);
+ dispatch(new IntentEvent(IntentEvent.Type.INSTALLED, intent));
+
} catch (IntentException e) {
setState(intent, IntentState.FAILED);
- throw e;
+ dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
}
}
- private void uninstallIntents(Intent intent, List<InstallableIntent> installable) {
+ private void executeWithdrawingPhase(Intent intent,
+ List<InstallableIntent> installable) {
+ setState(intent, IntentState.WITHDRAWING);
try {
for (InstallableIntent ii : installable) {
getInstaller(ii).uninstall(ii);
}
+ removeInstallable(intent.id());
setState(intent, IntentState.WITHDRAWN);
- removeInstallable(intent.getId());
+ dispatch(new IntentEvent(IntentEvent.Type.WITHDRAWN, intent));
} catch (IntentException e) {
+ // FIXME: Do we really want to do this?
setState(intent, IntentState.FAILED);
- throw e;
+ dispatch(new IntentEvent(IntentEvent.Type.FAILED, intent));
}
}
// Sets the internal state for the given intent and dispatches an event
private void setState(Intent intent, IntentState state) {
- IntentState previous = intentStates.get(intent.getId());
- intentStates.put(intent.getId(), state);
- dispatch(new IntentEvent(intent, state, previous, System.currentTimeMillis()));
+ intentStates.put(intent.id(), state);
}
private void putInstallable(IntentId id, List<InstallableIntent> installable) {
@@ -152,15 +158,15 @@
@Override
public void submit(Intent intent) {
- intents.put(intent.getId(), intent);
+ intents.put(intent.id(), intent);
setState(intent, IntentState.SUBMITTED);
+ dispatch(new IntentEvent(IntentEvent.Type.SUBMITTED, intent));
executeSubmit(intent);
}
@Override
public void withdraw(Intent intent) {
- intents.remove(intent.getId());
- setState(intent, IntentState.WITHDRAWING);
+ intents.remove(intent.id());
executeWithdraw(intent);
}
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java b/core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
index 825be86..7eb0e19 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
@@ -10,11 +10,9 @@
import java.util.Iterator;
import java.util.List;
-import static org.onlab.onos.net.intent.IntentState.*;
import static org.junit.Assert.*;
+import static org.onlab.onos.net.intent.IntentEvent.Type.*;
-// TODO: consider make it categorized as integration test when it become
-// slow test or fragile test
/**
* Suite of tests for the intent service contract.
*/
@@ -64,13 +62,13 @@
TestTools.assertAfter(GRACE_MS, new Runnable() {
@Override
public void run() {
- assertEquals("incorrect intent state", INSTALLED,
- service.getIntentState(intent.getId()));
+ assertEquals("incorrect intent state", IntentState.INSTALLED,
+ service.getIntentState(intent.id()));
}
});
// Make sure that all expected events have been emitted
- validateEvents(intent, SUBMITTED, COMPILED, INSTALLED);
+ validateEvents(intent, SUBMITTED, INSTALLED);
// Make sure there is just one intent (and is ours)
assertEquals("incorrect intent count", 1, service.getIntentCount());
@@ -85,19 +83,19 @@
TestTools.assertAfter(GRACE_MS, new Runnable() {
@Override
public void run() {
- assertEquals("incorrect intent state", WITHDRAWN,
- service.getIntentState(intent.getId()));
+ assertEquals("incorrect intent state", IntentState.WITHDRAWN,
+ service.getIntentState(intent.id()));
}
});
// Make sure that all expected events have been emitted
- validateEvents(intent, WITHDRAWING, WITHDRAWN);
+ validateEvents(intent, WITHDRAWN);
// TODO: discuss what is the fate of intents after they have been withdrawn
// Make sure that the intent is no longer in the system
// assertEquals("incorrect intent count", 0, service.getIntents().size());
-// assertNull("intent should not be found", service.getIntent(intent.getId()));
-// assertNull("intent state should not be found", service.getIntentState(intent.getId()));
+// assertNull("intent should not be found", service.getIntent(intent.id()));
+// assertNull("intent state should not be found", service.getIntentState(intent.id()));
}
@Test
@@ -113,8 +111,8 @@
TestTools.assertAfter(GRACE_MS, new Runnable() {
@Override
public void run() {
- assertEquals("incorrect intent state", FAILED,
- service.getIntentState(intent.getId()));
+ assertEquals("incorrect intent state", IntentState.FAILED,
+ service.getIntentState(intent.id()));
}
});
@@ -136,13 +134,13 @@
TestTools.assertAfter(GRACE_MS, new Runnable() {
@Override
public void run() {
- assertEquals("incorrect intent state", FAILED,
- service.getIntentState(intent.getId()));
+ assertEquals("incorrect intent state", IntentState.FAILED,
+ service.getIntentState(intent.id()));
}
});
// Make sure that all expected events have been emitted
- validateEvents(intent, SUBMITTED, COMPILED, FAILED);
+ validateEvents(intent, SUBMITTED, FAILED);
}
/**
@@ -151,23 +149,23 @@
* considered.
*
* @param intent intent subject
- * @param states list of states for which events are expected
+ * @param types list of event types for which events are expected
*/
- protected void validateEvents(Intent intent, IntentState... states) {
+ protected void validateEvents(Intent intent, IntentEvent.Type... types) {
Iterator<IntentEvent> events = listener.events.iterator();
- for (IntentState state : states) {
+ for (IntentEvent.Type type : types) {
IntentEvent event = events.hasNext() ? events.next() : null;
if (event == null) {
- fail("expected event not found: " + state);
- } else if (intent.equals(event.getIntent())) {
- assertEquals("incorrect state", state, event.getState());
+ fail("expected event not found: " + type);
+ } else if (intent.equals(event.subject())) {
+ assertEquals("incorrect state", type, event.type());
}
}
// Remainder of events should not apply to this intent; make sure.
while (events.hasNext()) {
assertFalse("unexpected event for intent",
- intent.equals(events.next().getIntent()));
+ intent.equals(events.next().subject()));
}
}
@@ -228,8 +226,8 @@
TestTools.assertAfter(GRACE_MS, new Runnable() {
@Override
public void run() {
- assertEquals("incorrect intent state", INSTALLED,
- service.getIntentState(intent.getId()));
+ assertEquals("incorrect intent state", IntentState.INSTALLED,
+ service.getIntentState(intent.id()));
}
});
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntentTest.java b/core/api/src/test/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntentTest.java
index d971ba2..66d294a 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntentTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntentTest.java
@@ -12,10 +12,10 @@
@Test
public void basics() {
MultiPointToSinglePointIntent intent = createOne();
- assertEquals("incorrect id", IID, intent.getId());
- assertEquals("incorrect match", MATCH, intent.getTrafficSelector());
- assertEquals("incorrect ingress", PS1, intent.getIngressPorts());
- assertEquals("incorrect egress", P2, intent.getEgressPort());
+ assertEquals("incorrect id", IID, intent.id());
+ assertEquals("incorrect match", MATCH, intent.selector());
+ assertEquals("incorrect ingress", PS1, intent.ingressPoints());
+ assertEquals("incorrect egress", P2, intent.egressPoint());
}
@Override
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/PathIntentTest.java b/core/api/src/test/java/org/onlab/onos/net/intent/PathIntentTest.java
index bd8dc08..7c15c37 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/PathIntentTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/PathIntentTest.java
@@ -16,12 +16,12 @@
@Test
public void basics() {
PathIntent intent = createOne();
- assertEquals("incorrect id", IID, intent.getId());
- assertEquals("incorrect match", MATCH, intent.getTrafficSelector());
- assertEquals("incorrect action", NOP, intent.getTrafficTreatment());
- assertEquals("incorrect ingress", P1, intent.getIngressPort());
- assertEquals("incorrect egress", P2, intent.getEgressPort());
- assertEquals("incorrect path", PATH1, intent.getPath());
+ assertEquals("incorrect id", IID, intent.id());
+ assertEquals("incorrect match", MATCH, intent.selector());
+ assertEquals("incorrect action", NOP, intent.treatment());
+ assertEquals("incorrect ingress", P1, intent.ingressPoint());
+ assertEquals("incorrect egress", P2, intent.egressPoint());
+ assertEquals("incorrect path", PATH1, intent.path());
}
@Override
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/PointToPointIntentTest.java b/core/api/src/test/java/org/onlab/onos/net/intent/PointToPointIntentTest.java
index 426a3d9..e0c5562 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/PointToPointIntentTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/PointToPointIntentTest.java
@@ -12,10 +12,10 @@
@Test
public void basics() {
PointToPointIntent intent = createOne();
- assertEquals("incorrect id", IID, intent.getId());
- assertEquals("incorrect match", MATCH, intent.getTrafficSelector());
- assertEquals("incorrect ingress", P1, intent.getIngressPort());
- assertEquals("incorrect egress", P2, intent.getEgressPort());
+ assertEquals("incorrect id", IID, intent.id());
+ assertEquals("incorrect match", MATCH, intent.selector());
+ assertEquals("incorrect ingress", P1, intent.ingressPoint());
+ assertEquals("incorrect egress", P2, intent.egressPoint());
}
@Override
diff --git a/core/api/src/test/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntentTest.java b/core/api/src/test/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntentTest.java
index 0561a87..64c9292 100644
--- a/core/api/src/test/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntentTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntentTest.java
@@ -12,10 +12,10 @@
@Test
public void basics() {
SinglePointToMultiPointIntent intent = createOne();
- assertEquals("incorrect id", IID, intent.getId());
- assertEquals("incorrect match", MATCH, intent.getTrafficSelector());
- assertEquals("incorrect ingress", P1, intent.getIngressPort());
- assertEquals("incorrect egress", PS2, intent.getEgressPorts());
+ assertEquals("incorrect id", IID, intent.id());
+ assertEquals("incorrect match", MATCH, intent.selector());
+ assertEquals("incorrect ingress", P1, intent.ingressPoint());
+ assertEquals("incorrect egress", PS2, intent.egressPoints());
}
@Override
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
index 541a702..de61e8e 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/HostToHostIntentCompiler.java
@@ -71,11 +71,11 @@
private Intent createPathIntent(Path path, Host src, Host dst,
HostToHostIntent intent) {
- TrafficSelector selector = builder(intent.getTrafficSelector())
+ TrafficSelector selector = builder(intent.selector())
.matchEthSrc(src.mac()).matchEthDst(dst.mac()).build();
return new PathIntent(intentIdGenerator.getNewId(),
- selector, intent.getTrafficTreatment(),
+ selector, intent.treatment(),
path.src(), path.dst(), path);
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
index 6268245..197c2b2 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
@@ -28,11 +28,15 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.onlab.onos.net.intent.IntentState.*;
+import static org.onlab.util.Tools.namedThreads;
import static org.slf4j.LoggerFactory.getLogger;
/**
@@ -56,6 +60,8 @@
private final AbstractListenerRegistry<IntentEvent, IntentListener>
listenerRegistry = new AbstractListenerRegistry<>();
+ private ExecutorService executor = newSingleThreadExecutor(namedThreads("onos-intents"));
+
private final IntentStoreDelegate delegate = new InternalStoreDelegate();
private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate();
@@ -63,7 +69,7 @@
protected IntentStore store;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected FlowTrackerService trackerService;
+ protected ObjectiveTrackerService trackerService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected EventDeliveryService eventDispatcher;
@@ -89,21 +95,16 @@
checkNotNull(intent, INTENT_NULL);
registerSubclassCompilerIfNeeded(intent);
IntentEvent event = store.createIntent(intent);
- processStoreEvent(event);
+ if (event != null) {
+ eventDispatcher.post(event);
+ executor.execute(new IntentTask(COMPILING, intent));
+ }
}
@Override
public void withdraw(Intent intent) {
checkNotNull(intent, INTENT_NULL);
- IntentEvent event = store.setState(intent, WITHDRAWING);
- List<InstallableIntent> installables = store.getInstallableIntents(intent.getId());
- if (installables != null) {
- for (InstallableIntent installable : installables) {
- trackerService.removeTrackedResources(intent.getId(),
- installable.requiredLinks());
- }
- }
- processStoreEvent(event);
+ executor.execute(new IntentTask(WITHDRAWING, intent));
}
// FIXME: implement this method
@@ -207,56 +208,122 @@
}
/**
- * Compiles an intent.
+ * Compiles the specified intent.
*
- * @param intent intent
+ * @param intent intent to be compiled
*/
- private void compileIntent(Intent intent) {
- // FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented
- // TODO: implement compilation traversing tree structure
+ private void executeCompilingPhase(Intent intent) {
+ // Indicate that the intent is entering the compiling phase.
+ store.setState(intent, COMPILING);
+
+ try {
+ // Compile the intent into installable derivatives.
+ List<InstallableIntent> installable = compileIntent(intent);
+
+ // If all went well, associate the resulting list of installable
+ // intents with the top-level intent and proceed to install.
+ store.addInstallableIntents(intent.id(), installable);
+ executeInstallingPhase(intent);
+
+ } catch (Exception e) {
+ // If compilation failed, mark the intent as failed.
+ store.setState(intent, FAILED);
+ }
+ }
+
+ // FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented
+ // TODO: implement compilation traversing tree structure
+ private List<InstallableIntent> compileIntent(Intent intent) {
List<InstallableIntent> installable = new ArrayList<>();
for (Intent compiled : getCompiler(intent).compile(intent)) {
InstallableIntent installableIntent = (InstallableIntent) compiled;
installable.add(installableIntent);
- trackerService.addTrackedResources(intent.getId(),
+ trackerService.addTrackedResources(intent.id(),
installableIntent.requiredLinks());
}
- IntentEvent event = store.addInstallableIntents(intent.getId(), installable);
- processStoreEvent(event);
+ return installable;
}
/**
- * Installs an intent.
+ * Installs all installable intents associated with the specified top-level
+ * intent.
*
- * @param intent intent
+ * @param intent intent to be installed
*/
- private void installIntent(Intent intent) {
- List<InstallableIntent> installables = store.getInstallableIntents(intent.getId());
- if (installables != null) {
- for (InstallableIntent installable : installables) {
- registerSubclassInstallerIfNeeded(installable);
- getInstaller(installable).install(installable);
+ private void executeInstallingPhase(Intent intent) {
+ // Indicate that the intent is entering the installing phase.
+ store.setState(intent, INSTALLING);
+
+ try {
+ List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
+ if (installables != null) {
+ for (InstallableIntent installable : installables) {
+ registerSubclassInstallerIfNeeded(installable);
+ getInstaller(installable).install(installable);
+ }
}
- }
- IntentEvent event = store.setState(intent, INSTALLED);
- processStoreEvent(event);
+ eventDispatcher.post(store.setState(intent, INSTALLED));
+ } catch (Exception e) {
+ // If compilation failed, kick off the recompiling phase.
+ executeRecompilingPhase(intent);
+ }
}
/**
- * Uninstalls an intent.
+ * Recompiles the specified intent.
*
- * @param intent intent
+ * @param intent intent to be recompiled
*/
- private void uninstallIntent(Intent intent) {
- List<InstallableIntent> installables = store.getInstallableIntents(intent.getId());
+ private void executeRecompilingPhase(Intent intent) {
+ // Indicate that the intent is entering the recompiling phase.
+ store.setState(intent, RECOMPILING);
+
+ try {
+ // Compile the intent into installable derivatives.
+ List<InstallableIntent> installable = compileIntent(intent);
+
+ // If all went well, compare the existing list of installable
+ // intents with the newly compiled list. If they are the same,
+ // bail, out since the previous approach was determined not to
+ // be viable.
+ List<InstallableIntent> originalInstallable =
+ store.getInstallableIntents(intent.id());
+
+ if (Objects.equals(originalInstallable, installable)) {
+ eventDispatcher.post(store.setState(intent, FAILED));
+ } else {
+ // Otherwise, re-associate the newly compiled installable intents
+ // with the top-level intent and kick off installing phase.
+ store.addInstallableIntents(intent.id(), installable);
+ executeInstallingPhase(intent);
+ }
+ } catch (Exception e) {
+ // If compilation failed, mark the intent as failed.
+ eventDispatcher.post(store.setState(intent, FAILED));
+ }
+ }
+
+ /**
+ * Uninstalls the specified intent by uninstalling all of its associated
+ * installable derivatives.
+ *
+ * @param intent intent to be installed
+ */
+ private void executeWithdrawingPhase(Intent intent) {
+ // Indicate that the intent is being withdrawn.
+ store.setState(intent, WITHDRAWING);
+ List<InstallableIntent> installables = store.getInstallableIntents(intent.id());
if (installables != null) {
for (InstallableIntent installable : installables) {
getInstaller(installable).uninstall(installable);
}
}
- store.removeInstalledIntents(intent.getId());
- store.setState(intent, WITHDRAWN);
+
+ // If all went well, disassociate the top-level intent with its
+ // installable derivatives and mark it as withdrawn.
+ store.removeInstalledIntents(intent.id());
+ eventDispatcher.post(store.setState(intent, WITHDRAWN));
}
/**
@@ -309,55 +376,58 @@
}
}
- /**
- * Handles state transition of submitted intents.
- */
- private void processStoreEvent(IntentEvent event) {
- eventDispatcher.post(event);
- Intent intent = event.getIntent();
- try {
- switch (event.getState()) {
- case SUBMITTED:
- compileIntent(intent);
- break;
- case COMPILED:
- installIntent(intent);
- break;
- case INSTALLED:
- break;
- case WITHDRAWING:
- uninstallIntent(intent);
- break;
- case WITHDRAWN:
- break;
- case FAILED:
- break;
- default:
- throw new IllegalStateException("the state of IntentEvent is illegal: " +
- event.getState());
- }
- } catch (IntentException e) {
- store.setState(intent, FAILED);
- }
-
- }
-
// Store delegate to re-post events emitted from the store.
private class InternalStoreDelegate implements IntentStoreDelegate {
@Override
public void notify(IntentEvent event) {
- processStoreEvent(event);
+ eventDispatcher.post(event);
+ if (event.type() == IntentEvent.Type.SUBMITTED) {
+ executor.execute(new IntentTask(COMPILING, event.subject()));
+ }
}
}
// Topology change delegate
private class InternalTopoChangeDelegate implements TopologyChangeDelegate {
@Override
- public void bumpIntents(Iterable<IntentId> intentIds) {
+ public void triggerCompile(Iterable<IntentId> intentIds,
+ boolean compileAllFailed) {
+ // Attempt recompilation of the specified intents first.
for (IntentId intentId : intentIds) {
- compileIntent(getIntent(intentId));
+ executeRecompilingPhase(getIntent(intentId));
+ }
+
+ if (compileAllFailed) {
+ // If required, compile all currently failed intents.
+ for (Intent intent : getIntents()) {
+ if (getIntentState(intent.id()) == FAILED) {
+ executeCompilingPhase(intent);
+ }
+ }
}
}
-
}
+
+ // Auxiliary runnable to perform asynchronous tasks.
+ private class IntentTask implements Runnable {
+ private final IntentState state;
+ private final Intent intent;
+
+ public IntentTask(IntentState state, Intent intent) {
+ this.state = state;
+ this.intent = intent;
+ }
+
+ @Override
+ public void run() {
+ if (state == COMPILING) {
+ executeCompilingPhase(intent);
+ } else if (state == RECOMPILING) {
+ executeRecompilingPhase(intent);
+ } else if (state == WITHDRAWING) {
+ executeWithdrawingPhase(intent);
+ }
+ }
+ }
+
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java
similarity index 81%
rename from core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java
rename to core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java
index f69bf78..17d420b 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTracker.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTracker.java
@@ -19,12 +19,15 @@
import org.slf4j.Logger;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Multimaps.synchronizedSetMultimap;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.onos.net.link.LinkEvent.Type.LINK_REMOVED;
import static org.onlab.util.Tools.namedThreads;
import static org.slf4j.LoggerFactory.getLogger;
@@ -34,7 +37,7 @@
*/
@Component
@Service
-public class FlowTracker implements FlowTrackerService {
+public class ObjectiveTracker implements ObjectiveTrackerService {
private final Logger log = getLogger(getClass());
@@ -110,14 +113,26 @@
@Override
public void run() {
if (event.reasons() == null) {
- delegate.bumpIntents(intentsByLink.values());
+ delegate.triggerCompile(null, false);
+
} else {
+ Set<IntentId> toBeRecompiled = new HashSet<>();
+ boolean recompileOnly = true;
+
+ // Scan through the list of reasons and keep accruing all
+ // intents that need to be recompiled.
for (Event reason : event.reasons()) {
if (reason instanceof LinkEvent) {
LinkEvent linkEvent = (LinkEvent) reason;
- delegate.bumpIntents(intentsByLink.get(new LinkKey(linkEvent.subject())));
+ if (linkEvent.type() == LINK_REMOVED) {
+ Set<IntentId> intentIds = intentsByLink.get(new LinkKey(linkEvent.subject()));
+ toBeRecompiled.addAll(intentIds);
+ }
+ recompileOnly = recompileOnly && linkEvent.type() == LINK_REMOVED;
}
}
+
+ delegate.triggerCompile(toBeRecompiled, !recompileOnly);
}
}
}
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTrackerService.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTrackerService.java
similarity index 96%
rename from core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTrackerService.java
rename to core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTrackerService.java
index b96de7c..15496ff 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/FlowTrackerService.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/ObjectiveTrackerService.java
@@ -9,7 +9,7 @@
* Auxiliary service for tracking intent path flows and for notifying the
* intent service of environment changes via topology change delegate.
*/
-public interface FlowTrackerService {
+public interface ObjectiveTrackerService {
/**
* Sets a topology change delegate.
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
index f9cfa67..eb2e113 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
@@ -49,8 +49,8 @@
@Override
public void install(PathIntent intent) {
TrafficSelector.Builder builder =
- DefaultTrafficSelector.builder(intent.getTrafficSelector());
- Iterator<Link> links = intent.getPath().links().iterator();
+ DefaultTrafficSelector.builder(intent.selector());
+ Iterator<Link> links = intent.path().links().iterator();
ConnectPoint prev = links.next().dst();
while (links.hasNext()) {
@@ -70,8 +70,8 @@
@Override
public void uninstall(PathIntent intent) {
TrafficSelector.Builder builder =
- DefaultTrafficSelector.builder(intent.getTrafficSelector());
- Iterator<Link> links = intent.getPath().links().iterator();
+ DefaultTrafficSelector.builder(intent.selector());
+ Iterator<Link> links = intent.path().links().iterator();
ConnectPoint prev = links.next().dst();
while (links.hasNext()) {
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java
index d8a5a95..7a9fd12 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/TopologyChangeDelegate.java
@@ -9,10 +9,14 @@
/**
* Notifies that topology has changed in such a way that the specified
- * intents should be recompiled.
+ * intents should be recompiled. If the {@code compileAllFailed} parameter
+ * is true, the all intents in {@link org.onlab.onos.net.intent.IntentState#FAILED}
+ * state should be compiled as well.
*
* @param intentIds intents that should be recompiled
+ * @param compileAllFailed true implies full compile is required; false for
+ * selective recompile only
*/
- void bumpIntents(Iterable<IntentId> intentIds);
+ void triggerCompile(Iterable<IntentId> intentIds, boolean compileAllFailed);
}
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleIntentStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleIntentStore.java
index 4143548..732d753 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleIntentStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleIntentStore.java
@@ -1,12 +1,6 @@
package org.onlab.onos.store.trivial.impl;
-import static org.onlab.onos.net.intent.IntentState.COMPILED;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
+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;
@@ -21,13 +15,18 @@
import org.onlab.onos.store.AbstractStore;
import org.slf4j.Logger;
-import com.google.common.collect.ImmutableSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.onlab.onos.net.intent.IntentState.*;
+import static org.slf4j.LoggerFactory.getLogger;
@Component(immediate = true)
@Service
public class SimpleIntentStore
- extends AbstractStore<IntentEvent, IntentStoreDelegate>
- implements IntentStore {
+ extends AbstractStore<IntentEvent, IntentStoreDelegate>
+ implements IntentStore {
private final Logger log = getLogger(getClass());
private final Map<IntentId, Intent> intents = new HashMap<>();
@@ -46,7 +45,7 @@
@Override
public IntentEvent createIntent(Intent intent) {
- intents.put(intent.getId(), intent);
+ intents.put(intent.id(), intent);
return this.setState(intent, IntentState.SUBMITTED);
}
@@ -54,7 +53,7 @@
public IntentEvent removeIntent(IntentId intentId) {
Intent intent = intents.remove(intentId);
installable.remove(intentId);
- IntentEvent event = this.setState(intent, IntentState.WITHDRAWN);
+ IntentEvent event = this.setState(intent, WITHDRAWN);
states.remove(intentId);
return event;
}
@@ -79,19 +78,21 @@
return states.get(id);
}
- // TODO return dispatch event here... replace with state transition methods
@Override
- public IntentEvent setState(Intent intent, IntentState newState) {
- IntentId id = intent.getId();
- IntentState oldState = states.get(id);
- states.put(id, newState);
- return new IntentEvent(intent, newState, oldState, System.currentTimeMillis());
+ public IntentEvent setState(Intent intent, IntentState state) {
+ IntentId id = intent.id();
+ states.put(id, state);
+ IntentEvent.Type type = (state == SUBMITTED ? IntentEvent.Type.SUBMITTED :
+ (state == INSTALLED ? IntentEvent.Type.INSTALLED :
+ (state == FAILED ? IntentEvent.Type.FAILED :
+ state == WITHDRAWN ? IntentEvent.Type.WITHDRAWN :
+ null)));
+ return type == null ? null : new IntentEvent(type, intent);
}
@Override
- public IntentEvent addInstallableIntents(IntentId intentId, List<InstallableIntent> result) {
+ public void addInstallableIntents(IntentId intentId, List<InstallableIntent> result) {
installable.put(intentId, result);
- return this.setState(intents.get(intentId), COMPILED);
}
@Override
diff --git a/tools/dev/bash_profile b/tools/dev/bash_profile
index 270370a..b44658d 100644
--- a/tools/dev/bash_profile
+++ b/tools/dev/bash_profile
@@ -89,5 +89,5 @@
}
function nuke {
- spy | cut -c7-11 | xargs kill
+ spy "$@" | cut -c7-11 | xargs kill
}