began implementing MastershipManager

Change-Id: I65b86dcfa062e4cfd74de588f4714b35e9d329f0
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipProvider.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipProvider.java
new file mode 100644
index 0000000..2cbad7f
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipProvider.java
@@ -0,0 +1,7 @@
+package org.onlab.onos.cluster;
+
+import org.onlab.onos.net.provider.Provider;
+
+public interface MastershipProvider extends Provider {
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipProviderService.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipProviderService.java
new file mode 100644
index 0000000..a777f63
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipProviderService.java
@@ -0,0 +1,18 @@
+package org.onlab.onos.cluster;
+
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.net.provider.ProviderService;
+
+public interface MastershipProviderService extends
+        ProviderService<MastershipProvider> {
+
+    /**
+     * Signals the core that mastership has changed for a device.
+     *
+     * @param deviceId the device ID
+     * @param role the new mastership role of this controller instance
+     */
+    void roleChanged(DeviceId deviceId, MastershipRole role);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java b/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
index 728e77d..cb4a076 100644
--- a/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
+++ b/core/api/src/main/java/org/onlab/onos/cluster/MastershipStore.java
@@ -25,7 +25,7 @@
                             MastershipRole role);
 
     /**
-     * Adds or updates the mastership information for a device.
+     * Adds or updates mastership information for a device.
      *
      * @param instance controller instance identifier
      * @param deviceId device identifier
diff --git a/core/net/src/main/java/org/onlab/onos/cluster/impl/MastershipManager.java b/core/net/src/main/java/org/onlab/onos/cluster/impl/MastershipManager.java
new file mode 100644
index 0000000..3d7b5bc
--- /dev/null
+++ b/core/net/src/main/java/org/onlab/onos/cluster/impl/MastershipManager.java
@@ -0,0 +1,122 @@
+package org.onlab.onos.cluster.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Set;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.onos.cluster.MastershipAdminService;
+import org.onlab.onos.cluster.MastershipEvent;
+import org.onlab.onos.cluster.MastershipListener;
+import org.onlab.onos.cluster.MastershipProvider;
+import org.onlab.onos.cluster.MastershipProviderService;
+import org.onlab.onos.cluster.MastershipService;
+import org.onlab.onos.cluster.MastershipStore;
+import org.onlab.onos.cluster.NodeId;
+import org.onlab.onos.event.AbstractListenerRegistry;
+import org.onlab.onos.event.EventDeliveryService;
+import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.MastershipRole;
+import org.onlab.onos.net.provider.AbstractProviderService;
+import org.slf4j.Logger;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class MastershipManager implements MastershipService,
+        MastershipAdminService {
+
+    private static final String NODE_ID_NULL = "Node ID cannot be null";
+    private static final String DEVICE_ID_NULL = "Device ID cannot be null";
+    private static final String ROLE_NULL = "Mastership role cannot be null";
+
+    private final Logger log = getLogger(getClass());
+
+    protected final AbstractListenerRegistry<MastershipEvent, MastershipListener>
+            listenerRegistry = new AbstractListenerRegistry<>();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipStore store;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected EventDeliveryService eventDispatcher;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterManager clusterManager;
+
+    @Activate
+    public void activate() {
+        eventDispatcher.addSink(MastershipEvent.class, listenerRegistry);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        eventDispatcher.removeSink(MastershipEvent.class);
+        log.info("Stopped");
+    }
+
+
+    @Override
+    public void setRole(NodeId nodeId, DeviceId deviceId, MastershipRole role) {
+        checkNotNull(nodeId, NODE_ID_NULL);
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        checkNotNull(role, ROLE_NULL);
+        store.setRole(nodeId, deviceId, role);
+    }
+
+    @Override
+    public NodeId getMasterFor(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        return store.getMaster(deviceId);
+    }
+
+    @Override
+    public Set<DeviceId> getDevicesOf(NodeId nodeId) {
+        checkNotNull(nodeId, NODE_ID_NULL);
+        return store.getDevices(nodeId);
+    }
+
+    @Override
+    public MastershipRole requestRoleFor(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICE_ID_NULL);
+        NodeId id = clusterManager.getLocalNode().id();
+        return store.getRole(id, deviceId);
+    }
+
+    @Override
+    public void addListener(MastershipListener listener) {
+        checkNotNull(listener);
+        listenerRegistry.addListener(listener);
+    }
+
+    @Override
+    public void removeListener(MastershipListener listener) {
+        checkNotNull(listener);
+        listenerRegistry.removeListener(listener);
+    }
+
+    private class InternalMastershipProviderService
+            extends AbstractProviderService<MastershipProvider>
+            implements MastershipProviderService {
+
+        protected InternalMastershipProviderService(MastershipProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void roleChanged(DeviceId deviceId, MastershipRole role) {
+            // TODO Auto-generated method stub
+
+        }
+    }
+
+    // Posts the specified event to the local event dispatcher.
+    private void post(MastershipEvent event) {
+        if (event != null && eventDispatcher != null) {
+            eventDispatcher.post(event);
+        }
+    }
+}