You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2017/11/01 15:51:01 UTC
[07/10] brooklyn-server git commit: maps for upgrade types and
bundles, and related test fixes incl tidy HA transition clearing
maps for upgrade types and bundles, and related test fixes incl tidy HA transition clearing
fix recent rebind header tests which i forgot to test in previous, some subtle HA behaviours,
but now all fixed and documented.
need to clear type registry as part of other clears on HA promotion fail
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/8473fb4b
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/8473fb4b
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/8473fb4b
Branch: refs/heads/master
Commit: 8473fb4be2c21d275bab8b2c92880abcf83eb68a
Parents: 00df1d5
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Oct 31 09:34:25 2017 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Oct 31 09:35:16 2017 +0000
----------------------------------------------------------------------
.../mgmt/ha/HighAvailabilityManagerImpl.java | 14 ++-
.../mgmt/rebind/RebindExceptionHandlerImpl.java | 2 +-
.../core/typereg/BasicBrooklynTypeRegistry.java | 7 +-
.../core/typereg/BundleUpgradeParser.java | 72 +++++++++++++--
.../core/typereg/BundleUpgradeParserTest.java | 5 +-
.../BrooklynLauncherRebindCatalogOsgiTest.java | 97 +++++++++-----------
6 files changed, 127 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8473fb4b/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 1d4d50c..7220091 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
@@ -66,6 +66,7 @@ import org.apache.brooklyn.core.mgmt.persist.PersistenceActivityMetrics;
import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl;
import org.apache.brooklyn.core.mgmt.usage.ManagementNodeStateListener;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.core.typereg.BasicBrooklynTypeRegistry;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.ScheduledTask;
@@ -939,12 +940,15 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
/**
* Clears all managed items from the management context.
*
- * The same items are destroyed as in the course of a rebind cycle, except for clearBrooklynManagedBundles.
- * That last operation could be expensive (causing bundles to be installed again). Therefore we only do it
- * when we stop being a hotProxy or when we are demoted (e.g. during the periodic rebind as hot_stanby
- * we will not repeatedly clear the brooklyn-managed-bundles).
+ * The same items are destroyed as in the course of a rebind cycle, with the addition of bundles/types
+ * which is comparatively more expensive, so we only do it when we stop being a hotProxy or when we are demoted
+ * (e.g. during the periodic rebind as hot_stanby we will not repeatedly clear the brooklyn-managed-bundles).
*/
protected void clearManagedItems(ManagementTransitionMode mode) {
+ // log this because it may be surprising, it is just HA transitions,
+ // not symmetric with usual single-node start
+ LOG.info("Clearing all managed items on transition to "+mode);
+
// start with the root applications
for (Application app: managementContext.getApplications()) {
if (((EntityInternal)app).getManagementSupport().isDeployed()) {
@@ -967,7 +971,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
}
((BasicBrooklynCatalog)managementContext.getCatalog()).reset(CatalogDto.newEmptyInstance("<reset-by-ha-status-change>"));
-
+ ((BasicBrooklynTypeRegistry)managementContext.getTypeRegistry()).clear();
managementContext.getCatalogInitialization().clearBrooklynManagedBundles();
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8473fb4b/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 794161b..54564a8 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
@@ -453,7 +453,7 @@ public class RebindExceptionHandlerImpl implements RebindExceptionHandler {
warn("Dangling item"+Strings.s(totalDangling)+" ("+totalDangling+" of "+totalItems+") found on rebind exceeds quorum, assuming failed: "+danglingIds);
allExceptions.add(new IllegalStateException("Too many dangling references: "+totalDangling+" of "+totalItems));
} else {
- LOG.info("Dangling item"+Strings.s(totalDangling)+" ("+totalDangling+" of "+totalItems+") found on rebind, assuming deleted: "+danglingIds);
+ LOG.info("Dangling item"+Strings.s(totalDangling)+" ("+totalDangling+" of "+totalItems+") found on rebind, within quorum, assuming deleted: "+danglingIds);
}
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8473fb4b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
index dd0b4b9..94e9b6b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java
@@ -51,7 +51,6 @@ import org.apache.brooklyn.util.concurrent.Locks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.osgi.VersionedName;
-import org.apache.brooklyn.util.osgi.VersionedName.VersionedNameComparator;
import org.apache.brooklyn.util.osgi.VersionedName.VersionedNameStringComparator;
import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
import org.apache.brooklyn.util.text.Identifiers;
@@ -425,6 +424,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
oldContainingBundlesToRemove.add(existingT.getContainingBundle());
}
if (canForce) {
+ // may be forcing because of internal type validation, or of course user flag
log.debug("Addition of "+type+" to replace "+existingT+" allowed because force is on");
continue;
}
@@ -616,5 +616,10 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry {
public void delete(String id) {
delete(VersionedName.fromString(id));
}
+
+ /** Deletes all items, for use when resetting management context */
+ public void clear() {
+ Locks.withLock(localRegistryLock.writeLock(), () -> localRegisteredTypesAndContainingBundles.clear());
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8473fb4b/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
index 24d905f..73327e9 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
@@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -32,6 +31,7 @@ import java.util.Set;
import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.osgi.VersionedName;
import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
@@ -45,7 +45,10 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.Multimap;
/**
* Internal class for parsing bundle manifests to extract their upgrade instructions.
@@ -119,8 +122,9 @@ public class BundleUpgradeParser {
* These will be advisory unless the bundle being upgraded is force-removed in which case it will be applied automatically
* wherever the bundle is in use.
*
- * The format is a comma separate list of {@code key=value} pairs, where each key and value is a name with a version range
- * (as per {@link #MANIFEST_HEADER_FORCE_REMOVE_BUNDLES}). The {@code =value} can be omitted, and usually is,
+ * The format is a comma separate list of {@code key=value} pairs, where each key is a name with a version range
+ * (as per {@link #MANIFEST_HEADER_FORCE_REMOVE_BUNDLES}) specifying what should be upgraded, and {@code value} is a name and
+ * version specifying what it should be ugpraded to. The {@code =value} can be omitted, and usually is,
* to mean this bundle at this version. (The {@code =value} is available if one bundle is defining upgrades for other bundles.)
*
* A wildcard can be given as the key, without a version ({@code *}) or with ({@code *:[0,1)}) to refer to
@@ -200,8 +204,8 @@ public class BundleUpgradeParser {
public static class Builder {
private Set<VersionRangedName> removedLegacyItems = new LinkedHashSet<>();
private Set<VersionRangedName> removedBundles = new LinkedHashSet<>();
- private Map<VersionedName,VersionRangedName> upgradeBundles = new LinkedHashMap<>();
- private Map<VersionedName,VersionRangedName> upgradeTypes = new LinkedHashMap<>();
+ private Multimap<VersionedName,VersionRangedName> upgradesProvidedByBundles = LinkedHashMultimap.create();
+ private Multimap<VersionedName,VersionRangedName> upgradesProvidedByTypes = LinkedHashMultimap.create();
public Builder removedLegacyItems(Collection<VersionRangedName> vals) {
removedLegacyItems.addAll(vals);
@@ -211,9 +215,19 @@ public class BundleUpgradeParser {
removedBundles.addAll(vals);
return this;
}
+ public Builder upgradeBundles(Multimap<VersionedName,VersionRangedName> vals) {
+ upgradesProvidedByBundles.putAll(vals);
+ return this;
+ }
+ public Builder upgradeTypes(Multimap<VersionedName,VersionRangedName> vals) {
+ upgradesProvidedByTypes.putAll(vals);
+ return this;
+ }
public Builder addAll(CatalogUpgrades other) {
removedLegacyItems.addAll(other.removedLegacyItems);
removedBundles.addAll(other.removedBundles);
+ upgradesProvidedByBundles.putAll(other.upgradesProvidedByBundles);
+ upgradesProvidedByTypes.putAll(other.upgradesProvidedByTypes);
return this;
}
public CatalogUpgrades build() {
@@ -227,10 +241,14 @@ public class BundleUpgradeParser {
private final Set<VersionRangedName> removedLegacyItems;
private final Set<VersionRangedName> removedBundles;
+ private final Multimap<VersionedName,VersionRangedName> upgradesProvidedByBundles;
+ private final Multimap<VersionedName,VersionRangedName> upgradesProvidedByTypes;
public CatalogUpgrades(Builder builder) {
this.removedLegacyItems = ImmutableSet.copyOf(builder.removedLegacyItems);
this.removedBundles = ImmutableSet.copyOf(builder.removedBundles);
+ this.upgradesProvidedByBundles = ImmutableMultimap.copyOf(builder.upgradesProvidedByBundles);
+ this.upgradesProvidedByTypes = ImmutableMultimap.copyOf(builder.upgradesProvidedByTypes);
}
public boolean isEmpty() {
@@ -245,6 +263,14 @@ public class BundleUpgradeParser {
return removedBundles;
}
+ public Multimap<VersionedName, VersionRangedName> getUpgradesProvidedByBundles() {
+ return upgradesProvidedByBundles;
+ }
+
+ public Multimap<VersionedName, VersionRangedName> getUpgradesProvidedByTypes() {
+ return upgradesProvidedByTypes;
+ }
+
public boolean isLegacyItemRemoved(CatalogItem<?, ?> legacyCatalogItem) {
VersionedName name = new VersionedName(legacyCatalogItem.getSymbolicName(), legacyCatalogItem.getVersion());
return contains(removedLegacyItems, name);
@@ -254,14 +280,36 @@ public class BundleUpgradeParser {
return contains(removedBundles, bundle);
}
- public boolean contains(Iterable<VersionRangedName> names, VersionedName name) {
+ public Set<VersionedName> getUpgradesForBundle(VersionedName bundle) {
+ return findUpgradesIn(bundle, upgradesProvidedByBundles);
+ }
+ public Set<VersionedName> getUpgradesForType(VersionedName type) {
+ return findUpgradesIn(type, upgradesProvidedByTypes);
+ }
+ private static Set<VersionedName> findUpgradesIn(VersionedName bundle, Multimap<VersionedName,VersionRangedName> upgradesMap) {
+ Set<VersionedName> result = MutableSet.of();
+ for (Map.Entry<VersionedName,VersionRangedName> n: upgradesMap.entries()) {
+ if (contains(n.getValue(), bundle)) {
+ result.add(n.getKey());
+ }
+ }
+ return result;
+ }
+
+ @Beta
+ public static boolean contains(Iterable<VersionRangedName> names, VersionedName name) {
for (VersionRangedName contender : names) {
- if (contender.getSymbolicName().equals(name.getSymbolicName()) && contender.getOsgiVersionRange().includes(name.getOsgiVersion())) {
+ if (contains(contender, name)) {
return true;
}
}
return false;
}
+
+ @Beta
+ public static boolean contains(VersionRangedName range, VersionedName name) {
+ return range.getSymbolicName().equals(name.getSymbolicName()) && range.getOsgiVersionRange().includes(name.getOsgiVersion());
+ }
}
/**
@@ -356,12 +404,22 @@ public class BundleUpgradeParser {
// section "Bundle Upgrade Metadata"
Dictionary<String, String> headers = bundle.getHeaders();
+ Multimap<VersionedName,VersionRangedName> upgradesForBundles = parseUpgradeForBundlesHeader(headers.get(MANIFEST_HEADER_UPGRADE_FOR_BUNDLES), bundle);
return CatalogUpgrades.builder()
.removedLegacyItems(parseForceRemoveLegacyItemsHeader(headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS), bundle, typeSupplier))
.removedBundles(parseForceRemoveBundlesHeader(headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES), bundle))
+ .upgradeBundles(upgradesForBundles)
+ .upgradeTypes(parseUpgradeForTypesHeader(headers.get(MANIFEST_HEADER_UPGRADE_FOR_TYPES), bundle, upgradesForBundles))
.build();
}
+ private static Multimap<VersionedName, VersionRangedName> parseUpgradeForBundlesHeader(String input, Bundle bundle) {
+ return LinkedHashMultimap.<VersionedName, VersionRangedName>create();
+ }
+ private static Multimap<VersionedName, VersionRangedName> parseUpgradeForTypesHeader(String input, Bundle bundle, Multimap<VersionedName, VersionRangedName> upgradesForBundles) {
+ return LinkedHashMultimap.<VersionedName, VersionRangedName>create();
+ }
+
@VisibleForTesting
static List<VersionRangedName> parseForceRemoveLegacyItemsHeader(String input, Bundle bundle, Supplier<? extends Iterable<? extends RegisteredType>> typeSupplier) {
if (input == null) return ImmutableList.of();
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8473fb4b/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java b/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
index 5fc5188..64c8a6e 100644
--- a/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
@@ -39,7 +39,6 @@ import org.mockito.Mockito;
import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
-import org.testng.Assert;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
@@ -158,7 +157,9 @@ public class BundleUpgradeParserTest {
public void testParseBundleManifest() throws Exception {
Bundle bundle = newMockBundle(ImmutableMap.of(
BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, "\"foo:[0,1.0.0)\",\"foo:1.0.0.SNAPSHOT\",\"bar:[0,1.0.0)\"",
- BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
+ BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)\"",
+ BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)=org.example.brooklyn.mybundle:1\"",
+ BundleUpgradeParser.MANIFEST_HEADER_UPGRADE_FOR_TYPES, "\"foo:[0,1)=foo:1\""));
checkParse(bundle);
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/8473fb4b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
index 3f261df..23f564c 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
@@ -30,7 +30,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
-import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
@@ -142,6 +141,7 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
}
l.start();
launcherLast = launcherT1 = l;
+ assertMasterEventually(launcherT1);
if (startupAssertions!=null) startupAssertions.run();
}
@@ -150,7 +150,7 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
startT2(l, true);
}
- protected void startT2(BrooklynLauncher l, boolean assertSuccess) {
+ protected void startT2(BrooklynLauncher l, boolean expectSuccess) {
if (launcherT2!=null) throw new IllegalStateException("Already started T2 launcher");
try {
@@ -165,8 +165,14 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
}
l.start();
launcherLast = launcherT2 = l;
- if (isT1KeptRunningWhenT2Starts()) {
- assertHotStandbyNow(launcherT2);
+ if (expectSuccess) {
+ if (isT1KeptRunningWhenT2Starts()) {
+ assertHotStandbyNow(launcherT2);
+ } else {
+ assertMasterEventually(launcherT2);
+ }
+ } else {
+ assertFailsEventually(launcherLast);
}
if (startupAssertions!=null) startupAssertions.run();
@@ -174,11 +180,13 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
protected void promoteT2IfStandby() {
promoteT2IfStandby(true);
}
- protected void promoteT2IfStandby(boolean assertSuccess) {
+ protected void promoteT2IfStandby(boolean expectHealthy) {
if (isT1KeptRunningWhenT2Starts()) {
launcherT1.terminate();
- if (assertSuccess) {
+ if (expectHealthy) {
assertMasterEventually(launcherT2);
+ } else {
+ assertFailsEventually(launcherT2);
}
if (startupAssertions!=null) startupAssertions.run();
@@ -617,37 +625,10 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
Assert.assertNotEquals(bundlePersistenceId1, bundlePersistenceId2);
}
}
-
- @Test
- public void testRebindRemovedItemWorksIfJavaClassFound() throws Exception {
- Set<VersionedName> bundleItemsV1 = ImmutableSet.of(VersionedName.fromString("one:1.0.0"));
- String bundleBomV1 = createCatalogYaml(ImmutableList.of(), bundleItemsV1);
- VersionedName bundleNameV1 = new VersionedName("org.example.testRebindGetsInitialOsgiCatalog", "1.0.0");
- File bundleFileV1 = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBomV1.getBytes(StandardCharsets.UTF_8)), bundleNameV1);
- File initialBomFileV1 = newTmpFile(createCatalogYaml(ImmutableList.of(bundleFileV1.toURI()), ImmutableList.of()));
-
- Set<VersionedName> bundleItemsV2 = ImmutableSet.of(VersionedName.fromString("one:2.0.0"));
- String bundleBomV2 = createCatalogYaml(ImmutableList.of(), bundleItemsV2);
- VersionedName bundleNameV2 = new VersionedName("org.example.testRebindGetsInitialOsgiCatalog", "2.0.0");
- File bundleFileV2 = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBomV2.getBytes(StandardCharsets.UTF_8)), bundleNameV2,
- ImmutableMap.of(BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "*"));
- File initialBomFileV2 = newTmpFile(createCatalogYaml(ImmutableList.of(bundleFileV2.toURI()), ImmutableList.of()));
-
- startT1(newLauncherForTests(initialBomFileV1.getAbsolutePath()));
- Application app = createAndStartApplication(launcherLast.getManagementContext(),
- "services: [ { type: 'one:1.0.0' } ]");
-
- // should start and promote fine, but entity's type shouldn't be loadable (and there will be warnings)
- startT2(newLauncherForTests(initialBomFileV2.getAbsolutePath()));
- promoteT2IfStandby();
-
- Entity entity = Iterables.getOnlyElement( Iterables.getOnlyElement(launcherLast.getManagementContext().getApplications()).getChildren() );
- Assert.assertEquals(entity.getCatalogItemId(), bundleItemsV1.iterator().next());
- }
@Test
public void testRebindRemovedItemButLeavingJavaSucceeds() throws Exception {
- File initialBomFileV2 = prepForRebindRemovedItemTestReturningBomV2(true);
+ File initialBomFileV2 = prepForRebindRemovedItemTestReturningBomV2(false);
createAndStartApplication(launcherLast.getManagementContext(),
"services: [ { type: 'simple-entity:1.0.0' } ]");
@@ -663,6 +644,7 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
// TODO prep should set upgrade types and this should be 2.0.0
Assert.assertEquals(entity.getCatalogItemId(), "simple-entity:1.0.0");
}
+
@Test
public void testRebindRemovedItemIncludingJavaFails() throws Exception {
File initialBomFileV2 = prepForRebindRemovedItemTestReturningBomV2(true);
@@ -673,16 +655,28 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
// TODO when we switch to loading from type registry types instead of persisted java type
// T2 startup should succeed as it knows the type is now a BasicEntity
- startT2(newLauncherForTests(initialBomFileV2.getAbsolutePath()));
- assertHotStandbyNow(launcherLast, false);
+
+ // for now however:
+ if (isT1KeptRunningWhenT2Starts()) {
+ // if starting hot-standby, HA manager will clear all state and set it to FAILED state;
+ // for master/standalone/single it treats it as a startup subsystem error and does not
+ // so for hot-standby we should assert everything is cleared
+ startupAssertions = () -> {
+ Asserts.assertSize(launcherLast.getManagementContext().getTypeRegistry().getAll(), 0);
+ Asserts.assertSize(launcherLast.getManagementContext().getEntityManager().getEntities(), 0);
+ };
+ }
+ startT2(newLauncherForTests(initialBomFileV2.getAbsolutePath()), false);
Assert.assertFalse( ((ManagementContextInternal)launcherLast.getManagementContext()).errors().isEmpty() );
- promoteT2IfStandby();
- assertMasterEventually(launcherLast, false);
+ promoteT2IfStandby(false);
Assert.assertFalse( ((ManagementContextInternal)launcherLast.getManagementContext()).errors().isEmpty() );
- // entity shouldn't be loaded
- Asserts.assertSize( launcherLast.getManagementContext().getApplications(), 0 );
+ if (!isT1KeptRunningWhenT2Starts()) {
+ // if it did start, then entity shouldn't be loaded, though app is
+ Asserts.assertSize( launcherLast.getManagementContext().getApplications(), 1 );
+ Asserts.assertSize( Iterables.getOnlyElement(launcherLast.getManagementContext().getApplications()).getChildren(), 0 );
+ }
}
private File prepForRebindRemovedItemTestReturningBomV2(boolean removeSourceJavaBundle) throws Exception {
@@ -718,7 +712,7 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
VersionedName bv = new VersionedName("org.example.testRebindGetsInitialOsgiCatalog", v);
VersionedName iv = new VersionedName("simple-entity", v);
assertManagedBundle(launcherLast, bv, MutableSet.of(iv));
- if (launcherT2==null) {
+ if (launcherT2==null || !removeSourceJavaBundle) {
assertCatalogConsistsOfIds(launcherLast, MutableList.copyOf(COM_EXAMPLE_BUNDLE_CATALOG_IDS).append(iv));
} else {
assertCatalogConsistsOfIds(launcherLast, MutableList.of(iv));
@@ -747,34 +741,28 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
}
protected void assertHotStandbyNow(BrooklynLauncher launcher) {
- assertHotStandbyNow(launcher, true);
- }
- protected void assertHotStandbyNow(BrooklynLauncher launcher, boolean assertHealthy) {
ManagementContext mgmt = launcher.getManagementContext();
assertTrue(mgmt.isStartupComplete());
assertTrue(mgmt.isRunning());
assertEquals(mgmt.getNodeState(), ManagementNodeState.HOT_STANDBY);
- if (assertHealthy) {
- Asserts.assertSize(((ManagementContextInternal)mgmt).errors(), 0);
- }
+ Asserts.assertSize(((ManagementContextInternal)mgmt).errors(), 0);
}
protected void assertMasterEventually(BrooklynLauncher launcher) {
- assertMasterEventually(launcher, true);
- }
- protected void assertMasterEventually(BrooklynLauncher launcher, boolean assertHealthy) {
ManagementContext mgmt = launcher.getManagementContext();
Asserts.succeedsEventually(new Runnable() {
public void run() {
assertTrue(mgmt.isStartupComplete());
assertTrue(mgmt.isRunning());
assertEquals(mgmt.getNodeState(), ManagementNodeState.MASTER);
- if (assertHealthy) {
- Asserts.assertSize(((ManagementContextInternal)mgmt).errors(), 0);
- }
+ Asserts.assertSize(((ManagementContextInternal)mgmt).errors(), 0);
}});
}
+ protected void assertFailsEventually(BrooklynLauncher launcher) {
+ Asserts.succeedsEventually(() -> assertEquals(launcher.getManagementContext().getNodeState(), ManagementNodeState.FAILED));
+ }
+
protected Bundle installBundle(Framework framework, File bundle) throws Exception {
try (FileInputStream stream = new FileInputStream(bundle)) {
return framework.getBundleContext().installBundle(bundle.toURI().toString(), stream);
@@ -831,13 +819,14 @@ public abstract class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBroo
return newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom.getBytes(StandardCharsets.UTF_8)), bundleName);
}
+ // convenience for testing just a single test (TestNG plugin otherwise runs lots of them)
public static void main(String[] args) throws Exception {
try {
BrooklynLauncherRebindCatalogOsgiTest fixture = new LauncherRebindSubTests();
fixture.setUp();
fixture.testRebindRemovedItemIncludingJavaFails();
fixture.tearDown();
- } catch (Exception e) {
+ } catch (Throwable e) {
e.printStackTrace();
System.exit(1);
}