Initial implementation: The init extended flow rule and store interface APIs

The APIs are for supporting service data to install on network devices.
This is related to JIRA ticket ID ONOS-869.

Updated API code and added implementation code files.

Modified API for supporting payload abstruction, and added routing mechanism for pushing flow rules to devices.
Added more javadoc, and fixed some minor issues.

Updated javadoc, removed unnecessary method, and test code.

Change-Id: I105defc92a9e01b30601fcb56a9dafa086d4adc0
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
index e555794..441f9a0 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowRule.java
@@ -172,7 +172,6 @@
         return treatment;
     }
 
-
     @Override
     /*
      * The priority and statistics can change on a given treatment and selector
diff --git a/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java b/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java
index 5570a40..2b9ca9d 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/FlowRuleBatchRequest.java
@@ -25,7 +25,7 @@
 public class FlowRuleBatchRequest {
 
     /**
-     * This id is used to cary to id of the original
+     * This id is used to carry to id of the original
      * FlowOperations and track where this batch operation
      * came from. The id is unique cluster wide.
      */
@@ -37,8 +37,6 @@
     public FlowRuleBatchRequest(long batchId, Set<FlowRuleBatchEntry> ops) {
         this.batchId = batchId;
         this.ops = Collections.unmodifiableSet(ops);
-
-
     }
 
     public Set<FlowRuleBatchEntry> ops() {
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/DefaultFlowRuleExt.java b/core/api/src/main/java/org/onosproject/net/flowext/DefaultFlowRuleExt.java
new file mode 100644
index 0000000..721cced
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/DefaultFlowRuleExt.java
@@ -0,0 +1,110 @@
+/*
+ * 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.flowext;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.DefaultGroupId;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * A temporary flow rule extend implementation, It will cover current onos flow rule and other flow extension.
+ */
+public class DefaultFlowRuleExt
+        extends DefaultFlowRule implements FlowRuleExt {
+
+    private FlowEntryExtension flowEntryExtension;
+
+    public DefaultFlowRuleExt(DeviceId deviceId, TrafficSelector selector,
+                              TrafficTreatment treatment, int priority, long flowId,
+                              int timeout, boolean permanent) {
+        super(deviceId, selector, treatment, priority, flowId, timeout, permanent);
+    }
+
+    public DefaultFlowRuleExt(DeviceId deviceId, TrafficSelector selector,
+                              TrafficTreatment treatment, int priority, ApplicationId appId,
+                              int timeout, boolean permanent) {
+        this(deviceId, selector, treatment, priority, appId, new DefaultGroupId(0),
+             timeout, permanent);
+    }
+
+    public DefaultFlowRuleExt(DeviceId deviceId, TrafficSelector selector,
+                              TrafficTreatment treatment, int priority, ApplicationId appId,
+                              GroupId groupId, int timeout, boolean permanent) {
+        super(deviceId, selector, treatment, priority, appId, groupId, timeout, permanent);
+    }
+
+    public DefaultFlowRuleExt(FlowRule rule) {
+        super(rule);
+    }
+
+    public DefaultFlowRuleExt(ApplicationId appId, DeviceId deviceId, FlowEntryExtension data) {
+        this(deviceId, null, null, FlowRule.MIN_PRIORITY, appId, 0, false);
+        this.flowEntryExtension = data;
+    }
+
+    @Override
+    public FlowEntryExtension getFlowEntryExt() {
+        return this.flowEntryExtension;
+    }
+
+    @Override
+    public int hashCode() {
+        return 31 * super.hashCode() + Objects.hash(flowEntryExtension);
+    }
+
+    public int hash() {
+        return 31 * super.hashCode() + Objects.hash(flowEntryExtension);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        if (!super.equals(obj)) {
+            return false;
+        }
+        final DefaultFlowRuleExt other = (DefaultFlowRuleExt) obj;
+        return Objects.equals(this.flowEntryExtension, other.flowEntryExtension);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                // TODO there might be a better way to grab super's string
+                .add("id", Long.toHexString(id().value()))
+                .add("deviceId", deviceId())
+                .add("priority", priority())
+                .add("selector", selector().criteria())
+                .add("treatment", treatment() == null ? "N/A" : treatment().instructions())
+                        //.add("created", created)
+                .add("flowEntryExtension", flowEntryExtension)
+                .toString();
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/DownStreamFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flowext/DownStreamFlowEntry.java
new file mode 100644
index 0000000..986adbc
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/DownStreamFlowEntry.java
@@ -0,0 +1,85 @@
+/*
+ * 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.flowext;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * Represents a generic abstraction of the service data. User app can customize whatever it needs to install on devices.
+ */
+public class DownStreamFlowEntry implements FlowEntryExtension {
+
+    /**
+     * temporarily only have byte stream, but it will be extract more abstract information from it later.
+     */
+    private final ByteBuffer payload;
+
+    public DownStreamFlowEntry(ByteBuffer data) {
+        this.payload = data;
+    }
+
+    /**
+     * Get the payload of flowExtension.
+     *
+     * @return the byte steam value of payload.
+     */
+//   @Override
+//   public ByteBuffer getPayload() {
+    // TODO Auto-generated method stub
+//       return payload;
+//   }
+
+    /**
+     * Returns a hash code value for the object.
+     * It use payload as parameter to hash.
+     *
+     * @return a hash code value for this object.
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(payload);
+    }
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     *
+     * @param obj the reference object with which to compare.
+     * @return {@code true} if this object is the same as the obj
+     * argument; {@code false} otherwise.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof DownStreamFlowEntry) {
+            DownStreamFlowEntry packet = (DownStreamFlowEntry) obj;
+            return Objects.equals(this.payload, packet.payload);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return a string representation of the object.
+     */
+    @Override
+    public String toString() {
+        String obj = new String(payload.array());
+        return obj;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/FlowEntryExtension.java b/core/api/src/main/java/org/onosproject/net/flowext/FlowEntryExtension.java
new file mode 100644
index 0000000..84129ad
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/FlowEntryExtension.java
@@ -0,0 +1,26 @@
+/*
+ * 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.flowext;
+
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * Represents a generic abstraction of the service data. User app can customize whatever it needs to install on devices.
+ */
+public interface FlowEntryExtension {
+    // some abstraction of the service data, like length, type, etc, will be added here later
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/FlowExtCompletedOperation.java b/core/api/src/main/java/org/onosproject/net/flowext/FlowExtCompletedOperation.java
new file mode 100644
index 0000000..1443855
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/FlowExtCompletedOperation.java
@@ -0,0 +1,62 @@
+/*
+ * 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.flowext;
+
+import com.google.common.base.MoreObjects;
+import org.onosproject.net.flow.CompletedBatchOperation;
+import org.onosproject.net.flow.FlowRule;
+
+import java.util.Set;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * <p>
+ * Representation of a completed flow rule batch operation.
+ * </p>
+ */
+//TODO explain the purpose of this class beyond FlowRuleProvider
+public class FlowExtCompletedOperation extends CompletedBatchOperation {
+    // the batchId is provided by application, once one flow rule of this batch failed
+    // all the batch should withdraw
+    private final long batchId;
+
+    public FlowExtCompletedOperation(long batchId, boolean success, Set<FlowRule> failures) {
+        super(success, failures, null);
+        this.batchId = batchId;
+    }
+
+    /**
+     * Returns the BatchId of this BatchOperation.
+     *
+     * @return the number of Batch
+     */
+    public long getBatchId() {
+        return batchId;
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return a string representation of the object.
+     */
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("success?", isSuccess())
+                .add("failedItems", failedIds())
+                .toString();
+    }
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExt.java b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExt.java
new file mode 100644
index 0000000..d97c950
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExt.java
@@ -0,0 +1,33 @@
+/*
+ * 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.flowext;
+
+import org.onosproject.net.flow.FlowRule;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * <p>
+ * FlowRule extended for current FlowRule API.
+ * </p>
+ */
+public interface FlowRuleExt extends FlowRule {
+    /**
+     * Get the flow entry extension.
+     *
+     * @return FlowEntryExtension value.
+     */
+    FlowEntryExtension getFlowEntryExt();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtRouter.java b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtRouter.java
new file mode 100644
index 0000000..1f516bf
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtRouter.java
@@ -0,0 +1,64 @@
+/*
+ * 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.flowext;
+
+import org.onosproject.net.flow.FlowRuleBatchEvent;
+import org.onosproject.net.flow.FlowRuleBatchRequest;
+
+import java.util.concurrent.Future;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * Represents a router-like mechanism which is in charge of sending flow rule to master;
+ * <p>
+ * The Router is in charge of sending flow rule to master;
+ * the core component of routing-like mechanism.
+ * </p>
+ */
+public interface FlowRuleExtRouter {
+
+    /**
+     * apply the sub batch of flow extension rules.
+     *
+     * @param batchOperation batch of flow rules.
+     *                       A batch can contain flow rules for a single device only.
+     * @return Future response indicating success/failure of the batch operation
+     * all the way down to the device.
+     */
+    Future<FlowExtCompletedOperation> applySubBatch(FlowRuleBatchRequest batchOperation);
+
+    /**
+     * Invoked on the completion of a storeBatch operation.
+     *
+     * @param event flow rule batch event
+     */
+    void batchOperationComplete(FlowRuleBatchEvent event);
+
+    /**
+     * Register the listener to monitor Router,
+     * The Router find master to send downStream.
+     *
+     * @param listener the listener to register
+     */
+    public void addListener(FlowRuleExtRouterListener listener);
+
+    /**
+     * Remove the listener of Router.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeListener(FlowRuleExtRouterListener listener);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtRouterListener.java b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtRouterListener.java
new file mode 100644
index 0000000..45caee9
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtRouterListener.java
@@ -0,0 +1,35 @@
+/*
+ * 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.flowext;
+
+import org.onosproject.net.flow.FlowRuleBatchEvent;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * The monitor module of the router.
+ * <p>
+ * The monitor module of router.
+ * </p>
+ */
+public interface FlowRuleExtRouterListener {
+
+    /**
+     * Notify monitor the router has down its work.
+     *
+     * @param event the event to notify
+     */
+    void notify(FlowRuleBatchEvent event);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtService.java b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtService.java
new file mode 100644
index 0000000..7db2545
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/FlowRuleExtService.java
@@ -0,0 +1,40 @@
+/*
+ * 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.flowext;
+
+import org.onosproject.net.flow.FlowRuleBatchRequest;
+import org.onosproject.net.flow.FlowRuleService;
+
+import java.util.concurrent.Future;
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * Service for injecting extended flow rules into the environment.
+ * This service just send the packet downstream. It won't store the
+ * flowRuleExtension in cache.
+ */
+public interface FlowRuleExtService extends FlowRuleService {
+    /**
+     * Applies a batch operation of FlowRules.
+     * this batch can be divided into many sub-batch by deviceId, and application
+     * gives a batchId, it means once one flowRule apply failed, all flow rules should
+     * withdraw.
+     *
+     * @param batch batch operation to apply
+     * @return future indicating the state of the batch operation
+     */
+    Future<FlowExtCompletedOperation> applyBatch(FlowRuleBatchRequest batch);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flowext/package-info.java b/core/api/src/main/java/org/onosproject/net/flowext/package-info.java
new file mode 100644
index 0000000..6f72ab1
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flowext/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/**
+ * Experimental extension to the flow rule subsystem; still under development.
+ * <p>
+ * This package is an extension for the current ONOS flow rule API.
+ * Its main purpose is to support external applications to push service data to network elements.
+ * The service data could be any kind of service related data or commands required for corresponding service
+ * setup and other operations as defined by application and its communicating device.
+ * </p>
+ */
+package org.onosproject.net.flowext;