Initial implementation of SNAT functionality.

Change-Id: I9094755c6d25a62e527976b9bf275d7c1e2a3f86
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouter.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouter.java
index 98653d9..f6a9545 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouter.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouter.java
@@ -40,6 +40,7 @@
     private final Set<String> internal;
     private final Map<String, String> external;
     private final KubevirtPeerRouter peerRouter;
+    private final String gateway;
 
     /**
      * A default constructor.
@@ -50,17 +51,20 @@
      * @param internal      internal networks
      * @param external      external network
      * @param peerRouter    external peer router
+     * @param gateway       elected gateway node id
      */
     public DefaultKubevirtRouter(String name, String description, boolean enableSnat,
                                  Set<String> internal,
                                  Map<String, String> external,
-                                 KubevirtPeerRouter peerRouter) {
+                                 KubevirtPeerRouter peerRouter,
+                                 String gateway) {
         this.name = name;
         this.description = description;
         this.enableSnat = enableSnat;
         this.internal = internal;
         this.external = external;
         this.peerRouter = peerRouter;
+        this.gateway = gateway;
     }
 
     @Override
@@ -102,6 +106,11 @@
     }
 
     @Override
+    public String electedGateway() {
+        return gateway;
+    }
+
+    @Override
     public KubevirtRouter updatePeerRouter(KubevirtPeerRouter updated) {
         return DefaultKubevirtRouter.builder()
                 .name(name)
@@ -110,6 +119,20 @@
                 .internal(internal)
                 .external(external)
                 .peerRouter(updated)
+                .electedGateway(gateway)
+                .build();
+    }
+
+    @Override
+    public KubevirtRouter updatedElectedGateway(String updated) {
+        return DefaultKubevirtRouter.builder()
+                .name(name)
+                .enableSnat(enableSnat)
+                .description(description)
+                .internal(internal)
+                .external(external)
+                .peerRouter(peerRouter)
+                .electedGateway(updated)
                 .build();
     }
 
@@ -124,12 +147,14 @@
         DefaultKubevirtRouter that = (DefaultKubevirtRouter) o;
         return enableSnat == that.enableSnat && name.equals(that.name) &&
                 description.equals(that.description) && internal.equals(that.internal) &&
-                external.equals(that.external) && peerRouter.equals(that.peerRouter);
+                external.equals(that.external) && peerRouter.equals(that.peerRouter) &&
+                gateway.equals(that.electedGateway());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(name, description, enableSnat, internal, external, peerRouter);
+        return Objects.hash(name, description, enableSnat,
+                internal, external, peerRouter, gateway);
     }
 
     @Override
@@ -141,6 +166,7 @@
                 .add("internal", internal)
                 .add("external", external)
                 .add("peerRouter", peerRouter)
+                .add("electedGateway", gateway)
                 .toString();
     }
 
@@ -161,13 +187,14 @@
         private Set<String> internal;
         private Map<String, String> external;
         private KubevirtPeerRouter peerRouter;
+        private String gateway;
 
         @Override
         public KubevirtRouter build() {
             checkArgument(name != null, NOT_NULL_MSG, "name");
 
             return new DefaultKubevirtRouter(name, description, enableSnat,
-                    internal, external, peerRouter);
+                    internal, external, peerRouter, gateway);
         }
 
         @Override
@@ -205,5 +232,11 @@
             this.peerRouter = router;
             return this;
         }
+
+        @Override
+        public Builder electedGateway(String gateway) {
+            this.gateway = gateway;
+            return this;
+        }
     }
 }
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouter.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouter.java
index 697198b..c7ae7b4 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouter.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouter.java
@@ -67,13 +67,29 @@
     KubevirtPeerRouter peerRouter();
 
     /**
+     * Returns elected gateway node hostname.
+     *
+     * @return gateway node hostname.
+     */
+    String electedGateway();
+
+    /**
      * Updates the peer router.
      *
      * @param updated updated peer router
-     * @return kubevirt router with the updated peer router
+     * @return kubevirt router with updated peer router
      */
     KubevirtRouter updatePeerRouter(KubevirtPeerRouter updated);
 
+    /**
+     * Updates the elected gateway node host name.
+     *
+     * @param updated updated elected gateway node hostname
+     * @return kubevirt router with the updated gateway node hostname
+     */
+    KubevirtRouter updatedElectedGateway(String updated);
+
+
     interface Builder {
 
         /**
@@ -130,5 +146,13 @@
          * @return router builder
          */
         Builder peerRouter(KubevirtPeerRouter router);
+
+        /**
+         * Returns kubevirt router builder with supplied elected gateway node hostname.
+         *
+         * @param gateway gateway node hostname
+         * @return router builder
+         */
+        Builder electedGateway(String gateway);
     }
 }
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
index d4d6b23..e9bb84f 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterEvent.java
@@ -32,6 +32,7 @@
     private final String externalIp;
     private final String externalNet;
     private final String peerRouterIp;
+    private final String gateway;
 
     /**
      * Creates an event of a given type for the specified kubevirt router.
@@ -47,6 +48,7 @@
         this.externalIp = null;
         this.externalNet = null;
         this.peerRouterIp = null;
+        this.gateway = null;
     }
 
     /**
@@ -64,6 +66,8 @@
         this.externalIp = null;
         this.externalNet = null;
         this.peerRouterIp = null;
+        this.gateway = null;
+
     }
 
     /**
@@ -82,6 +86,7 @@
         this.externalIp = null;
         this.externalNet = null;
         this.peerRouterIp = null;
+        this.gateway = null;
     }
 
     /**
@@ -99,6 +104,7 @@
         this.externalIp = null;
         this.externalNet = null;
         this.peerRouterIp = null;
+        this.gateway = null;
     }
 
     /**
@@ -120,6 +126,19 @@
         this.externalIp = externalIp;
         this.externalNet = externalNet;
         this.peerRouterIp = peerRouterIp;
+        this.gateway = null;
+    }
+
+    public KubevirtRouterEvent(Type type, KubevirtRouter subject,
+                               String gateway) {
+        super(type, subject);
+        this.gateway = gateway;
+        this.floatingIp = null;
+        this.podName = null;
+        this.internal = null;
+        this.externalIp = null;
+        this.externalNet = null;
+        this.peerRouterIp = null;
     }
 
     public enum Type {
@@ -181,7 +200,20 @@
         /**
          * Signifies that the floating IP disassociated from the fixed IP.
          */
-        KUBEVIRT_FLOATING_IP_DISASSOCIATED
+        KUBEVIRT_FLOATING_IP_DISASSOCIATED,
+
+        /**
+         * Signified that the gateway node associated for this router.
+         */
+        KUBEVIRT_GATEWAY_NODE_ATTACHED,
+        /**
+         * Signified that the gateway node disassociated for this router.
+         */
+        KUBEVIRT_GATEWAY_NODE_DETACHED,
+        /**
+         * Signified that the gateway node changed for this router.
+         */
+        KUBEVIRT_GATEWAY_NODE_CHANGED
     }
 
     /**
@@ -229,6 +261,15 @@
         return externalNet;
     }
 
+    /**
+     * Returns the gateway of the router event.
+     *
+     * @return gateway if exists, null otherwise
+     */
+    public String gateway() {
+        return gateway;
+    }
+
     @Override
     public String toString() {
         if (floatingIp == null) {
@@ -243,6 +284,7 @@
                 .add("externalIp", externalIp)
                 .add("externalNet", externalNet)
                 .add("peerRouterIp", peerRouterIp)
+                .add("gatewayNodeHostName", gateway)
                 .toString();
     }
 }