Add a new method sendMsg(OFMessage msg, TableType type) in OpenFlowSwitch interface to support multiple-table aware FlowRuleService.
  Other changes are caused due to the new method.
Add type() in FlowRule interface to determine the table in which the flow rule need to be set.

Change-Id: I6518a01f4a5fba23f09f70b619f3844b5e33ce8f
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 c83c156..e555794 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
@@ -40,6 +40,8 @@
     private final boolean permanent;
     private final GroupId groupId;
 
+    private final Type type;
+
 
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
             TrafficTreatment treatment, int priority, long flowId,
@@ -55,12 +57,42 @@
         this.appId = (short) (flowId >>> 48);
         this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
         this.id = FlowId.valueOf(flowId);
+        this.type = Type.DEFAULT;
     }
 
     public DefaultFlowRule(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);
+        this(deviceId, selector, treatment, priority, appId, new DefaultGroupId(0),
+                timeout, permanent);
+    }
+
+    public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
+                           TrafficTreatment treatment, int priority, ApplicationId appId,
+                           int timeout, boolean permanent, Type type) {
+
+        if (priority < FlowRule.MIN_PRIORITY) {
+            throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
+        }
+
+        this.deviceId = deviceId;
+        this.priority = priority;
+        this.selector = selector;
+        this.treatment = treatment;
+        this.appId = appId.id();
+        this.groupId = new DefaultGroupId(0);
+        this.timeout = timeout;
+        this.permanent = permanent;
+        this.created = System.currentTimeMillis();
+        this.type = type;
+
+        /*
+         * id consists of the following.
+         * | appId (16 bits) | groupId (16 bits) | flowId (32 bits) |
+         */
+        this.id = FlowId.valueOf((((long) this.appId) << 48) | (((long) this.groupId.id()) << 32)
+                | (this.hash() & 0xffffffffL));
+
     }
 
     public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
@@ -80,6 +112,7 @@
         this.timeout = timeout;
         this.permanent = permanent;
         this.created = System.currentTimeMillis();
+        this.type = Type.DEFAULT;
 
         /*
          * id consists of the following.
@@ -100,10 +133,10 @@
         this.timeout = rule.timeout();
         this.permanent = rule.isPermanent();
         this.created = System.currentTimeMillis();
+        this.type = rule.type();
 
     }
 
-
     @Override
     public FlowId id() {
         return id;
@@ -198,4 +231,9 @@
         return permanent;
     }
 
+    @Override
+    public Type type() {
+        return type;
+    }
+
 }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java b/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java
index 0a13d40..b03f620 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/FlowRule.java
@@ -27,6 +27,22 @@
     static final int MAX_TIMEOUT = 60;
     static final int MIN_PRIORITY = 0;
 
+    /**
+     * The FlowRule type is used to determine in which table the flow rule
+     * needs to be put for multi-table support switch.
+     * For single table switch, Default is used.
+     */
+    public static enum Type {
+        /* Default type - used in flow rule for single table switch */
+        DEFAULT,
+        /* Used in flow entry for IP table */
+        IP,
+        /* Used in flow entry for MPLS table */
+        MPLS,
+        /* Used in flow entry for ACL table */
+        ACL
+    }
+
     //TODO: build cookie value
     /**
      * Returns the ID of this flow.
@@ -93,4 +109,11 @@
      */
     boolean isPermanent();
 
+    /**
+     * Returns the flow rule type.
+     *
+     * @return flow rule type
+     */
+    Type type();
+
 }
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index 6a5e73f..6d3605a 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -296,8 +296,11 @@
     public static class MockFlowRule implements FlowRule {
 
         int priority;
+        Type type;
+
         public MockFlowRule(int priority) {
             this.priority = priority;
+            this.type = Type.DEFAULT;
         }
 
         @Override
@@ -361,6 +364,11 @@
             final MockFlowRule other = (MockFlowRule) obj;
             return Objects.equals(this.priority, other.priority);
         }
+
+        @Override
+        public Type type() {
+            return type;
+        }
     }
 
 
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index f843cc4..6b0db59 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -53,6 +53,7 @@
 import org.onosproject.net.device.DefaultDeviceDescription;
 import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.flow.CompletedBatchOperation;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.DefaultFlowEntry;
 import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -214,6 +215,7 @@
                     DefaultHostDescription.class,
                     DefaultFlowEntry.class,
                     StoredFlowEntry.class,
+                    FlowRule.Type.class,
                     DefaultFlowRule.class,
                     DefaultFlowEntry.class,
                     FlowEntry.FlowEntryState.class,
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java
index 11cb705..f020a1a 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/OpenFlowSwitch.java
@@ -27,6 +27,22 @@
 public interface OpenFlowSwitch {
 
     /**
+     * The TableType is used to determine in which table (TableID) each flow rule
+     * needs to be put for multi-table support switch.
+     * It is used only for multi-table support switch.
+     */
+    public static enum TableType {
+        /* IP table */
+        IP,
+        /* MPLS table */
+        MPLS,
+        /* ACL table */
+        ACL,
+        /* Single table */
+        NONE,
+    }
+
+    /**
      * Writes the message to the driver.
      *
      * @param msg the message to write
@@ -41,6 +57,16 @@
     public void sendMsg(List<OFMessage> msgs);
 
     /**
+     * Writes to the OFMessage list to the driver.
+     * TableType is used to determine the table ID for the OFMessage.
+     * The switch driver that supports multi-table should implement the function.
+     *
+     * @param msg the message to be written
+     * @param tableType the type of table in which the OFMessage needs to put
+     */
+    public void sendMsg(OFMessage msg, TableType tableType);
+
+    /**
      * Handle a message from the switch.
      * @param fromSwitch the message to handle
      */
diff --git a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
index bd5547e..6235c5c 100644
--- a/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
+++ b/openflow/api/src/main/java/org/onosproject/openflow/controller/driver/AbstractOpenFlowSwitch.java
@@ -110,6 +110,13 @@
     }
 
     @Override
+    public void sendMsg(OFMessage msg, TableType tableType) {
+        if (role == RoleState.MASTER) {
+            this.write(msg);
+        }
+    }
+
+    @Override
     public abstract void write(OFMessage msg);
 
     @Override
diff --git a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
index 25ceb13..5d3d827 100644
--- a/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
+++ b/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/RoleManagerTest.java
@@ -111,6 +111,10 @@
         }
 
         @Override
+        public void sendMsg(OFMessage msg, TableType tableType) {
+        }
+
+        @Override
         public void handleMessage(OFMessage fromSwitch) {
         }
 
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java
index b804cd9..9b68fa8 100644
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java
+++ b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplCPqD13.java
@@ -669,7 +669,6 @@
         }
         return subnetIps;
     }
-
     private static class RouteEntry {
         String prefix;
         String mask;
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTP.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTP.java
new file mode 100644
index 0000000..925a744
--- /dev/null
+++ b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFSwitchImplSpringOpenTTP.java
@@ -0,0 +1,63 @@
+/*
+ * 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.openflow.drivers;
+
+import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+
+import java.util.List;
+
+/**
+ * Created by sanghoshin on 1/22/15.
+ */
+public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
+
+    protected OFSwitchImplSpringOpenTTP(Dpid dp) {
+        super(dp);
+    }
+
+    @Override
+    public void write(OFMessage msg) {
+
+    }
+
+    @Override
+    public void write(List<OFMessage> msgs) {
+
+    }
+
+    @Override
+    public Boolean supportNxRole() {
+        return null;
+    }
+
+    @Override
+    public void startDriverHandshake() {
+
+    }
+
+    @Override
+    public boolean isDriverHandshakeComplete() {
+        return false;
+    }
+
+    @Override
+    public void processDriverHandshakeMessage(OFMessage m) {
+
+    }
+
+}
diff --git a/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java b/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java
index 6ff0cc5..e92d1be 100644
--- a/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java
+++ b/providers/openflow/device/src/test/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProviderTest.java
@@ -310,6 +310,10 @@
         }
 
         @Override
+        public void sendMsg(OFMessage msg, TableType tableType) {
+        }
+
+        @Override
         public void handleMessage(OFMessage fromSwitch) {
         }
 
diff --git a/providers/openflow/link/src/test/java/org/onosproject/provider/of/link/impl/OpenFlowLinkProviderTest.java b/providers/openflow/link/src/test/java/org/onosproject/provider/of/link/impl/OpenFlowLinkProviderTest.java
index 7684ba6..311a728 100644
--- a/providers/openflow/link/src/test/java/org/onosproject/provider/of/link/impl/OpenFlowLinkProviderTest.java
+++ b/providers/openflow/link/src/test/java/org/onosproject/provider/of/link/impl/OpenFlowLinkProviderTest.java
@@ -414,6 +414,10 @@
         }
 
         @Override
+        public void sendMsg(OFMessage msg, TableType tableType) {
+        }
+
+        @Override
         public void handleMessage(OFMessage fromSwitch) {
         }
 
diff --git a/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java b/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java
index c975135..9f03527 100644
--- a/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java
+++ b/providers/openflow/packet/src/test/java/org/onosproject/provider/of/packet/impl/OpenFlowPacketProviderTest.java
@@ -347,6 +347,10 @@
         }
 
         @Override
+        public void sendMsg(OFMessage msg, TableType tableType) {
+        }
+
+        @Override
         public void handleMessage(OFMessage fromSwitch) {
         }
 
diff --git a/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java
index 5f52081..e05cbe3 100644
--- a/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java
+++ b/web/api/src/test/java/org/onosproject/rest/FlowsResourceTest.java
@@ -186,6 +186,10 @@
         public boolean isPermanent() {
             return false;
         }
+
+        public Type type() {
+            return Type.DEFAULT;
+        }
     }
 
     /**