BROOKLYN-149: incorporate review comments (PR #683) Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/bfe52d41 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/bfe52d41 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/bfe52d41
Branch: refs/heads/master Commit: bfe52d41489beacad817f522e81b8e71bf23fc5e Parents: 1c68990 Author: Aled Sage <[email protected]> Authored: Mon Jun 8 21:10:41 2015 +0100 Committer: Aled Sage <[email protected]> Committed: Mon Jun 8 21:10:41 2015 +0100 ---------------------------------------------------------------------- .../brooklyn/entity/rebind/RebindIteration.java | 96 +++++++++++++++----- .../BrooklynMementoPersisterToObjectStore.java | 12 +-- .../internal/BrooklynFeatureEnablement.java | 14 ++- .../brooklyn/catalog/CatalogYamlRebindTest.java | 66 ++++++++++---- 4 files changed, 134 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bfe52d41/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java index d6b3365..8c606ff 100644 --- a/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java +++ b/core/src/main/java/brooklyn/entity/rebind/RebindIteration.java @@ -439,12 +439,11 @@ public abstract class RebindIteration { for (Map.Entry<String, EntityMementoManifest> entry : mementoManifest.getEntityIdToManifest().entrySet()) { String entityId = entry.getKey(); EntityMementoManifest entityManifest = entry.getValue(); - String catalogItemId = findCatalogItemId(classLoader, mementoManifest.getEntityIdToManifest(), entityManifest); if (LOG.isTraceEnabled()) LOG.trace("RebindManager instantiating entity {}", entityId); try { - Entity entity = (Entity) instantiator.newEntity(entityId, entityManifest.getType(), catalogItemId); + Entity entity = (Entity) instantiator.newEntity(entityManifest); ((EntityInternal)entity).getManagementSupport().setReadOnly( rebindContext.isReadOnly(entity) ); rebindContext.registerEntity(entityId, entity); @@ -778,7 +777,7 @@ public abstract class RebindIteration { return entityManifest.getCatalogItemId(); } - if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_INFER_CATALOG_ITEM_ON_REBIND)) { + if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_BACKWARDS_COMPATIBILITY_INFER_CATALOG_ITEM_ON_REBIND)) { //First check if any of the parent entities has a catalogItemId set. EntityMementoManifest ptr = entityManifest; while (ptr != null) { @@ -838,6 +837,16 @@ public abstract class RebindIteration { return null; } + protected static class LoadedClass<T extends BrooklynObject> { + protected final Class<? extends T> clazz; + protected final String catalogItemId; + + protected LoadedClass(Class<? extends T> clazz, String catalogItemId) { + this.clazz = clazz; + this.catalogItemId = catalogItemId; + } + } + protected class BrooklynObjectInstantiator { protected final ClassLoader classLoader; @@ -850,9 +859,15 @@ public abstract class RebindIteration { this.reflections = reflections; } - protected Entity newEntity(String entityId, String entityType, String catalogItemId) { - Class<? extends Entity> entityClazz = load(Entity.class, entityType, catalogItemId, entityId); - + protected Entity newEntity(EntityMementoManifest entityManifest) { + String entityId = entityManifest.getId(); + String catalogItemId = findCatalogItemId(classLoader, mementoManifest.getEntityIdToManifest(), entityManifest); + String entityType = entityManifest.getType(); + + LoadedClass<? extends Entity> loaded = load(Entity.class, entityType, catalogItemId, entityId); + Class<? extends Entity> entityClazz = loaded.clazz; + String transformedCatalogItemId = loaded.catalogItemId; + Entity entity; if (InternalFactory.isNewStyle(entityClazz)) { @@ -889,7 +904,7 @@ public abstract class RebindIteration { managementContext.prePreManage(entity); } - setCatalogItemId(entity, catalogItemId); + setCatalogItemId(entity, transformedCatalogItemId); return entity; } @@ -899,28 +914,34 @@ public abstract class RebindIteration { } } - protected <T extends BrooklynObject> Class<? extends T> load(Class<T> bType, Memento memento) { + protected <T extends BrooklynObject> LoadedClass<? extends T> load(Class<T> bType, Memento memento) { return load(bType, memento.getType(), memento.getCatalogItemId(), memento.getId()); } @SuppressWarnings("unchecked") - protected <T extends BrooklynObject> Class<? extends T> load(Class<T> bType, String jType, String catalogItemId, String contextSuchAsId) { + protected <T extends BrooklynObject> LoadedClass<? extends T> load(Class<T> bType, String jType, String catalogItemId, String contextSuchAsId) { checkNotNull(jType, "Type of %s (%s) must not be null", contextSuchAsId, bType.getSimpleName()); if (catalogItemId != null) { CatalogItem<?, ?> catalogItem = rebindContext.lookup().lookupCatalogItem(catalogItemId); - if (catalogItem == null && BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_INFER_CATALOG_ITEM_ON_REBIND)) { + if (catalogItem == null && BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND)) { // See https://issues.apache.org/jira/browse/BROOKLYN-149 // This is a dangling reference to the catalog item (which will have been logged by lookupCatalogItem). // Try loading as any version. if (CatalogUtils.looksLikeVersionedId(catalogItemId)) { String symbolicName = CatalogUtils.getIdFromVersionedId(catalogItemId); catalogItem = rebindContext.lookup().lookupCatalogItem(symbolicName); + + if (catalogItem != null) { + LOG.warn("Unable to load catalog item "+catalogItemId+" for "+contextSuchAsId + +" ("+bType.getSimpleName()+"); will auto-upgrade to "+catalogItem.getCatalogItemId()); + catalogItemId = catalogItem.getCatalogItemId(); + } } } if (catalogItem != null) { BrooklynClassLoadingContext loader = CatalogUtils.newClassLoadingContext(managementContext, catalogItem); - return loader.loadClass(jType, bType); + return new LoadedClass<T>(loader.loadClass(jType, bType), catalogItemId); } else { LOG.warn("Unable to load catalog item "+catalogItemId+" for "+contextSuchAsId +" ("+bType.getSimpleName()+"); will try default class loader"); @@ -928,7 +949,7 @@ public abstract class RebindIteration { } try { - return (Class<T>)reflections.loadClass(jType); + return new LoadedClass<T>((Class<T>)reflections.loadClass(jType), catalogItemId); } catch (Exception e) { Exceptions.propagateIfFatal(e); LOG.warn("Unable to load "+jType+" using reflections; will try standard context"); @@ -936,14 +957,14 @@ public abstract class RebindIteration { if (catalogItemId != null) { throw new IllegalStateException("Unable to load catalog item "+catalogItemId+" for "+contextSuchAsId+", or load class from classpath"); - } else if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_INFER_CATALOG_ITEM_ON_REBIND)) { + } else if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_BACKWARDS_COMPATIBILITY_INFER_CATALOG_ITEM_ON_REBIND)) { //Try loading from whichever catalog bundle succeeds. BrooklynCatalog catalog = managementContext.getCatalog(); for (CatalogItem<?, ?> item : catalog.getCatalogItems()) { BrooklynClassLoadingContext catalogLoader = CatalogUtils.newClassLoadingContext(managementContext, item); Maybe<Class<?>> catalogClass = catalogLoader.tryLoadClass(jType); if (catalogClass.isPresent()) { - return (Class<? extends T>) catalogClass.get(); + return new LoadedClass<T>((Class<? extends T>) catalogClass.get(), catalogItemId); } } throw new IllegalStateException("No catalogItemId specified for "+contextSuchAsId+" and can't load class from either classpath or catalog items"); @@ -952,6 +973,33 @@ public abstract class RebindIteration { } } + @SuppressWarnings("unchecked") + protected String transformCatalogId(Class<?> bType, String jType, String catalogItemId, String contextSuchAsId) { + if (catalogItemId != null) { + CatalogItem<?, ?> catalogItem = rebindContext.lookup().lookupCatalogItem(catalogItemId); + if (catalogItem == null && BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND)) { + // See https://issues.apache.org/jira/browse/BROOKLYN-149 + // This is a dangling reference to the catalog item (which will have been logged by lookupCatalogItem). + // Try loading as any version. + if (CatalogUtils.looksLikeVersionedId(catalogItemId)) { + String symbolicName = CatalogUtils.getIdFromVersionedId(catalogItemId); + catalogItem = rebindContext.lookup().lookupCatalogItem(symbolicName); + + if (catalogItem != null) { + LOG.warn("Unable to load catalog item "+catalogItemId+" for "+contextSuchAsId + +" ("+bType.getSimpleName()+"); will auto-upgrade to "+catalogItem.getCatalogItemId()); + catalogItemId = catalogItem.getCatalogItemId(); + } else { + LOG.warn("Unable to load catalog item "+catalogItemId+" for "+contextSuchAsId + +" ("+bType.getSimpleName()+"); no alternative version available"); + } + } + } + } + + return catalogItemId; + } + /** * Constructs a new location, passing to its constructor the location id and all of memento.getFlags(). */ @@ -988,8 +1036,10 @@ public abstract class RebindIteration { */ protected Policy newPolicy(PolicyMemento memento) { String id = memento.getId(); - Class<? extends Policy> policyClazz = load(Policy.class, memento.getType(), memento.getCatalogItemId(), id); - + LoadedClass<? extends Policy> loaded = load(Policy.class, memento.getType(), memento.getCatalogItemId(), id); + Class<? extends Policy> policyClazz = loaded.clazz; + String transformedCatalogItemId = loaded.catalogItemId; + Policy policy; if (InternalFactory.isNewStyle(policyClazz)) { InternalPolicyFactory policyFactory = managementContext.getPolicyFactory(); @@ -1012,7 +1062,7 @@ public abstract class RebindIteration { policy = invokeConstructor(null, policyClazz, new Object[] {flags}); } - setCatalogItemId(policy, memento.getCatalogItemId()); + setCatalogItemId(policy, transformedCatalogItemId); return policy; } @@ -1020,8 +1070,10 @@ public abstract class RebindIteration { * Constructs a new enricher, passing to its constructor the enricher id and all of memento.getConfig(). */ protected Enricher newEnricher(EnricherMemento memento) { - Class<? extends Enricher> enricherClazz = load(Enricher.class, memento); String id = memento.getId(); + LoadedClass<? extends Enricher> loaded = load(Enricher.class, memento); + Class<? extends Enricher> enricherClazz = loaded.clazz; + String transformedCatalogItemId = loaded.catalogItemId; Enricher enricher; if (InternalFactory.isNewStyle(enricherClazz)) { @@ -1045,7 +1097,7 @@ public abstract class RebindIteration { enricher = invokeConstructor(reflections, enricherClazz, new Object[] {flags}); } - setCatalogItemId(enricher, memento.getCatalogItemId()); + setCatalogItemId(enricher, transformedCatalogItemId); return enricher; } @@ -1053,8 +1105,10 @@ public abstract class RebindIteration { * Constructs a new enricher, passing to its constructor the enricher id and all of memento.getConfig(). */ protected Feed newFeed(FeedMemento memento) { - Class<? extends Feed> feedClazz = load(Feed.class, memento); String id = memento.getId(); + LoadedClass<? extends Feed> loaded = load(Feed.class, memento); + Class<? extends Feed> feedClazz = loaded.clazz; + String transformedCatalogItemId = loaded.catalogItemId; Feed feed; if (InternalFactory.isNewStyle(feedClazz)) { @@ -1067,7 +1121,7 @@ public abstract class RebindIteration { throw new IllegalStateException("rebind of feed without no-arg constructor unsupported: id="+id+"; type="+feedClazz); } - setCatalogItemId(feed, memento.getCatalogItemId()); + setCatalogItemId(feed, transformedCatalogItemId); return feed; } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bfe52d41/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java index 87ef4fa..6e3c24d 100644 --- a/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java +++ b/core/src/main/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterToObjectStore.java @@ -53,8 +53,6 @@ import brooklyn.entity.rebind.dto.BrooklynMementoImpl; import brooklyn.entity.rebind.dto.BrooklynMementoManifestImpl; import brooklyn.entity.rebind.persister.PersistenceObjectStore.StoreObjectAccessor; import brooklyn.entity.rebind.persister.PersistenceObjectStore.StoreObjectAccessorWithLock; -import brooklyn.internal.BrooklynFeatureEnablement; -import brooklyn.management.classloading.BrooklynClassLoadingContext; import brooklyn.management.classloading.ClassLoaderFromBrooklynClassLoadingContext; import brooklyn.mementos.BrooklynMemento; import brooklyn.mementos.BrooklynMementoManifest; @@ -172,20 +170,14 @@ public class BrooklynMementoPersisterToObjectStore implements BrooklynMementoPer @Nullable protected ClassLoader getCustomClassLoaderForBrooklynObject(LookupContext lookupContext, BrooklynObjectType type, String objectId) { BrooklynObject item = lookupContext.peek(type, objectId); + String catalogItemId = (item == null) ? null : item.getCatalogItemId(); // TODO enrichers etc aren't yet known -- would need to backtrack to the entity to get them from bundles - if (item==null || item.getCatalogItemId()==null) { + if (catalogItemId == null) { return null; } // See RebindIteration.BrooklynObjectInstantiator.load(), for handling where catalog item is missing; // similar logic here. - String catalogItemId = item.getCatalogItemId(); CatalogItem<?, ?> catalogItem = CatalogUtils.getCatalogItemOptionalVersion(lookupContext.lookupManagementContext(), catalogItemId); - if (catalogItem == null && BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_INFER_CATALOG_ITEM_ON_REBIND)) { - if (CatalogUtils.looksLikeVersionedId(catalogItemId)) { - String symbolicName = CatalogUtils.getIdFromVersionedId(catalogItemId); - catalogItem = CatalogUtils.getCatalogItemOptionalVersion(lookupContext.lookupManagementContext(), symbolicName); - } - } if (catalogItem == null) { // TODO do we need to only log once, rather than risk log.warn too often? I think this only happens on rebind, so ok. LOG.warn("Unable to load catalog item "+catalogItemId+" for custom class loader of "+type+" "+objectId+"; will use default class loader"); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bfe52d41/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java b/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java index 6839a75..053400a 100644 --- a/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java +++ b/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java @@ -78,7 +78,7 @@ public class BrooklynFeatureEnablement { public static final String FEATURE_RENAME_THREADS = "brooklyn.executionManager.renameThreads"; /** - * When rebinding to store created from a previous version the catalogItemId properties will be missing which + * When rebinding to state created from very old versions, the catalogItemId properties will be missing which * results in errors when OSGi bundles are used. When enabled the code tries to infer the catalogItemId from * <ul> * <li> parent entities @@ -86,7 +86,14 @@ public class BrooklynFeatureEnablement { * <li> iterating through all catalog items and checking if they can provide the needed type * </ul> */ - public static final String FEATURE_INFER_CATALOG_ITEM_ON_REBIND = "brooklyn.backwardCompatibility.feature.inferCatalogItemOnRebind"; + public static final String FEATURE_BACKWARDS_COMPATIBILITY_INFER_CATALOG_ITEM_ON_REBIND = "brooklyn.backwardCompatibility.feature.inferCatalogItemOnRebind"; + + /** + * When rebinding, an entity could reference a catalog item that no longer exists. This option + * will automatically update the catalog item reference to what is inferred as the most + * suitable catalog symbolicName:version. + */ + public static final String FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND = "brooklyn.quickfix.fixDanglingCatalogItemOnRebind"; /** * When executing over ssh, whether to support the "async exec" approach, or only the classic approach. @@ -115,7 +122,8 @@ public class BrooklynFeatureEnablement { setDefault(FEATURE_DEFAULT_STANDBY_IS_HOT_PROPERTY, false); setDefault(FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE, false); setDefault(FEATURE_RENAME_THREADS, false); - setDefault(FEATURE_INFER_CATALOG_ITEM_ON_REBIND, true); + setDefault(FEATURE_BACKWARDS_COMPATIBILITY_INFER_CATALOG_ITEM_ON_REBIND, true); + setDefault(FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND, false); setDefault(FEATURE_SSH_ASYNC_EXEC, false); setDefault(FEATURE_VALIDATE_LOCATION_SSH_KEYS, true); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/bfe52d41/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java index ca8dd75..2562d5e 100644 --- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java +++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/catalog/CatalogYamlRebindTest.java @@ -1,5 +1,6 @@ package io.brooklyn.camp.brooklyn.catalog; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import io.brooklyn.camp.brooklyn.AbstractYamlRebindTest; @@ -9,11 +10,13 @@ import brooklyn.catalog.internal.CatalogUtils; import brooklyn.entity.basic.BasicEntity; import brooklyn.entity.basic.Entities; import brooklyn.entity.basic.StartableApplication; +import brooklyn.internal.BrooklynFeatureEnablement; import brooklyn.policy.Enricher; import brooklyn.policy.Policy; import brooklyn.test.policy.TestEnricher; import brooklyn.test.policy.TestPolicy; +import com.google.common.base.Joiner; import com.google.common.base.Predicates; import com.google.common.collect.Iterables; @@ -24,35 +27,51 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest { // - config/attribute cannot be instantiated (e.g. because class no longer on classpath) // - entity file corrupt + enum RebindWithCatalogTestMode { + NO_OP, + DELETE_CATALOG, + REPLACE_CATALOG_WITH_NEWER_VERSION; + } + + @Test + public void testRebindWithCatalogAndApp() throws Exception { + runRebindWithCatalogAndApp(RebindWithCatalogTestMode.NO_OP); + } + // See https://issues.apache.org/jira/browse/BROOKLYN-149. // Deletes the catalog item before rebind, but the referenced types are still on the // default classpath. + // Will fallback to loading from classpath. @Test public void testRebindWithCatalogDeletedAndAppExisting() throws Exception { - runRebindWithCatalogAndApp(true); + runRebindWithCatalogAndApp(RebindWithCatalogTestMode.DELETE_CATALOG); } + // Upgrades the catalog item before rebind, deleting the old version. + // Will automatically upgrade. @Test - public void testRebindWithCatalogAndApp() throws Exception { - runRebindWithCatalogAndApp(false); + public void testRebindWithCatalogUpgradedWithOldDeletedAndAppExisting() throws Exception { + BrooklynFeatureEnablement.enable(BrooklynFeatureEnablement.FEATURE_AUTO_FIX_CATALOG_REF_ON_REBIND); + runRebindWithCatalogAndApp(RebindWithCatalogTestMode.REPLACE_CATALOG_WITH_NEWER_VERSION); } @SuppressWarnings("unused") - protected void runRebindWithCatalogAndApp(boolean deleteCatalogBeforeRebind) throws Exception { + protected void runRebindWithCatalogAndApp(RebindWithCatalogTestMode mode) throws Exception { String symbolicName = "my.catalog.app.id.load"; String version = "0.1.2"; + String catalogFormat = Joiner.on("\n").join( + "brooklyn.catalog:", + " id: " + symbolicName, + " version: %s", + " item:", + " type: "+ BasicEntity.class.getName(), + " brooklyn.enrichers:", + " - type: "+TestEnricher.class.getName(), + " brooklyn.policies:", + " - type: "+TestPolicy.class.getName()); // Create the catalog item - addCatalogItems( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + version, - " item:", - " type: "+ BasicEntity.class.getName(), - " brooklyn.enrichers:", - " - type: "+TestEnricher.class.getName(), - " brooklyn.policies:", - " - type: "+TestPolicy.class.getName()); + addCatalogItems(String.format(catalogFormat, version)); // Create an app, using that catalog item String yaml = "name: simple-app-yaml\n" + @@ -63,10 +82,20 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest { BasicEntity origEntity = (BasicEntity) Iterables.getOnlyElement(origApp.getChildren()); TestPolicy origPolicy = (TestPolicy) Iterables.getOnlyElement(origEntity.getPolicies()); TestEnricher origEnricher = (TestEnricher) Iterables.tryFind(origEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get(); + assertEquals(origEntity.getCatalogItemId(), symbolicName+":"+version); // Depending on test-mode, delete the catalog item, and then rebind - if (deleteCatalogBeforeRebind) { - mgmt().getCatalog().deleteCatalogItem(symbolicName, version); + switch (mode) { + case DELETE_CATALOG: + mgmt().getCatalog().deleteCatalogItem(symbolicName, version); + break; + case REPLACE_CATALOG_WITH_NEWER_VERSION: + mgmt().getCatalog().deleteCatalogItem(symbolicName, version); + version = "0.1.3"; + addCatalogItems(String.format(catalogFormat, version)); + break; + case NO_OP: + // no-op } rebind(); @@ -75,14 +104,11 @@ public class CatalogYamlRebindTest extends AbstractYamlRebindTest { BasicEntity newEntity = (BasicEntity) Iterables.getOnlyElement(newApp.getChildren()); Policy newPolicy = Iterables.getOnlyElement(newEntity.getPolicies()); Enricher newEnricher = Iterables.tryFind(newEntity.getEnrichers(), Predicates.instanceOf(TestEnricher.class)).get(); + assertEquals(newEntity.getCatalogItemId(), symbolicName+":"+version); // Ensure app is still usable - e.g. "stop" effector functions as expected newApp.stop(); assertFalse(Entities.isManaged(newApp)); assertFalse(Entities.isManaged(newEntity)); - - if (!deleteCatalogBeforeRebind) { - mgmt().getCatalog().deleteCatalogItem(symbolicName, version); - } } }
