[Falcon] Refactored mcast store implementation.

Change-Id: Ie3fbc675d02c5abe5f5a419d2fc12dbe8fb4ec35

refactored mcast store implementation

Change-Id: I67d70d678813184c522c78e0771f6b8f8f9c25f8
diff --git a/core/api/src/main/java/org/onosproject/net/mcast/McastEvent.java b/core/api/src/main/java/org/onosproject/net/mcast/McastEvent.java
index 979194c..ec45a8b 100644
--- a/core/api/src/main/java/org/onosproject/net/mcast/McastEvent.java
+++ b/core/api/src/main/java/org/onosproject/net/mcast/McastEvent.java
@@ -17,9 +17,6 @@
 
 import com.google.common.annotations.Beta;
 import org.onosproject.event.AbstractEvent;
-import org.onosproject.net.ConnectPoint;
-
-import java.util.Optional;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
 
@@ -28,10 +25,8 @@
  * sinks or sources.
  */
 @Beta
-public class McastEvent extends AbstractEvent<McastEvent.Type, McastRoute> {
+public class McastEvent extends AbstractEvent<McastEvent.Type, McastRouteInfo> {
 
-    private final Optional<ConnectPoint> sink;
-    private final Optional<ConnectPoint> source;
 
     public enum Type {
         /**
@@ -60,59 +55,15 @@
         SINK_REMOVED
     }
 
-    private McastEvent(McastEvent.Type type, McastRoute subject) {
+    public McastEvent(McastEvent.Type type, McastRouteInfo subject) {
         super(type, subject);
-        sink = Optional.empty();
-        source = Optional.empty();
     }
 
-    private McastEvent(McastEvent.Type type, McastRoute subject, long time) {
-        super(type, subject, time);
-        sink = Optional.empty();
-        source = Optional.empty();
-    }
-
-    public McastEvent(McastEvent.Type type, McastRoute subject,
-                      ConnectPoint sink,
-                      ConnectPoint source) {
-        super(type, subject);
-        this.sink = Optional.ofNullable(sink);
-        this.source = Optional.ofNullable(source);
-    }
-
-    public McastEvent(McastEvent.Type type, McastRoute subject, long time,
-                       ConnectPoint sink,
-                       ConnectPoint source) {
-        super(type, subject, time);
-        this.sink = Optional.ofNullable(sink);
-        this.source = Optional.ofNullable(source);
-    }
-
-    /**
-     * The sink which has been removed or added. The field may not be set
-     * if the sink has not been detected yet or has been removed.
-     *
-     * @return an optional connect point
-     */
-    public Optional<ConnectPoint> sink() {
-        return sink;
-    }
-
-    /**
-     * The source which has been removed or added.
-
-     * @return an optional connect point
-     */
-    public Optional<ConnectPoint> source() {
-        return source;
-    }
 
     @Override
     public String toString() {
         return toStringHelper(this)
                 .add("type", type())
-                .add("route", subject())
-                .add("source", source)
-                .add("sinks", sink).toString();
+                .add("info", subject()).toString();
     }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/mcast/McastRoute.java b/core/api/src/main/java/org/onosproject/net/mcast/McastRoute.java
index ff1292b..496b93b 100644
--- a/core/api/src/main/java/org/onosproject/net/mcast/McastRoute.java
+++ b/core/api/src/main/java/org/onosproject/net/mcast/McastRoute.java
@@ -17,7 +17,7 @@
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
-import org.onlab.packet.IpPrefix;
+import org.onlab.packet.IpAddress;
 
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -46,11 +46,11 @@
         STATIC
     }
 
-    private final IpPrefix source;
-    private final IpPrefix group;
+    private final IpAddress source;
+    private final IpAddress group;
     private final Type type;
 
-    public McastRoute(IpPrefix source, IpPrefix group, Type type) {
+    public McastRoute(IpAddress source, IpAddress group, Type type) {
         checkNotNull(source, "Multicast route must have a source");
         checkNotNull(group, "Multicast route must specify a group address");
         checkNotNull(type, "Must indicate what type of route");
@@ -64,7 +64,7 @@
      *
      * @return an ip address
      */
-    public IpPrefix source() {
+    public IpAddress source() {
         return source;
     }
 
@@ -73,7 +73,7 @@
      *
      * @return an ip address
      */
-    public IpPrefix group() {
+    public IpAddress group() {
         return group;
     }
 
diff --git a/core/api/src/main/java/org/onosproject/net/mcast/McastRouteInfo.java b/core/api/src/main/java/org/onosproject/net/mcast/McastRouteInfo.java
new file mode 100644
index 0000000..92087c1
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/mcast/McastRouteInfo.java
@@ -0,0 +1,90 @@
+package org.onosproject.net.mcast;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Collections;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Multicast information as stored in the store.
+ */
+public final class McastRouteInfo {
+
+    private static final String ROUTE_NOT_NULL = "Route cannot be null";
+
+    private final McastRoute route;
+    private final Optional<ConnectPoint> sink;
+    private final Optional<ConnectPoint> source;
+    private final Set<ConnectPoint> sinks;
+
+    private McastRouteInfo(McastRoute route, ConnectPoint sink,
+                           ConnectPoint source, Set<ConnectPoint> sinks) {
+        this.route = checkNotNull(route, ROUTE_NOT_NULL);
+        this.sink = Optional.ofNullable(sink);
+        this.source = Optional.ofNullable(source);
+        this.sinks = sinks;
+    }
+
+    public static McastRouteInfo mcastRouteInfo(McastRoute route) {
+        return new McastRouteInfo(route, null, null, Collections.EMPTY_SET);
+    }
+
+    public static McastRouteInfo mcastRouteInfo(McastRoute route,
+                                                ConnectPoint sink,
+                                                ConnectPoint source) {
+        return new McastRouteInfo(route, sink, source, Collections.EMPTY_SET);
+    }
+
+    public static McastRouteInfo mcastRouteInfo(McastRoute route,
+                                                Set<ConnectPoint> sinks,
+                                                ConnectPoint source) {
+        return new McastRouteInfo(route, null, source, ImmutableSet.copyOf(sinks));
+    }
+
+    public boolean isComplete() {
+        return ((sink.isPresent() || sinks.size() > 0) && source.isPresent());
+    }
+
+    /**
+     * The route associated with this multicast information.
+     *
+     * @return a mulicast route
+     */
+    public McastRoute route() {
+        return route;
+    }
+
+    /**
+     * The source which has been removed or added.
+
+     * @return an optional connect point
+     */
+    public Optional<ConnectPoint> source() {
+        return source;
+    }
+
+    /**
+     * The sink which has been removed or added. The field may not be set
+     * if the sink has not been detected yet or has been removed.
+     *
+     * @return an optional connect point
+     */
+    public Optional<ConnectPoint> sink() {
+        return sink;
+    }
+
+    /**
+     * Returns the set of sinks associated with this route. Only valid with
+     * SOURCE_ADDED events.
+     *
+     * @return a set of connect points
+     */
+    public Set<ConnectPoint> sinks() {
+        return sinks;
+    }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/mcast/McastStore.java b/core/api/src/main/java/org/onosproject/net/mcast/McastStore.java
new file mode 100644
index 0000000..96b21f6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/mcast/McastStore.java
@@ -0,0 +1,68 @@
+package org.onosproject.net.mcast;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.store.Store;
+
+import java.util.Set;
+
+/**
+ * Entity responsible for storing multicast state information.
+ */
+public interface McastStore extends Store<McastEvent, McastStoreDelegate> {
+
+    enum Type {
+        /**
+         * Adding a route to the mcast rib.
+         */
+        ADD,
+
+        /**
+         * Removing a route from the mcast rib.
+         */
+        REMOVE
+    }
+
+    /**
+     * Updates the store with the route information.
+     *
+     * @param route a multicast route
+     * @param operation an operation
+     */
+    void storeRoute(McastRoute route, Type operation);
+
+    /**
+     * Updates the store with source information for the given route. Only one
+     * source is permitted. Submitting another source will replace the previous
+     * value.
+     *
+     * @param route a multicast route
+     * @param source a source
+     */
+    void storeSource(McastRoute route, ConnectPoint source);
+
+    /**
+     * Updates the store with sink information for a given route. There may be
+     * multiple sinks.
+     *
+     * @param route a multicast route
+     * @param sink a sink
+     * @param operation an operation
+     */
+    void storeSink(McastRoute route, ConnectPoint sink, Type operation);
+
+    /**
+     * Obtain the source for a multicast route.
+     *
+     * @param route a multicast route
+     * @return a connect point
+     */
+    ConnectPoint sourceFor(McastRoute route);
+
+    /**
+     * Obtain the sinks for a multicast route.
+     *
+     * @param route a multicast route
+     * @return a set of sinks
+     */
+    Set<ConnectPoint> sinksFor(McastRoute route);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/mcast/McastStoreDelegate.java b/core/api/src/main/java/org/onosproject/net/mcast/McastStoreDelegate.java
new file mode 100644
index 0000000..bdedce8
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/mcast/McastStoreDelegate.java
@@ -0,0 +1,10 @@
+package org.onosproject.net.mcast;
+
+
+import org.onosproject.store.StoreDelegate;
+
+/**
+ * Mcast store delegate abstraction.
+ */
+public interface McastStoreDelegate extends StoreDelegate<McastEvent> {
+}
diff --git a/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java b/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java
index bf65033..05bd6cb 100644
--- a/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java
+++ b/core/api/src/main/java/org/onosproject/net/mcast/MulticastRouteService.java
@@ -19,7 +19,7 @@
 import org.onosproject.event.ListenerService;
 import org.onosproject.net.ConnectPoint;
 
-import java.util.List;
+import java.util.Set;
 
 /**
  * A service interface for maintaining multicast information.
@@ -82,5 +82,5 @@
      * @param route a multicast route
      * @return a list of connect points
      */
-    List<ConnectPoint> fetchSinks(McastRoute route);
+    Set<ConnectPoint> fetchSinks(McastRoute route);
 }