Add mac address field into virtual router

Change-Id: I387507756d88732f9e1733b9d1037f8d0861f848
(cherry picked from commit c49017d483949554ab85c36b0f4cfd7b23d31690)
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 f6a9545..84a5998 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
@@ -18,6 +18,7 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.MacAddress;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -37,6 +38,7 @@
     private final String name;
     private final String description;
     private final boolean enableSnat;
+    private final MacAddress mac;
     private final Set<String> internal;
     private final Map<String, String> external;
     private final KubevirtPeerRouter peerRouter;
@@ -48,12 +50,14 @@
      * @param name          router name
      * @param description   router description
      * @param enableSnat    snat use indicator
+     * @param mac           MAC address
      * @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,
+    public DefaultKubevirtRouter(String name, String description,
+                                 boolean enableSnat, MacAddress mac,
                                  Set<String> internal,
                                  Map<String, String> external,
                                  KubevirtPeerRouter peerRouter,
@@ -61,6 +65,7 @@
         this.name = name;
         this.description = description;
         this.enableSnat = enableSnat;
+        this.mac = mac;
         this.internal = internal;
         this.external = external;
         this.peerRouter = peerRouter;
@@ -83,6 +88,11 @@
     }
 
     @Override
+    public MacAddress mac() {
+        return mac;
+    }
+
+    @Override
     public Set<String> internal() {
         if (internal == null) {
             return ImmutableSet.of();
@@ -116,6 +126,7 @@
                 .name(name)
                 .enableSnat(enableSnat)
                 .description(description)
+                .mac(mac)
                 .internal(internal)
                 .external(external)
                 .peerRouter(updated)
@@ -129,6 +140,7 @@
                 .name(name)
                 .enableSnat(enableSnat)
                 .description(description)
+                .mac(mac)
                 .internal(internal)
                 .external(external)
                 .peerRouter(peerRouter)
@@ -146,14 +158,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) &&
-                gateway.equals(that.electedGateway());
+                description.equals(that.description) && mac.equals(that.mac) &&
+                internal.equals(that.internal) && external.equals(that.external) &&
+                peerRouter.equals(that.peerRouter) && gateway.equals(that.electedGateway());
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(name, description, enableSnat,
+        return Objects.hash(name, description, mac, enableSnat,
                 internal, external, peerRouter, gateway);
     }
 
@@ -163,6 +175,7 @@
                 .add("name", name)
                 .add("description", description)
                 .add("enableSnat", enableSnat)
+                .add("mac", mac)
                 .add("internal", internal)
                 .add("external", external)
                 .add("peerRouter", peerRouter)
@@ -184,6 +197,7 @@
         private String name;
         private String description;
         private boolean enableSnat;
+        private MacAddress mac;
         private Set<String> internal;
         private Map<String, String> external;
         private KubevirtPeerRouter peerRouter;
@@ -193,7 +207,7 @@
         public KubevirtRouter build() {
             checkArgument(name != null, NOT_NULL_MSG, "name");
 
-            return new DefaultKubevirtRouter(name, description, enableSnat,
+            return new DefaultKubevirtRouter(name, description, enableSnat, mac,
                     internal, external, peerRouter, gateway);
         }
 
@@ -216,6 +230,12 @@
         }
 
         @Override
+        public Builder mac(MacAddress mac) {
+            this.mac = mac;
+            return this;
+        }
+
+        @Override
         public Builder internal(Set<String> internal) {
             this.internal = Objects.requireNonNullElseGet(internal, HashSet::new);
             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 c7ae7b4..db62c77 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
@@ -15,6 +15,8 @@
  */
 package org.onosproject.kubevirtnetworking.api;
 
+import org.onlab.packet.MacAddress;
+
 import java.util.Map;
 import java.util.Set;
 
@@ -45,6 +47,13 @@
     boolean enableSnat();
 
     /**
+     * Returns the MAC address.
+     *
+     * @return mac address
+     */
+    MacAddress mac();
+
+    /**
      * Returns a set of internal networks.
      *
      * @return a set of internal networks
@@ -124,6 +133,14 @@
         Builder enableSnat(boolean flag);
 
         /**
+         * Returns kubevirt router builder with supplied MAC address.
+         *
+         * @param mac MAC address
+         * @return router builder
+         */
+        Builder mac(MacAddress mac);
+
+        /**
          * Returns kubevirt router builder with supplied internal networks.
          *
          * @param internal internal network set
diff --git a/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouterTest.java b/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouterTest.java
index 1ad8d87..644b839 100644
--- a/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouterTest.java
+++ b/apps/kubevirt-networking/api/src/test/java/org/onosproject/kubevirtnetworking/api/DefaultKubevirtRouterTest.java
@@ -39,6 +39,8 @@
     private static final String DESCRIPTION_2 = "dummy router 2";
     private static final boolean ENABLE_SNAT_1 = false;
     private static final boolean ENABLE_SNAT_2 = true;
+    private static final MacAddress MAC_ADDRESS_1 = MacAddress.valueOf("11:22:33:44:55:66");
+    private static final MacAddress MAC_ADDRESS_2 = MacAddress.valueOf("22:33:44:55:66:77");
     private static final KubevirtNetwork.Type TYPE_1 = FLAT;
     private static final KubevirtNetwork.Type TYPE_2 = VXLAN;
     private static final String NETWORK_NAME_1 = "net-1";
@@ -74,6 +76,7 @@
                 .name(NAME_1)
                 .description(DESCRIPTION_1)
                 .enableSnat(ENABLE_SNAT_1)
+                .mac(MAC_ADDRESS_1)
                 .internal(ImmutableSet.of(NETWORK_NAME_1))
                 .external(ImmutableMap.of("10.10.10.10", NETWORK_NAME_1))
                 .peerRouter(PEER_ROUTER_1)
@@ -83,6 +86,7 @@
                 .name(NAME_1)
                 .description(DESCRIPTION_1)
                 .enableSnat(ENABLE_SNAT_1)
+                .mac(MAC_ADDRESS_1)
                 .internal(ImmutableSet.of(NETWORK_NAME_1))
                 .external(ImmutableMap.of("10.10.10.10", NETWORK_NAME_1))
                 .peerRouter(PEER_ROUTER_1)
@@ -92,6 +96,7 @@
                 .name(NAME_2)
                 .description(DESCRIPTION_2)
                 .enableSnat(ENABLE_SNAT_2)
+                .mac(MAC_ADDRESS_2)
                 .internal(ImmutableSet.of(NETWORK_NAME_2))
                 .external(ImmutableMap.of("20.20.20.20", NETWORK_NAME_2))
                 .peerRouter(PEER_ROUTER_2)
@@ -119,6 +124,7 @@
         assertEquals(NAME_1, router.name());
         assertEquals(DESCRIPTION_1, router.description());
         assertEquals(ENABLE_SNAT_1, router.enableSnat());
+        assertEquals(MAC_ADDRESS_1, router.mac());
         assertEquals(ImmutableSet.of(NETWORK_NAME_1), router.internal());
         assertEquals(ImmutableMap.of("10.10.10.10", NETWORK_NAME_1), router.external());
         assertEquals(PEER_ROUTER_1, router.peerRouter());
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodec.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodec.java
index d1239de..5ca4ab6 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodec.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodec.java
@@ -62,7 +62,8 @@
 
         ObjectNode result = context.mapper().createObjectNode()
                 .put(NAME, router.name())
-                .put(ENABLE_SNAT, router.enableSnat());
+                .put(ENABLE_SNAT, router.enableSnat())
+                .put(MAC_ADDRESS, router.mac().toString());
 
         if (router.description() != null) {
             result.put(DESCRIPTION, router.description());
@@ -113,8 +114,12 @@
         String name = nullIsIllegal(json.get(NAME).asText(),
                 NAME + MISSING_MESSAGE);
 
+        String vrouterMac = nullIsIllegal(json.get(MAC_ADDRESS).asText(),
+                MAC_ADDRESS + MISSING_MESSAGE);
+
         KubevirtRouter.Builder builder = DefaultKubevirtRouter.builder()
-                .name(name);
+                .name(name)
+                .mac(MacAddress.valueOf(vrouterMac));
 
         JsonNode descriptionJson = json.get(DESCRIPTION);
         if (descriptionJson != null) {
diff --git a/apps/kubevirt-networking/app/src/main/resources/definitions/KubevirtRouters.json b/apps/kubevirt-networking/app/src/main/resources/definitions/KubevirtRouters.json
index 3546dff..835dfea 100644
--- a/apps/kubevirt-networking/app/src/main/resources/definitions/KubevirtRouters.json
+++ b/apps/kubevirt-networking/app/src/main/resources/definitions/KubevirtRouters.json
@@ -17,6 +17,7 @@
         "required": [
           "name",
           "enableSnat",
+          "mac",
           "internal",
           "external",
           "peerRouter"
@@ -32,6 +33,11 @@
             "example": "true",
             "description": "Enable SNAT flag."
           },
+          "mac": {
+            "type": "string",
+            "example": "11:22:33:44:55:66",
+            "description": "The MAC address of virtual router."
+          },
           "internal": {
             "type": "array",
             "xml": {
@@ -77,7 +83,7 @@
                 "example": "10.10.10.1",
                 "description": "IP address of the peer router"
               },
-              "macaddress": {
+              "mac": {
                 "type": "string",
                 "example": "11:22:33:44:55:66",
                 "description": "MAC address of the peer router"
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java
index 3af305c..1ff8951 100644
--- a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterCodecTest.java
@@ -79,6 +79,7 @@
         KubevirtRouter router = DefaultKubevirtRouter.builder()
                 .name("router-1")
                 .enableSnat(true)
+                .mac(MacAddress.valueOf("11:22:33:44:55:66"))
                 .description("router-1")
                 .internal(ImmutableSet.of("vlan-1"))
                 .external(ImmutableMap.of("10.10.10.20", "flat-1"))
@@ -97,6 +98,7 @@
         assertEquals("router-1", router.name());
         assertEquals("Example Virtual Router", router.description());
         assertTrue(router.enableSnat());
+        assertEquals("11:22:33:44:55:66", router.mac().toString());
         assertEquals("192.168.10.5",
                 router.external().keySet().stream().findAny().orElse(null));
         assertEquals("external-network", router.external().get("192.168.10.5"));
diff --git a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java
index 1b394e7..a855f42 100644
--- a/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java
+++ b/apps/kubevirt-networking/app/src/test/java/org/onosproject/kubevirtnetworking/codec/KubevirtRouterJsonMatcher.java
@@ -73,6 +73,14 @@
             }
         }
 
+        // check vrouter MAC
+        String jsonMac = jsonNode.get(MAC_ADDRESS).asText();
+        String mac = router.mac().toString();
+        if (!jsonMac.equals(mac)) {
+            description.appendText("MAC was " + jsonMac);
+            return false;
+        }
+
         // check internal
         JsonNode jsonInternal = jsonNode.get(INTERNAL);
         if (jsonInternal != null) {
@@ -134,10 +142,10 @@
                 }
             }
 
-            JsonNode jsonMac = jsonPeerRouter.get(MAC_ADDRESS);
+            JsonNode jsonProuterMac = jsonPeerRouter.get(MAC_ADDRESS);
 
-            if (jsonMac != null) {
-                if (!jsonMac.asText().equals(router.peerRouter().macAddress().toString())) {
+            if (jsonProuterMac != null) {
+                if (!jsonProuterMac.asText().equals(router.peerRouter().macAddress().toString())) {
                     description.appendText("Peer router MAC was " + jsonMac);
                     return false;
                 }
diff --git a/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtRouter.json b/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtRouter.json
index 14e60ec..5d9d53c 100644
--- a/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtRouter.json
+++ b/apps/kubevirt-networking/app/src/test/resources/org/onosproject/kubevirtnetworking/codec/KubevirtRouter.json
@@ -2,6 +2,7 @@
   "name": "router-1",
   "description": "Example Virtual Router",
   "enableSnat": true,
+  "mac": "11:22:33:44:55:66",
   "external": {
     "ip": "192.168.10.5",
     "network": "external-network"