Fix: enforce to synchronize all flow rules in case sync failures

Change-Id: Ife2905802424e3a8cc050fd4587a81eb756027d6
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncRulesCommand.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncRulesCommand.java
index 214cfe7..0270b26 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncRulesCommand.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/cli/OpenstackSyncRulesCommand.java
@@ -23,6 +23,7 @@
 import org.onosproject.openstacknode.api.OpenstackNodeAdminService;
 
 import static java.lang.Thread.sleep;
+import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
 
@@ -35,6 +36,7 @@
 public class OpenstackSyncRulesCommand extends AbstractShellCommand {
 
     private static final long SLEEP_MS = 3000; // we wait 3s for init each node
+    private static final long TIMEOUT_MS = 10000; // we wait 10s
 
     @Override
     protected void doExecute() {
@@ -61,16 +63,36 @@
         OpenstackNode updated = osNode.updateState(NodeState.INIT);
         osNodeService.updateNode(updated);
 
-        try {
-            sleep(SLEEP_MS);
-        } catch (InterruptedException e) {
-            log.error("Exception caused during node synchronization...");
+        boolean result = true;
+        long timeoutExpiredMs = System.currentTimeMillis() + TIMEOUT_MS;
+
+        while (osNodeService.node(osNode.hostname()).state() != COMPLETE) {
+
+            long  waitMs = timeoutExpiredMs - System.currentTimeMillis();
+
+            try {
+                sleep(SLEEP_MS);
+            } catch (InterruptedException e) {
+                error("Exception caused during node synchronization...");
+            }
+
+            if (osNodeService.node(osNode.hostname()).state() == COMPLETE) {
+                break;
+            } else {
+                osNodeService.updateNode(updated);
+                print("Failed to synchronize flow rules, retrying...");
+            }
+
+            if (waitMs <= 0) {
+                result = false;
+                break;
+            }
         }
 
-        if (osNodeService.node(osNode.hostname()).state() == NodeState.COMPLETE) {
-            print("Finished sync rules for node %s", osNode.hostname());
+        if (result) {
+            print("Successfully synchronize flow rules for node {}!", osNode.hostname());
         } else {
-            error("Failed to sync rules for node %s", osNode.hostname());
+            error("Failed to synchronize flow rules for node {}.", osNode.hostname());
         }
     }
 }
diff --git a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java
index bd828aa..febcb7a 100644
--- a/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java
+++ b/apps/openstacknetworking/app/src/main/java/org/onosproject/openstacknetworking/web/OpenstackManagementWebResource.java
@@ -61,6 +61,7 @@
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkActivationFlag;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.checkArpMode;
 import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
+import static org.onosproject.openstacknode.api.NodeState.COMPLETE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
 import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
@@ -345,16 +346,36 @@
         OpenstackNode updated = osNode.updateState(NodeState.INIT);
         osNodeAdminService.updateNode(updated);
 
-        try {
-            sleep(SLEEP_MS);
-        } catch (InterruptedException e) {
-            log.error("Exception caused during node synchronization...");
+        boolean result = true;
+        long timeoutExpiredMs = System.currentTimeMillis() + TIMEOUT_MS;
+
+        while (osNodeAdminService.node(osNode.hostname()).state() != COMPLETE) {
+
+            long  waitMs = timeoutExpiredMs - System.currentTimeMillis();
+
+            try {
+                sleep(SLEEP_MS);
+            } catch (InterruptedException e) {
+                log.error("Exception caused during node synchronization...");
+            }
+
+            if (osNodeAdminService.node(osNode.hostname()).state() == COMPLETE) {
+                break;
+            } else {
+                osNodeAdminService.updateNode(updated);
+                log.info("Failed to synchronize flow rules, retrying...");
+            }
+
+            if (waitMs <= 0) {
+                result = false;
+                break;
+            }
         }
 
-        if (osNodeAdminService.node(osNode.hostname()).state() == NodeState.COMPLETE) {
-            log.info("Finished sync rules for node {}", osNode.hostname());
+        if (result) {
+            log.info("Successfully synchronize flow rules for node {}!", osNode.hostname());
         } else {
-            log.info("Failed to sync rules for node {}", osNode.hostname());
+            log.warn("Failed to synchronize flow rules for node {}.", osNode.hostname());
         }
     }