Fix: add the kubevirt port to the store only if it is not existed

Remove all flows before remove bridge and ports

Change-Id: I8027bc19b70dce10612f8bc32da6062937299d89
(cherry picked from commit e66ed69033b65ad8ec1c6e1405f87b9be304cfd7)
diff --git a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFlowRuleService.java b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFlowRuleService.java
index e9196c8..563fffe 100644
--- a/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFlowRuleService.java
+++ b/apps/kubevirt-networking/api/src/main/java/org/onosproject/kubevirtnetworking/api/KubevirtFlowRuleService.java
@@ -60,4 +60,11 @@
      * @param toTable table number of table B
      */
     void connectTables(DeviceId deviceId, int fromTable, int toTable);
+
+    /**
+     * Remove all flow rules of a device.
+     *
+     * @param deviceId device identifier
+     */
+    void purgeRules(DeviceId deviceId);
 }
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java
index fd0669a..6fe457a 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtFlowRuleManager.java
@@ -35,6 +35,7 @@
 import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleOperations;
 import org.onosproject.net.flow.FlowRuleOperationsContext;
@@ -55,6 +56,7 @@
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.stream.StreamSupport;
 
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.kubevirtnetworking.api.Constants.ACL_EGRESS_TABLE;
@@ -213,6 +215,13 @@
                 true);
     }
 
+    @Override
+    public void purgeRules(DeviceId deviceId) {
+        Iterable<FlowEntry> fes = flowRuleService.getFlowEntries(deviceId);
+        flowRuleService.removeFlowRules(StreamSupport.stream(
+                    fes.spliterator(), false).toArray(FlowEntry[]::new));
+    }
+
     private void applyRule(FlowRule flowRule, boolean install) {
         FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
 
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
index 47f778a..b829980 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtNetworkHandler.java
@@ -141,7 +141,8 @@
     private static final String DEFAULT_OF_PROTO = "tcp";
     private static final int DEFAULT_OFPORT = 6653;
     private static final int DPID_BEGIN = 3;
-    private static final long SLEEP_MS = 3000; // we wait 3s for init each node
+    private static final long SLEEP_MS = 3000;
+    private static final long SLEEP_LARGE_MS = 5000;
     private static final int DEFAULT_TTL = 0xff;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
@@ -311,6 +312,11 @@
         ifaceConfig.addPatchMode(tunToTenantIntf, brTunTenantPatchDesc);
     }
 
+    private void removeAllFlows(KubevirtNode node, KubevirtNetwork network) {
+        DeviceId deviceId = network.tenantDeviceId(node.hostname());
+        flowService.purgeRules(deviceId);
+    }
+
     private void removePatchInterface(KubevirtNode node, KubevirtNetwork network) {
         Device device = deviceService.getDevice(node.ovsdb());
 
@@ -1231,7 +1237,15 @@
             }
 
             nodeService.completeNodes(WORKER).forEach(n -> {
+                removeAllFlows(n, network);
                 removePatchInterface(n, network);
+
+                try {
+                    sleep(SLEEP_LARGE_MS);
+                } catch (InterruptedException e) {
+                    log.error("Sleep exception", e);
+                }
+
                 removeBridge(n, network);
             });
         }
diff --git a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java
index 43d3e64..fc3baab 100644
--- a/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java
+++ b/apps/kubevirt-networking/app/src/main/java/org/onosproject/kubevirtnetworking/impl/KubevirtVmWatcher.java
@@ -248,7 +248,9 @@
                     port = port.updateDeviceId(deviceId);
                 }
 
-                portAdminService.createPort(port);
+                if (portAdminService.port(port.macAddress()) == null) {
+                    portAdminService.createPort(port);
+                }
             });
         }