Support to inject external bridge into k8s node for external routing

1. Add group bucket related rules on receiving endpoint events
   rather than POD events.

Change-Id: I1152343cf8ff6bbccaed3dc34908a3affbc70980
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
index bcc154b..a04664f 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/Constants.java
@@ -24,6 +24,9 @@
     }
 
     public static final String INTEGRATION_BRIDGE = "kbr-int";
+    public static final String EXTERNAL_BRIDGE = "kbr-ex";
+    public static final String INTEGRATION_TO_EXTERNAL_BRIDGE = "kbr-int-ex";
+    public static final String PHYSICAL_EXTERNAL_BRIDGE = "phy-kbr-ex";
     public static final String VXLAN_TUNNEL = "vxlan";
     public static final String GRE_TUNNEL = "gre";
     public static final String GENEVE_TUNNEL = "geneve";
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
index c7c08d3..e38d0a4 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/DefaultK8sNode.java
@@ -49,6 +49,7 @@
     private final String hostname;
     private final Type type;
     private final DeviceId intgBridge;
+    private final DeviceId extBridge;
     private final IpAddress managementIp;
     private final IpAddress dataIp;
     private final K8sNodeState state;
@@ -63,16 +64,18 @@
      * @param hostname          hostname
      * @param type              node type
      * @param intgBridge        integration bridge
+     * @param extBridge         external bridge
      * @param managementIp      management IP address
      * @param dataIp            data IP address
      * @param state             node state
      */
     protected DefaultK8sNode(String hostname, Type type, DeviceId intgBridge,
-                             IpAddress managementIp, IpAddress dataIp,
-                             K8sNodeState state) {
+                             DeviceId extBridge, IpAddress managementIp,
+                             IpAddress dataIp, K8sNodeState state) {
         this.hostname = hostname;
         this.type = type;
         this.intgBridge = intgBridge;
+        this.extBridge = extBridge;
         this.managementIp = managementIp;
         this.dataIp = dataIp;
         this.state = state;
@@ -99,11 +102,30 @@
     }
 
     @Override
+    public DeviceId extBridge() {
+        return extBridge;
+    }
+
+    @Override
     public K8sNode updateIntgBridge(DeviceId deviceId) {
         return new Builder()
                 .hostname(hostname)
                 .type(type)
                 .intgBridge(deviceId)
+                .extBridge(extBridge)
+                .managementIp(managementIp)
+                .dataIp(dataIp)
+                .state(state)
+                .build();
+    }
+
+    @Override
+    public K8sNode updateExtBridge(DeviceId deviceId) {
+        return new Builder()
+                .hostname(hostname)
+                .type(type)
+                .intgBridge(intgBridge)
+                .extBridge(deviceId)
                 .managementIp(managementIp)
                 .dataIp(dataIp)
                 .state(state)
@@ -189,6 +211,7 @@
             return hostname.equals(that.hostname) &&
                     type == that.type &&
                     intgBridge.equals(that.intgBridge) &&
+                    extBridge.equals(that.extBridge) &&
                     managementIp.equals(that.managementIp) &&
                     dataIp.equals(that.dataIp) &&
                     state == that.state;
@@ -199,7 +222,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(hostname, type, intgBridge, managementIp, dataIp, state);
+        return Objects.hash(hostname, type, intgBridge, extBridge,
+                            managementIp, dataIp, state);
     }
 
     @Override
@@ -208,6 +232,7 @@
                 .add("hostname", hostname)
                 .add("type", type)
                 .add("intgBridge", intgBridge)
+                .add("extBridge", extBridge)
                 .add("managementIp", managementIp)
                 .add("dataIp", dataIp)
                 .add("state", state)
@@ -246,6 +271,7 @@
                 .hostname(node.hostname())
                 .type(node.type())
                 .intgBridge(node.intgBridge())
+                .extBridge(node.extBridge())
                 .managementIp(node.managementIp())
                 .dataIp(node.dataIp())
                 .state(node.state());
@@ -256,6 +282,7 @@
         private String hostname;
         private Type type;
         private DeviceId intgBridge;
+        private DeviceId extBridge;
         private IpAddress managementIp;
         private IpAddress dataIp;
         private K8sNodeState state;
@@ -275,6 +302,7 @@
             return new DefaultK8sNode(hostname,
                     type,
                     intgBridge,
+                    extBridge,
                     managementIp,
                     dataIp,
                     state);
@@ -299,6 +327,12 @@
         }
 
         @Override
+        public Builder extBridge(DeviceId deviceId) {
+            this.extBridge = deviceId;
+            return this;
+        }
+
+        @Override
         public Builder managementIp(IpAddress managementIp) {
             this.managementIp = managementIp;
             return this;
diff --git a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
index 2c539f3..6dfbead 100644
--- a/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
+++ b/apps/k8s-node/api/src/main/java/org/onosproject/k8snode/api/K8sNode.java
@@ -69,6 +69,13 @@
     DeviceId intgBridge();
 
     /**
+     * Returns the device ID of the external bridge at the node.
+     *
+     * @return device id
+     */
+    DeviceId extBridge();
+
+    /**
      * Returns new kubernetes node instance with given integration bridge.
      *
      * @param deviceId  integration bridge device ID
@@ -77,6 +84,14 @@
     K8sNode updateIntgBridge(DeviceId deviceId);
 
     /**
+     * Returns new kubernetes node instance with given external bridge.
+     *
+     * @param deviceId external bridge device ID
+     * @return updated kubernetes node
+     */
+    K8sNode updateExtBridge(DeviceId deviceId);
+
+    /**
      * Returns the management network IP address of the node.
      *
      * @return ip address
@@ -169,7 +184,7 @@
         Builder type(Type type);
 
         /**
-         * Returns kubernetes node builder with supplied bridge name.
+         * Returns kubernetes node builder with supplied integration bridge name.
          *
          * @param deviceId integration bridge device ID
          * @return kubernetes node builder
@@ -177,6 +192,14 @@
         Builder intgBridge(DeviceId deviceId);
 
         /**
+         * Returns kubernetes node builder with supplied external bridge name.
+         *
+         * @param deviceId external bridge deviceID
+         * @return kubernetes node builder
+         */
+        Builder extBridge(DeviceId deviceId);
+
+        /**
          * Returns kubernetes node builder with supplied management IP address.
          *
          * @param managementIp management IP address
diff --git a/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java b/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java
index d30c798..d93c8dc 100644
--- a/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java
+++ b/apps/k8s-node/api/src/test/java/org/onosproject/k8snode/api/DefaultK8sNodeTest.java
@@ -55,18 +55,21 @@
             HOSTNAME_1,
             MINION,
             DEVICE_1,
+            DEVICE_1,
             TEST_IP,
             INIT);
     private static final K8sNode K8S_NODE_2 = createNode(
             HOSTNAME_1,
             MINION,
             DEVICE_1,
+            DEVICE_1,
             TEST_IP,
             INIT);
     private static final K8sNode K8S_NODE_3 = createNode(
             HOSTNAME_2,
             MINION,
             DEVICE_2,
+            DEVICE_2,
             TEST_IP,
             INIT);
 
@@ -81,6 +84,7 @@
                 .managementIp(MANAGEMENT_IP)
                 .dataIp(DATA_IP)
                 .intgBridge(DEVICE_1.id())
+                .extBridge(DEVICE_1.id())
                 .state(COMPLETE)
                 .build();
     }
@@ -103,6 +107,7 @@
         checkCommonProperties(refNode);
         assertSame(refNode.state(), COMPLETE);
         assertEquals(refNode.intgBridge(), DEVICE_1.id());
+        assertEquals(refNode.extBridge(), DEVICE_1.id());
     }
 
     /**
@@ -134,6 +139,7 @@
         DefaultK8sNode.builder()
                 .type(MINION)
                 .intgBridge(DEVICE_1.id())
+                .extBridge(DEVICE_1.id())
                 .managementIp(TEST_IP)
                 .dataIp(TEST_IP)
                 .state(INIT)
@@ -148,6 +154,7 @@
         DefaultK8sNode.builder()
                 .hostname(HOSTNAME_1)
                 .intgBridge(DEVICE_1.id())
+                .extBridge(DEVICE_1.id())
                 .managementIp(TEST_IP)
                 .dataIp(TEST_IP)
                 .state(INIT)
@@ -164,6 +171,7 @@
                 .hostname(HOSTNAME_1)
                 .type(MINION)
                 .intgBridge(DEVICE_1.id())
+                .extBridge(DEVICE_1.id())
                 .dataIp(TEST_IP)
                 .state(INIT)
                 .build();
@@ -188,12 +196,13 @@
     }
 
     private static K8sNode createNode(String hostname, Type type,
-                                      Device intgBridge, IpAddress ipAddr,
-                                      K8sNodeState state) {
+                                      Device intgBridge, Device extBridge,
+                                      IpAddress ipAddr, K8sNodeState state) {
         return DefaultK8sNode.builder()
                 .hostname(hostname)
                 .type(type)
                 .intgBridge(intgBridge.id())
+                .extBridge(extBridge.id())
                 .managementIp(ipAddr)
                 .dataIp(ipAddr)
                 .state(state)