You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2017/04/21 22:55:37 UTC

[18/39] brooklyn-server git commit: Add (some) tests of rebind of previously persisted state.

Add (some) tests of rebind of previously persisted state.


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

Branch: refs/heads/master
Commit: 63f4a9415901fece4b63fc0cd676b7812959ea9d
Parents: b5ca71b
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Mon Oct 3 10:13:30 2016 +0100
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Thu Apr 20 11:20:36 2017 +0100

----------------------------------------------------------------------
 .../brooklyn/catalog/CatalogYamlRebindTest.java | 65 ++++++++++++++++++--
 .../core/mgmt/rebind/dto/AbstractMemento.java   | 42 +++++++++++--
 .../rebind/transformer/CompoundTransformer.java |  3 +-
 3 files changed, 99 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/63f4a941/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
index e6aff50..ff0c794 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java
@@ -39,6 +39,8 @@ import javax.xml.transform.stream.StreamResult;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
 import org.apache.brooklyn.api.policy.Policy;
 import org.apache.brooklyn.api.sensor.Enricher;
 import org.apache.brooklyn.api.typereg.RegisteredType;
@@ -51,7 +53,9 @@ import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest;
 import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
 import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore.StoreObjectAccessor;
+import org.apache.brooklyn.core.mgmt.rebind.RebindExceptionHandlerImpl;
 import org.apache.brooklyn.core.mgmt.rebind.RebindOptions;
+import org.apache.brooklyn.core.mgmt.rebind.transformer.CompoundTransformer;
 import org.apache.brooklyn.core.test.policy.TestEnricher;
 import org.apache.brooklyn.core.test.policy.TestPolicy;
 import org.apache.brooklyn.entity.stock.BasicEntity;
@@ -103,7 +107,7 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
         LIBRARY,
         PREFIX
     }
-    
+
     private Boolean defaultEnablementOfFeatureAutoFixatalogRefOnRebind;
     
     @BeforeMethod(alwaysRun=true)
@@ -162,8 +166,61 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
     }
 
     @Test(dataProvider = "dataProvider")
+    public void testRebindWithCatalogAndApp(RebindWithCatalogTestMode mode, boolean useOsgi) throws Exception {
+        testRebindWithCatalogAndAppUsingOptions(mode, useOsgi, RebindOptions.create());
+    }
+
+    @Test(dataProvider = "dataProvider")
+    public void testRebindWithCatalogAndAppRebindCatalogItemIds(RebindWithCatalogTestMode mode, boolean useOsgi) throws Exception {
+        testRebindWithCatalogAndAppUsingOptions(mode, useOsgi, rebindCatalogItemIds());
+    }
+
+    private RebindOptions rebindCatalogItemIds() {
+        CompoundTransformer transformer = CompoundTransformer.builder()
+            .xmlReplaceItem("//catalogItemSuperIds", "<catalogItemId><xsl:value-of select=\"string\"/></catalogItemId>")
+            .build();
+        return applyStateTransformer(transformer);
+    }
+
+    private RebindOptions applyStateTransformer(final CompoundTransformer transformer) {
+        return RebindOptions.create()
+            .stateTransformer(new Function<BrooklynMementoPersister, Void>() {
+                @Override public Void apply(BrooklynMementoPersister input) {
+
+                    BrooklynMementoRawData transformed = null;
+                    try {
+                        transformed = transformer.transform((BrooklynMementoPersisterToObjectStore) input, RebindExceptionHandlerImpl.builder().build());
+                    } catch (Exception e) {
+                        Exceptions.propagateIfFatal(e);
+                        getLogger().warn(Strings.join(new Object[]{
+                            "Caught'", e.getMessage(), "' when transforming '", input.getBackingStoreDescription()
+                        }, ""), e);
+                    }
+
+                    PersistenceObjectStore objectStore = ((BrooklynMementoPersisterToObjectStore)input).getObjectStore();
+                    for (BrooklynObjectType type : BrooklynObjectType.values()) {
+                        final List<String> contents = objectStore.listContentsWithSubPath(type.getSubPathName());
+                        for (String path : contents) {
+                            StoreObjectAccessor accessor = objectStore.newAccessor(path);
+                            String memento = checkNotNull(accessor.get(), path);
+                            String replacement = transformed.getObjectsOfType(type).get(idFromPath(type, path));
+                            getLogger().trace("Replacing {} with {}", memento, replacement);
+                            accessor.put(replacement);
+                        }
+                    }
+
+                    return null;
+                }});
+    }
+
+    private String idFromPath(BrooklynObjectType type, String path) {
+        // the replace underscore with colon below handles file names of catalog items like "catalog/my.catalog.app.id.load_0.1.0"
+        return path.substring(type.getSubPathName().length()+1).replace('_', ':');
+    }
+
+
     @SuppressWarnings({ "deprecation", "unused" })
-    public void testRebindWithCatalogAndApp(RebindWithCatalogTestMode mode, OsgiMode osgiMode) throws Exception {
+    public void testRebindWithCatalogAndAppUsingOptions(RebindWithCatalogTestMode mode, boolean useOsgi, RebindOptions options) throws Exception {
         if (osgiMode != OsgiMode.NONE) {
             TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH);
         }
@@ -298,7 +355,7 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
         // Rebind
         if (mode == RebindWithCatalogTestMode.STRIP_DEPRECATION_AND_ENABLEMENT_FROM_CATALOG_ITEM) {
             // Edit the persisted state to remove the "deprecated" and "enablement" tags for our catalog items
-            rebind(RebindOptions.create()
+            rebind(RebindOptions.create(options)
                     .stateTransformer(new Function<BrooklynMementoPersister, Void>() {
                         @Override public Void apply(BrooklynMementoPersister input) {
                             PersistenceObjectStore objectStore = ((BrooklynMementoPersisterToObjectStore)input).getObjectStore();
@@ -313,7 +370,7 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest {
                             return null;
                         }}));
         } else {
-            rebind();
+            rebind(options);
         }
 
         // Ensure app is still there, and that it is usable - e.g. "stop" effector functions as expected

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/63f4a941/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/AbstractMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/AbstractMemento.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/AbstractMemento.java
index 5feb0af..cf3a033 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/AbstractMemento.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/AbstractMemento.java
@@ -35,6 +35,7 @@ import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
+import org.apache.brooklyn.util.collections.MutableList;
 
 public abstract class AbstractMemento implements Memento, Serializable {
 
@@ -46,7 +47,9 @@ public abstract class AbstractMemento implements Memento, Serializable {
         protected String type;
         protected Class<?> typeClass;
         protected String displayName;
-        protected List<String> catalogItemSuperIds;
+        // catalogItemId is retained to support rebind of previously persisted state (prior to catalogItemSuperIds)
+        protected String catalogItemId;
+        protected List<String> catalogItemSuperIds = MutableList.of();
         protected Map<String, Object> customFields = Maps.newLinkedHashMap();
         protected List<Object> tags = Lists.newArrayList();
         protected Map<String,Set<String>> relations = Maps.newLinkedHashMap();
@@ -65,14 +68,28 @@ public abstract class AbstractMemento implements Memento, Serializable {
             type = other.getType();
             typeClass = other.getTypeClass();
             displayName = other.getDisplayName();
-            catalogItemSuperIds = other.getCatalogItemSuperIds();
+            setCatalogItemIds(other.getCatalogItemSuperIds(), other.getCatalogItemId());
             customFields.putAll(other.getCustomFields());
             tags.addAll(other.getTags());
             relations.putAll(other.getRelations());
             uniqueTag = other.getUniqueTag();
             return self();
         }
-        
+
+        private void setCatalogItemIds(List<String> otherItemSuperIds, String otherItemId) {
+            if (isEmpty(otherItemSuperIds) && otherItemId == null) {
+                catalogItemSuperIds = MutableList.of();
+            } else if (isEmpty(otherItemSuperIds) && otherItemId != null) {
+                catalogItemSuperIds = MutableList.of(otherItemId);
+            } else {
+                catalogItemSuperIds = MutableList.copyOf(otherItemSuperIds);
+            }
+        }
+
+        private boolean isEmpty(List<String> ids) {
+            return ids == null || ids.isEmpty();
+        }
+
         /**
          * @deprecated since 0.7.0; use config/attributes so generic persistence will work, rather than requiring "custom fields"
          */
@@ -86,7 +103,9 @@ public abstract class AbstractMemento implements Memento, Serializable {
     private String type;
     private String id;
     private String displayName;
-    private List<String> catalogItemSuperIds;
+    // catalogItemId is retained to support rebind of previously persisted state (prior to catalogItemSuperIds)
+    protected String catalogItemId;
+    private List<String> catalogItemSuperIds = MutableList.of();
     private List<Object> tags;
     private Map<String,Set<String>> relations;
     
@@ -116,7 +135,18 @@ public abstract class AbstractMemento implements Memento, Serializable {
     // "fields" is not included as a field here, so that it is serialized after selected subclass fields
     // but the method declared here simplifies how it is connected in via builder etc
     protected abstract void setCustomFields(Map<String, Object> fields);
-    
+
+    // deals with value created by deserialization of state persisted with <catalogItemId>
+    private void normalizeCatalogItemIds() {
+        if (catalogItemSuperIds == null) {
+            catalogItemSuperIds = MutableList.of();
+        }
+        if (catalogItemSuperIds.isEmpty() && catalogItemId != null) {
+            catalogItemSuperIds = MutableList.of(catalogItemId);
+            catalogItemId = null;
+        }
+    }
+
     @Override
     public void injectTypeClass(Class<?> clazz) {
         this.typeClass = clazz;
@@ -149,11 +179,13 @@ public abstract class AbstractMemento implements Memento, Serializable {
 
     @Override
     public String getCatalogItemId() {
+        normalizeCatalogItemIds();
         return Iterables.getFirst(getCatalogItemSuperIds(), null);
     }
 
     @Override
     public List<String> getCatalogItemSuperIds() {
+        normalizeCatalogItemIds();
         return catalogItemSuperIds;
     }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/63f4a941/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java
index 59d7fe6..c9bf703 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/transformer/CompoundTransformer.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
 import org.apache.brooklyn.api.objs.BrooklynObjectType;
 import org.apache.brooklyn.core.mgmt.persist.BrooklynMementoPersisterToObjectStore;
@@ -188,8 +189,6 @@ public class CompoundTransformer {
          *        &lt;string>two&lt;/string>
          *     &lt;/catalogItemSuperIds>
          * </pre>
-         * </p><p>
-         *
          * </p>
          * This provides a programmatic way to change the catalogItemID. */
         public Builder changeCatalogItemId(String oldSymbolicName, String oldVersion,