ONOS-3453 Fixed an issue with a race condition in loading/installing apps from disk in multi-cluster environments.

Fixed onos-gen-partitions.

Change-Id: Iadbb86119477b52d29a80515fc42e3d90012a216
diff --git a/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java b/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
index d09eb1f..80a5ca7 100644
--- a/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
+++ b/core/net/src/main/java/org/onosproject/app/impl/ApplicationManager.java
@@ -237,12 +237,22 @@
         boolean changed = false;
         for (String name : app.features()) {
             Feature feature = featuresService.getFeature(name);
+
+            // If we see an attempt at activation of a non-existent feature
+            // attempt to install the app artifacts first and then retry.
+            // This can be triggered by a race condition between different ONOS
+            // instances "installing" the apps from disk at their own pace.
+            // Perhaps there is a more elegant solution to be explored in the
+            // future.
+            if (feature == null) {
+                installAppArtifacts(app);
+                feature = featuresService.getFeature(name);
+            }
+
             if (feature != null && !featuresService.isInstalled(feature)) {
                 featuresService.installFeature(name);
                 changed = true;
-            } else if (feature == null && !initializing) {
-                // Suppress feature-not-found reporting during startup since these
-                // can arise naturally from the staggered cluster install.
+            } else if (feature == null) {
                 log.warn("Feature {} not found", name);
             }
         }
diff --git a/tools/test/bin/onos-gen-partitions b/tools/test/bin/onos-gen-partitions
index bbf6f93..5da0807 100755
--- a/tools/test/bin/onos-gen-partitions
+++ b/tools/test/bin/onos-gen-partitions
@@ -11,8 +11,7 @@
 import re
 import json
 import sys
-import random
-import string
+import hashlib
 
 convert = lambda text: int(text) if text.isdigit() else text.lower()
 alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
@@ -46,7 +45,7 @@
   partitions = generate_permutations([v.get('id') for v in nodes], 3)
   name = 0
   for node in nodes:
-      name = name ^ node['ip']
+      name = name ^ hash(node['ip'])
   data = {
            'name': name,
            'nodes': nodes,