Implement kubevirt router store, manager and codec with unit tests

Change-Id: Ib93a71326aa35b4817f0e6b6c97d5f57b26fe470
diff --git a/apps/kubevirt-networking/api/BUILD b/apps/kubevirt-networking/api/BUILD
index d935077..968dd56 100644
--- a/apps/kubevirt-networking/api/BUILD
+++ b/apps/kubevirt-networking/api/BUILD
@@ -24,6 +24,7 @@
     "@okhttp//jar",
     "@okio//jar",
     "@logging_interceptor//jar",
+    "@jackson_databind//jar",
     "@jackson_dataformat_yaml//jar",
     "@jackson_datatype_jsr310//jar",
     "@snakeyaml//jar",
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/AbstractWatcher.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/AbstractWatcher.java
new file mode 100644
index 0000000..f7fcfc1
--- /dev/null
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/AbstractWatcher.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2021-present Open Networking Foundation
+ *
+ * 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.kubevirtnetworking.api;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.JsonCodec;
+
+/**
+ * Abstract watcher.
+ */
+public class AbstractWatcher implements CodecContext {
+
+    private static ServiceDirectory services = new DefaultServiceDirectory();
+    private final ObjectMapper mapper = new ObjectMapper();
+
+    @Override
+    public ObjectMapper mapper() {
+        return mapper;
+    }
+
+    @Override
+    public <T> JsonCodec<T> codec(Class<T> entityClass) {
+        return services.get(CodecService.class).getCodec(entityClass);
+    }
+
+    @Override
+    public <T> T getService(Class<T> serviceClass) {
+        return services.get(serviceClass);
+    }
+}
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
index 3f5620e..0c97fb6 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/Constants.java
@@ -87,6 +87,7 @@
     public static final int CLI_SEG_ID_LENGTH = 10;
     public static final int CLI_LABELS_LENGTH = 30;
     public static final int CLI_CONTAINERS_LENGTH = 30;
+    public static final int CLI_FLAG_LENGTH = 10;
     public static final int CLI_MARGIN_LENGTH = 2;
 
     public static final int PRIORITY_STATEFUL_SNAT_RULE = 40500;
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 e606275..4bf04a2 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,7 +18,6 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import org.onlab.packet.IpAddress;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -39,7 +38,7 @@
     private final String description;
     private final boolean enableSnat;
     private final Set<String> internal;
-    private final Map<IpAddress, String> external;
+    private final Map<String, String> external;
     private final KubevirtPeerRouter peerRouter;
 
     /**
@@ -54,7 +53,7 @@
      */
     public DefaultKubevirtRouter(String name, String description, boolean enableSnat,
                                  Set<String> internal,
-                                 Map<IpAddress, String> external,
+                                 Map<String, String> external,
                                  KubevirtPeerRouter peerRouter) {
         this.name = name;
         this.description = description;
@@ -85,7 +84,7 @@
     }
 
     @Override
-    public Map<IpAddress, String> external() {
+    public Map<String, String> external() {
         return ImmutableMap.copyOf(external);
     }
 
@@ -95,6 +94,18 @@
     }
 
     @Override
+    public KubevirtRouter updatePeerRouter(KubevirtPeerRouter updated) {
+        return DefaultKubevirtRouter.builder()
+                .name(name)
+                .enableSnat(enableSnat)
+                .description(description)
+                .internal(internal)
+                .external(external)
+                .peerRouter(updated)
+                .build();
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -140,7 +151,7 @@
         private String description;
         private boolean enableSnat;
         private Set<String> internal;
-        private Map<IpAddress, String> external;
+        private Map<String, String> external;
         private KubevirtPeerRouter peerRouter;
 
         @Override
@@ -176,7 +187,7 @@
         }
 
         @Override
-        public Builder external(Map<IpAddress, String> external) {
+        public Builder external(Map<String, String> external) {
             this.external = Objects.requireNonNullElseGet(external, HashMap::new);
             return this;
         }
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtPeerRouter.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtPeerRouter.java
index 00dbc2f..4ebe556 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtPeerRouter.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtPeerRouter.java
@@ -35,7 +35,7 @@
      * @param ipAddress  IP address
      * @param macAddress MAC address
      */
-    KubevirtPeerRouter(IpAddress ipAddress, MacAddress macAddress) {
+    public KubevirtPeerRouter(IpAddress ipAddress, MacAddress macAddress) {
         this.ipAddress = ipAddress;
         this.macAddress = macAddress;
     }
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 c10116f..e9f5e88 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,8 +15,6 @@
  */
 package org.onosproject.kubevirtnetworking.api;
 
-import org.onlab.packet.IpAddress;
-
 import java.util.Map;
 import java.util.Set;
 
@@ -59,7 +57,7 @@
      *
      * @return external network paired with external router IP address
      */
-    Map<IpAddress, String> external();
+    Map<String, String> external();
 
     /**
      * Returns external peer router.
@@ -68,6 +66,14 @@
      */
     KubevirtPeerRouter peerRouter();
 
+    /**
+     * Updates the peer router.
+     *
+     * @param updated updated peer router
+     * @return kubevirt router with the updated peer router
+     */
+    KubevirtRouter updatePeerRouter(KubevirtPeerRouter updated);
+
     interface Builder {
 
         /**
@@ -115,7 +121,7 @@
          * @param external external network with IP
          * @return router builder
          */
-        Builder external(Map<IpAddress, String> external);
+        Builder external(Map<String, String> external);
 
         /**
          * Returns kubevirt router builder with supplied peer router.
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterAdminService.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterAdminService.java
index c963551..1ec1cee 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterAdminService.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtRouterAdminService.java
@@ -15,6 +15,8 @@
  */
 package org.onosproject.kubevirtnetworking.api;
 
+import org.onlab.packet.MacAddress;
+
 /**
  * Service for administering the inventory of kubevirt router service.
  */
@@ -42,6 +44,14 @@
     void removeRouter(String name);
 
     /**
+     * Updates the MAC address of the peer router.
+     *
+     * @param name router name
+     * @param mac peer router MAC address
+     */
+    void updatePeerRouterMac(String name, MacAddress mac);
+
+    /**
      * Removes all routers.
      */
     void clear();
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 52d4824..b195ecb 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
@@ -28,7 +28,7 @@
      * @param type      kubevirt router event type
      * @param subject   kubevirt router
      */
-    protected KubevirtRouterEvent(Type type, KubevirtRouter subject) {
+    public KubevirtRouterEvent(Type type, KubevirtRouter subject) {
         super(type, subject);
     }
 
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 2ced87e..91ff8ad 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
@@ -73,7 +73,7 @@
                 .description(DESCRIPTION_1)
                 .enableSnat(ENABLE_SNAT_1)
                 .internal(ImmutableSet.of(NETWORK_NAME_1))
-                .external(ImmutableMap.of(IpAddress.valueOf("10.10.10.10"), NETWORK_NAME_1))
+                .external(ImmutableMap.of("10.10.10.10", NETWORK_NAME_1))
                 .peerRouter(PEER_ROUTER_1)
                 .build();
         sameAsRouter1 = DefaultKubevirtRouter.builder()
@@ -81,7 +81,7 @@
                 .description(DESCRIPTION_1)
                 .enableSnat(ENABLE_SNAT_1)
                 .internal(ImmutableSet.of(NETWORK_NAME_1))
-                .external(ImmutableMap.of(IpAddress.valueOf("10.10.10.10"), NETWORK_NAME_1))
+                .external(ImmutableMap.of("10.10.10.10", NETWORK_NAME_1))
                 .peerRouter(PEER_ROUTER_1)
                 .build();
         router2 = DefaultKubevirtRouter.builder()
@@ -89,7 +89,7 @@
                 .description(DESCRIPTION_2)
                 .enableSnat(ENABLE_SNAT_2)
                 .internal(ImmutableSet.of(NETWORK_NAME_2))
-                .external(ImmutableMap.of(IpAddress.valueOf("20.20.20.20"), NETWORK_NAME_2))
+                .external(ImmutableMap.of("20.20.20.20", NETWORK_NAME_2))
                 .peerRouter(PEER_ROUTER_2)
                 .build();
     }
@@ -115,7 +115,7 @@
         assertEquals(DESCRIPTION_1, router.description());
         assertEquals(ENABLE_SNAT_1, router.enableSnat());
         assertEquals(ImmutableSet.of(NETWORK_NAME_1), router.internal());
-        assertEquals(ImmutableMap.of(IpAddress.valueOf("10.10.10.10"), NETWORK_NAME_1), router.external());
+        assertEquals(ImmutableMap.of("10.10.10.10", NETWORK_NAME_1), router.external());
         assertEquals(PEER_ROUTER_1, router.peerRouter());
     }
 }