This is an automated email from the ASF dual-hosted git repository. heneveld pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
commit 06bb567aa4de75dcb1d24e3e909bbb2b81c11bb7 Author: Alex Heneveld <[email protected]> AuthorDate: Sat Nov 12 04:39:52 2022 +0000 fix feed persistence, and stronger tests --- .../rebind/mementos/BrooklynMementoPersister.java | 2 + .../camp/brooklyn/WorkflowYamlRebindTest.java | 24 ++++++++ .../core/mgmt/persist/XmlMementoSerializer.java | 72 ++++++++++++---------- .../mgmt/rebind/RebindContextLookupContext.java | 20 ++++++ .../mgmt/persist/XmlMementoSerializerTest.java | 18 ++++++ 5 files changed, 103 insertions(+), 33 deletions(-) diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java index 9f059c0cf3..bdbd7640c3 100644 --- a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java +++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java @@ -34,6 +34,7 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler; import org.apache.brooklyn.api.mgmt.rebind.RebindManager; import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.objs.BrooklynObjectType; +import org.apache.brooklyn.api.objs.EntityAdjunct; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.sensor.Enricher; import org.apache.brooklyn.api.sensor.Feed; @@ -56,6 +57,7 @@ public interface BrooklynMementoPersister { Policy lookupPolicy(String id); Enricher lookupEnricher(String id); Feed lookupFeed(String id); + EntityAdjunct lookupAnyEntityAdjunct(String id); CatalogItem<?, ?> lookupCatalogItem(String id); ManagedBundle lookupBundle(String id); diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlRebindTest.java index a887c7fe5b..c15cd913a1 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlRebindTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/WorkflowYamlRebindTest.java @@ -27,7 +27,9 @@ import org.apache.brooklyn.api.entity.EntityLocal; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.objs.EntityAdjunct; import org.apache.brooklyn.api.sensor.AttributeSensor; +import org.apache.brooklyn.api.sensor.Feed; import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.BrooklynDslCommon; import org.apache.brooklyn.core.config.ConfigKeys; import org.apache.brooklyn.core.entity.*; @@ -176,6 +178,18 @@ public class WorkflowYamlRebindTest extends AbstractYamlRebindTest { Asserts.assertEquals(output.toString().trim(), message + " world"); } + static class AdjunctHolder { + String name; + EntityAdjunct adjunct; + + public static AdjunctHolder of(String name, EntityAdjunct x) { + AdjunctHolder result = new AdjunctHolder(); + result.name = name; + result.adjunct = x; + return result; + } + } + @Test void testWorkflowSensorRebind() throws Exception { Entity app = createAndStartApplication( @@ -203,6 +217,9 @@ public class WorkflowYamlRebindTest extends AbstractYamlRebindTest { Set<Task<?>> tt = BrooklynTaskTags.getTasksInAdjunctContext(mgmt().getExecutionManager(), Iterables.getOnlyElement(((EntityInternal) child).feeds().getFeeds())); Asserts.assertThat(tt, ts -> ts.stream().anyMatch(ti -> ti.getDisplayName().contains("Workflow for sensor"))); + Feed f = ((EntityInternal) child).feeds().getFeeds().iterator().next(); + app.tags().addTag(AdjunctHolder.of("1", f)); + Dumper.dumpInfo(app); app = rebind(); child = Iterables.getOnlyElement(app.getChildren()); @@ -212,6 +229,13 @@ public class WorkflowYamlRebindTest extends AbstractYamlRebindTest { tt = BrooklynTaskTags.getTasksInAdjunctContext(mgmt().getExecutionManager(), Iterables.getOnlyElement(((EntityInternal) child).feeds().getFeeds())); Asserts.assertThat(tt, ts -> ts.stream().anyMatch(ti -> ti.getDisplayName().contains("Workflow for sensor"))); + + f = ((EntityInternal) child).feeds().getFeeds().iterator().next(); + app.tags().addTag(AdjunctHolder.of("2", f)); + + // assert adjuncts rebind and rebind quite happily + switchOriginalToNewManagementContext(); + app = rebind(); } @Test(groups="WIP") diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java index 86c2f2eb41..85326099b3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java @@ -18,18 +18,20 @@ */ package org.apache.brooklyn.core.mgmt.persist; -import static com.google.common.base.Preconditions.checkNotNull; - +import com.google.common.base.Objects; import com.google.common.collect.ImmutableMap; -import java.io.IOException; -import java.io.Writer; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.concurrent.ExecutionException; - -import java.util.function.Function; +import com.thoughtworks.xstream.converters.Converter; +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.SingleValueConverter; +import com.thoughtworks.xstream.converters.UnmarshallingContext; +import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; +import com.thoughtworks.xstream.core.ReferenceByXPathUnmarshaller; +import com.thoughtworks.xstream.core.ReferencingMarshallingContext; +import com.thoughtworks.xstream.io.HierarchicalStreamReader; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.io.path.PathTrackingReader; +import com.thoughtworks.xstream.mapper.Mapper; +import com.thoughtworks.xstream.mapper.MapperWrapper; import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.effector.Effector; import org.apache.brooklyn.api.entity.Entity; @@ -39,6 +41,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.Task; import org.apache.brooklyn.api.mgmt.classloading.BrooklynClassLoadingContext; import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister.LookupContext; +import org.apache.brooklyn.api.objs.EntityAdjunct; import org.apache.brooklyn.api.objs.Identifiable; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.sensor.Enricher; @@ -54,17 +57,10 @@ import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory; import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory; import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromStackOfBrooklynClassLoadingContext; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicCatalogItemMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicEnricherMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicEntityMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicFeedMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicLocationMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicManagedBundleMemento; -import org.apache.brooklyn.core.mgmt.rebind.dto.BasicPolicyMemento; +import org.apache.brooklyn.core.mgmt.rebind.dto.*; import org.apache.brooklyn.core.sensor.BasicAttributeSensor; import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades; import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.collections.MutableSet.Builder; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.core.xstream.LambdaPreventionMapper; import org.apache.brooklyn.util.core.xstream.XmlSerializer; @@ -73,19 +69,16 @@ import org.apache.brooklyn.util.text.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Objects; -import com.thoughtworks.xstream.converters.Converter; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.SingleValueConverter; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; -import com.thoughtworks.xstream.core.ReferenceByXPathUnmarshaller; -import com.thoughtworks.xstream.core.ReferencingMarshallingContext; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.path.PathTrackingReader; -import com.thoughtworks.xstream.mapper.Mapper; -import com.thoughtworks.xstream.mapper.MapperWrapper; +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +import static com.google.common.base.Preconditions.checkNotNull; /* uses xml, cleaned up a bit * @@ -188,12 +181,14 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento xstream.alias("locationRef", Location.class); xstream.alias("policyRef", Policy.class); xstream.alias("enricherRef", Enricher.class); + xstream.alias("feedRef", Feed.class); xstream.registerConverter(new LocationConverter()); + // xstream.registerConverter(new EntityAdjunctConverter()); // not needed, but kept for a bit in case it is, 2022-11 xstream.registerConverter(new PolicyConverter()); xstream.registerConverter(new EnricherConverter()); - xstream.registerConverter(new EntityConverter()); xstream.registerConverter(new FeedConverter()); + xstream.registerConverter(new EntityConverter()); xstream.registerConverter(new CatalogItemConverter()); xstream.registerConverter(new SpecConverter()); @@ -221,6 +216,7 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento mapper = new CustomMapper(mapper, Policy.class, "policyRef"); mapper = new CustomMapper(mapper, Enricher.class, "enricherRef"); + mapper = new CustomMapper(mapper, Feed.class, "feedRef"); mapper = new UnwantedStateLoggingMapper(mapper); return mapper; @@ -377,6 +373,16 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento return lookupContext.lookupFeed(id); } } + + public class EntityAdjunctConverter extends IdentifiableConverter<EntityAdjunct> { + EntityAdjunctConverter() { + super(EntityAdjunct.class); + } + @Override + protected EntityAdjunct lookup(String id) { + return lookupContext.lookupAnyEntityAdjunct(id); + } + } public class EntityConverter extends IdentifiableConverter<Entity> { EntityConverter() { diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextLookupContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextLookupContext.java index 18097dc7ad..03900f03af 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextLookupContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextLookupContext.java @@ -31,6 +31,7 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler; import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoPersister.LookupContext; import org.apache.brooklyn.api.objs.BrooklynObject; import org.apache.brooklyn.api.objs.BrooklynObjectType; +import org.apache.brooklyn.api.objs.EntityAdjunct; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.sensor.Enricher; import org.apache.brooklyn.api.sensor.Feed; @@ -138,6 +139,25 @@ public class RebindContextLookupContext implements LookupContext { return result; } + @Override public EntityAdjunct lookupAnyEntityAdjunct(String id) { + EntityAdjunct result; + + result = rebindContext.getPolicy(id); + if (result != null) return result; + result = rebindContext.getEnricher(id); + if (result != null) return result; + result = rebindContext.getFeed(id); + if (result != null) return result; + result = managementContext.lookup(id, Policy.class); + if (result != null) return result; + result = managementContext.lookup(id, Enricher.class); + if (result != null) return result; + result = managementContext.lookup(id, Feed.class); + if (result != null) return result; + + return exceptionHandler.onDanglingFeedRef(id); + } + @SuppressWarnings("deprecation") @Override // only used for persisted xml catalog items; not used for registered types diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java index 9024d59e35..54d13b8dab 100644 --- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java +++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializerTest.java @@ -18,6 +18,7 @@ */ package org.apache.brooklyn.core.mgmt.persist; +import org.apache.brooklyn.api.objs.EntityAdjunct; import org.apache.brooklyn.core.mgmt.persist.XmlMementoSerializer.XmlMementoSerializerBuilder; import static org.testng.Assert.assertEquals; @@ -778,6 +779,23 @@ public class XmlMementoSerializerTest { } return null; } + + @Override public EntityAdjunct lookupAnyEntityAdjunct(String id) { + if (policies.containsKey(id)) { + return policies.get(id); + } + if (enrichers.containsKey(id)) { + return enrichers.get(id); + } + if (feeds.containsKey(id)) { + return feeds.get(id); + } + if (failOnDangling) { + throw new NoSuchElementException("no feed with id "+id+"; contenders are "+feeds.keySet()); + } + return null; + } + @Override public CatalogItem<?, ?> lookupCatalogItem(String id) { if (catalogItems.containsKey(id)) { return catalogItems.get(id);
