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);
+    }
+
+}