initial import
Change-Id: Ief25aef0066ea96bd2c329ccef974c072b3a5a73
diff --git a/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/ControllerRegistryEntry.java b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/ControllerRegistryEntry.java
new file mode 100644
index 0000000..2472f64
--- /dev/null
+++ b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/ControllerRegistryEntry.java
@@ -0,0 +1,66 @@
+package net.onrc.onos.of.ctl.registry;
+
+
+
+public class ControllerRegistryEntry implements Comparable<ControllerRegistryEntry> {
+ //
+ // TODO: Refactor the implementation and decide whether controllerId
+ // is needed. If "yes", we might need to consider it inside the
+ // compareTo(), equals() and hashCode() implementations.
+ //
+ private final String controllerId;
+ private final int sequenceNumber;
+
+ public ControllerRegistryEntry(String controllerId, int sequenceNumber) {
+ this.controllerId = controllerId;
+ this.sequenceNumber = sequenceNumber;
+ }
+
+ public String getControllerId() {
+ return controllerId;
+ }
+
+ /**
+ * Compares this object with the specified object for order.
+ * NOTE: the test is based on ControllerRegistryEntry sequence numbers,
+ * and doesn't include the controllerId.
+ *
+ * @param o the object to be compared.
+ * @return a negative integer, zero, or a positive integer as this object
+ * is less than, equal to, or greater than the specified object.
+ */
+ @Override
+ public int compareTo(ControllerRegistryEntry o) {
+ return this.sequenceNumber - o.sequenceNumber;
+ }
+
+ /**
+ * Test whether some other object is "equal to" this one.
+ * NOTE: the test is based on ControllerRegistryEntry sequence numbers,
+ * and doesn't include the controllerId.
+ *
+ * @param obj the reference object with which to compare.
+ * @return true if this object is the same as the obj argument; false
+ * otherwise.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof ControllerRegistryEntry) {
+ ControllerRegistryEntry other = (ControllerRegistryEntry) obj;
+ return this.sequenceNumber == other.sequenceNumber;
+ }
+ return false;
+ }
+
+ /**
+ * Get the hash code for the object.
+ * NOTE: the computation is based on ControllerRegistryEntry sequence
+ * numbers, and doesn't include the controller ID.
+ *
+ * @return a hash code value for this object.
+ */
+ @Override
+ public int hashCode() {
+ return Integer.valueOf(this.sequenceNumber).hashCode();
+ }
+}
diff --git a/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/IControllerRegistry.java b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/IControllerRegistry.java
new file mode 100644
index 0000000..0b67338
--- /dev/null
+++ b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/IControllerRegistry.java
@@ -0,0 +1,155 @@
+package net.onrc.onos.of.ctl.registry;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import net.onrc.onos.of.ctl.util.InstanceId;
+
+/**
+ * A registry service that allows ONOS to register controllers and switches in a
+ * way that is global to the entire ONOS cluster. The registry is the arbiter
+ * for allowing controllers to control switches.
+ * <p/>
+ * The OVS/OF1.{2,3} fault tolerance model is a switch connects to multiple
+ * controllers, and the controllers send role requests to tell the switch their
+ * role in controlling the switch.
+ * <p/>
+ * The ONOS fault tolerance model allows only a single controller to have
+ * control of a switch (MASTER role) at once. Controllers therefore need a
+ * mechanism that enables them to decide who should control a each switch. The
+ * registry service provides this mechanism.
+ */
+public interface IControllerRegistry {
+
+ /**
+ * Callback interface for control change events.
+ */
+ public interface ControlChangeCallback {
+ /**
+ * Called whenever the control changes from the point of view of the
+ * registry. The callee can check whether they have control or not using
+ * the hasControl parameter.
+ *
+ * @param dpid The switch that control has changed for
+ * @param hasControl Whether the listener now has control or not
+ */
+ void controlChanged(long dpid, boolean hasControl);
+ }
+
+ /**
+ * Request for control of a switch. This method does not block. When control
+ * for a switch changes, the controlChanged method on the callback object
+ * will be called. This happens any time the control changes while the
+ * request is still active (until releaseControl is called)
+ *
+ * @param dpid Switch to request control for
+ * @param cb Callback that will be used to notify caller of control changes
+ * @throws RegistryException Errors contacting the registry service
+ */
+ public void requestControl(long dpid, ControlChangeCallback cb)
+ throws RegistryException;
+
+ /**
+ * Stop trying to take control of a switch. This removes the entry for this
+ * controller requesting this switch in the registry. If the controller had
+ * control when this is called, another controller will now gain control of
+ * the switch. This call doesn't block.
+ *
+ * @param dpid Switch to release control of
+ */
+ public void releaseControl(long dpid);
+
+ /**
+ * Check whether the controller has control of the switch This call doesn't
+ * block.
+ *
+ * @param dpid Switch to check control of
+ * @return true if controller has control of the switch.
+ */
+ public boolean hasControl(long dpid);
+
+ /**
+ * Check whether this instance is the leader for the cluster. This call
+ * doesn't block.
+ *
+ * @return true if the instance is the leader for the cluster, otherwise
+ * false.
+ */
+ public boolean isClusterLeader();
+
+ /**
+ * Gets the unique ID used to identify this ONOS instance in the cluster.
+ *
+ * @return Instance ID.
+ */
+ public InstanceId getOnosInstanceId();
+
+ /**
+ * Register a controller to the ONOS cluster. Must be called before the
+ * registry can be used to take control of any switches.
+ *
+ * @param controllerId A unique string ID identifying this controller in the
+ * cluster
+ * @throws RegistryException for errors connecting to registry service,
+ * controllerId already registered
+ */
+ public void registerController(String controllerId)
+ throws RegistryException;
+
+ /**
+ * Get all controllers in the cluster.
+ *
+ * @return Collection of controller IDs
+ * @throws RegistryException on error
+ */
+ public Collection<String> getAllControllers() throws RegistryException;
+
+ /**
+ * Get all switches in the cluster, along with which controller is in
+ * control of them (if any) and any other controllers that have requested
+ * control.
+ *
+ * @return Map of all switches.
+ */
+ public Map<String, List<ControllerRegistryEntry>> getAllSwitches();
+
+ /**
+ * Get the controller that has control of a given switch.
+ *
+ * @param dpid Switch to find controller for
+ * @return controller ID
+ * @throws RegistryException Errors contacting registry service
+ */
+ public String getControllerForSwitch(long dpid) throws RegistryException;
+
+ /**
+ * Get all switches controlled by a given controller.
+ *
+ * @param controllerId ID of the controller
+ * @return Collection of dpids
+ */
+ public Collection<Long> getSwitchesControlledByController(String controllerId);
+
+ /**
+ * Get a unique Id Block.
+ *
+ * @return Id Block.
+ */
+ public IdBlock allocateUniqueIdBlock();
+
+ /**
+ * Get next unique id and retrieve a new range of ids if needed.
+ *
+ * @param range range to use for the identifier
+ * @return Id Block.
+ */
+ public IdBlock allocateUniqueIdBlock(long range);
+
+ /**
+ * Get a globally unique ID.
+ *
+ * @return a globally unique ID.
+ */
+ public long getNextUniqueId();
+}
diff --git a/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/IdBlock.java b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/IdBlock.java
new file mode 100644
index 0000000..45d3c83
--- /dev/null
+++ b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/IdBlock.java
@@ -0,0 +1,32 @@
+package net.onrc.onos.of.ctl.registry;
+
+public class IdBlock {
+ private final long start;
+ private final long end;
+ private final long size;
+
+ public IdBlock(long start, long end, long size) {
+ this.start = start;
+ this.end = end;
+ this.size = size;
+ }
+
+ public long getStart() {
+ return start;
+ }
+
+ public long getEnd() {
+ return end;
+ }
+
+ public long getSize() {
+ return size;
+ }
+
+ @Override
+ public String toString() {
+ return "IdBlock [start=" + start + ", end=" + end + ", size=" + size
+ + "]";
+ }
+}
+
diff --git a/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/RegistryException.java b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/RegistryException.java
new file mode 100644
index 0000000..06f5932
--- /dev/null
+++ b/of/ctl/src/main/java/net/onrc/onos/of/ctl/registry/RegistryException.java
@@ -0,0 +1,15 @@
+package net.onrc.onos.of.ctl.registry;
+
+public class RegistryException extends Exception {
+
+ private static final long serialVersionUID = -8276300722010217913L;
+
+ public RegistryException(String message) {
+ super(message);
+ }
+
+ public RegistryException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}