Fix incorrect state of Intent after re-installed from FAILED state.

Avoid same IntentData resubmitted by multiple ONOS nodes.
Also, avoid same IntentData/IntentOperationContext modified by different
threds.

Change-Id: Ifb550c41204d6e86e379fd44c2787980920d2b9e
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java
index d5eb1fd..af311f4 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java
@@ -179,10 +179,12 @@
             if (toInstall.isPresent()) {
                 IntentData installData = toInstall.get();
                 log.debug("Completed installing: {}", installData.key());
+                installData = new IntentData(installData, installData.installables());
                 installData.setState(INSTALLED);
                 intentStore.write(installData);
             } else if (toUninstall.isPresent()) {
                 IntentData uninstallData = toUninstall.get();
+                uninstallData = new IntentData(uninstallData, Collections.emptyList());
                 log.debug("Completed withdrawing: {}", uninstallData.key());
                 switch (uninstallData.request()) {
                     case INSTALL_REQ:
@@ -196,7 +198,7 @@
                         break;
                 }
                 // Intent has been withdrawn; we can clear the installables
-                intentStore.write(new IntentData(uninstallData, Collections.emptyList()));
+                intentStore.write(uninstallData);
             }
         } else {
             // if toInstall was cause of error, then recompile (manage/increment counter, when exceeded -> CORRUPT)
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 14d2bea..f94ad8c 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -460,6 +460,9 @@
                                        boolean compileAllFailed) {
         // Attempt recompilation of the specified intents first.
         for (Key key : intentKeys) {
+            if (!store.isMaster(key)) {
+                continue;
+            }
             Intent intent = store.getIntent(key);
             if (intent == null) {
                 continue;
@@ -470,6 +473,9 @@
         if (compileAllFailed) {
             // If required, compile all currently failed intents.
             for (Intent intent : getIntents()) {
+                if (!store.isMaster(intent.key())) {
+                    continue;
+                }
                 IntentState state = getIntentState(intent.key());
                 if (RECOMPILE.contains(state) || intentAllowsPartialFailure(intent)) {
                     if (WITHDRAW.contains(state)) {
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
index f29ceec..df2c28c 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.net.intent.impl.installer;
 
+import com.google.common.collect.Lists;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -40,6 +41,7 @@
 import java.util.List;
 import java.util.Optional;
 import java.util.Set;
+
 import static org.onosproject.net.intent.IntentInstaller.Direction.ADD;
 import static org.onosproject.net.intent.IntentInstaller.Direction.REMOVE;
 import static org.onosproject.net.intent.IntentState.INSTALLED;
@@ -79,8 +81,8 @@
         Optional<IntentData> toUninstall = context.toUninstall();
         Optional<IntentData> toInstall = context.toInstall();
 
-        List<FlowRuleIntent> uninstallIntents = context.intentsToUninstall();
-        List<FlowRuleIntent> installIntents = context.intentsToInstall();
+        List<FlowRuleIntent> uninstallIntents = Lists.newArrayList(context.intentsToUninstall());
+        List<FlowRuleIntent> installIntents = Lists.newArrayList(context.intentsToInstall());
 
         if (!toInstall.isPresent() && !toUninstall.isPresent()) {
             intentInstallCoordinator.intentInstallSuccess(context);
@@ -94,7 +96,6 @@
         } else {
             IntentData uninstall = toUninstall.get();
             IntentData install = toInstall.get();
-
             // Filter out same intents and intents with same flow rules
             Iterator<FlowRuleIntent> iterator = installIntents.iterator();
             while (iterator.hasNext()) {
@@ -145,8 +146,6 @@
         };
 
         FlowRuleOperations operations = builder.build(flowRuleOperationsContext);
-
-
         log.debug("applying intent {} -> {} with {} rules: {}",
                   toUninstall.map(x -> x.key().toString()).orElse("<empty>"),
                   toInstall.map(x -> x.key().toString()).orElse("<empty>"),