Repository: brooklyn-server
Updated Branches:
  refs/heads/master baad0c039 -> e040f074f


does a yaml parse and compares the hash of the result when checking plan 
equivalence

means that the same plan entered twice but with different comments, spacing, 
quotations etc,
will not result in an error.  it only treats a plan as non-equivalent if their 
yaml is different
after a deserialize-then-serialize cycle.  previously a catalog push for an 
already-present
non-snapshot plan would fail unless the plan was identical up to a trim.  now 
it only fails if
the objects are different.


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/066cbbf2
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/066cbbf2
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/066cbbf2

Branch: refs/heads/master
Commit: 066cbbf2f70cb9b7e4b79a6eeb29bf87422dd2f6
Parents: 6f093c7
Author: Alex Heneveld <alex.henev...@cloudsoftcorp.com>
Authored: Sat Jun 2 00:29:02 2018 +0100
Committer: Duncan Grant <duncan.gr...@cloudsoftcorp.com>
Committed: Mon Jun 4 12:11:40 2018 +0100

----------------------------------------------------------------------
 .../brooklyn/core/typereg/RegisteredTypes.java  | 47 ++++++++++++++++++--
 1 file changed, 43 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/066cbbf2/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java 
b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
index 9a4a5dd..83e7f05 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/RegisteredTypes.java
@@ -50,6 +50,7 @@ import org.apache.brooklyn.core.mgmt.BrooklynTags;
 import org.apache.brooklyn.core.mgmt.BrooklynTags.NamedStringTag;
 import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
 import 
org.apache.brooklyn.core.typereg.JavaClassNameTypePlanTransformer.JavaClassNameTypeImplementationPlan;
+import org.apache.brooklyn.util.collections.Jsonya;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.guava.Maybe.Absent;
@@ -682,27 +683,65 @@ public class RegisteredTypes {
         // it does mean a format change will be ignored
         return 
"equivalent-plan("+Streams.getMd5Checksum(Streams.newInputStreamWithContents(input.trim()))+")";
     }
-    
+
+    /** parse the plan as yaml/json, re-serialize it, and take that checksum.
+     * this allows plans that are equivalent post-parse to be treated as 
equivalent.
+     * returns {@link Absent} if the input is not valid yaml.
+     */
+    private static Maybe<String> tagForEquivalentYamlPlan(String input) {
+        // plans may be trimmed by yaml parser so do that before checking 
equivalence
+        // it does mean a format change will be ignored
+        try {
+            Iterator<Object> plansI = Yamls.parseAll(input).iterator();
+            if (!plansI.hasNext()) {
+                return Maybe.absent("No data found");
+            }
+            String planOut = "";
+            while (plansI.hasNext()) {
+                Object plan = plansI.next();
+                if (!planOut.isEmpty()) planOut += "\n";
+                planOut += Jsonya.render(plan);
+            }
+            return Maybe.of(tagForEquivalentPlan(planOut));
+        } catch (Exception e) {
+            return Maybe.absent(e);
+        }
+    }
+
     @Beta
     public static void notePlanEquivalentToThis(RegisteredType type, 
TypeImplementationPlan plan) {
         Object data = plan.getPlanData();
         if (data==null) throw new IllegalStateException("No plan data for 
"+plan+" noted equivalent to "+type);
         if (!(data instanceof String)) throw new 
IllegalStateException("Expected plan for equivalent to "+type+" to be a string; 
was "+data);
         
((BasicRegisteredType)type).tags.add(tagForEquivalentPlan((String)data));
+        Maybe<String> reserializeEquivalenceTag = 
tagForEquivalentYamlPlan((String)data);
+        if (reserializeEquivalenceTag.isPresent()) 
((BasicRegisteredType)type).tags.add(reserializeEquivalenceTag.get());
     }
 
+    /** Checks whether two types have plans which are identical, or identical 
after a YAML parse,
+     * or if either has an "equivalent-plan" tag indicating its equivalence to 
the other plan
+     * (as set by {@link #notePlanEquivalentToThis(RegisteredType, 
TypeImplementationPlan)}). 
+     */
     @Beta
     public static boolean arePlansEquivalent(RegisteredType type1, 
RegisteredType type2) {
         String plan1 = getImplementationDataStringForSpec(type1);
         String plan2 = getImplementationDataStringForSpec(type2);
         if (Strings.isNonBlank(plan1) && Strings.isNonBlank(plan2)) {
-            String p2tag = tagForEquivalentPlan(plan2);
             String p1tag = tagForEquivalentPlan(plan1);
-            // allow same plan under trimming,
-            // or any recorded tag in either direction
+            String p2tag = tagForEquivalentPlan(plan2);
+            
             if (Objects.equal(p1tag, p2tag)) return true;
+            
             if (type1.getTags().contains(p2tag)) return true;
             if (type2.getTags().contains(p1tag)) return true;
+            
+            Maybe<String> rp2tag = tagForEquivalentYamlPlan(plan2);
+            if (rp2tag.isPresent() && type1.getTags().contains(rp2tag.get())) 
return true;
+            
+            Maybe<String> rp1tag = tagForEquivalentYamlPlan(plan1);
+            if (rp1tag.isPresent() && type2.getTags().contains(rp1tag.get())) 
return true;
+            
+            if (rp1tag.isPresent() && rp2tag.isPresent() && 
rp1tag.get().equals(rp2tag.get())) return true; 
         }
         return Objects.equal(type1.getPlan(), type2.getPlan());
     }

Reply via email to