Check node init status when probing node health through REST API

Support to inject controller IP address to API config.

Change-Id: Iece8a84b698ef0da9803f11d473257c84e5adc4d
(cherry picked from commit 6a08072a2c1c3094818268ebf22ffa82f9713125)
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java
index af280fb..1cf58ed 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfig.java
@@ -40,6 +40,7 @@
     private final String clientKeyData;
     private final String serviceFqdn;
     private final String apiServerFqdn;
+    private final IpAddress controllerIp;
 
     /**
      * Default constructor for Kubevirt API config.
@@ -54,12 +55,14 @@
      * @param clientKeyData     client key data
      * @param serviceFqdn       service FQDN
      * @param apiServerFqdn     API server FQDN
+     * @param controllerIp      controller IP address
      */
     private DefaultKubevirtApiConfig(Scheme scheme, IpAddress ipAddress,
                                     int port, State state,
                                     String token, String caCertData,
                                     String clientCertData, String clientKeyData,
-                                    String serviceFqdn, String apiServerFqdn) {
+                                    String serviceFqdn, String apiServerFqdn,
+                                    IpAddress controllerIp) {
         this.scheme = scheme;
         this.ipAddress = ipAddress;
         this.port = port;
@@ -70,6 +73,7 @@
         this.clientKeyData = clientKeyData;
         this.serviceFqdn = serviceFqdn;
         this.apiServerFqdn = apiServerFqdn;
+        this.controllerIp = controllerIp;
     }
 
     @Override
@@ -105,6 +109,7 @@
                 .clientKeyData(clientKeyData)
                 .serviceFqdn(serviceFqdn)
                 .apiServerFqdn(apiServerFqdn)
+                .controllerIp(controllerIp)
                 .build();
     }
 
@@ -121,6 +126,7 @@
                 .clientKeyData(clientKeyData)
                 .serviceFqdn(serviceFqdn)
                 .apiServerFqdn(apiServerFqdn)
+                .controllerIp(controllerIp)
                 .build();
     }
 
@@ -137,6 +143,7 @@
                 .clientKeyData(clientKeyData)
                 .serviceFqdn(serviceFqdn)
                 .apiServerFqdn(apiServerFqdn)
+                .controllerIp(controllerIp)
                 .build();
     }
 
@@ -171,6 +178,11 @@
     }
 
     @Override
+    public IpAddress controllerIp() {
+        return controllerIp;
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) {
             return true;
@@ -185,13 +197,15 @@
                 clientCertData.equals(that.clientCertData) &&
                 clientKeyData.equals(that.clientKeyData) &&
                 Objects.equals(serviceFqdn, that.serviceFqdn) &&
-                Objects.equals(apiServerFqdn, that.apiServerFqdn);
+                Objects.equals(apiServerFqdn, that.apiServerFqdn) &&
+                Objects.equals(controllerIp, that.controllerIp);
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(scheme, ipAddress, port, state, token,
-                caCertData, clientCertData, clientKeyData, serviceFqdn, apiServerFqdn);
+                caCertData, clientCertData, clientKeyData, serviceFqdn,
+                apiServerFqdn, controllerIp);
     }
 
     @Override
@@ -207,6 +221,7 @@
                 .add("clientKeyData", clientKeyData)
                 .add("serviceFqdn", serviceFqdn)
                 .add("apiServerFqdn", apiServerFqdn)
+                .add("controllerIp", controllerIp)
                 .toString();
     }
 
@@ -231,6 +246,7 @@
         private String clientKeyData;
         private String serviceFqdn;
         private String apiServerFqdn;
+        private IpAddress controllerIp;
 
         @Override
         public KubevirtApiConfig build() {
@@ -245,7 +261,8 @@
             }
 
             return new DefaultKubevirtApiConfig(scheme, ipAddress, port, state,
-                    token, caCertData, clientCertData, clientKeyData, serviceFqdn, apiServerFqdn);
+                    token, caCertData, clientCertData, clientKeyData, serviceFqdn,
+                    apiServerFqdn, controllerIp);
         }
 
         @Override
@@ -307,5 +324,11 @@
             this.apiServerFqdn = apiServerFqdn;
             return this;
         }
+
+        @Override
+        public Builder controllerIp(IpAddress controllerIp) {
+            this.controllerIp = controllerIp;
+            return this;
+        }
     }
 }
diff --git a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java
index c323625..74ad4cb 100644
--- a/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java
+++ b/apps/kubevirt-node/api/src/main/java/org/onosproject/kubevirtnode/api/KubevirtApiConfig.java
@@ -147,6 +147,13 @@
     String apiServerFqdn();
 
     /**
+     * Returns the controller IP address.
+     *
+     * @return controller IP address
+     */
+    IpAddress controllerIp();
+
+    /**
      * Builder of new API config entity.
      */
     interface Builder {
@@ -237,5 +244,13 @@
          * @return Kubevirt API config builder
          */
         Builder apiServerFqdn(String apiServerFqdn);
+
+        /**
+         * Returns kubevirt API server config builder with the supplied controller IP.
+         *
+         * @param controllerIp controller IP address
+         * @return Kubevirt API config builder
+         */
+        Builder controllerIp(IpAddress controllerIp);
     }
 }
diff --git a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java
index bd40ab1..7b98323 100644
--- a/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java
+++ b/apps/kubevirt-node/api/src/test/java/org/onosproject/kubevirtnode/api/DefaultKubevirtApiConfigTest.java
@@ -59,6 +59,9 @@
     private static final String API_SERVER_FQDN_1 = "kubernetes.default.svc.cluster.local";
     private static final String API_SERVER_FQDN_2 = "kubernetes.default.svc.cluster.sona";
 
+    private static final IpAddress CONTROLLER_IP_1 = IpAddress.valueOf("127.0.0.1");
+    private static final IpAddress CONTROLLER_IP_2 = IpAddress.valueOf("169.254.169.254");
+
     private KubevirtApiConfig config1;
     private KubevirtApiConfig sameAsConfig1;
     private KubevirtApiConfig config2;
@@ -87,6 +90,7 @@
                 .clientKeyData(CLIENT_KEY_DATA_1)
                 .serviceFqdn(SERVICE_FQDN_1)
                 .apiServerFqdn(API_SERVER_FQDN_1)
+                .controllerIp(CONTROLLER_IP_1)
                 .build();
 
         sameAsConfig1 = DefaultKubevirtApiConfig.builder()
@@ -100,6 +104,7 @@
                 .clientKeyData(CLIENT_KEY_DATA_1)
                 .serviceFqdn(SERVICE_FQDN_1)
                 .apiServerFqdn(API_SERVER_FQDN_1)
+                .controllerIp(CONTROLLER_IP_1)
                 .build();
 
         config2 = DefaultKubevirtApiConfig.builder()
@@ -113,6 +118,7 @@
                 .clientKeyData(CLIENT_KEY_DATA_2)
                 .serviceFqdn(SERVICE_FQDN_2)
                 .apiServerFqdn(API_SERVER_FQDN_2)
+                .controllerIp(CONTROLLER_IP_2)
                 .build();
     }
 
@@ -143,5 +149,6 @@
         assertEquals(CLIENT_KEY_DATA_1, config.clientKeyData());
         assertEquals(SERVICE_FQDN_1, config.serviceFqdn());
         assertEquals(API_SERVER_FQDN_1, config.apiServerFqdn());
+        assertEquals(CONTROLLER_IP_1, config.controllerIp());
     }
 }
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/cli/KubevirtListApiConfigsCommand.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/cli/KubevirtListApiConfigsCommand.java
index d01c33a..5b9c268 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/cli/KubevirtListApiConfigsCommand.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/cli/KubevirtListApiConfigsCommand.java
@@ -33,7 +33,7 @@
         description = "Lists all KubeVirt API server configs registered to the service")
 public class KubevirtListApiConfigsCommand extends AbstractShellCommand {
 
-    private static final String FORMAT = "%-10s%-25s%-10s%-10s";
+    private static final String FORMAT = "%-10s%-20s%-10s%-25s%-10s";
 
     @Override
     protected void doExecute() throws Exception {
@@ -43,10 +43,14 @@
         if (outputJson()) {
             print("%s", json(config));
         } else {
-            print(FORMAT, "Scheme", "IpAddress", "Port", "State");
+            print(FORMAT, "Scheme", "Server IP", "Port", "Controller IP", "State");
+            String controllerIp = "N/A";
             if (config != null) {
+                if (config.controllerIp() != null) {
+                    controllerIp = config.controllerIp().toString();
+                }
                 print(FORMAT, config.scheme().name(), config.ipAddress().toString(),
-                        config.port(), config.state().name());
+                        config.port(), controllerIp, config.state().name());
             } else {
                 print("Kubevirt config not found!");
             }
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java
index aa2bfa1..9fc2099 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodec.java
@@ -43,6 +43,7 @@
     private static final String CLIENT_KEY_DATA = "clientKeyData";
     private static final String SERVICE_FQDN = "serviceFqdn";
     private static final String API_SERVER_FQDN = "apiServerFqdn";
+    private static final String CONTROLLER_IP = "controllerIp";
 
     private static final String MISSING_MESSAGE = " is required in KubevirtApiConfig";
 
@@ -89,6 +90,10 @@
             node.put(API_SERVER_FQDN, entity.apiServerFqdn());
         }
 
+        if (entity.controllerIp() != null) {
+            node.put(CONTROLLER_IP, entity.controllerIp().toString());
+        }
+
         return node;
     }
 
@@ -116,6 +121,7 @@
         JsonNode clientKeyDataJson = json.get(CLIENT_KEY_DATA);
         JsonNode serviceFqdn = json.get(SERVICE_FQDN);
         JsonNode apiServerFqdn = json.get(API_SERVER_FQDN);
+        JsonNode controllerIp = json.get(CONTROLLER_IP);
 
         String token = "";
         String caCertData = "";
@@ -176,6 +182,10 @@
             builder.apiServerFqdn(apiServerFqdn.asText());
         }
 
+        if (controllerIp != null) {
+            builder.controllerIp(IpAddress.valueOf(controllerIp.asText()));
+        }
+
         return builder.build();
     }
 }
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
index de45151..3408ed1 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/impl/DefaultKubevirtNodeHandler.java
@@ -303,21 +303,23 @@
     private void createBridge(KubevirtNode node, String bridgeName, DeviceId devId) {
         Device device = deviceService.getDevice(node.ovsdb());
 
-        IpAddress serverIp;
+        IpAddress controllerIp = apiConfigService.apiConfig().controllerIp();
         String serviceFqdn = apiConfigService.apiConfig().serviceFqdn();
         IpAddress serviceIp = null;
 
-        if (serviceFqdn != null) {
-            serviceIp = resolveHostname(serviceFqdn);
+        if (controllerIp == null) {
+            if (serviceFqdn != null) {
+                serviceIp = resolveHostname(serviceFqdn);
+            }
+
+            if (serviceIp != null) {
+                controllerIp = serviceIp;
+            } else {
+                controllerIp = apiConfigService.apiConfig().ipAddress();
+            }
         }
 
-        if (serviceIp != null) {
-            serverIp = serviceIp;
-        } else {
-            serverIp = apiConfigService.apiConfig().ipAddress();
-        }
-
-        ControllerInfo controlInfo = new ControllerInfo(serverIp, DEFAULT_OFPORT, DEFAULT_OF_PROTO);
+        ControllerInfo controlInfo = new ControllerInfo(controllerIp, DEFAULT_OFPORT, DEFAULT_OF_PROTO);
         List<ControllerInfo> controllers = Lists.newArrayList(controlInfo);
 
         String dpid = devId.toString().substring(DPID_BEGIN);
diff --git a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java
index c3861f7..b659ec6 100644
--- a/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java
+++ b/apps/kubevirt-node/app/src/main/java/org/onosproject/kubevirtnode/web/KubevirtNodeWebResource.java
@@ -23,6 +23,7 @@
 import org.onosproject.kubevirtnode.api.KubevirtApiConfigService;
 import org.onosproject.kubevirtnode.api.KubevirtNode;
 import org.onosproject.kubevirtnode.api.KubevirtNodeAdminService;
+import org.onosproject.kubevirtnode.api.KubevirtNodeService;
 import org.onosproject.kubevirtnode.api.KubevirtNodeState;
 import org.onosproject.rest.AbstractWebResource;
 import org.slf4j.Logger;
@@ -281,11 +282,28 @@
     @Path("healthz")
     public Response healthz() {
         KubevirtApiConfigService configService = get(KubevirtApiConfigService.class);
-        KubevirtApiConfig config = configService.apiConfig();
+        KubevirtNodeService nodeService = get(KubevirtNodeService.class);
 
         // TODO: we need to add more health check items
+        boolean allInit = true;
+        KubevirtApiConfig config = configService.apiConfig();
+
+        if (nodeService.nodes().size() == 0) {
+            allInit = false;
+        } else {
+            for (KubevirtNode node : nodeService.nodes()) {
+                if (node.state() != INIT) {
+                    allInit = false;
+                }
+            }
+        }
+
+        String result = ERROR;
+        if (config != null && !allInit) {
+            result = OK;
+        }
+
         ObjectNode jsonResult = mapper().createObjectNode();
-        String result = config != null ? OK : ERROR;
         jsonResult.put(API_CONFIG, result);
         return ok(jsonResult).build();
     }
diff --git a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java
index 32a4505..16af906 100644
--- a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java
+++ b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigCodecTest.java
@@ -88,6 +88,7 @@
                 .clientKeyData("clientKeyData")
                 .serviceFqdn("kubevirt.edgestack.svc.cluster.local")
                 .apiServerFqdn("kubernetes.default.svc.cluster.local")
+                .controllerIp(IpAddress.valueOf("127.0.0.1"))
                 .build();
         ObjectNode configJson = kubevirtApiConfigCodec.encode(config, context);
         assertThat(configJson, matchesKubevirtApiConfig(config));
@@ -111,6 +112,7 @@
         assertEquals("clientKeyData", config.clientKeyData());
         assertEquals("kubevirt.edgestack.svc.cluster.local", config.serviceFqdn());
         assertEquals("kubernetes.default.svc.cluster.local", config.apiServerFqdn());
+        assertEquals("127.0.0.1", config.controllerIp().toString());
     }
 
     private KubevirtApiConfig getKubevirtApiConfig(String resourceName) throws IOException {
diff --git a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java
index 52c488c..2163f12 100644
--- a/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java
+++ b/apps/kubevirt-node/app/src/test/java/org/onosproject/kubevirtnode/codec/KubevirtApiConfigJsonMatcher.java
@@ -37,6 +37,7 @@
     private static final String CLIENT_KEY_DATA = "clientKeyData";
     private static final String SERVICE_FQDN = "serviceFqdn";
     private static final String API_SERVER_FQDN = "apiServerFqdn";
+    private static final String CONTROLLER_IP = "controllerIp";
 
     private KubevirtApiConfigJsonMatcher(KubevirtApiConfig kubevirtApiConfig) {
         this.kubevirtApiConfig = kubevirtApiConfig;
@@ -142,6 +143,17 @@
             }
         }
 
+        // Controller IP
+        JsonNode jsonControllerIp = jsonNode.get(CONTROLLER_IP);
+        String controllerIp = kubevirtApiConfig.controllerIp().toString();
+
+        if (jsonControllerIp != null) {
+            if (!jsonControllerIp.asText().equals(controllerIp)) {
+                description.appendText("controller IP was " + jsonControllerIp);
+                return false;
+            }
+        }
+
         return true;
     }
 
diff --git a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json
index b19c9e4..b95c29a 100644
--- a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json
+++ b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/codec/KubevirtApiConfig.json
@@ -7,5 +7,6 @@
   "clientCertData": "clientCertData",
   "clientKeyData": "clientKeyData",
   "serviceFqdn": "kubevirt.edgestack.svc.cluster.local",
-  "apiServerFqdn": "kubernetes.default.svc.cluster.local"
+  "apiServerFqdn": "kubernetes.default.svc.cluster.local",
+  "controllerIp": "127.0.0.1"
 }
\ No newline at end of file
diff --git a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/web/kubevirt-api-config.json b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/web/kubevirt-api-config.json
index f706cc3..7a5c5f5 100644
--- a/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/web/kubevirt-api-config.json
+++ b/apps/kubevirt-node/app/src/test/resources/org/onosproject/kubevirtnode/web/kubevirt-api-config.json
@@ -5,5 +5,6 @@
   "token": "token",
   "caCertData": "caCertData",
   "clientCertData": "clientCertData",
-  "clientKeyData": "clientKeyData"
+  "clientKeyData": "clientKeyData",
+  "controllerIp": "127.0.0.1"
 }
\ No newline at end of file