done the basics, bundle persistence working and with a test note `PersistenceObjectStore` for accessing blob store impls have been changed to handle byte streams better. also comments on managementPlaneId updated and more logging around it, as i was getting confused debugging this.
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/abd0cb8b Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/abd0cb8b Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/abd0cb8b Branch: refs/heads/master Commit: abd0cb8bf79457396036d870d9f3ba3c41e6aa80 Parents: e8b5fd0 Author: Alex Heneveld <[email protected]> Authored: Fri Apr 21 11:52:02 2017 +0100 Committer: Alex Heneveld <[email protected]> Committed: Fri Apr 21 14:55:53 2017 +0100 ---------------------------------------------------------------------- .../brooklyn/api/mgmt/ManagementContext.java | 23 +--- .../api/mgmt/rebind/RebindExceptionHandler.java | 8 +- .../mgmt/rebind/mementos/BrooklynMemento.java | 3 + .../mementos/BrooklynMementoPersister.java | 2 + .../spi/creation/CampToSpecTransformer.java | 8 +- .../camp/brooklyn/AbstractYamlRebindTest.java | 13 ++ .../catalog/CatalogMakeOsgiBundleTest.java | 2 +- .../CatalogOsgiVersionMoreEntityRebindTest.java | 33 ++++- .../CatalogOsgiVersionMoreEntityTest.java | 30 ++++- .../internal/JavaCatalogToSpecTransformer.java | 10 +- .../mgmt/ha/HighAvailabilityManagerImpl.java | 26 ++-- .../brooklyn/core/mgmt/ha/OsgiManager.java | 58 +++++++-- .../internal/AbstractManagementContext.java | 2 +- .../mgmt/internal/LocalManagementContext.java | 11 +- .../NonDeploymentManagementContext.java | 5 +- .../BrooklynMementoPersisterToObjectStore.java | 42 ++++--- .../mgmt/persist/BrooklynPersistenceUtils.java | 3 +- .../persist/FileBasedStoreObjectAccessor.java | 15 ++- .../mgmt/persist/PersistenceObjectStore.java | 2 + .../persist/StoreObjectAccessorLocking.java | 24 ++++ .../core/mgmt/persist/XmlMementoSerializer.java | 5 +- .../rebind/BasicManagedBundleRebindSupport.java | 41 +++++++ .../core/mgmt/rebind/RebindContextImpl.java | 24 +++- .../mgmt/rebind/RebindContextLookupContext.java | 13 ++ .../mgmt/rebind/RebindExceptionHandlerImpl.java | 8 +- .../core/mgmt/rebind/RebindIteration.java | 4 +- .../core/mgmt/rebind/RebindManagerImpl.java | 2 +- .../mgmt/rebind/dto/BrooklynMementoImpl.java | 25 +++- .../mgmt/rebind/dto/MutableBrooklynMemento.java | 27 ++++ .../brooklyn/core/plan/PlanToSpecFactory.java | 6 +- .../core/plan/PlanToSpecTransformer.java | 9 +- .../core/typereg/BasicManagedBundle.java | 3 +- .../core/typereg/TypePlanTransformers.java | 6 +- .../HighAvailabilityManagerSplitBrainTest.java | 4 +- .../brooklyn/core/mgmt/ha/HotStandbyTest.java | 2 +- .../brooklyn/core/mgmt/ha/WarmStandbyTest.java | 2 +- .../mgmt/osgi/OsgiVersionMoreEntityTest.java | 31 +---- .../BrooklynMementoPersisterTestFixture.java | 4 +- .../core/mgmt/persist/InMemoryObjectStore.java | 47 ++++--- .../core/mgmt/persist/ListeningObjectStore.java | 18 +++ .../mgmt/persist/XmlMementoSerializerTest.java | 122 ++++++++++--------- .../core/mgmt/rebind/ManagementPlaneIdTest.java | 22 ++-- .../core/mgmt/rebind/RebindTestFixture.java | 1 - .../transformer/CompoundTransformerTest.java | 2 +- .../core/plan/XmlPlanToSpecTransformer.java | 7 +- .../jclouds/JcloudsStoreObjectAccessor.java | 19 +-- .../rest/resources/CatalogResource.java | 36 +----- .../apache/brooklyn/util/stream/Streams.java | 11 ++ .../brooklyn/util/text/StringShortener.java | 6 +- .../brooklyn/util/osgi/OsgiTestResources.java | 11 +- .../brooklyn/util/text/StringShortenerTest.java | 2 +- 51 files changed, 555 insertions(+), 285 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java index aacc33d..515ec6b 100644 --- a/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java +++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/ManagementContext.java @@ -39,7 +39,6 @@ import org.apache.brooklyn.config.StringConfigMap; import org.apache.brooklyn.util.guava.Maybe; import com.google.common.annotations.Beta; -import com.google.common.base.Optional; /** * This is the entry point for accessing and interacting with a realm of applications and their entities in Brooklyn. @@ -59,22 +58,9 @@ public interface ManagementContext { // - interface PropertiesReloadListener /** - * UID for the Brooklyn management plane which this {@link ManagementContext} node is a part of. - * <p> - * Each Brooklyn entity is actively managed by a unique management plane - * whose ID which should not normally change for the duration of that entity, - * even though the nodes in that plane might, and the plane may go down and come back up. - * In other words the value of {@link Application#getManagementContext()#getManagementPlaneId()} - * will generally be constant (in contrast to {@link #getManagementNodeId()}). - * <p> - * This value should not be null unless the management context is still initialising. The value is set: - * <ul> - * <li>no persistence - during launch - * <li>persistence enabled, HA disabled - on rebind (during launch) - * <li>persistence enabled, HA enabled - on the first HA state check (async to launch) - * </ul> + * As {@link #getManagementPlaneIdMaybe()}, but throws if not available, to prevent callers accessing prematurely. * - * @deprecated since 0.11.0, use {@link #getOptionalManagementPlaneId()} instead. + * @deprecated since 0.11.0, use {@link #getManagementPlaneIdMaybe()} instead. */ @Deprecated String getManagementPlaneId(); @@ -95,14 +81,15 @@ public interface ManagementContext { * <li>persistence enabled, HA enabled - on the first HA state check (async to launch) * </ul> */ - Optional<String> getOptionalManagementPlaneId(); + Maybe<String> getManagementPlaneIdMaybe(); /** * UID for this {@link ManagementContext} node (as part of a single management plane). * <p> * No two instances of {@link ManagementContext} should ever have the same node UID. * The value of {@link Application#getManagementContext()#getManagementNodeId()} may - * change many times (in contrast to {@link #getOptionalManagementPlaneId()}). + * change if it is rebinded to a different node, + * in contrast to {@link #getManagementPlaneIdMaybe()} which is the same for all nodes in a Brooklyn plane. * <p> * This value should not be null unless the management context is a non-functional * (non-deployment) instance. */ http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java index 574a680..76002e0 100644 --- a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java +++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/RebindExceptionHandler.java @@ -30,9 +30,10 @@ 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.sensor.Feed; +import org.apache.brooklyn.api.typereg.ManagedBundle; +import org.apache.brooklyn.config.ConfigKey; import com.google.common.annotations.Beta; -import org.apache.brooklyn.config.ConfigKey; /** * Handler called on all exceptions to do with rebind. @@ -81,6 +82,11 @@ public interface RebindExceptionHandler { * @return the catalog item to use in place of the missing one */ CatalogItem<?, ?> onDanglingCatalogItemRef(String id); + + /** + * @return the bundle to use in place of a missing one + */ + ManagedBundle onDanglingBundleRef(String id); /** * @return the item to use in place of the missing one http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java ---------------------------------------------------------------------- diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java index 8ee23da..aa8422f 100644 --- a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java +++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMemento.java @@ -45,6 +45,7 @@ public interface BrooklynMemento extends Serializable { public EnricherMemento getEnricherMemento(String id); public FeedMemento getFeedMemento(String id); public CatalogItemMemento getCatalogItemMemento(String id); + public ManagedBundleMemento getManagedBundleMemento(String id); public Collection<String> getApplicationIds(); public Collection<String> getTopLevelLocationIds(); @@ -55,6 +56,7 @@ public interface BrooklynMemento extends Serializable { public Collection<String> getEnricherIds(); public Collection<String> getFeedIds(); public Collection<String> getCatalogItemIds(); + public Collection<String> getManagedBundleIds(); public Map<String, EntityMemento> getEntityMementos(); public Map<String, LocationMemento> getLocationMementos(); @@ -62,5 +64,6 @@ public interface BrooklynMemento extends Serializable { public Map<String, EnricherMemento> getEnricherMementos(); public Map<String, FeedMemento> getFeedMementos(); public Map<String, CatalogItemMemento> getCatalogItemMementos(); + public Map<String, ManagedBundleMemento> getManagedBundleMementos(); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/BrooklynMementoPersister.java ---------------------------------------------------------------------- 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 f600418..e352200 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 @@ -37,6 +37,7 @@ 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.sensor.Feed; +import org.apache.brooklyn.api.typereg.ManagedBundle; import org.apache.brooklyn.util.time.Duration; import com.google.common.annotations.Beta; @@ -56,6 +57,7 @@ public interface BrooklynMementoPersister { Enricher lookupEnricher(String id); Feed lookupFeed(String id); CatalogItem<?, ?> lookupCatalogItem(String id); + ManagedBundle lookupBundle(String id); /** retrieve the item with the given ID, optionally ensuring it is of the indicated type; null if not found */ BrooklynObject lookup(@Nullable BrooklynObjectType type, String objectId); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java ---------------------------------------------------------------------- diff --git a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java index 4c94b16..cb6b740 100644 --- a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java +++ b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/creation/CampToSpecTransformer.java @@ -32,9 +32,9 @@ import org.apache.brooklyn.camp.brooklyn.api.AssemblyTemplateSpecInstantiator; import org.apache.brooklyn.camp.spi.AssemblyTemplate; import org.apache.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator; import org.apache.brooklyn.core.mgmt.classloading.JavaBrooklynClassLoadingContext; -import org.apache.brooklyn.core.plan.PlanNotRecognizedException; import org.apache.brooklyn.core.plan.PlanToSpecTransformer; import org.apache.brooklyn.core.typereg.RegisteredTypes; +import org.apache.brooklyn.core.typereg.UnsupportedTypePlanException; import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; @@ -74,10 +74,10 @@ public class CampToSpecTransformer implements PlanToSpecTransformer { if (at.getPlatformComponentTemplates()==null || at.getPlatformComponentTemplates().isEmpty()) { if (at.getCustomAttributes().containsKey(BrooklynCampReservedKeys.BROOKLYN_CATALOG)) throw new IllegalArgumentException("Unrecognized application blueprint format: expected an application, not a brooklyn.catalog"); - throw new PlanNotRecognizedException("Unrecognized application blueprint format: no services defined"); + throw new UnsupportedTypePlanException("Unrecognized application blueprint format: no services defined"); } // map this (expected) error to a nicer message - throw new PlanNotRecognizedException("Unrecognized application blueprint format"); + throw new UnsupportedTypePlanException("Unrecognized application blueprint format"); } } catch (Exception e) { // TODO how do we figure out that the plan is not supported vs. invalid to wrap in a PlanNotRecognizedException? @@ -92,7 +92,7 @@ public class CampToSpecTransformer implements PlanToSpecTransformer { public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec(CatalogItem<T, SpecT> item, Set<String> encounteredTypes) { // Ignore old-style java type catalog items - there is a different (deprecated) transformer for that if (item.getPlanYaml() == null) { - throw new PlanNotRecognizedException("Old style catalog item " + item + " not supported."); + throw new UnsupportedTypePlanException("Old style catalog item " + item + " not supported."); } if (encounteredTypes.contains(item.getSymbolicName())) { throw new IllegalStateException("Already encountered types " + encounteredTypes + " must not contain catalog item being resolver " + item.getSymbolicName()); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java ---------------------------------------------------------------------- diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java index 0d6d5c2..1248110 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlRebindTest.java @@ -18,6 +18,7 @@ */ package org.apache.brooklyn.camp.brooklyn; +import java.io.File; import java.io.Reader; import java.io.StringReader; import java.util.Map; @@ -29,7 +30,9 @@ import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode; import org.apache.brooklyn.camp.brooklyn.spi.creation.CampTypePlanTransformer; +import org.apache.brooklyn.camp.spi.PlatformRootSummary; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; import org.apache.brooklyn.core.entity.Entities; import org.apache.brooklyn.core.entity.StartableApplication; @@ -72,6 +75,16 @@ public class AbstractYamlRebindTest extends RebindTestFixture<StartableApplicati platform = launcher.getCampPlatform(); } + @Override + protected LocalManagementContext createNewManagementContext(File mementoDir, HighAvailabilityMode haMode, Map<?, ?> additionalProperties) { + LocalManagementContext newMgmt = super.createNewManagementContext(mementoDir, haMode, additionalProperties); + new BrooklynCampPlatform( + PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(), + newMgmt) + .setConfigKeyAtManagmentContext(); + return newMgmt; + } + @AfterMethod(alwaysRun = true) @Override public void tearDown() throws Exception { http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogMakeOsgiBundleTest.java ---------------------------------------------------------------------- diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogMakeOsgiBundleTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogMakeOsgiBundleTest.java index 6f7117e..c1030c1 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogMakeOsgiBundleTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogMakeOsgiBundleTest.java @@ -174,7 +174,7 @@ public class CatalogMakeOsgiBundleTest extends AbstractYamlTest { try (FileInputStream fin = new FileInputStream(jf)) { BasicManagedBundle bundleMetadata = new BasicManagedBundle(); Bundle bundle = - ((LocalManagementContext)mgmt()).getOsgiManager().get().installUploadedBundle(bundleMetadata, fin); + ((LocalManagementContext)mgmt()).getOsgiManager().get().installUploadedBundle(bundleMetadata, fin, true); bundlesToRemove.add(bundle); } catch (Exception e) { throw Exceptions.propagate(e); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java ---------------------------------------------------------------------- diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java index cee7a4d..a3ca51b 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityRebindTest.java @@ -20,23 +20,32 @@ package org.apache.brooklyn.camp.brooklyn.catalog; import static org.testng.Assert.assertEquals; +import java.util.Map; + import org.apache.brooklyn.api.effector.Effector; import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.location.Location; import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.typereg.ManagedBundle; +import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.camp.brooklyn.AbstractYamlRebindTest; import org.apache.brooklyn.core.entity.EntityInternal; import org.apache.brooklyn.core.entity.StartableApplication; +import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.mgmt.osgi.OsgiVersionMoreEntityTest; import org.apache.brooklyn.core.test.entity.TestEntity; +import org.apache.brooklyn.core.typereg.BasicManagedBundle; import org.apache.brooklyn.entity.stock.BasicApplication; +import org.apache.brooklyn.test.Asserts; import org.apache.brooklyn.test.support.TestResourceUnavailableException; import org.apache.brooklyn.util.core.ClassLoaderUtils; +import org.apache.brooklyn.util.core.ResourceUtils; import org.apache.brooklyn.util.javalang.Reflections; import org.apache.brooklyn.util.osgi.OsgiTestResources; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.testng.Assert; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; @@ -44,7 +53,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; /** Many of the same tests as per {@link OsgiVersionMoreEntityTest} but using YAML for catalog and entities, so catalog item ID is set automatically */ -public class CatalogOsgiVersionMoreEntityRebindTest extends AbstractYamlRebindTest { +public class CatalogOsgiVersionMoreEntityRebindTest extends AbstractYamlRebindTest implements OsgiTestResources { @SuppressWarnings("unused") private static final Logger log = LoggerFactory.getLogger(CatalogOsgiVersionMoreEntityRebindTest.class); @@ -54,7 +63,27 @@ public class CatalogOsgiVersionMoreEntityRebindTest extends AbstractYamlRebindTe return true; } - // See https://issues.apache.org/jira/browse/BROOKLYN-409 + @Test + public void testRebindAppIncludingBundle() throws Exception { + TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_PATH); + ((ManagementContextInternal)mgmt()).getOsgiManager().get().installUploadedBundle(new BasicManagedBundle(), + new ResourceUtils(getClass()).getResourceFromUrl(BROOKLYN_TEST_MORE_ENTITIES_V1_URL), true); + + createAndStartApplication("services: [ { type: "+BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY+" } ]"); + + StartableApplication newApp = rebind(); + + // bundles installed + Map<String, ManagedBundle> bundles = ((ManagementContextInternal)mgmt()).getOsgiManager().get().getManagedBundles(); + Asserts.assertSize(bundles.keySet(), 1); + + // types installed + RegisteredType t = mgmt().getTypeRegistry().get("org.apache.brooklyn.test.osgi.entities.more.MoreEntity"); + Assert.assertNotNull(t); + + Assert.assertNotNull(newApp); + } + @Test public void testPolicyInBundleReferencedByStockCatalogItem() throws Exception { TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_PATH); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java ---------------------------------------------------------------------- diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java index 15ff38e..118c518 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogOsgiVersionMoreEntityTest.java @@ -20,6 +20,8 @@ package org.apache.brooklyn.camp.brooklyn.catalog; import static org.testng.Assert.assertTrue; +import java.util.Map; + import org.apache.brooklyn.api.entity.Entity; import org.apache.brooklyn.api.entity.EntitySpec; import org.apache.brooklyn.api.location.Location; @@ -27,16 +29,22 @@ import org.apache.brooklyn.api.location.LocationSpec; import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry; +import org.apache.brooklyn.api.typereg.ManagedBundle; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.camp.brooklyn.AbstractYamlTest; import org.apache.brooklyn.camp.brooklyn.spi.creation.BrooklynEntityMatcher; +import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.mgmt.osgi.OsgiVersionMoreEntityTest; import org.apache.brooklyn.core.objs.BrooklynTypes; +import org.apache.brooklyn.core.typereg.BasicManagedBundle; import org.apache.brooklyn.core.typereg.RegisteredTypePredicates; import org.apache.brooklyn.core.typereg.RegisteredTypes; +import org.apache.brooklyn.test.Asserts; import org.apache.brooklyn.test.support.TestResourceUnavailableException; import org.apache.brooklyn.util.core.ResourceUtils; +import org.apache.brooklyn.util.osgi.OsgiTestResources; import org.apache.brooklyn.util.text.Strings; +import org.osgi.framework.Bundle; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.Assert; @@ -45,7 +53,7 @@ import org.testng.annotations.Test; import com.google.common.collect.Iterables; /** Many of the same tests as per {@link OsgiVersionMoreEntityTest} but using YAML for catalog and entities, so catalog item ID is set automatically */ -public class CatalogOsgiVersionMoreEntityTest extends AbstractYamlTest { +public class CatalogOsgiVersionMoreEntityTest extends AbstractYamlTest implements OsgiTestResources { private static final Logger log = LoggerFactory.getLogger(CatalogOsgiVersionMoreEntityTest.class); @@ -58,6 +66,26 @@ public class CatalogOsgiVersionMoreEntityTest extends AbstractYamlTest { return ResourceUtils.create(CatalogOsgiVersionMoreEntityTest.class).getResourceAsString( "classpath:/"+CatalogOsgiVersionMoreEntityTest.class.getPackage().getName().replace('.', '/')+"/"+filename); } + + @Test + public void testBrooklynManagedBundleInstall() throws Exception { + BasicManagedBundle mb = new BasicManagedBundle(); + Bundle b = ((ManagementContextInternal)mgmt()).getOsgiManager().get().installUploadedBundle(mb, + new ResourceUtils(getClass()).getResourceFromUrl(BROOKLYN_TEST_MORE_ENTITIES_V1_URL), true); + Assert.assertEquals(mb.getSymbolicName(), b.getSymbolicName()); + + // bundle installed + Map<String, ManagedBundle> bundles = ((ManagementContextInternal)mgmt()).getOsgiManager().get().getManagedBundles(); + Asserts.assertSize(bundles.keySet(), 1); + Assert.assertEquals(mb.getId(), Iterables.getOnlyElement( bundles.keySet() )); + + // types installed + RegisteredType t = mgmt().getTypeRegistry().get(BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY); + Assert.assertNotNull(t); + + // can deploy + createAndStartApplication("services: [ { type: "+BROOKLYN_TEST_MORE_ENTITIES_MORE_ENTITY+" } ]"); + } @Test public void testMoreEntityV1() throws Exception { http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java index 4e15d24..2c76520 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/JavaCatalogToSpecTransformer.java @@ -30,8 +30,8 @@ import org.apache.brooklyn.api.policy.Policy; import org.apache.brooklyn.api.policy.PolicySpec; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.core.objs.BasicSpecParameter; -import org.apache.brooklyn.core.plan.PlanNotRecognizedException; import org.apache.brooklyn.core.plan.PlanToSpecTransformer; +import org.apache.brooklyn.core.typereg.UnsupportedTypePlanException; import org.apache.brooklyn.util.exceptions.Exceptions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,13 +65,13 @@ public class JavaCatalogToSpecTransformer implements PlanToSpecTransformer { } @Override - public EntitySpec<? extends Application> createApplicationSpec(String plan) throws PlanNotRecognizedException { - throw new PlanNotRecognizedException(getClass().getName() + " doesn't parse application plans."); + public EntitySpec<? extends Application> createApplicationSpec(String plan) throws UnsupportedTypePlanException { + throw new UnsupportedTypePlanException(getClass().getName() + " doesn't parse application plans."); } @Override public <T, SpecT extends AbstractBrooklynObjectSpec<? extends T, SpecT>> SpecT createCatalogSpec( - CatalogItem<T, SpecT> item, Set<String> encounteredTypes) throws PlanNotRecognizedException { + CatalogItem<T, SpecT> item, Set<String> encounteredTypes) throws UnsupportedTypePlanException { @SuppressWarnings("deprecation") String javaType = item.getJavaType(); if (javaType != null) { @@ -104,7 +104,7 @@ public class JavaCatalogToSpecTransformer implements PlanToSpecTransformer { SpecT untypedSpc = (SpecT) spec; return untypedSpc; } else { - throw new PlanNotRecognizedException(getClass().getName() + " parses only old-style catalog items containing javaType"); + throw new UnsupportedTypePlanException(getClass().getName() + " parses only old-style catalog items containing javaType"); } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java index db65c9b..11cf9f3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/HighAvailabilityManagerImpl.java @@ -333,7 +333,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { ManagementPlaneSyncRecord newState = loadManagementPlaneSyncRecord(true); String masterNodeId = newState.getMasterNodeId(); ManagementNodeSyncRecord masterNodeDetails = newState.getManagementNodes().get(masterNodeId); - LOG.info("Management node "+ownNodeId+" running as HA " + getInternalNodeState() + " autodetected" + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" running as HA " + getInternalNodeState() + " autodetected" + (startMode == HighAvailabilityMode.HOT_STANDBY || startMode == HighAvailabilityMode.HOT_BACKUP ? " (will change to "+startMode+")" : "") + ", " + @@ -343,25 +343,25 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { (masterNodeDetails==null || masterNodeDetails.getUri()==null ? " (no url)" : " at "+masterNodeDetails.getUri()))); break; case MASTER: - LOG.info("Management node "+ownNodeId+" running as HA MASTER autodetected"); + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" running as HA MASTER autodetected"); break; default: - throw new IllegalStateException("Management node "+ownNodeId+" set to HA AUTO, encountered unexpected mode "+getInternalNodeState()); + throw new IllegalStateException("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" set to HA AUTO, encountered unexpected mode "+getInternalNodeState()); } break; case MASTER: if (!failOnExplicitModesIfUnusual || existingMaster==null) { promoteToMaster(); if (existingMaster!=null) { - LOG.info("Management node "+ownNodeId+" running as HA MASTER explicitly"); + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" running as HA MASTER explicitly"); } else { - LOG.info("Management node "+ownNodeId+" running as HA MASTER explicitly, stealing from "+existingMaster); + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" running as HA MASTER explicitly, stealing from "+existingMaster); } } else if (!weAreRecognisedAsMaster) { throw new IllegalStateException("Master already exists; cannot run as master (master "+existingMaster.toVerboseString()+"); " + "to trigger a promotion, set a priority and demote the current master"); } else { - LOG.info("Management node "+ownNodeId+" already running as HA MASTER, when set explicitly"); + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" already running as HA MASTER, when set explicitly"); } break; case HOT_BACKUP: @@ -383,11 +383,11 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { publishAndCheck(true); } if (failOnExplicitModesIfUnusual && existingMaster==null) { - LOG.error("Management node "+ownNodeId+" detected no master when "+startMode+" requested and existing master required; failing."); + LOG.error("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" detected no master when "+startMode+" requested and existing master required; failing."); throw new IllegalStateException("No existing master; cannot start as "+startMode); } } - String message = "Management node "+ownNodeId+" running as HA "+getNodeState()+" ("; + String message = "Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" running as HA "+getNodeState()+" ("; if (getNodeState().toString().equals(startMode.toString())) message += "explicitly requested"; else if (startMode==HighAvailabilityMode.HOT_STANDBY && getNodeState()==ManagementNodeState.STANDBY) @@ -410,7 +410,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { break; case DISABLED: // safe just to run even if we weren't master - LOG.info("Management node "+ownNodeId+" HA DISABLED (was "+getInternalNodeState()+")"); + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" HA DISABLED (was "+getInternalNodeState()+")"); demoteTo(ManagementNodeState.FAILED); if (pollingTask!=null) pollingTask.cancel(true); break; @@ -435,15 +435,15 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { publishHealth(); if (getNodeState()==ManagementNodeState.HOT_STANDBY || getNodeState()==ManagementNodeState.HOT_BACKUP) { - LOG.info("Management node "+ownNodeId+" now running as HA "+getNodeState()+"; " + LOG.info("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" now running as HA "+getNodeState()+"; " + managementContext.getApplications().size()+" application"+Strings.s(managementContext.getApplications().size())+" loaded"); } else { // shouldn't come here, we should have gotten an error above - LOG.warn("Management node "+ownNodeId+" unable to promote to "+startMode+" (currently "+getNodeState()+"); " + LOG.warn("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" unable to promote to "+startMode+" (currently "+getNodeState()+"); " + "(see log for further details)"); } } catch (Exception e) { - LOG.warn("Management node "+ownNodeId+" unable to promote to "+startMode+" (currently "+getNodeState()+"); rethrowing: "+Exceptions.collapseText(e)); + LOG.warn("Management node "+ownNodeId+" in "+managementContext.getManagementPlaneIdMaybe().or("<new-plane>")+" unable to promote to "+startMode+" (currently "+getNodeState()+"); rethrowing: "+Exceptions.collapseText(e)); nodeStateTransitionComplete = true; throw Exceptions.propagate(e); } @@ -980,7 +980,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager { if (disabled) { // if HA is disabled, then we are the only node - no persistence; just load a memento to describe this node Builder builder = ManagementPlaneSyncRecordImpl.builder() - .planeId(managementContext.getOptionalManagementPlaneId().orNull()) + .planeId(managementContext.getManagementPlaneIdMaybe().orNull()) .node(createManagementNodeSyncRecord(true)); if (getTransitionTargetNodeState() == ManagementNodeState.MASTER) { builder.masterNodeId(ownNodeId); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java index 37ba4ce..fbef947 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java @@ -32,16 +32,20 @@ import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicReference; +import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.catalog.CatalogItem.CatalogBundle; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.api.typereg.ManagedBundle; import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl; import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.core.BrooklynFeatureEnablement; import org.apache.brooklyn.core.BrooklynVersion; +import org.apache.brooklyn.core.catalog.internal.CatalogBundleLoader; import org.apache.brooklyn.core.mgmt.persist.OsgiClassPrefixer; import org.apache.brooklyn.core.server.BrooklynServerConfig; import org.apache.brooklyn.core.server.BrooklynServerPaths; import org.apache.brooklyn.core.typereg.BasicManagedBundle; +import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.MutableSet; import org.apache.brooklyn.util.core.osgi.Osgis; @@ -57,11 +61,15 @@ import org.apache.brooklyn.util.stream.Streams; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import org.osgi.framework.Bundle; +import org.osgi.framework.BundleException; import org.osgi.framework.launch.Framework; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.annotations.Beta; import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; @@ -125,7 +133,7 @@ public class OsgiManager { return ImmutableMap.copyOf(managedBundles); } - public Bundle installUploadedBundle(ManagedBundle bundleMetadata, InputStream zipIn) { + public Bundle installUploadedBundle(ManagedBundle bundleMetadata, InputStream zipIn, boolean loadCatalogBom) { try { Bundle alreadyBundle = checkBundleInstalledThrowIfInconsistent(bundleMetadata, false); if (alreadyBundle!=null) { @@ -152,19 +160,18 @@ public class OsgiManager { } mgmt.getRebindManager().getChangeListener().onChanged(bundleMetadata); + // starting here flags wiring issues earlier + // but may break some things running from the IDE bundleInstalled.start(); - // benefits of start: - // a) we get wiring issues thrown here, and - // b) catalog.bom in root will be scanned synchronously here - // however drawbacks: - // c) other code doesn't always do it (see eg BundleMaker) - // d) heavier-weight earlier - // e) tests in IDE break (but mvn fine) + + if (loadCatalogBom) { + loadCatalogBom(bundleInstalled); + } return bundleInstalled; } catch (Exception e) { Exceptions.propagateIfFatal(e); - throw new IllegalStateException("Bundle "+bundleMetadata+" failed to install: " + e.getMessage(), e); + throw new IllegalStateException("Bundle "+bundleMetadata+" failed to install: " + Exceptions.collapseText(e), e); } } @@ -188,6 +195,39 @@ public class OsgiManager { } } + @Beta + // TODO this is designed to work if the FEATURE_LOAD_BUNDLE_CATALOG_BOM is disabled, the default, but unintuitive here + // it probably works even if that is true, but we should consider what to do; + // possibly remove that other capability, so that bundles with BOMs _have_ to be installed via this method. + // (load order gets confusing with auto-scanning...) + public List<? extends CatalogItem<?,?>> loadCatalogBom(Bundle bundle) { + List<? extends CatalogItem<?, ?>> catalogItems = MutableList.of(); + loadCatalogBom(mgmt, bundle, catalogItems); + return catalogItems; + } + + private static Iterable<? extends CatalogItem<?, ?>> loadCatalogBom(ManagementContext mgmt, Bundle bundle, Iterable<? extends CatalogItem<?, ?>> catalogItems) { + if (!BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_LOAD_BUNDLE_CATALOG_BOM)) { + // if the above feature is not enabled, let's do it manually (as a contract of this method) + try { + // TODO improve on this - it ignores the configuration of whitelists, see CatalogBomScanner. + // One way would be to add the CatalogBomScanner to the new Scratchpad area, then retrieving the singleton + // here to get back the predicate from it. + final Predicate<Bundle> applicationsPermitted = Predicates.<Bundle>alwaysTrue(); + + catalogItems = new CatalogBundleLoader(applicationsPermitted, mgmt).scanForCatalog(bundle); + } catch (RuntimeException ex) { + try { + bundle.uninstall(); + } catch (BundleException e) { + log.error("Cannot uninstall bundle " + bundle.getSymbolicName() + ":" + bundle.getVersion(), e); + } + throw new IllegalArgumentException("Error installing catalog items", ex); + } + } + return catalogItems; + } + private void checkCorrectlyInstalled(OsgiBundleWithUrl bundle, Bundle b) { String nv = b.getSymbolicName()+":"+b.getVersion().toString(); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java index 89d5b3c..9bd4d21 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/AbstractManagementContext.java @@ -524,7 +524,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte result = getLocationManager().getLocation(id); if (result!=null && type.isInstance(result)) return (T)result; - // TODO policies, enrichers, feeds + // TODO policies, enrichers, feeds; bundles? return null; } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java index ccc59b1..bdb6302 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java @@ -69,7 +69,6 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.Beta; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; -import com.google.common.base.Optional; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; @@ -217,21 +216,21 @@ public class LocalManagementContext extends AbstractManagementContext { } @Override - public Optional<String> getOptionalManagementPlaneId() { - return Optional.fromNullable(managementPlaneId); + public Maybe<String> getManagementPlaneIdMaybe() { + return Maybe.ofDisallowingNull(managementPlaneId); } public void setManagementPlaneId(String newPlaneId) { if (managementPlaneId != null && !managementPlaneId.equals(newPlaneId)) { - log.warn("Management plane ID changed from {} to {}", managementPlaneId, newPlaneId); - log.debug("Management plane ID changed from {} to {}", new Object[] {managementPlaneId, newPlaneId, new RuntimeException("Stack trace for setManagementPlaneId")}); + log.warn("Management plane ID at {} {} changed from {} to {} (can happen on concurrent startup of multiple nodes)", new Object[] { managementNodeId, getHighAvailabilityManager().getNodeState(), managementPlaneId, newPlaneId }); + log.debug("Management plane ID at {} {} changed from {} to {} (can happen on concurrent startup of multiple nodes)", new Object[] {managementNodeId, getHighAvailabilityManager().getNodeState(), managementPlaneId, newPlaneId, new RuntimeException("Stack trace for setManagementPlaneId")}); } this.managementPlaneId = newPlaneId; } public void generateManagementPlaneId() { if (this.managementPlaneId != null) { - throw new IllegalStateException("Request to generate a management plane ID but one already exists (" + managementPlaneId + ")"); + throw new IllegalStateException("Request to generate a management plane ID for node "+managementNodeId+" but one already exists (" + managementPlaneId + ")"); } this.managementPlaneId = Strings.makeRandomId(8); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java index 10f49cd..4e14207 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/NonDeploymentManagementContext.java @@ -76,7 +76,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Objects; -import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -130,8 +129,8 @@ public class NonDeploymentManagementContext implements ManagementContextInternal } @Override - public Optional<String> getOptionalManagementPlaneId() { - return (initialManagementContext == null) ? Optional.<String>absent() : initialManagementContext.getOptionalManagementPlaneId(); + public Maybe<String> getManagementPlaneIdMaybe() { + return (initialManagementContext == null) ? Maybe.<String>absent("Uninitialized non-deployment management context") : initialManagementContext.getManagementPlaneIdMaybe(); } @Override http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterToObjectStore.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterToObjectStore.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterToObjectStore.java index f0af9d1..142bcbc 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterToObjectStore.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterToObjectStore.java @@ -65,11 +65,9 @@ import org.apache.brooklyn.core.mgmt.rebind.dto.BrooklynMementoManifestImpl; import org.apache.brooklyn.core.typereg.BasicManagedBundle; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.collections.MutableSet; -import org.apache.brooklyn.util.core.ResourceUtils; import org.apache.brooklyn.util.core.xstream.XmlUtil; import org.apache.brooklyn.util.exceptions.CompoundRuntimeException; import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.stream.Streams; import org.apache.brooklyn.util.text.Strings; import org.apache.brooklyn.util.time.Duration; import org.apache.brooklyn.util.time.Time; @@ -311,6 +309,11 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer Visitor loaderVisitor = new Visitor() { @Override public void visit(BrooklynObjectType type, String id, String contentsSubpath) throws Exception { + if (type == BrooklynObjectType.MANAGED_BUNDLE && id.endsWith(".jar")) { + // don't visit jar files directly; someone else will read them + return; + } + String contents = null; try { contents = read(contentsSubpath); @@ -325,9 +328,9 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer LOG.warn("ID mismatch on "+type.toCamelCase()+", "+id+" from path, "+safeXmlId+" from xml"); if (type == BrooklynObjectType.MANAGED_BUNDLE) { - // TODO write to temp file - String jarData = read(contentsSubpath+".jar"); - builder.bundleJar(id, ByteSource.wrap(jarData.getBytes())); + // TODO write to temp file, destroy when loaded + byte[] jarData = readBytes(contentsSubpath+".jar"); + builder.bundleJar(id, ByteSource.wrap(jarData)); } builder.put(type, xmlId, contents); } @@ -669,7 +672,7 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer } } - private void addPersistContentIfManagedBundle(BrooklynObjectType type, String id, List<ListenableFuture<?>> futures, PersistenceExceptionHandler exceptionHandler) { + private void addPersistContentIfManagedBundle(final BrooklynObjectType type, final String id, List<ListenableFuture<?>> futures, final PersistenceExceptionHandler exceptionHandler) { if (type==BrooklynObjectType.MANAGED_BUNDLE) { if (mgmt==null) { throw new IllegalStateException("Cannot persist bundles without a mangaement context"); @@ -677,26 +680,20 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer final ManagedBundle mb = ((ManagementContextInternal)mgmt).getOsgiManager().get().getManagedBundles().get(id); if (mb==null) { LOG.warn("Cannot find managed bundle for added bundle "+id+"; ignoring"); - } - if (mb.getUrl()==null) { - LOG.trace("No URL for managed bundle for bundle "+id+", so not persisting"); return; } - String jarContent = Streams.readFullyStringAndClose(new ResourceUtils("persist").getResourceFromUrl(mb.getUrl())); - - // erase the URL once persisted - this prevents it from re-persisting - // (could introduce multiple or a transient field instead?) if (mb instanceof BasicManagedBundle) { final File f = ((BasicManagedBundle)mb).getTempLocalFileWhenJustUploaded(); + // use the above transient field to know when to upload if (f!=null) { - futures.add(asyncPersist(type.getSubPathName(), type, id+".jar", jarContent, exceptionHandler)); - executor.submit(new Runnable() { + futures.add( executor.submit(new Runnable() { @Override public void run() { + persist(type.getSubPathName(), type, id+".jar", com.google.common.io.Files.asByteSource(f), exceptionHandler); ((BasicManagedBundle)mb).setTempLocalFileWhenJustUploaded(null); f.delete(); - }}); + } }) ); } } } @@ -727,6 +724,11 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer return objectAccessor.get(); } + private byte[] readBytes(String subPath) { + StoreObjectAccessor objectAccessor = objectStore.newAccessor(subPath); + return objectAccessor.getBytes(); + } + private void persist(String subPath, Memento memento, PersistenceExceptionHandler exceptionHandler) { try { getWriter(getPath(subPath, memento.getId())).put(getSerializerWithStandardClassLoader().toString(memento)); @@ -746,6 +748,14 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer } } + private void persist(String subPath, BrooklynObjectType type, String id, ByteSource content, PersistenceExceptionHandler exceptionHandler) { + try { + getWriter(getPath(subPath, id)).put(content); + } catch (Exception e) { + exceptionHandler.onPersistRawMementoFailed(type, id, e); + } + } + private void delete(String subPath, String id, PersistenceExceptionHandler exceptionHandler) { try { StoreObjectAccessorWithLock w = getWriter(getPath(subPath, id)); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java index c509208..b3e17c5 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/BrooklynPersistenceUtils.java @@ -44,7 +44,6 @@ import org.apache.brooklyn.core.mgmt.ha.ManagementPlaneSyncRecordPersisterToObje import org.apache.brooklyn.core.mgmt.ha.OsgiManager; import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager; import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl; import org.apache.brooklyn.core.mgmt.rebind.transformer.CompoundTransformer; import org.apache.brooklyn.core.mgmt.rebind.transformer.CompoundTransformerLoader; @@ -166,7 +165,7 @@ public class BrooklynPersistenceUtils { MementoSerializer<Object> rawSerializer = new XmlMementoSerializer<Object>(mgmt.getClass().getClassLoader()); RetryingMementoSerializer<Object> serializer = new RetryingMementoSerializer<Object>(rawSerializer, 1); - result.planeId(mgmt.getOptionalManagementPlaneId().orNull()); + result.planeId(mgmt.getManagementPlaneIdMaybe().orNull()); for (Location instance: mgmt.getLocationManager().getLocations()) result.location(instance.getId(), serializer.toString(newObjectMemento(instance))); for (Entity instance: mgmt.getEntityManager().getEntities()) { http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessor.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessor.java index f061884..a9f0613 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessor.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/FileBasedStoreObjectAccessor.java @@ -19,17 +19,20 @@ package org.apache.brooklyn.core.mgmt.persist; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.io.FileUtil; +import org.apache.brooklyn.util.stream.Streams; import org.apache.brooklyn.util.text.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Charsets; -import com.google.common.base.Objects; +import com.google.common.base.MoreObjects; +import com.google.common.io.ByteSource; import com.google.common.io.Files; /** @@ -76,10 +79,14 @@ public class FileBasedStoreObjectAccessor implements PersistenceObjectStore.Stor @Override public void put(String val) { + put(ByteSource.wrap(val.getBytes(Charsets.UTF_8))); + } + + @Override + public void put(ByteSource bytes) { try { - if (val==null) val = ""; FileUtil.setFilePermissionsTo600(tmpFile); - Files.write(val, tmpFile, Charsets.UTF_8); + Streams.copyClose(bytes.openStream(), new FileOutputStream(tmpFile)); FileBasedObjectStore.moveFile(tmpFile, file); } catch (IOException e) { throw Exceptions.propagate("Problem writing data to file "+file+" (via temporary file "+tmpFile+")", e); @@ -125,6 +132,6 @@ public class FileBasedStoreObjectAccessor implements PersistenceObjectStore.Stor @Override public String toString() { - return Objects.toStringHelper(this).add("file", file).toString(); + return MoreObjects.toStringHelper(this).add("file", file).toString(); } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/PersistenceObjectStore.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/PersistenceObjectStore.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/PersistenceObjectStore.java index aa83e14..18a5b64 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/PersistenceObjectStore.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/PersistenceObjectStore.java @@ -28,6 +28,7 @@ import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode; import org.apache.brooklyn.util.time.Duration; import com.google.common.annotations.Beta; +import com.google.common.io.ByteSource; /** * Interface for working with persistence targets, including file system and jclouds object stores. @@ -42,6 +43,7 @@ public interface PersistenceObjectStore { byte[] getBytes(); boolean exists(); void put(String contentsToReplaceOrCreate); + void put(ByteSource bytes); void append(String contentsToAppendOrCreate); void delete(); // NB: creation date is available for many blobstores but http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/StoreObjectAccessorLocking.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/StoreObjectAccessorLocking.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/StoreObjectAccessorLocking.java index 302121f..49de188 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/StoreObjectAccessorLocking.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/StoreObjectAccessorLocking.java @@ -32,6 +32,8 @@ import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.javalang.JavaClassNames; import org.apache.brooklyn.util.time.Duration; +import com.google.common.io.ByteSource; + /** Wraps access to an object (the delegate {@link StoreObjectAccessor} * in a guarded read-write context such that callers will be blocked if another thread * is accessing the object in an incompatible way (e.g. trying to read when someone is writing). @@ -146,6 +148,28 @@ public class StoreObjectAccessorLocking implements PersistenceObjectStore.StoreO } @Override + public void put(ByteSource val) { + try { + queuedWriters.add(Thread.currentThread()); + lock.writeLock().lockInterruptibly(); + try { + queuedWriters.remove(Thread.currentThread()); + if (hasScheduledPutOrDeleteWithNoRead()) + // don't bother writing if someone will write after us and no one is reading + return; + delegate.put(val); + + } finally { + lock.writeLock().unlock(); + } + } catch (InterruptedException e) { + throw Exceptions.propagate(e); + } finally { + queuedWriters.remove(Thread.currentThread()); + } + } + + @Override public void append(String val) { try { lock.writeLock().lockInterruptibly(); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java ---------------------------------------------------------------------- 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 16beb4e..1bded8b 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 @@ -57,6 +57,7 @@ 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.MutableBrooklynMemento; import org.apache.brooklyn.core.sensor.BasicAttributeSensor; @@ -102,9 +103,6 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento this.delegatingClassLoader = new OsgiClassLoader(classLoader); xstream.setClassLoader(this.delegatingClassLoader); - // old (deprecated in 070? or earlier) single-file persistence uses this keyword; TODO remove soon in 080 ? - xstream.alias("brooklyn", MutableBrooklynMemento.class); - xstream.alias("entity", BasicEntityMemento.class); xstream.alias("location", BasicLocationMemento.class); xstream.alias("policy", BasicPolicyMemento.class); @@ -112,6 +110,7 @@ public class XmlMementoSerializer<T> extends XmlSerializer<T> implements Memento xstream.alias("enricher", BasicEnricherMemento.class); xstream.alias("configKey", BasicConfigKey.class); xstream.alias("catalogItem", BasicCatalogItemMemento.class); + xstream.alias("managedBundle", BasicManagedBundleMemento.class); xstream.alias("bundle", CatalogBundleDto.class); xstream.alias("attributeSensor", BasicAttributeSensor.class); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicManagedBundleRebindSupport.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicManagedBundleRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicManagedBundleRebindSupport.java new file mode 100644 index 0000000..384fa65 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicManagedBundleRebindSupport.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.core.mgmt.rebind; + +import org.apache.brooklyn.api.mgmt.rebind.RebindContext; +import org.apache.brooklyn.api.mgmt.rebind.mementos.ManagedBundleMemento; +import org.apache.brooklyn.core.typereg.BasicManagedBundle; + +public class BasicManagedBundleRebindSupport extends AbstractBrooklynObjectRebindSupport<ManagedBundleMemento> { + + public BasicManagedBundleRebindSupport(BasicManagedBundle mb) { + super(mb); + } + + @Override + protected void addConfig(RebindContext rebindContext, ManagedBundleMemento memento) { + // no op + } + + @Override + protected void addCustoms(RebindContext rebindContext, ManagedBundleMemento memento) { + // no op + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextImpl.java index 262c4a1..cc301c9 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextImpl.java @@ -49,6 +49,7 @@ public class RebindContextImpl implements RebindContext { private final Map<String, Enricher> enrichers = Maps.newLinkedHashMap(); private final Map<String, Feed> feeds = Maps.newLinkedHashMap(); private final Map<String, CatalogItem<?, ?>> catalogItems = Maps.newLinkedHashMap(); + private final Map<String, ManagedBundle> bundles = Maps.newLinkedHashMap(); private final ClassLoader classLoader; private final ManagementContext mgmt; @@ -88,8 +89,12 @@ public class RebindContextImpl implements RebindContext { catalogItems.put(id, catalogItem); } + public void registerBundle(String id, ManagedBundle bundle) { + bundles.put(id, bundle); + } + public void installBundle(ManagedBundle bundle, InputStream zipInput) { - ((LocalManagementContext)mgmt).getOsgiManager().get().installUploadedBundle(bundle, zipInput); + ((LocalManagementContext)mgmt).getOsgiManager().get().installUploadedBundle(bundle, zipInput, true); } public void unregisterPolicy(Policy policy) { @@ -108,6 +113,10 @@ public class RebindContextImpl implements RebindContext { catalogItems.remove(item.getId()); } + public void unregisterBundle(ManagedBundle bundle) { + bundles.remove(bundle.getId()); + } + public void clearCatalogItems() { catalogItems.clear(); } @@ -128,12 +137,16 @@ public class RebindContextImpl implements RebindContext { return enrichers.get(id); } + public Feed getFeed(String id) { + return feeds.get(id); + } + public CatalogItem<?, ?> getCatalogItem(String id) { return catalogItems.get(id); } - public Feed getFeed(String id) { - return feeds.get(id); + public ManagedBundle getBundle(String id) { + return bundles.get(id); } @Override @@ -170,6 +183,10 @@ public class RebindContextImpl implements RebindContext { return catalogItems.values(); } + public Collection<ManagedBundle> getBundles() { + return bundles.values(); + } + @Override public Map<String,BrooklynObject> getAllBrooklynObjects() { MutableMap<String,BrooklynObject> result = MutableMap.of(); @@ -179,6 +196,7 @@ public class RebindContextImpl implements RebindContext { result.putAll(enrichers); result.putAll(feeds); result.putAll(catalogItems); + result.putAll(bundles); return result.asUnmodifiable(); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindContextLookupContext.java ---------------------------------------------------------------------- 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 eb55784..f463047 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 @@ -32,6 +32,7 @@ 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.sensor.Feed; +import org.apache.brooklyn.api.typereg.ManagedBundle; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -129,6 +130,16 @@ public class RebindContextLookupContext implements LookupContext { } @Override + public ManagedBundle lookupBundle(String id) { + ManagedBundle result = rebindContext.getBundle(id); + if (result == null) { + // no need for managementContext.lookup(id, ManagedBundle.class); + result = exceptionHandler.onDanglingBundleRef(id); + } + return result; + } + + @Override public BrooklynObject lookup(BrooklynObjectType type, String id) { if (type==null) { BrooklynObject result = peek(null, id); @@ -140,6 +151,7 @@ public class RebindContextLookupContext implements LookupContext { switch (type) { case CATALOG_ITEM: return lookupCatalogItem(id); + case MANAGED_BUNDLE: return lookupBundle(id); case ENRICHER: return lookupEnricher(id); case ENTITY: return lookupEntity(id); case FEED: return lookupFeed(id); @@ -162,6 +174,7 @@ public class RebindContextLookupContext implements LookupContext { switch (type) { case CATALOG_ITEM: return rebindContext.getCatalogItem(id); + case MANAGED_BUNDLE: return rebindContext.getBundle(id); case ENRICHER: return rebindContext.getEnricher(id); case ENTITY: return rebindContext.getEntity(id); case FEED: return rebindContext.getFeed(id); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindExceptionHandlerImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindExceptionHandlerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindExceptionHandlerImpl.java index 08a1eef..17d4073 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindExceptionHandlerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindExceptionHandlerImpl.java @@ -38,6 +38,7 @@ 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.sensor.Feed; +import org.apache.brooklyn.api.typereg.ManagedBundle; import org.apache.brooklyn.config.ConfigKey; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.QuorumCheck; @@ -247,7 +248,12 @@ public class RebindExceptionHandlerImpl implements RebindExceptionHandler { } @Override - public CatalogItem<?, ?> onDanglingUntypedItemRef(String id) { + public ManagedBundle onDanglingBundleRef(String id) { + return (ManagedBundle) onDanglingUntypedItemRef(id); + } + + @Override + public BrooklynObject onDanglingUntypedItemRef(String id) { missingUntypedItems.add(id); if (danglingRefFailureMode == RebindManager.RebindFailureMode.FAIL_FAST) { throw new IllegalStateException("No item found with id "+id); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java index e12c796..92a87a7 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java @@ -499,7 +499,9 @@ public abstract class RebindIteration { LOG.warn("Rebinding against existing persisted state, but no planeId found. Will generate a new one. " + "Expected if this is the first rebind after upgrading to Brooklyn 0.12.0+"); } - ((LocalManagementContext)managementContext).generateManagementPlaneId(); + if (managementContext.getManagementPlaneIdMaybe().isAbsent()) { + ((LocalManagementContext)managementContext).generateManagementPlaneId(); + } } else { ((LocalManagementContext)managementContext).setManagementPlaneId(persistedPlaneId); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java index f7ee653..d605753 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java @@ -175,7 +175,7 @@ public class RebindManagerImpl implements RebindManager { private class PlaneIdSupplier implements Supplier<String> { @Override public String get() { - return managementContext.getOptionalManagementPlaneId().orNull(); + return managementContext.getManagementPlaneIdMaybe().orNull(); } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BrooklynMementoImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BrooklynMementoImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BrooklynMementoImpl.java index d6dd359..d60c8f3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BrooklynMementoImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BrooklynMementoImpl.java @@ -30,6 +30,7 @@ import org.apache.brooklyn.api.mgmt.rebind.mementos.EnricherMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.EntityMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.FeedMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento; +import org.apache.brooklyn.api.mgmt.rebind.mementos.ManagedBundleMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.Memento; import org.apache.brooklyn.api.mgmt.rebind.mementos.PolicyMemento; import org.apache.brooklyn.core.BrooklynVersion; @@ -57,7 +58,7 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { protected final Map<String, EnricherMemento> enrichers = Maps.newConcurrentMap(); protected final Map<String, FeedMemento> feeds = Maps.newConcurrentMap(); protected final Map<String, CatalogItemMemento> catalogItems = Maps.newConcurrentMap(); - + protected final Map<String, ManagedBundleMemento> bundles = Maps.newConcurrentMap(); public Builder planeId(String val) { planeId = val; return this; @@ -89,6 +90,8 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { feed((FeedMemento)memento); } else if (memento instanceof CatalogItemMemento) { catalogItem((CatalogItemMemento) memento); + } else if (memento instanceof ManagedBundleMemento) { + bundle((ManagedBundleMemento) memento); } else { throw new IllegalStateException("Unexpected memento type :"+memento); } @@ -133,6 +136,9 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { public Builder catalogItem(CatalogItemMemento val) { catalogItems.put(val.getId(), val); return this; } + public Builder bundle(ManagedBundleMemento val) { + bundles.put(val.getId(), val); return this; + } public BrooklynMemento build() { return new BrooklynMementoImpl(this); } @@ -149,6 +155,7 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { private Map<String, EnricherMemento> enrichers; private Map<String, FeedMemento> feeds; private Map<String, CatalogItemMemento> catalogItems; + private Map<String, ManagedBundleMemento> bundles; private BrooklynMementoImpl(Builder builder) { planeId = builder.planeId; @@ -161,6 +168,7 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { enrichers = builder.enrichers; feeds = builder.feeds; catalogItems = builder.catalogItems; + bundles = builder.bundles; } @Override @@ -199,6 +207,11 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { } @Override + public ManagedBundleMemento getManagedBundleMemento(String id) { + return bundles.get(id); + } + + @Override public Collection<String> getApplicationIds() { return ImmutableList.copyOf(applicationIds); } @@ -229,6 +242,11 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { } @Override + public Collection<String> getManagedBundleIds() { + return Collections.unmodifiableSet(bundles.keySet()); + } + + @Override public Collection<String> getFeedIds() { return Collections.unmodifiableSet(feeds.keySet()); } @@ -266,4 +284,9 @@ public class BrooklynMementoImpl implements BrooklynMemento, Serializable { public Map<String, CatalogItemMemento> getCatalogItemMementos() { return Collections.unmodifiableMap(catalogItems); } + + @Override + public Map<String, ManagedBundleMemento> getManagedBundleMementos() { + return Collections.unmodifiableMap(bundles); + } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MutableBrooklynMemento.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MutableBrooklynMemento.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MutableBrooklynMemento.java index 7dce070..a7dcbe9 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MutableBrooklynMemento.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MutableBrooklynMemento.java @@ -30,7 +30,11 @@ import org.apache.brooklyn.api.mgmt.rebind.mementos.EnricherMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.EntityMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.FeedMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.LocationMemento; +import org.apache.brooklyn.api.mgmt.rebind.mementos.ManagedBundleMemento; import org.apache.brooklyn.api.mgmt.rebind.mementos.PolicyMemento; +import org.apache.brooklyn.util.collections.MutableList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.google.common.collect.ImmutableList; @@ -48,7 +52,10 @@ import com.google.common.collect.Sets; public class MutableBrooklynMemento implements BrooklynMemento { // TODO Is this class pulling its weight? Do we really need it? + // (shouldn't be used anymore -- have added logging April 2017 to ensure not used) + private static final Logger log = LoggerFactory.getLogger(MutableBrooklynMemento.class); + private static final long serialVersionUID = -442895028005849060L; private String planeId; @@ -60,7 +67,12 @@ public class MutableBrooklynMemento implements BrooklynMemento { private final Map<String, EnricherMemento> enrichers = Maps.newLinkedHashMap(); private final Map<String, FeedMemento> feeds = Maps.newLinkedHashMap(); private final Map<String, CatalogItemMemento> catalogItems = Maps.newLinkedHashMap(); + private final Map<String, ManagedBundleMemento> bundles = Maps.newLinkedHashMap(); + { + log.warn("Using legacy "+this, new Exception("location of use of legacy "+this)); + } + public MutableBrooklynMemento() { } @@ -301,4 +313,19 @@ public class MutableBrooklynMemento implements BrooklynMemento { public Map<String, CatalogItemMemento> getCatalogItemMementos() { return ImmutableMap.copyOf(catalogItems); } + + @Override + public ManagedBundleMemento getManagedBundleMemento(String id) { + return null; + } + + @Override + public Collection<String> getManagedBundleIds() { + return MutableList.of(); + } + + @Override + public Map<String, ManagedBundleMemento> getManagedBundleMementos() { + return bundles; + } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/abd0cb8b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java index 9281e81..84cbdf3 100644 --- a/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java +++ b/core/src/main/java/org/apache/brooklyn/core/plan/PlanToSpecFactory.java @@ -22,10 +22,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; + import org.apache.brooklyn.api.framework.FrameworkLookup; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.core.typereg.BrooklynTypePlanTransformer; import org.apache.brooklyn.core.typereg.TypePlanTransformers; +import org.apache.brooklyn.core.typereg.UnsupportedTypePlanException; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException; @@ -127,7 +129,7 @@ public class PlanToSpecFactory { continue; } return Maybe.of(result); - } catch (PlanNotRecognizedException e) { + } catch (PlanNotRecognizedException|UnsupportedTypePlanException e) { transformersWhoDontSupport.add(t.getShortDescription() + (Strings.isNonBlank(e.getMessage()) ? " ("+e.getMessage()+")" : "")); } catch (Throwable e) { @@ -144,7 +146,7 @@ public class PlanToSpecFactory { result = otherProblemsFromTransformers.size()==1 ? Exceptions.create(null, otherProblemsFromTransformers) : Exceptions.create("All plan transformers failed", otherProblemsFromTransformers); } else { - result = new PlanNotRecognizedException("Invalid plan; format could not be recognized, trying with: "+transformersWhoDontSupport); + result = new UnsupportedTypePlanException("Invalid plan; format could not be recognized, trying with: "+transformersWhoDontSupport); } return Maybe.absent(result); }
