Group subsystem Northbound and Southbound API definition

Change-Id: I1843562ff7fdf0dfdf82a8757382d494698ded3f
diff --git a/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java
new file mode 100644
index 0000000..693f957
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupBucket.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.core.GroupId;
+
+/* Group bucket implementation. A group bucket is collection of
+ * instructions that can be performed on a traffic flow. A select
+ * Group can have one or more Buckets where traffic will be
+ * processed by a single bucket in the group, based on device
+ * specific selection algorithm (e.g. hash on some fields of the
+ * incoming traffic flows or round robin) and hence can contains
+ * optional weight field to define the weights among the buckets
+ * in the group. A failover group bucket is associated with a
+ * specific port or group that controls its liveness.
+ */
+public final class DefaultGroupBucket implements GroupBucket {
+    private final GroupDescription.Type type;
+    private final TrafficTreatment treatment;
+    private final short weight;
+    private final PortNumber watchPort;
+    private final GroupId watchGroup;
+
+    /**
+     * Group bucket constructor with the parameters.
+     *
+     * @param type group bucket type
+     * @param treatment traffic treatment associated with group bucket
+     * @param weight optional weight associated with group bucket
+     * @param watchPort port that determines the liveness of group bucket
+     * @param watchPort group that determines the liveness of group bucket
+     */
+    private DefaultGroupBucket(GroupDescription.Type type,
+                               TrafficTreatment treatment,
+                               short weight,
+                               PortNumber watchPort,
+                               GroupId watchGroup) {
+        this.type = type;
+        this.treatment = checkNotNull(treatment);
+        this.weight = weight;
+        this.watchPort = watchPort;
+        this.watchGroup = watchGroup;
+    }
+
+    /**
+     * Creates indirect group bucket.
+     *
+     * @param treatment traffic treatment associated with group bucket
+     *
+     * @return indirect group bucket object
+     */
+    public static GroupBucket createIndirectGroupBucket(
+                                TrafficTreatment treatment) {
+        return new DefaultGroupBucket(GroupDescription.Type.INDIRECT,
+                                      treatment,
+                                      (short) -1,
+                                      null,
+                                      null);
+    }
+
+    /**
+     * Creates select group bucket with weight as 1.
+     *
+     * @param treatment traffic treatment associated with group bucket
+     *
+     * @return select group bucket object
+     */
+    public static GroupBucket createSelectGroupBucket(
+                                 TrafficTreatment treatment) {
+        return new DefaultGroupBucket(GroupDescription.Type.SELECT,
+                                      treatment,
+                                      (short) 1,
+                                      null,
+                                      null);
+    }
+
+    /**
+     * Creates select group bucket with specified weight.
+     *
+     * @param treatment traffic treatment associated with group bucket
+     * @param weight weight associated with group bucket
+     *
+     * @return select group bucket object
+     */
+    public static GroupBucket createSelectGroupBucket(
+                                 TrafficTreatment treatment,
+                                 short weight) {
+        if (weight == 0) {
+            return null;
+        }
+
+        return new DefaultGroupBucket(GroupDescription.Type.SELECT,
+                                      treatment,
+                                      weight,
+                                      null,
+                                      null);
+    }
+
+    /**
+     * Creates failover group bucket with watchport or watchgroup.
+     *
+     * @param treatment traffic treatment associated with group bucket
+     * @param watchPort port that determines the liveness of group bucket
+     * @param watchPort group that determines the liveness of group bucket
+     *
+     * @return failover group bucket object
+     */
+    public static GroupBucket createFailoverGroupBucket(
+                                 TrafficTreatment treatment,
+                                 PortNumber watchPort,
+                                 GroupId watchGroup) {
+        checkArgument(((watchPort != null) || (watchGroup != null)));
+        return new DefaultGroupBucket(GroupDescription.Type.FAILOVER,
+                                      treatment,
+                                      (short) -1,
+                                      watchPort,
+                                      watchGroup);
+    }
+
+    @Override
+    public GroupDescription.Type type() {
+        return this.type;
+    }
+
+    /**
+     * Return list of Traffic instructions that are part of the bucket.
+     *
+     * @return TrafficTreatment Traffic instruction list
+     */
+    @Override
+    public TrafficTreatment treatment() {
+        return treatment;
+    }
+
+    /**
+     * Return weight of select group bucket.
+     *
+     * @return short weight associated with a bucket
+     */
+    @Override
+    public short weight() {
+        return weight;
+    }
+
+    /**
+     * Return port number used for liveness detection for a
+     * failover bucket.
+     *
+     * @return PortNumber port number used for liveness detection
+     */
+    @Override
+    public PortNumber watchPort() {
+        return watchPort;
+    }
+
+    /**
+     * Return group identifier used for liveness detection for a
+     * failover bucket.
+     *
+     * @return GroupId group identifier to be used for liveness detection
+     */
+    @Override
+    public GroupId watchGroup() {
+        return watchGroup;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java
new file mode 100644
index 0000000..46ccafd
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/DefaultGroupDescription.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+
+public class DefaultGroupDescription implements GroupDescription {
+    private final GroupDescription.Type type;
+    private final GroupBuckets buckets;
+    private final GroupKey appCookie;
+    private final ApplicationId appId;
+    private final DeviceId deviceId;
+
+    /**
+     *
+     * @param deviceId device identifier
+     * @param type type of the group
+     * @param buckets immutable list of group bucket
+     * @param appCookie immutable application cookie to be associated with the group
+     * @param appId application id
+     *
+     * NOTE: The caller of this subsystem MUST ensure the appCookie
+     * provided in this API is immutable
+     */
+    public DefaultGroupDescription(DeviceId deviceId,
+                                   GroupDescription.Type type,
+                                   GroupBuckets buckets,
+                                   GroupKey appCookie,
+                                   ApplicationId appId) {
+        this.type = checkNotNull(type);
+        this.deviceId = checkNotNull(deviceId);
+        this.buckets = checkNotNull(buckets);
+        this.appCookie = checkNotNull(appCookie);
+        this.appId = checkNotNull(appId);
+    }
+
+    /**
+     * Return type of a group object.
+     *
+     * @return GroupType group type
+     */
+    @Override
+    public GroupDescription.Type type() {
+        return this.type;
+    }
+
+    /**
+     * Return device identifier on which this group object is created.
+     *
+     * @return DeviceId device identifier
+     */
+    @Override
+    public DeviceId deviceId() {
+        return this.deviceId;
+    }
+
+    /**
+     * Return application identifier that has created this group object.
+     *
+     * @return ApplicationId application identifier
+     */
+    @Override
+    public ApplicationId appId() {
+        return this.appId;
+    }
+
+    /**
+     * Return application cookie associated with a group object.
+     *
+     * @return GroupKey application cookie
+     */
+    @Override
+    public GroupKey appCookie() {
+        return this.appCookie;
+    }
+
+    /**
+     * Return group buckets of a group.
+     *
+     * @return GroupBuckets immutable list of group bucket
+     */
+    @Override
+    public GroupBuckets buckets() {
+        return this.buckets;
+    }
+
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/group/Group.java b/core/api/src/main/java/org/onosproject/net/group/Group.java
new file mode 100644
index 0000000..33a7969
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/Group.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.core.GroupId;
+
+/**
+ * ONOS representation of group that is stored in the system.
+ */
+public interface Group extends GroupDescription {
+    /**
+     * State of the group object in ONOS.
+     * PENDING_ADD: group create request is processed by ONOS and
+     * not yet received the confirmation from data plane
+     * ADDED: group is created in the data plane
+     * PENDING_UPDATE: group update request is processed by ONOS and
+     * not received the confirmation from data plane post which state
+     * moves to ADDED state
+     * PENDING_DELETE: group delete request is processed by ONOS and
+     * not received the confirmation from data plane
+     */
+    public enum GroupState {
+        PENDING_ADD,
+        ADDED,
+        PENDING_UPDATE,
+        PENDING_DELETE
+    }
+
+    /**
+     * Return group identifier associated with a group object.
+     *
+     * @return GroupId Group Identifier
+     */
+    public GroupId id();
+
+    /**
+     * Return current state of a group object.
+     *
+     * @return GroupState Group State
+     */
+    public GroupState state();
+
+    /**
+     * Returns the number of milliseconds this group has been alive.
+     *
+     * @return number of millis
+     */
+    long life();
+
+    /**
+     * Returns the number of packets processed by this group.
+     *
+     * @return number of packets
+     */
+    long packets();
+
+    /**
+     * Returns the number of bytes processed by this group.
+     *
+     * @return number of bytes
+     */
+    long bytes();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java b/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java
new file mode 100644
index 0000000..3c2e1ec
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupBucket.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.core.GroupId;
+
+/* Group Bucket definition. A default group Bucket is collection of
+ * Instructions that can be performed on a traffic flow. A failover
+ * group bucket is associated with a specific port or group that
+ * controls its liveness. A select group bucket contains optional
+ * weight field to define the weights among the buckets in the group.
+ */
+public interface GroupBucket {
+    /**
+     * Return group type of the bucket.
+     *
+     * @return GroupType group type
+     */
+    public GroupDescription.Type type();
+
+    /**
+     * Return list of Traffic instructions that are part of the bucket.
+     *
+     * @return TrafficTreatment traffic instruction list
+     */
+    public TrafficTreatment treatment();
+
+    /**
+     * Return weight of select group bucket.
+     *
+     * @return short weight associated with a bucket
+     */
+    public short weight();
+
+    /**
+     * Return port number used for liveness detection for a
+     * failover bucket.
+     *
+     * @return PortNumber port number used for liveness detection
+     */
+    public PortNumber watchPort();
+
+    /**
+     * Return group identifier used for liveness detection for a
+     * failover bucket.
+     *
+     * @return GroupId group identifier to be used for liveness detection
+     */
+    public GroupId watchGroup();
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupBucketEntry.java b/core/api/src/main/java/org/onosproject/net/group/GroupBucketEntry.java
new file mode 100644
index 0000000..c8805ad
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupBucketEntry.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+/* Generic group bucket entry representation that is stored in a
+ * group object. A group bucket entry provides additional info of
+ * group bucket like statistics...etc
+ */
+public interface GroupBucketEntry extends GroupBucket {
+    /**
+     * Return Number of packets processed by bucket.
+     *
+     * @return long
+     */
+    public long packets();
+
+    /**
+     * Return Number of bytes processed by bucket.
+     *
+     * @return long
+     */
+    public long bytes();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java b/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java
new file mode 100644
index 0000000..c4aaad2
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupBuckets.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+
+import com.google.common.collect.ImmutableList;
+
+public final class GroupBuckets {
+    private final List<GroupBucket> buckets;
+
+    /**
+     * Creates a immutable list of group bucket.
+     *
+     * @param buckets list of group bucket
+     */
+    public GroupBuckets(List<GroupBucket> buckets) {
+        this.buckets = ImmutableList.copyOf(checkNotNull(buckets));
+    }
+
+    /**
+     * Immutable list of group buckets.
+     *
+     * @return list of group bucket
+     */
+    public List<GroupBucket> buckets() {
+        return buckets;
+    }
+
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupDescription.java b/core/api/src/main/java/org/onosproject/net/group/GroupDescription.java
new file mode 100644
index 0000000..e4ae7ed
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupDescription.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.DeviceId;
+
+/**
+ * ONOS representation of group description that is used to create
+ * a group. It contains immutable properties of a ONOS group construct
+ * such as "type", "DeviceId", "appCookie", "appId" and "buckets"
+ */
+public interface GroupDescription {
+    /**
+     * Types of the group supported by ONOS.
+     */
+    public enum Type {
+        /**
+         * Load-balancing among different buckets in a group.
+         */
+        SELECT,
+        /**
+         * Single Bucket Group.
+         */
+        INDIRECT,
+        /**
+         * Multicast to all buckets in a group.
+         */
+        ALL,
+        /**
+         * Uses the first live bucket in a group.
+         */
+        FAILOVER
+    }
+
+    /**
+     * Return type of a group object.
+     *
+     * @return GroupType group type
+     */
+    public Type type();
+
+    /**
+     * Return device identifier on which this group object is created.
+     *
+     * @return DeviceId device identifier
+     */
+    public DeviceId deviceId();
+
+    /**
+     * Return application identifier that has created this group object.
+     *
+     * @return ApplicationId application identifier
+     */
+    public ApplicationId appId();
+
+    /**
+     * Return application cookie associated with a group object.
+     *
+     * @return GroupKey application cookie
+     */
+    public GroupKey appCookie();
+
+    /**
+     * Return group buckets of a group.
+     *
+     * @return GroupBuckets immutable list of group bucket
+     */
+    public GroupBuckets buckets();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupEvent.java b/core/api/src/main/java/org/onosproject/net/group/GroupEvent.java
new file mode 100644
index 0000000..8bbe742
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupEvent.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Describes flow rule event.
+ */
+public class GroupEvent extends AbstractEvent<GroupEvent.Type, Group> {
+
+    /**
+     * Type of flow rule events.
+     */
+    public enum Type {
+        /**
+         * Signifies that a new Group has been detected.
+         */
+        GROUP_ADDED,
+
+        /**
+         * Signifies that a Group has been removed.
+         */
+        GROUP_REMOVED,
+
+        /**
+         * Signifies that a Group has been updated.
+         */
+        GROUP_UPDATED,
+
+        // internal event between Manager <-> Store
+
+        /*
+         * Signifies that a request to create Group has been added to the store.
+         */
+        GROUP_ADD_REQUESTED,
+        /*
+         * Signifies that a request to delete Group has been added to the store.
+         */
+        GROUP_REMOVE_REQUESTED,
+    }
+
+    /**
+     * Creates an event of a given type and for the specified Group and the
+     * current time.
+     *
+     * @param type  Group event type
+     * @param group event subject
+     */
+    public GroupEvent(Type type, Group group) {
+        super(type, group);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified Group and time.
+     *
+     * @param type  Group event type
+     * @param group event subject
+     * @param time  occurrence time
+     */
+    public GroupEvent(Type type, Group group, long time) {
+        super(type, group, time);
+    }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupKey.java b/core/api/src/main/java/org/onosproject/net/group/GroupKey.java
new file mode 100644
index 0000000..17cb560
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupKey.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+/* Representation of generalized Key that would be used to store
+ * groups in <Key, Value> store. Implementation of this interface
+ * MUST override "equals()" and "hashcode()" methods.
+ */
+public interface GroupKey  {
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupListener.java b/core/api/src/main/java/org/onosproject/net/group/GroupListener.java
new file mode 100644
index 0000000..349ce6a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of receiving Group related events.
+ */
+public interface GroupListener extends EventListener<GroupEvent> {
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java b/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java
new file mode 100644
index 0000000..a99ed07
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.core.GroupId;
+
+public final class GroupOperation {
+    private final Type opType;
+    private final GroupId groupId;
+    private final GroupDescription.Type groupType;
+    private final GroupBuckets buckets;
+
+    public enum Type {
+        /**
+         * Create a group in a device with the specified parameters.
+         */
+        ADD,
+        /**
+         * Modify a group in a device with the specified parameters.
+         */
+        MODIFY,
+        /**
+         * Delete a specified group.
+         */
+        DELETE
+    }
+
+    /**
+     * Group operation constructor with the parameters.
+     *
+     * @param opType group operation type
+     * @param groupId group Identifier
+     * @param groupType type of the group
+     * @param buckets immutable list of group buckets to be part of group
+     */
+    private GroupOperation(Type opType,
+                           GroupId groupId,
+                           GroupDescription.Type groupType,
+                           GroupBuckets buckets) {
+        this.opType = checkNotNull(opType);
+        this.groupId = checkNotNull(groupId);
+        this.groupType = checkNotNull(groupType);
+        this.buckets = buckets;
+    }
+
+    /**
+     * Creates ADD group operation object.
+     *
+     * @param groupId group Identifier
+     * @param groupType type of the group
+     * @param buckets immutable list of group buckets to be part of group
+     *
+     * @return add group operation object
+     */
+    public static GroupOperation createAddGroupOperation(GroupId groupId,
+                                     GroupDescription.Type groupType,
+                                     GroupBuckets buckets) {
+        checkNotNull(buckets);
+        return new GroupOperation(Type.ADD, groupId, groupType, buckets);
+    }
+
+    /**
+     * Creates MODIFY group operation object.
+     *
+     * @param groupId group Identifier
+     * @param groupType type of the group
+     * @param buckets immutable list of group buckets to be part of group
+     *
+     * @return modify group operation object
+     */
+    public static GroupOperation createModifyGroupOperation(GroupId groupId,
+                               GroupDescription.Type groupType,
+                               GroupBuckets buckets) {
+        checkNotNull(buckets);
+        return new GroupOperation(Type.MODIFY, groupId, groupType, buckets);
+
+    }
+
+    /**
+     * Creates DELETE group operation object.
+     *
+     * @param groupId group Identifier
+     * @param groupType type of the group
+     *
+     * @return delete group operation object
+     */
+    public static GroupOperation createDeleteGroupOperation(GroupId groupId,
+                                  GroupDescription.Type groupType) {
+        return new GroupOperation(Type.DELETE, groupId, groupType, null);
+
+    }
+
+    /**
+     * Return group operation type.
+     *
+     * @return GroupOpType group operation type
+     */
+    public Type opType() {
+        return this.opType;
+    }
+
+    /**
+     * Return group identifier attribute of the operation.
+     *
+     * @return GroupId group identifier
+     */
+    public GroupId groupId() {
+        return this.groupId;
+    }
+
+    /**
+     * Return group type attribute of the operation.
+     *
+     * @return GroupType group type
+     */
+    public GroupDescription.Type groupType() {
+        return this.groupType;
+    }
+
+    /**
+     * Return group buckets associated with the operation.
+     *
+     * @return GroupBuckets group buckets
+     */
+    public GroupBuckets buckets() {
+        return this.buckets;
+    }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupOperations.java b/core/api/src/main/java/org/onosproject/net/group/GroupOperations.java
new file mode 100644
index 0000000..629ecd3
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupOperations.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+
+import com.google.common.collect.ImmutableList;
+
+public final class GroupOperations {
+    private final List<GroupOperation> operations;
+
+    /**
+     * Creates a immutable list of group operation.
+     *
+     * @param operations list of group operation
+     */
+    public GroupOperations(List<GroupOperation> operations) {
+        this.operations = ImmutableList.copyOf(checkNotNull(operations));
+    }
+
+    /**
+     * Immutable list of group operation.
+     *
+     * @return list of group operation
+     */
+    public List<GroupOperation> operations() {
+        return operations;
+    }
+
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupProvider.java b/core/api/src/main/java/org/onosproject/net/group/GroupProvider.java
new file mode 100644
index 0000000..35d949f
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupProvider.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.Provider;
+
+/**
+ * Abstraction of a flow rule provider.
+ */
+public interface GroupProvider extends Provider {
+
+    /**
+     * Perform a group operation in the specified device with the
+     * specified parameters.
+     *
+     * @param deviceId device identifier on which the batch of group
+     * operations to be executed
+     * @param groupOps immutable list of group operation
+     */
+    void performGroupOperation(DeviceId deviceId,
+                               GroupOperations groupOps);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupProviderService.java b/core/api/src/main/java/org/onosproject/net/group/GroupProviderService.java
new file mode 100644
index 0000000..bfa0522
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupProviderService.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import java.util.Collection;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderService;
+
+/**
+ * Service through which Group providers can inject information into
+ * the core.
+ */
+public interface GroupProviderService extends ProviderService<GroupProvider> {
+
+    void groupOperationFailed(GroupOperation operation);
+
+    /**
+     * Pushes the collection of group detected in the data plane along
+     * with statistics.
+     *
+     * @param deviceId device identifier
+     * @param groupEntries collection of group entries as seen in data plane
+     */
+    void pushGroupMetrics(DeviceId deviceId,
+                       Collection<Group> groupEntries);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupService.java b/core/api/src/main/java/org/onosproject/net/group/GroupService.java
new file mode 100644
index 0000000..eb733e1
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupService.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.group;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Service for create/update/delete "group" in the devices.
+ * Flow entries can point to a "group" defined in the devices that enables
+ * to represent additional methods of forwarding like load-balancing or
+ * failover among different group of ports or multicast to all ports
+ * specified in a group.
+ * "group" can also be used for grouping common actions of different flows,
+ * so that in some scenarios only one group entry required to be modified
+ * for all the referencing flow entries instead of modifying all of them
+ *
+ * This implements semantics of a distributed authoritative group store
+ * where the master copy of the groups lies with the controller and
+ * the devices hold only the 'cached' copy.
+ */
+public interface GroupService {
+
+    /**
+     * Create a group in the specified device with the provided buckets.
+     * This API provides an option for application to associate a cookie
+     * while creating a group, so that applications can look-up the
+     * groups based on the cookies. These Groups will be retained by
+     * the core system and re-applied if any groups found missing in the
+     * device when it reconnects. This API would immediately return after
+     * submitting the request locally or to a remote Master controller
+     * instance. As a response to this API invocation, GROUP_ADDED or
+     * GROUP_ADD_FAILED notifications would be provided along with cookie
+     * depending on the result of the operation on the device in the
+     * data plane. The caller may also use "getGroup" API to get the
+     * Group object created as part of this request.
+     *
+     * @param groupDesc group creation parameters
+     *
+     */
+    void addGroup(GroupDescription groupDesc);
+
+    /**
+     * Return a group object associated to an application cookie.
+     *
+     * NOTE1: The presence of group object in the system does not
+     * guarantee that the "group" is actually created in device.
+     * GROUP_ADDED notification would confirm the creation of
+     * this group in data plane
+     *
+     * @param deviceId device identifier
+     * @param appCookie application cookie to be used for lookup
+     *
+     * @return group associated with the application cookie or
+     *               NULL if Group is not found for the provided cookie
+     */
+    Group getGroup(DeviceId deviceId, GroupKey appCookie);
+
+    /**
+     * Append buckets to existing group. The caller can optionally
+     * associate a new cookie during this updation. GROUP_UPDATED or
+     * GROUP_UPDATE_FAILED notifications would be provided along with
+     * cookie depending on the result of the operation on the device
+     *
+     * @param deviceId device identifier
+     * @param oldCookie cookie to be used to retrieve the existing group
+     * @param buckets immutable list of group bucket to be added
+     * @param newCookie immutable cookie to be used post update operation
+     * @param appId Application Id
+     */
+    void addBucketsToGroup(DeviceId deviceId,
+                           GroupKey oldCookie,
+                           GroupBuckets buckets,
+                           GroupKey newCookie,
+                           ApplicationId appId);
+
+    /**
+     * Remove buckets from existing group. The caller can optionally
+     * associate a new cookie during this updation. GROUP_UPDATED or
+     * GROUP_UPDATE_FAILED notifications would be provided along with
+     * cookie depending on the result of the operation on the device
+     *
+     * @param deviceId device identifier
+     * @param oldCookie cookie to be used to retrieve the existing group
+     * @param buckets immutable list of group bucket to be removed
+     * @param newCookie immutable cookie to be used post update operation
+     * @param appId Application Id
+     */
+    void removeBucketsFromGroup(Device deviceId,
+                                GroupKey oldCookie,
+                                GroupBuckets buckets,
+                                GroupKey newCookie,
+                                ApplicationId appId);
+
+    /**
+     * Delete a group associated to an application cookie.
+     * GROUP_DELETED or GROUP_DELETE_FAILED notifications would be
+     * provided along with cookie depending on the result of the
+     * operation on the device
+     *
+     * @param deviceId device identifier
+     * @param appCookie application cookie to be used for lookup
+     * @param appId Application Id
+     */
+    void removeGroup(Device deviceId, GroupKey appCookie, ApplicationId appId);
+
+    /**
+     * Retrieve all groups created by an application in the specified device
+     * as seen by current controller instance.
+     *
+     * @param deviceId device identifier
+     * @param appId application id
+     *
+     * @return collection of immutable group objects created by the application
+     */
+    Iterable<Group> getGroups(Device deviceId, ApplicationId appId);
+
+    /**
+     * Adds the specified group listener.
+     *
+     * @param listener group listener
+     */
+    void addListener(GroupListener listener);
+
+    /**
+     * Removes the specified group listener.
+     *
+     * @param listener group listener
+     */
+    void removeListener(GroupListener listener);
+}