Adding Intent Impl and shell command to install simple intent
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
new file mode 100644
index 0000000..ff6e7c6
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/HostToHostIntent.java
@@ -0,0 +1,92 @@
+package org.onlab.onos.net.intent;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onlab.onos.net.HostId;
+import org.onlab.onos.net.flow.TrafficSelector;
+import org.onlab.onos.net.flow.TrafficTreatment;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Abstraction of point-to-point connectivity.
+ */
+public class HostToHostIntent extends ConnectivityIntent {
+
+ private final HostId src;
+ private final HostId dst;
+
+ /**
+ * Creates a new point-to-point intent with the supplied ingress/egress
+ * ports.
+ *
+ * @param id intent identifier
+ * @param match traffic match
+ * @param action action
+ * @param ingressPort ingress port
+ * @param egressPort egress port
+ * @throws NullPointerException if {@code ingressPort} or {@code egressPort}
+ * is null.
+ */
+ public HostToHostIntent(IntentId id, HostId src, HostId dst,
+ TrafficSelector selector, TrafficTreatment treatment) {
+ super(id, selector, treatment);
+ this.src = checkNotNull(src);
+ this.dst = checkNotNull(dst);
+ }
+
+ /**
+ * Returns the port on which the ingress traffic should be connected to the
+ * egress.
+ *
+ * @return ingress port
+ */
+ public HostId getSrc() {
+ return src;
+ }
+
+ /**
+ * Returns the port on which the traffic should egress.
+ *
+ * @return egress port
+ */
+ public HostId getDst() {
+ return dst;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ HostToHostIntent that = (HostToHostIntent) o;
+ return Objects.equals(this.src, that.src)
+ && Objects.equals(this.dst, that.dst);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(super.hashCode(), src, dst);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("id", getId())
+ .add("selector", getTrafficSelector())
+ .add("treatmetn", getTrafficTreatment())
+ .add("src", src)
+ .add("dst", dst)
+ .toString();
+ }
+
+}
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 27ae834..b8f0344 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
@@ -4,14 +4,17 @@
import java.util.Objects;
+import org.onlab.onos.event.AbstractEvent;
+
import com.google.common.base.MoreObjects;
/**
* A class to represent an intent related event.
*/
-public class IntentEvent {
+public class IntentEvent extends AbstractEvent<IntentState, Intent> {
- // TODO: determine a suitable parent class; if one does not exist, consider introducing one
+ // TODO: determine a suitable parent class; if one does not exist, consider
+ // introducing one
private final long time;
private final Intent intent;
@@ -28,6 +31,7 @@
* @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;
@@ -35,16 +39,6 @@
}
/**
- * Constructor for serializer.
- */
- protected IntentEvent() {
- this.intent = null;
- this.state = null;
- this.previous = null;
- this.time = 0;
- }
-
- /**
* Returns the state of the intent which caused the event.
*
* @return the state of the intent
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentEventListener.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentEventListener.java
deleted file mode 100644
index f59ecfc..0000000
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentEventListener.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.onlab.onos.net.intent;
-
-/**
- * Listener for {@link IntentEvent intent events}.
- */
-public interface IntentEventListener {
- /**
- * Processes the specified intent event.
- *
- * @param event the event to process
- */
- void event(IntentEvent event);
-}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentListener.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentListener.java
new file mode 100644
index 0000000..c00c1f6
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentListener.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.intent;
+
+import org.onlab.onos.event.EventListener;
+
+/**
+ * Listener for {@link IntentEvent intent events}.
+ */
+public interface IntentListener extends EventListener<IntentEvent> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
index 2b4fb59..8d550e8 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
@@ -1,6 +1,5 @@
package org.onlab.onos.net.intent;
-import java.util.Set;
/**
* Service for application submitting or withdrawing their intents.
@@ -9,8 +8,8 @@
/**
* Submits an intent into the system.
*
- * This is an asynchronous request meaning that any compiling
- * or installation activities may be done at later time.
+ * This is an asynchronous request meaning that any compiling or
+ * installation activities may be done at later time.
*
* @param intent intent to be submitted
*/
@@ -19,8 +18,8 @@
/**
* Withdraws an intent from the system.
*
- * This is an asynchronous request meaning that the environment
- * may be affected at later time.
+ * This is an asynchronous request meaning that the environment may be
+ * affected at later time.
*
* @param intent intent to be withdrawn
*/
@@ -30,19 +29,26 @@
* Submits a batch of submit & withdraw operations. Such a batch is
* assumed to be processed together.
*
- * This is an asynchronous request meaning that the environment
- * may be affected at later time.
+ * This is an asynchronous request meaning that the environment may be
+ * affected at later time.
*
* @param operations batch of intent operations
*/
void execute(IntentOperations operations);
/**
- * Returns immutable set of intents currently in the system.
+ * Returns an iterable of intents currently in the system.
*
* @return set of intents
*/
- Set<Intent> getIntents();
+ Iterable<Intent> getIntents();
+
+ /**
+ * Returns the number of intents currently in the system.
+ *
+ * @return number of intents
+ */
+ long getIntentCount();
/**
* Retrieves the intent specified by its identifier.
@@ -56,7 +62,8 @@
* Retrieves the state of an intent by its identifier.
*
* @param id intent identifier
- * @return the intent state or null if one with the given identifier is not found
+ * @return the intent state or null if one with the given identifier is not
+ * found
*/
IntentState getIntentState(IntentId id);
@@ -65,12 +72,12 @@
*
* @param listener listener to be added
*/
- void addListener(IntentEventListener listener);
+ void addListener(IntentListener listener);
/**
* Removes the specified listener for intent events.
*
* @param listener listener to be removed
*/
- void removeListener(IntentEventListener listener);
+ void removeListener(IntentListener listener);
}
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
new file mode 100644
index 0000000..792398e
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentStore.java
@@ -0,0 +1,64 @@
+package org.onlab.onos.net.intent;
+
+import java.util.List;
+
+import org.onlab.onos.store.Store;
+
+/**
+ * Manages inventory of end-station intents; not intended for direct use.
+ */
+public interface IntentStore extends Store<IntentEvent, IntentStoreDelegate> {
+
+ /**
+ * Creates a new intent.
+ *
+ * @param intent intent
+ * @return appropriate event or null if no change resulted
+ */
+ IntentEvent createIntent(Intent intent);
+
+ /**
+ * Removes the specified intent from the inventory.
+ *
+ * @param intentId intent identification
+ * @return remove event or null if intent was not found
+ */
+ IntentEvent removeIntent(IntentId intent);
+
+ /**
+ * Returns the number of intents in the store.
+ *
+ */
+ long getIntentCount();
+
+ /**
+ * Returns a collection of all intents in the store.
+ *
+ * @return iterable collection of all intents
+ */
+ Iterable<Intent> getIntents();
+
+ /**
+ * Returns the intent with the specified identifer.
+ *
+ * @param intentId intent identification
+ * @return intent or null if not found
+ */
+ Intent getIntent(IntentId intentId);
+
+ IntentState getIntentState(IntentId id);
+
+ /**
+ * Sets the state of the specified intent to the new state.
+ *
+ * @param intent intent whose state is to be changed
+ * @param newState new state
+ */
+ IntentEvent setState(Intent intent, IntentState newState);
+
+ IntentEvent addInstallableIntents(IntentId intentId, List<InstallableIntent> result);
+
+ List<InstallableIntent> getInstallableIntents(IntentId intentId);
+
+ void removeInstalledIntents(IntentId intentId);
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/IntentStoreDelegate.java b/core/api/src/main/java/org/onlab/onos/net/intent/IntentStoreDelegate.java
new file mode 100644
index 0000000..5a4da1a
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/IntentStoreDelegate.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.intent;
+
+import org.onlab.onos.store.StoreDelegate;
+
+/**
+ * Infrastructure link store delegate abstraction.
+ */
+public interface IntentStoreDelegate extends StoreDelegate<IntentEvent> {
+}
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 39ad011..6809ce2 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
@@ -12,7 +12,7 @@
/**
* Abstraction of explicitly path specified connectivity intent.
*/
-public class PathIntent extends PointToPointIntent {
+public class PathIntent extends PointToPointIntent implements InstallableIntent {
private final Path path;
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 df46ec5..349749e 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
@@ -11,19 +11,19 @@
import java.util.concurrent.Executors;
/**
- * Fake implementation of the intent service to assist in developing tests
- * of the interface contract.
+ * Fake implementation of the intent service to assist in developing tests of
+ * the interface contract.
*/
public class FakeIntentManager implements TestableIntentService {
private final Map<IntentId, Intent> intents = new HashMap<>();
private final Map<IntentId, IntentState> intentStates = new HashMap<>();
private final Map<IntentId, List<InstallableIntent>> installables = new HashMap<>();
- private final Set<IntentEventListener> listeners = new HashSet<>();
+ private final Set<IntentListener> listeners = new HashSet<>();
private final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers = new HashMap<>();
- private final Map<Class<? extends InstallableIntent>,
- IntentInstaller<? extends InstallableIntent>> installers = new HashMap<>();
+ private final Map<Class<? extends InstallableIntent>, IntentInstaller<? extends InstallableIntent>> installers
+ = new HashMap<>();
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final List<IntentException> exceptions = new ArrayList<>();
@@ -76,7 +76,8 @@
private <T extends InstallableIntent> IntentInstaller<T> getInstaller(T intent) {
@SuppressWarnings("unchecked")
- IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent.getClass());
+ IntentInstaller<T> installer = (IntentInstaller<T>) installers.get(intent
+ .getClass());
if (installer == null) {
throw new IntentException("no installer for class " + intent.getClass());
}
@@ -125,7 +126,6 @@
}
}
-
// 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());
@@ -175,6 +175,11 @@
}
@Override
+ public long getIntentCount() {
+ return intents.size();
+ }
+
+ @Override
public Intent getIntent(IntentId id) {
return intents.get(id);
}
@@ -185,23 +190,24 @@
}
@Override
- public void addListener(IntentEventListener listener) {
+ public void addListener(IntentListener listener) {
listeners.add(listener);
}
@Override
- public void removeListener(IntentEventListener listener) {
+ public void removeListener(IntentListener listener) {
listeners.remove(listener);
}
private void dispatch(IntentEvent event) {
- for (IntentEventListener listener : listeners) {
+ for (IntentListener listener : listeners) {
listener.event(event);
}
}
@Override
- public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
+ public <T extends Intent> void registerCompiler(Class<T> cls,
+ IntentCompiler<T> compiler) {
compilers.put(cls, compiler);
}
@@ -216,7 +222,8 @@
}
@Override
- public <T extends InstallableIntent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+ public <T extends InstallableIntent> void registerInstaller(Class<T> cls,
+ IntentInstaller<T> installer) {
installers.put(cls, installer);
}
@@ -227,7 +234,7 @@
@Override
public Map<Class<? extends InstallableIntent>,
- IntentInstaller<? extends InstallableIntent>> getInstallers() {
+ IntentInstaller<? extends InstallableIntent>> getInstallers() {
return Collections.unmodifiableMap(installers);
}
@@ -252,7 +259,8 @@
if (!installers.containsKey(intent.getClass())) {
Class<?> cls = intent.getClass();
while (cls != Object.class) {
- // As long as we're within the InstallableIntent class descendants
+ // As long as we're within the InstallableIntent class
+ // descendants
if (InstallableIntent.class.isAssignableFrom(cls)) {
IntentInstaller<?> installer = installers.get(cls);
if (installer != null) {
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 c7682b1..825be86 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
@@ -51,7 +51,7 @@
@Test
public void basics() {
// Make sure there are no intents
- assertEquals("incorrect intent count", 0, service.getIntents().size());
+ assertEquals("incorrect intent count", 0, service.getIntentCount());
// Register a compiler and an installer both setup for success.
service.registerCompiler(TestIntent.class, new TestCompiler(new TestInstallableIntent(INSTALLABLE_IID)));
@@ -73,8 +73,7 @@
validateEvents(intent, SUBMITTED, COMPILED, INSTALLED);
// Make sure there is just one intent (and is ours)
- assertEquals("incorrect intent count", 1, service.getIntents().size());
- assertEquals("incorrect intent", intent, service.getIntent(intent.getId()));
+ assertEquals("incorrect intent count", 1, service.getIntentCount());
// Reset the listener events
listener.events.clear();
@@ -250,7 +249,7 @@
// Fixture to track emitted intent events
- protected class TestListener implements IntentEventListener {
+ protected class TestListener implements IntentListener {
final List<IntentEvent> events = new ArrayList<>();
@Override