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/10/27 10:57:03 UTC
[1/7] brooklyn-server git commit: Support force-bundle-removal on init
Repository: brooklyn-server
Updated Branches:
refs/heads/master 05d6ee096 -> 9045005dd
Support force-bundle-removal on init
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/dba226fc
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/dba226fc
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/dba226fc
Branch: refs/heads/master
Commit: dba226fc2aa7fa6fd8eb6569fadb3aaf6bb6b052
Parents: 98731c2
Author: Aled Sage <al...@gmail.com>
Authored: Fri Oct 20 15:41:50 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Oct 23 17:41:46 2017 +0100
----------------------------------------------------------------------
.../catalog/internal/BundleUpgradeParser.java | 150 ++++++++++++-------
.../catalog/internal/CatalogInitialization.java | 57 ++++---
.../core/mgmt/rebind/RebindIteration.java | 13 ++
.../internal/BundleUpgradeParserTest.java | 79 +++++++++-
.../AbstractBrooklynLauncherRebindTest.java | 119 +++++++++++----
.../BrooklynLauncherUpgradeCatalogOsgiTest.java | 78 ++++++++--
6 files changed, 378 insertions(+), 118 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/dba226fc/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
index 31df462..0773014 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
@@ -21,43 +21,62 @@ package org.apache.brooklyn.core.catalog.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Dictionary;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.catalog.BrooklynCatalog;
import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.util.osgi.VersionedName;
import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
import org.apache.brooklyn.util.text.QuotedStringTokenizer;
import org.apache.brooklyn.util.text.Strings;
import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
public class BundleUpgradeParser {
@Beta
- public static final String MANIFEST_HEADER_REMOVE_LEGACY_ITEMS = "brooklyn-catalog-force-remove-legacy-items";
+ public static final String MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS = "brooklyn-catalog-force-remove-legacy-items";
+
+ @Beta
+ public static final String MANIFEST_HEADER_FORCE_REMOVE_BUNDLES = "brooklyn-catalog-force-remove-bundles";
+
+ @Beta
+ public static final String MANIFEST_HEADER_UPGRADE_BUNDLES = "brooklyn-catalog-upgrade-for-bundles";
- public static class TypeUpgrades {
- static final TypeUpgrades EMPTY = new TypeUpgrades(ImmutableSet.of());
+ /**
+ * The result from parsing bundle(s) to find their upgrade info.
+ */
+ public static class CatalogUpgrades {
+ static final CatalogUpgrades EMPTY = new CatalogUpgrades(builder());
static class Builder {
private Set<VersionRangedName> removedLegacyItems = new LinkedHashSet<>();
-
- public void addAll(TypeUpgrades other) {
+ private Set<VersionRangedName> removedBundles = new LinkedHashSet<>();
+
+ public Builder removedLegacyItems(Collection<VersionRangedName> vals) {
+ removedLegacyItems.addAll(vals);
+ return this;
+ }
+ public Builder removedBundles(Collection<VersionRangedName> vals) {
+ removedBundles.addAll(vals);
+ return this;
+ }
+ public Builder addAll(CatalogUpgrades other) {
removedLegacyItems.addAll(other.removedLegacyItems);
+ removedBundles.addAll(other.removedBundles);
+ return this;
}
- public TypeUpgrades build() {
- return new TypeUpgrades(removedLegacyItems);
+ public CatalogUpgrades build() {
+ return new CatalogUpgrades(this);
}
}
@@ -65,23 +84,38 @@ public class BundleUpgradeParser {
return new Builder();
}
- private Set<VersionRangedName> removedLegacyItems; // TODO Want version ranges as well
+ private Set<VersionRangedName> removedLegacyItems;
+ private Set<VersionRangedName> removedBundles;
- public TypeUpgrades(Iterable<? extends VersionRangedName> removedLegacyItems) {
- this.removedLegacyItems = ImmutableSet.copyOf(removedLegacyItems);
+ public CatalogUpgrades(Builder builder) {
+ this.removedLegacyItems = ImmutableSet.copyOf(builder.removedLegacyItems);
+ this.removedBundles = ImmutableSet.copyOf(builder.removedBundles);
}
public boolean isEmpty() {
- return removedLegacyItems.isEmpty();
+ return removedLegacyItems.isEmpty() && removedBundles.isEmpty();
}
- public boolean isRemoved(CatalogItem<?, ?> legacyCatalogItem) {
- String name = legacyCatalogItem.getSymbolicName();
- String versionStr = legacyCatalogItem.getVersion();
- Version version = Version.valueOf(BrooklynVersionSyntax.toValidOsgiVersion(versionStr == null ? BrooklynCatalog.DEFAULT_VERSION : versionStr));
-
- for (VersionRangedName removedLegacyItem : removedLegacyItems) {
- if (removedLegacyItem.getSymbolicName().equals(name) && removedLegacyItem.getOsgiVersionRange().includes(version)) {
+ public Set<VersionRangedName> getRemovedLegacyItems() {
+ return removedLegacyItems;
+ }
+
+ public Set<VersionRangedName> getRemovedBundles() {
+ return removedBundles;
+ }
+
+ public boolean isLegacyItemRemoved(CatalogItem<?, ?> legacyCatalogItem) {
+ VersionedName name = new VersionedName(legacyCatalogItem.getSymbolicName(), legacyCatalogItem.getVersion());
+ return contains(removedLegacyItems, name);
+ }
+
+ public boolean isBundleRemoved(VersionedName bundle) {
+ return contains(removedBundles, bundle);
+ }
+
+ public boolean contains(Iterable<VersionRangedName> names, VersionedName name) {
+ for (VersionRangedName contender : names) {
+ if (contender.getSymbolicName().equals(name.getSymbolicName()) && contender.getOsgiVersionRange().includes(name.getOsgiVersion())) {
return true;
}
}
@@ -89,12 +123,18 @@ public class BundleUpgradeParser {
}
}
- /** Records a name (string) and version range (string),
- * with conveniences for pretty-printing and converting to OSGi format. */
+ /**
+ * Records a name (string) and version range (string),
+ * with conveniences for pretty-printing and converting to OSGi format.
+ *
+ * Implementation-wise, this is similar to {@link VersionedName}, but is intended
+ * as internal-only so is cut down to only what is needed.
+ */
public static class VersionRangedName {
private final String name;
private final String v;
-
+ private transient volatile VersionRange cachedOsgiVersionRange;
+
public static VersionRangedName fromString(String val, boolean singleVersionIsOsgiRange) {
if (Strings.isBlank(val)) {
throw new IllegalArgumentException("Must not be blank");
@@ -112,13 +152,14 @@ public class BundleUpgradeParser {
}
}
- public VersionRangedName(String name, String v) {
- this.name = checkNotNull(name, "name");
- this.v = v;
- }
- public VersionRangedName(String name, @Nullable VersionRange v) {
+ public VersionRangedName(String name, VersionRange v) {
this.name = checkNotNull(name, "name").toString();
- this.v = v==null ? null : v.toString();
+ this.v = checkNotNull(v, "versionRange").toString();
+ }
+
+ private VersionRangedName(String name, String v) {
+ this.name = checkNotNull(name, "name");
+ this.v = checkNotNull(v, "versionRange");
}
@Override
@@ -130,35 +171,17 @@ public class BundleUpgradeParser {
return name + ":" + getOsgiVersionRange();
}
- public boolean equals(String sn, String v) {
- return name.equals(sn) && Objects.equal(this.v, v);
- }
-
- public boolean equals(String sn, VersionRange v) {
- return name.equals(sn) && Objects.equal(getOsgiVersionRange(), v);
- }
-
public String getSymbolicName() {
return name;
}
- private transient VersionRange cachedOsgiVersionRange;
- @Nullable
public VersionRange getOsgiVersionRange() {
- if (cachedOsgiVersionRange==null && v!=null) {
- cachedOsgiVersionRange = v==null ? null : VersionRange.valueOf(BrooklynVersionSyntax.toValidOsgiVersionRange(v));
+ if (cachedOsgiVersionRange == null) {
+ cachedOsgiVersionRange = VersionRange.valueOf(BrooklynVersionSyntax.toValidOsgiVersionRange(v));
}
return cachedOsgiVersionRange;
}
- @Nullable
- public String getOsgiVersionRangeString() {
- VersionRange ov = getOsgiVersionRange();
- if (ov==null) return null;
- return ov.toString();
- }
-
- @Nullable
public String getVersionString() {
return v;
}
@@ -178,14 +201,25 @@ public class BundleUpgradeParser {
}
}
- public static TypeUpgrades parseBundleManifestForTypeUpgrades(Bundle bundle) {
+ public static CatalogUpgrades parseBundleManifestForCatalogUpgrades(Bundle bundle) {
Dictionary<String, String> headers = bundle.getHeaders();
- String removedLegacyItems = headers.get(MANIFEST_HEADER_REMOVE_LEGACY_ITEMS);
- if (removedLegacyItems != null) {
- List<VersionRangedName> versionedItems = parseVersionRangedNameList(removedLegacyItems, false);
- return new TypeUpgrades(versionedItems);
- }
- return TypeUpgrades.EMPTY;
+ String removedLegacyItemsHeader = headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS);
+ String removedBundlesHeader = headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES);
+ List<VersionRangedName> removedLegacyItems = ImmutableList.of();
+ List<VersionRangedName> removedBundles = ImmutableList.of();
+ if (removedLegacyItemsHeader == null && removedBundlesHeader == null) {
+ return CatalogUpgrades.EMPTY;
+ }
+ if (removedLegacyItemsHeader != null) {
+ removedLegacyItems = parseVersionRangedNameList(removedLegacyItemsHeader, false);
+ }
+ if (removedBundlesHeader != null) {
+ removedBundles = parseVersionRangedNameList(removedBundlesHeader, false);
+ }
+ return CatalogUpgrades.builder()
+ .removedLegacyItems(removedLegacyItems)
+ .removedBundles(removedBundles)
+ .build();
}
@VisibleForTesting
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/dba226fc/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
index 87e52e0..9f9da67 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
@@ -25,6 +25,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -41,7 +42,7 @@ import org.apache.brooklyn.api.objs.BrooklynObjectType;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
import org.apache.brooklyn.api.typereg.ManagedBundle;
import org.apache.brooklyn.api.typereg.RegisteredType;
-import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.TypeUpgrades;
+import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult;
import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
@@ -528,37 +529,59 @@ public class CatalogInitialization implements ManagementContextInjectable {
}
private PersistedCatalogState filterPersistedState(PersistedCatalogState persistedState, RebindLogger rebindLogger) {
- Maybe<OsgiManager> osgiManager = ((ManagementContextInternal)managementContext).getOsgiManager();
- if (osgiManager.isAbsent()) {
- // Could be running tests; do no filtering
+ CatalogUpgrades catalogUpgrades = findCatalogUpgrades(rebindLogger);
+
+ if (catalogUpgrades.isEmpty()) {
return persistedState;
+ } else {
+ rebindLogger.info("Filtering out persisted catalog: removedBundles="+catalogUpgrades.getRemovedBundles()+"; removedLegacyItems="+catalogUpgrades.getRemovedLegacyItems());
}
- TypeUpgrades.Builder typeUpgradesBuilder = TypeUpgrades.builder();
- Collection<ManagedBundle> managedBundles = osgiManager.get().getManagedBundles().values();
- for (ManagedBundle managedBundle : managedBundles) {
- Maybe<Bundle> bundle = osgiManager.get().findBundle(managedBundle);
- if (bundle.isPresent()) {
- typeUpgradesBuilder.addAll(BundleUpgradeParser.parseBundleManifestForTypeUpgrades(bundle.get()));
+ Map<VersionedName, InstallableManagedBundle> bundles = new LinkedHashMap<>();
+ for (Map.Entry<VersionedName, InstallableManagedBundle> entry : persistedState.getBundles().entrySet()) {
+ if (catalogUpgrades.isBundleRemoved(entry.getKey())) {
+ rebindLogger.debug("Filtering out persisted bundle "+entry.getKey());
+ } else {
+ bundles.put(entry.getKey(), entry.getValue());
}
}
- TypeUpgrades typeUpgrades = typeUpgradesBuilder.build();
-
- if (typeUpgrades.isEmpty()) {
- return persistedState;
- }
- Map<VersionedName, InstallableManagedBundle> bundles = persistedState.getBundles();
+
List<CatalogItem<?, ?>> legacyCatalogItems = new ArrayList<>();
for (CatalogItem<?, ?> legacyCatalogItem : persistedState.getLegacyCatalogItems()) {
- if (!typeUpgrades.isRemoved(legacyCatalogItem)) {
+ if (catalogUpgrades.isLegacyItemRemoved(legacyCatalogItem)) {
+ rebindLogger.debug("Filtering out persisted legacy catalog item "+legacyCatalogItem.getId());
+ } else {
legacyCatalogItems.add(legacyCatalogItem);
}
}
+
return new PersistedCatalogState(bundles, legacyCatalogItems);
}
+ private CatalogUpgrades findCatalogUpgrades(RebindLogger rebindLogger) {
+ Maybe<OsgiManager> osgiManager = ((ManagementContextInternal)managementContext).getOsgiManager();
+ if (osgiManager.isAbsent()) {
+ // Can't find any bundles to tell if there are upgrades. Could be running tests; do no filtering.
+ return CatalogUpgrades.EMPTY;
+ }
+
+ CatalogUpgrades.Builder catalogUpgradesBuilder = CatalogUpgrades.builder();
+ Collection<ManagedBundle> managedBundles = osgiManager.get().getManagedBundles().values();
+ for (ManagedBundle managedBundle : managedBundles) {
+ Maybe<Bundle> bundle = osgiManager.get().findBundle(managedBundle);
+ if (bundle.isPresent()) {
+ catalogUpgradesBuilder.addAll(BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle.get()));
+ } else {
+ rebindLogger.info("Managed bundle "+managedBundle.getId()+" not found by OSGi Manager; "
+ + "ignoring when calculating persisted state catalog upgrades");
+ }
+ }
+ return catalogUpgradesBuilder.build();
+ }
+
public interface RebindLogger {
void debug(String message, Object... args);
+ void info(String message, Object... args);
}
public interface InstallableManagedBundle {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/dba226fc/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 20c20e3..3038429 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
@@ -331,6 +331,10 @@ public abstract class RebindIteration {
public void debug(String message, Object... args) {
logRebindingDebug(message, args);
}
+ @Override
+ public void info(String message, Object... args) {
+ logRebindingInfo(message, args);
+ }
};
class InstallableManagedBundleImpl implements CatalogInitialization.InstallableManagedBundle {
@@ -1276,6 +1280,15 @@ public abstract class RebindIteration {
}
}
+ /** logs at info, except during subsequent read-only rebinds, in which it logs trace */
+ protected void logRebindingInfo(String message, Object... args) {
+ if (shouldLogRebinding()) {
+ LOG.info(message, args);
+ } else {
+ LOG.trace(message, args);
+ }
+ }
+
protected boolean shouldLogRebinding() {
return (readOnlyRebindCount.get() < 5) || (readOnlyRebindCount.get()%1000==0);
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/dba226fc/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
index 08cc4c9..a409eaf 100644
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
@@ -19,15 +19,27 @@
package org.apache.brooklyn.core.catalog.internal;
import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import java.util.Dictionary;
+import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.VersionRangedName;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.osgi.VersionedName;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
public class BundleUpgradeParserTest {
@@ -37,6 +49,18 @@ public class BundleUpgradeParserTest {
private VersionRangedName barFrom0lessThan1 = new VersionRangedName("bar", from0lessThan1);
@Test
+ public void testVersionRangedName() throws Exception {
+ assertEquals(VersionRangedName.fromString("foo:0.1.0", true).toOsgiString(), "foo:0.1.0");
+ assertEquals(VersionRangedName.fromString("foo:0.1.0", false).toOsgiString(), "foo:[0.1.0,0.1.0]");
+ assertEquals(VersionRangedName.fromString("foo:[0,1)", false).toOsgiString(), "foo:[0.0.0,1.0.0)");
+
+ assertVersionRangedNameFails("foo", "'foo' must be of 'name:versionRange' syntax");
+ assertVersionRangedNameFails("foo:bar:0.1.0", "has too many parts");
+ assertVersionRangedNameFails("", "Must not be blank");
+ assertVersionRangedNameFails(null, "Must not be blank");
+ }
+
+ @Test
public void testParseSingleQuotedVal() throws Exception {
String input = "\"foo:[0,1.0.0)\"";
assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
@@ -60,7 +84,51 @@ public class BundleUpgradeParserTest {
assertParsed(input, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
}
- protected void assertParsed(String input, List<VersionRangedName> expected) throws Exception {
+ @Test
+ public void testParseBundleEmptyManifest() throws Exception {
+ Bundle bundle = newMockBundle(ImmutableMap.of());
+
+ CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
+ assertTrue(upgrades.isEmpty());
+ assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
+ }
+
+ @Test
+ public void testParseBundleManifest() throws Exception {
+ Bundle bundle = newMockBundle(ImmutableMap.of(
+ BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"",
+ BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
+
+ CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
+ assertFalse(upgrades.isEmpty());
+ assertTrue(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
+ assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "1.0.0")));
+
+ assertTrue(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "1.0.0")));
+ assertTrue(upgrades.isLegacyItemRemoved(newMockCatalogItem("bar", "0.1.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("bar", "1.0.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("different", "0.1.0")));
+ }
+
+ private Bundle newMockBundle(Map<String, String> rawHeaders) {
+ Dictionary<String, String> headers = new Hashtable<>(rawHeaders);
+ Bundle result = Mockito.mock(Bundle.class);
+ Mockito.when(result.getHeaders()).thenReturn(headers);
+ return result;
+ }
+
+ private CatalogItem<?,?> newMockCatalogItem(String symbolicName, String version) {
+ CatalogItem<?,?> result = Mockito.mock(CatalogItem.class);
+ Mockito.when(result.getSymbolicName()).thenReturn(symbolicName);
+ Mockito.when(result.getVersion()).thenReturn(version);
+ Mockito.when(result.getId()).thenReturn(symbolicName+":"+version);
+ Mockito.when(result.getCatalogItemId()).thenReturn(symbolicName+":"+version);
+ return result;
+ }
+
+ private void assertParsed(String input, List<VersionRangedName> expected) throws Exception {
List<VersionRangedName> actual = BundleUpgradeParser.parseVersionRangedNameList(input, false);
assertEquals(actual.size(), expected.size(), "actual="+actual);
for (int i = 0; i < actual.size(); i++) {
@@ -68,4 +136,13 @@ public class BundleUpgradeParserTest {
assertEquals(actual.get(i).getOsgiVersionRange(), expected.get(i).getOsgiVersionRange());
}
}
+
+ private void assertVersionRangedNameFails(String input, String expectedFailure, String... optionalOtherExpectedFailures) {
+ try {
+ VersionRangedName.fromString(input, false);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (IllegalArgumentException e) {
+ Asserts.expectedFailureContains(e, expectedFailure, optionalOtherExpectedFailures);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/dba226fc/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
index b4b5361..0369862 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
@@ -20,9 +20,11 @@ package org.apache.brooklyn.launcher;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
@@ -53,6 +55,7 @@ import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.osgi.BundleMaker;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.osgi.VersionedName;
+import org.apache.brooklyn.util.stream.Streams;
import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.time.Duration;
import org.osgi.framework.Constants;
@@ -209,6 +212,12 @@ public abstract class AbstractBrooklynLauncherRebindTest {
assertEquals(actualCatalogItems, expectedCatalogItems, "actual="+actualCatalogItems+"; expected="+expectedCatalogItems);
}
+ protected void assertNotManagedBundle(BrooklynLauncher launcher, VersionedName bundleId) {
+ ManagementContextInternal mgmt = (ManagementContextInternal)launcher.getManagementContext();
+ ManagedBundle bundle = mgmt.getOsgiManager().get().getManagedBundle(bundleId);
+ assertNull(bundle, bundleId+" should not exist");
+ }
+
private static <T> boolean compareIterablesWithoutOrderMatters(Iterable<T> a, Iterable<T> b) {
List<T> aList = Lists.newArrayList(a);
List<T> bList = Lists.newArrayList(b);
@@ -216,36 +225,17 @@ public abstract class AbstractBrooklynLauncherRebindTest {
return aList.containsAll(bList) && bList.containsAll(aList);
}
- protected void initPersistedState(Map<String, String> legacyCatalogContents) throws Exception {
- CatalogInitialization catalogInitialization = new CatalogInitialization(CATALOG_EMPTY_INITIAL);
- BrooklynLauncher launcher = newLauncherForTests()
- .catalogInitialization(catalogInitialization);
- launcher.start();
- assertCatalogConsistsOfIds(launcher, ImmutableList.of());
- launcher.terminate();
-
- for (Map.Entry<String, String> entry : legacyCatalogContents.entrySet()) {
- addMemento(BrooklynObjectType.CATALOG_ITEM, entry.getKey(), entry.getValue());
- }
- }
-
- protected void addMemento(BrooklynObjectType type, String id, String contents) throws Exception {
- File persistedFile = getPersistanceFile(type, id);
- Files.write(contents.getBytes(StandardCharsets.UTF_8), persistedFile);
- }
-
- protected File getPersistanceFile(BrooklynObjectType type, String id) {
- String dir;
- switch (type) {
- case ENTITY: dir = "entities"; break;
- case LOCATION: dir = "locations"; break;
- case POLICY: dir = "policies"; break;
- case ENRICHER: dir = "enrichers"; break;
- case FEED: dir = "feeds"; break;
- case CATALOG_ITEM: dir = "catalog"; break;
- default: throw new UnsupportedOperationException("type="+type);
- }
- return new File(persistenceDir, Os.mergePaths(dir, id));
+ protected String createPersistenceManagedBundle(String randomId, VersionedName bundleName) {
+ return Joiner.on("\n").join(
+ "<managedBundle>",
+ "<brooklynVersion>1.0.0-SNAPSHOT</brooklynVersion>",
+ "<type>org.apache.brooklyn.core:org.apache.brooklyn.core.typereg.BasicManagedBundle</type>",
+ "<id>"+randomId+"</id>",
+ "<searchPath class=\"ImmutableList\"/>",
+ "<symbolicName>"+bundleName.getSymbolicName()+"</symbolicName>",
+ "<version>"+bundleName.getVersionString()+"</version>",
+ "<url>http://example.org/brooklyn/"+bundleName.getSymbolicName()+"/"+bundleName.getVersionString()+"</url>",
+ "</managedBundle>");
}
protected String createLegacyPersistenceCatalogItem(VersionedName itemName) {
@@ -293,4 +283,73 @@ public abstract class AbstractBrooklynLauncherRebindTest {
}
return result.toString();
}
+
+ public PersistedStateInitializer newPersistedStateInitializer() {
+ return new PersistedStateInitializer();
+ }
+
+ public class PersistedStateInitializer {
+ private final Map<String, String> legacyCatalogContents = new LinkedHashMap<>();
+ private final Map<VersionedName, File> bundles = new LinkedHashMap<>();
+
+ public PersistedStateInitializer legacyCatalogItems(Map<String, String> vals) throws Exception {
+ legacyCatalogContents.putAll(vals);
+ return this;
+ }
+
+ public PersistedStateInitializer bundle(VersionedName bundleName, File file) throws Exception {
+ bundles.put(bundleName, file);
+ return this;
+ }
+
+ public PersistedStateInitializer bundles(Map<VersionedName, File> vals) throws Exception {
+ bundles.putAll(vals);
+ return this;
+ }
+
+ public void initState() throws Exception {
+ initEmptyState();
+
+ for (Map.Entry<String, String> entry : legacyCatalogContents.entrySet()) {
+ addMemento(BrooklynObjectType.CATALOG_ITEM, entry.getKey(), entry.getValue().getBytes(StandardCharsets.UTF_8));
+ }
+ for (Map.Entry<VersionedName, File> entry : bundles.entrySet()) {
+ VersionedName bundleName = entry.getKey();
+ String randomId = Identifiers.makeRandomId(8);
+ String managedBundleXml = createPersistenceManagedBundle(randomId, bundleName);
+ addMemento(BrooklynObjectType.MANAGED_BUNDLE, randomId, managedBundleXml.getBytes(StandardCharsets.UTF_8));
+ addMemento(BrooklynObjectType.MANAGED_BUNDLE, randomId+".jar", Streams.readFullyAndClose(new FileInputStream(entry.getValue())));
+ }
+ }
+
+ private void addMemento(BrooklynObjectType type, String id, byte[] contents) throws Exception {
+ File persistedFile = getPersistanceFile(type, id);
+ Files.createParentDirs(persistedFile);
+ Files.write(contents, persistedFile);
+ }
+
+ private File getPersistanceFile(BrooklynObjectType type, String id) {
+ String dir;
+ switch (type) {
+ case ENTITY: dir = "entities"; break;
+ case LOCATION: dir = "locations"; break;
+ case POLICY: dir = "policies"; break;
+ case ENRICHER: dir = "enrichers"; break;
+ case FEED: dir = "feeds"; break;
+ case CATALOG_ITEM: dir = "catalog"; break;
+ case MANAGED_BUNDLE: dir = "bundles"; break;
+ default: throw new UnsupportedOperationException("type="+type);
+ }
+ return new File(persistenceDir, Os.mergePaths(dir, id));
+ }
+
+ private void initEmptyState() {
+ CatalogInitialization catalogInitialization = new CatalogInitialization(CATALOG_EMPTY_INITIAL);
+ BrooklynLauncher launcher = newLauncherForTests()
+ .catalogInitialization(catalogInitialization);
+ launcher.start();
+ assertCatalogConsistsOfIds(launcher, ImmutableList.of());
+ launcher.terminate();
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/dba226fc/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
index 1922d72..8ef3466 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
@@ -18,13 +18,16 @@
*/
package org.apache.brooklyn.launcher;
+import static org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.CATALOG_BOM;
+import static org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES;
+import static org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS;
+
import java.io.File;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
-import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser;
import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
import org.apache.brooklyn.util.osgi.VersionedName;
import org.testng.annotations.BeforeMethod;
@@ -67,20 +70,21 @@ public class BrooklynLauncherUpgradeCatalogOsgiTest extends AbstractBrooklynLaun
VersionedName three_0_2_0 = VersionedName.fromString("three:0.2.0");
VersionedName four_0_1_0 = VersionedName.fromString("four:0.1.0");
- initPersistedState(ImmutableMap.<String, String>builder()
- .put("one_0.1.0", createLegacyPersistenceCatalogItem(one_0_1_0))
- .put("two_0.1.0", createLegacyPersistenceCatalogItem(two_0_1_0))
- .put("two_1.0.0", createLegacyPersistenceCatalogItem(two_1_0_0))
- .put("three_0.1.0", createLegacyPersistenceCatalogItem(three_0_1_0))
- .put("three_0.2.0", createLegacyPersistenceCatalogItem(three_0_2_0))
- .put("four_0.1.0", createLegacyPersistenceCatalogItem(four_0_1_0))
- .build());
+ newPersistedStateInitializer()
+ .legacyCatalogItems(ImmutableMap.<String, String>builder()
+ .put("one_0.1.0", createLegacyPersistenceCatalogItem(one_0_1_0))
+ .put("two_0.1.0", createLegacyPersistenceCatalogItem(two_0_1_0))
+ .put("two_1.0.0", createLegacyPersistenceCatalogItem(two_1_0_0))
+ .put("three_0.1.0", createLegacyPersistenceCatalogItem(three_0_1_0))
+ .put("three_0.2.0", createLegacyPersistenceCatalogItem(three_0_2_0))
+ .put("four_0.1.0", createLegacyPersistenceCatalogItem(four_0_1_0))
+ .build())
+ .initState();
String bundleBom = createCatalogYaml(ImmutableList.<URI>of(), ImmutableSet.<VersionedName>of());
VersionedName bundleName = new VersionedName("org.example.testRemoveLegacyItems", "1.0.0");
- String removedLegacyItems = "\"one:[0,1.0.0)\",\"two:[0,1.0.0)\",\"three:0.1.0\"";
- Map<String, String> bundleManifest = ImmutableMap.of(BundleUpgradeParser.MANIFEST_HEADER_REMOVE_LEGACY_ITEMS, removedLegacyItems);
- File bundleFile = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom.getBytes(StandardCharsets.UTF_8)), bundleName, bundleManifest);
+ Map<String, String> bundleManifest = ImmutableMap.of(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, "\"one:[0,1.0.0)\",\"two:[0,1.0.0)\",\"three:0.1.0\"");
+ File bundleFile = newTmpBundle(ImmutableMap.of(CATALOG_BOM, bundleBom.getBytes(StandardCharsets.UTF_8)), bundleName, bundleManifest);
File initialBomFile = newTmpFile(createCatalogYaml(ImmutableList.of(bundleFile.toURI()), ImmutableList.of()));
BrooklynLauncher launcher = newLauncherForTests(initialBomFile.getAbsolutePath());
@@ -90,4 +94,54 @@ public class BrooklynLauncherUpgradeCatalogOsgiTest extends AbstractBrooklynLaun
launcher.terminate();
}
+
+ @Test
+ public void testForceUpgradeBundle() throws Exception {
+ VersionedName one_1_0_0 = VersionedName.fromString("one:1.0.0");
+ VersionedName one_2_0_0 = VersionedName.fromString("one:2.0.0");
+
+ String bundleSymbolicName = "org.example.testForceUpgradeBundle";
+ VersionedName bundleVersionedName1 = new VersionedName(bundleSymbolicName, "1.0.0");
+ String bundleBom1 = createCatalogYaml(ImmutableList.<URI>of(), ImmutableSet.<VersionedName>of(one_1_0_0));
+ File bundleFile1 = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom1.getBytes(StandardCharsets.UTF_8)), bundleVersionedName1);
+
+ newPersistedStateInitializer()
+ .bundle(bundleVersionedName1, bundleFile1)
+ .initState();
+
+ VersionedName bundleVersionedName2 = new VersionedName(bundleSymbolicName, "2.0.0");
+ String bundleBom2 = createCatalogYaml(ImmutableList.<URI>of(), ImmutableSet.<VersionedName>of(one_2_0_0));
+ Map<String, String> bundleManifest2 = ImmutableMap.of(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\""+bundleSymbolicName+":[0.0.0,2.0.0)\"");
+ File bundleFile2 = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom2.getBytes(StandardCharsets.UTF_8)), bundleVersionedName2, bundleManifest2);
+
+ File initialBomFile = newTmpFile(createCatalogYaml(ImmutableList.of(bundleFile2.toURI()), ImmutableList.of()));
+
+ BrooklynLauncher launcher = newLauncherForTests(initialBomFile.getAbsolutePath());
+ launcher.start();
+ assertCatalogConsistsOfIds(launcher, ImmutableList.of(one_2_0_0));
+ assertManagedBundle(launcher, bundleVersionedName2, ImmutableSet.<VersionedName>of(one_2_0_0));
+ assertNotManagedBundle(launcher, bundleVersionedName1);
+ launcher.terminate();
+ }
+
+ // Simple test (no upgrade), important for validating that other tests really do as expected!
+ @Test
+ public void testLoadsBundleFromPersistedState() throws Exception {
+ VersionedName one_1_0_0 = VersionedName.fromString("one:1.0.0");
+
+ String bundleSymbolicName = "org.example.testForceUpgradeBundle";
+ VersionedName bundleVersionedName = new VersionedName(bundleSymbolicName, "1.0.0");
+ String bundleBom = createCatalogYaml(ImmutableList.<URI>of(), ImmutableSet.<VersionedName>of(one_1_0_0));
+ File bundleFile = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom.getBytes(StandardCharsets.UTF_8)), bundleVersionedName);
+
+ newPersistedStateInitializer()
+ .bundle(bundleVersionedName, bundleFile)
+ .initState();
+
+ BrooklynLauncher launcher = newLauncherForTests(CATALOG_EMPTY_INITIAL);
+ launcher.start();
+ assertCatalogConsistsOfIds(launcher, ImmutableList.of(one_1_0_0));
+ assertManagedBundle(launcher, bundleVersionedName, ImmutableSet.<VersionedName>of(one_1_0_0));
+ launcher.terminate();
+ }
}
[2/7] brooklyn-server git commit: Support catalog item removal on init
Posted by he...@apache.org.
Support catalog item removal on init
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/98731c21
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/98731c21
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/98731c21
Branch: refs/heads/master
Commit: 98731c212602e96428c32fbbdf2a0cc1fe91cbda
Parents: 05d6ee0
Author: Aled Sage <al...@gmail.com>
Authored: Thu Oct 19 09:47:57 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Mon Oct 23 17:41:46 2017 +0100
----------------------------------------------------------------------
.../catalog/internal/BundleUpgradeParser.java | 205 +++++++++++++++++++
.../catalog/internal/CatalogInitialization.java | 39 +++-
.../internal/BundleUpgradeParserTest.java | 71 +++++++
.../AbstractBrooklynLauncherRebindTest.java | 137 ++++++++++++-
.../BrooklynLauncherRebindCatalogOsgiTest.java | 47 -----
.../BrooklynLauncherUpgradeCatalogOsgiTest.java | 93 +++++++++
.../util/text/BrooklynVersionSyntax.java | 26 +++
.../util/text/BrooklynVersionSyntaxTest.java | 15 ++
8 files changed, 572 insertions(+), 61 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
new file mode 100644
index 0000000..31df462
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
@@ -0,0 +1,205 @@
+/*
+ * 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.catalog.internal;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.catalog.BrooklynCatalog;
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
+import org.apache.brooklyn.util.text.QuotedStringTokenizer;
+import org.apache.brooklyn.util.text.Strings;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+public class BundleUpgradeParser {
+
+ @Beta
+ public static final String MANIFEST_HEADER_REMOVE_LEGACY_ITEMS = "brooklyn-catalog-force-remove-legacy-items";
+
+ public static class TypeUpgrades {
+ static final TypeUpgrades EMPTY = new TypeUpgrades(ImmutableSet.of());
+
+ static class Builder {
+ private Set<VersionRangedName> removedLegacyItems = new LinkedHashSet<>();
+
+ public void addAll(TypeUpgrades other) {
+ removedLegacyItems.addAll(other.removedLegacyItems);
+ }
+ public TypeUpgrades build() {
+ return new TypeUpgrades(removedLegacyItems);
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private Set<VersionRangedName> removedLegacyItems; // TODO Want version ranges as well
+
+ public TypeUpgrades(Iterable<? extends VersionRangedName> removedLegacyItems) {
+ this.removedLegacyItems = ImmutableSet.copyOf(removedLegacyItems);
+ }
+
+ public boolean isEmpty() {
+ return removedLegacyItems.isEmpty();
+ }
+
+ public boolean isRemoved(CatalogItem<?, ?> legacyCatalogItem) {
+ String name = legacyCatalogItem.getSymbolicName();
+ String versionStr = legacyCatalogItem.getVersion();
+ Version version = Version.valueOf(BrooklynVersionSyntax.toValidOsgiVersion(versionStr == null ? BrooklynCatalog.DEFAULT_VERSION : versionStr));
+
+ for (VersionRangedName removedLegacyItem : removedLegacyItems) {
+ if (removedLegacyItem.getSymbolicName().equals(name) && removedLegacyItem.getOsgiVersionRange().includes(version)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /** Records a name (string) and version range (string),
+ * with conveniences for pretty-printing and converting to OSGi format. */
+ public static class VersionRangedName {
+ private final String name;
+ private final String v;
+
+ public static VersionRangedName fromString(String val, boolean singleVersionIsOsgiRange) {
+ if (Strings.isBlank(val)) {
+ throw new IllegalArgumentException("Must not be blank");
+ }
+ String[] parts = val.split(":");
+ if (parts.length > 2) {
+ throw new IllegalArgumentException("Identifier '"+val+"' has too many parts; max one ':' symbol");
+ }
+ if (parts.length == 1 || Strings.isBlank(parts[1])) {
+ throw new IllegalArgumentException("Identifier '"+val+"' must be of 'name:versionRange' syntax");
+ } else if (singleVersionIsOsgiRange || (parts[1].startsWith("(") || parts[1].startsWith("["))) {
+ return new VersionRangedName(parts[0], parts[1]);
+ } else {
+ return new VersionRangedName(parts[0], "["+parts[1]+","+parts[1]+"]");
+ }
+ }
+
+ public VersionRangedName(String name, String v) {
+ this.name = checkNotNull(name, "name");
+ this.v = v;
+ }
+ public VersionRangedName(String name, @Nullable VersionRange v) {
+ this.name = checkNotNull(name, "name").toString();
+ this.v = v==null ? null : v.toString();
+ }
+
+ @Override
+ public String toString() {
+ return name + ":" + v;
+ }
+
+ public String toOsgiString() {
+ return name + ":" + getOsgiVersionRange();
+ }
+
+ public boolean equals(String sn, String v) {
+ return name.equals(sn) && Objects.equal(this.v, v);
+ }
+
+ public boolean equals(String sn, VersionRange v) {
+ return name.equals(sn) && Objects.equal(getOsgiVersionRange(), v);
+ }
+
+ public String getSymbolicName() {
+ return name;
+ }
+
+ private transient VersionRange cachedOsgiVersionRange;
+ @Nullable
+ public VersionRange getOsgiVersionRange() {
+ if (cachedOsgiVersionRange==null && v!=null) {
+ cachedOsgiVersionRange = v==null ? null : VersionRange.valueOf(BrooklynVersionSyntax.toValidOsgiVersionRange(v));
+ }
+ return cachedOsgiVersionRange;
+ }
+
+ @Nullable
+ public String getOsgiVersionRangeString() {
+ VersionRange ov = getOsgiVersionRange();
+ if (ov==null) return null;
+ return ov.toString();
+ }
+
+ @Nullable
+ public String getVersionString() {
+ return v;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, v);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof VersionRangedName)) {
+ return false;
+ }
+ VersionRangedName o = (VersionRangedName) other;
+ return Objects.equal(name, o.name) && Objects.equal(v, o.v);
+ }
+ }
+
+ public static TypeUpgrades parseBundleManifestForTypeUpgrades(Bundle bundle) {
+ Dictionary<String, String> headers = bundle.getHeaders();
+ String removedLegacyItems = headers.get(MANIFEST_HEADER_REMOVE_LEGACY_ITEMS);
+ if (removedLegacyItems != null) {
+ List<VersionRangedName> versionedItems = parseVersionRangedNameList(removedLegacyItems, false);
+ return new TypeUpgrades(versionedItems);
+ }
+ return TypeUpgrades.EMPTY;
+ }
+
+ @VisibleForTesting
+ static List<VersionRangedName> parseVersionRangedNameList(String input, boolean singleVersionIsOsgiRange) {
+ List<String> vals = QuotedStringTokenizer.builder()
+ .delimiterChars(",")
+ .includeQuotes(false)
+ .includeDelimiters(false)
+ .buildList(input);
+
+ List<VersionRangedName> versionedItems = new ArrayList<>();
+ for (String val : vals) {
+ versionedItems.add(VersionRangedName.fromString(val, singleVersionIsOsgiRange));
+ }
+ return versionedItems;
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
index 58999a2..87e52e0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
@@ -25,8 +25,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Dictionary;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -43,6 +41,7 @@ import org.apache.brooklyn.api.objs.BrooklynObjectType;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
import org.apache.brooklyn.api.typereg.ManagedBundle;
import org.apache.brooklyn.api.typereg.RegisteredType;
+import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.TypeUpgrades;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult;
import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
@@ -73,10 +72,8 @@ import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Splitter;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
@Beta
@@ -237,7 +234,9 @@ public class CatalogInitialization implements ManagementContextInjectable {
}
populateInitialCatalogImpl(true);
- addPersistedCatalogImpl(persistedState, exceptionHandler, rebindLogger);
+
+ PersistedCatalogState filteredPersistedState = filterPersistedState(persistedState, rebindLogger);
+ addPersistedCatalogImpl(filteredPersistedState, exceptionHandler, rebindLogger);
if (mode == ManagementNodeState.MASTER) {
// TODO ideally this would remain false until it has *persisted* the changed catalog;
@@ -528,6 +527,36 @@ public class CatalogInitialization implements ManagementContextInjectable {
}
}
+ private PersistedCatalogState filterPersistedState(PersistedCatalogState persistedState, RebindLogger rebindLogger) {
+ Maybe<OsgiManager> osgiManager = ((ManagementContextInternal)managementContext).getOsgiManager();
+ if (osgiManager.isAbsent()) {
+ // Could be running tests; do no filtering
+ return persistedState;
+ }
+
+ TypeUpgrades.Builder typeUpgradesBuilder = TypeUpgrades.builder();
+ Collection<ManagedBundle> managedBundles = osgiManager.get().getManagedBundles().values();
+ for (ManagedBundle managedBundle : managedBundles) {
+ Maybe<Bundle> bundle = osgiManager.get().findBundle(managedBundle);
+ if (bundle.isPresent()) {
+ typeUpgradesBuilder.addAll(BundleUpgradeParser.parseBundleManifestForTypeUpgrades(bundle.get()));
+ }
+ }
+ TypeUpgrades typeUpgrades = typeUpgradesBuilder.build();
+
+ if (typeUpgrades.isEmpty()) {
+ return persistedState;
+ }
+ Map<VersionedName, InstallableManagedBundle> bundles = persistedState.getBundles();
+ List<CatalogItem<?, ?>> legacyCatalogItems = new ArrayList<>();
+ for (CatalogItem<?, ?> legacyCatalogItem : persistedState.getLegacyCatalogItems()) {
+ if (!typeUpgrades.isRemoved(legacyCatalogItem)) {
+ legacyCatalogItems.add(legacyCatalogItem);
+ }
+ }
+ return new PersistedCatalogState(bundles, legacyCatalogItems);
+ }
+
public interface RebindLogger {
void debug(String message, Object... args);
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
new file mode 100644
index 0000000..08cc4c9
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.catalog.internal;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.List;
+
+import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.VersionRangedName;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class BundleUpgradeParserTest {
+
+ private VersionRange from0lessThan1 = new VersionRange('[', Version.valueOf("0"), Version.valueOf("1.0.0"), ')');
+ private VersionRange exactly0dot1 = new VersionRange('[', Version.valueOf("0.1.0"), Version.valueOf("0.1.0"), ']');
+ private VersionRangedName fooFrom0lessThan1 = new VersionRangedName("foo", from0lessThan1);
+ private VersionRangedName barFrom0lessThan1 = new VersionRangedName("bar", from0lessThan1);
+
+ @Test
+ public void testParseSingleQuotedVal() throws Exception {
+ String input = "\"foo:[0,1.0.0)\"";
+ assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
+ }
+
+ @Test
+ public void testParseSingleQuotedValWithNestedQuotes() throws Exception {
+ String input = "\"foo:[0,\"1.0.0\")\"";
+ assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
+ }
+
+ @Test
+ public void testParseMultipleVals() throws Exception {
+ String input = "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"";
+ assertParsed(input, ImmutableList.of(fooFrom0lessThan1, barFrom0lessThan1));
+ }
+
+ @Test
+ public void testParseValWithExactVersion() throws Exception {
+ String input = "\"foo:0.1.0\"";
+ assertParsed(input, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
+ }
+
+ protected void assertParsed(String input, List<VersionRangedName> expected) throws Exception {
+ List<VersionRangedName> actual = BundleUpgradeParser.parseVersionRangedNameList(input, false);
+ assertEquals(actual.size(), expected.size(), "actual="+actual);
+ for (int i = 0; i < actual.size(); i++) {
+ assertEquals(actual.get(i).getSymbolicName(), expected.get(i).getSymbolicName());
+ assertEquals(actual.get(i).getOsgiVersionRange(), expected.get(i).getOsgiVersionRange());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
index 6b13313..b4b5361 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/AbstractBrooklynLauncherRebindTest.java
@@ -18,13 +18,20 @@
*/
package org.apache.brooklyn.launcher;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.zip.ZipEntry;
import javax.annotation.Nullable;
@@ -32,10 +39,15 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.api.catalog.BrooklynCatalog;
import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
+import org.apache.brooklyn.api.objs.BrooklynObjectType;
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.core.catalog.internal.CatalogInitialization;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.mgmt.persist.PersistMode;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.osgi.BundleMaker;
@@ -43,7 +55,6 @@ import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.osgi.VersionedName;
import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.time.Duration;
-import org.apache.commons.collections.IteratorUtils;
import org.osgi.framework.Constants;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
@@ -51,12 +62,18 @@ import org.testng.annotations.BeforeMethod;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
public abstract class AbstractBrooklynLauncherRebindTest {
+ protected static final String CATALOG_EMPTY_INITIAL = "classpath://rebind-test-empty-catalog.bom";
+
protected List<BrooklynLauncher> launchers = Lists.newCopyOnWriteArrayList();
protected List<File> tmpFiles = new ArrayList<>();
@@ -118,8 +135,12 @@ public abstract class AbstractBrooklynLauncherRebindTest {
Files.write(contents, file, Charsets.UTF_8);
return file;
}
-
+
protected File newTmpBundle(Map<String, byte[]> files, VersionedName bundleName) {
+ return newTmpBundle(files, bundleName, ImmutableMap.of());
+ }
+
+ protected File newTmpBundle(Map<String, byte[]> files, VersionedName bundleName, Map<String, String> manifestLines) {
Map<ZipEntry, InputStream> zipEntries = new LinkedHashMap<>();
for (Map.Entry<String, byte[]> entry : files.entrySet()) {
zipEntries.put(new ZipEntry(entry.getKey()), new ByteArrayInputStream(entry.getValue()));
@@ -129,11 +150,16 @@ public abstract class AbstractBrooklynLauncherRebindTest {
File bf = bundleMaker.createTempZip("test", zipEntries);
tmpFiles.add(bf);
- if (bundleName!=null) {
- bf = bundleMaker.copyAddingManifest(bf, MutableMap.of(
- "Manifest-Version", "2.0",
- Constants.BUNDLE_SYMBOLICNAME, bundleName.getSymbolicName(),
- Constants.BUNDLE_VERSION, bundleName.getOsgiVersion().toString()));
+ if (bundleName != null || manifestLines.size() > 0) {
+ Map<String, String> manifestAllLines = MutableMap.<String, String>builder()
+ .putAll(manifestLines)
+ .putIfAbsent("Manifest-Version", "2.0")
+ .build();
+ if (bundleName != null) {
+ manifestAllLines.putIfAbsent(Constants.BUNDLE_SYMBOLICNAME, bundleName.getSymbolicName());
+ manifestAllLines.putIfAbsent(Constants.BUNDLE_VERSION, bundleName.getOsgiVersion().toString());
+ }
+ bf = bundleMaker.copyAddingManifest(bf, manifestAllLines);
tmpFiles.add(bf);
}
return bf;
@@ -168,10 +194,103 @@ public abstract class AbstractBrooklynLauncherRebindTest {
Assert.assertTrue(compareIterablesWithoutOrderMatters(ids, idsFromItems), String.format("Expected %s, found %s", ids, idsFromItems));
}
+ protected void assertManagedBundle(BrooklynLauncher launcher, VersionedName bundleId, Set<VersionedName> expectedCatalogItems) {
+ ManagementContextInternal mgmt = (ManagementContextInternal)launcher.getManagementContext();
+ ManagedBundle bundle = mgmt.getOsgiManager().get().getManagedBundle(bundleId);
+ assertNotNull(bundle, bundleId+" not found");
+
+ Set<VersionedName> actualCatalogItems = new LinkedHashSet<>();
+ Iterable<RegisteredType> types = launcher.getManagementContext().getTypeRegistry().getAll();
+ for (RegisteredType type : types) {
+ if (Objects.equal(bundleId.toOsgiString(), type.getContainingBundle())) {
+ actualCatalogItems.add(type.getVersionedName());
+ }
+ }
+ assertEquals(actualCatalogItems, expectedCatalogItems, "actual="+actualCatalogItems+"; expected="+expectedCatalogItems);
+ }
+
private static <T> boolean compareIterablesWithoutOrderMatters(Iterable<T> a, Iterable<T> b) {
- List<T> aList = IteratorUtils.toList(a.iterator());
- List<T> bList = IteratorUtils.toList(b.iterator());
+ List<T> aList = Lists.newArrayList(a);
+ List<T> bList = Lists.newArrayList(b);
return aList.containsAll(bList) && bList.containsAll(aList);
}
+
+ protected void initPersistedState(Map<String, String> legacyCatalogContents) throws Exception {
+ CatalogInitialization catalogInitialization = new CatalogInitialization(CATALOG_EMPTY_INITIAL);
+ BrooklynLauncher launcher = newLauncherForTests()
+ .catalogInitialization(catalogInitialization);
+ launcher.start();
+ assertCatalogConsistsOfIds(launcher, ImmutableList.of());
+ launcher.terminate();
+
+ for (Map.Entry<String, String> entry : legacyCatalogContents.entrySet()) {
+ addMemento(BrooklynObjectType.CATALOG_ITEM, entry.getKey(), entry.getValue());
+ }
+ }
+
+ protected void addMemento(BrooklynObjectType type, String id, String contents) throws Exception {
+ File persistedFile = getPersistanceFile(type, id);
+ Files.write(contents.getBytes(StandardCharsets.UTF_8), persistedFile);
+ }
+
+ protected File getPersistanceFile(BrooklynObjectType type, String id) {
+ String dir;
+ switch (type) {
+ case ENTITY: dir = "entities"; break;
+ case LOCATION: dir = "locations"; break;
+ case POLICY: dir = "policies"; break;
+ case ENRICHER: dir = "enrichers"; break;
+ case FEED: dir = "feeds"; break;
+ case CATALOG_ITEM: dir = "catalog"; break;
+ default: throw new UnsupportedOperationException("type="+type);
+ }
+ return new File(persistenceDir, Os.mergePaths(dir, id));
+ }
+
+ protected String createLegacyPersistenceCatalogItem(VersionedName itemName) {
+ return Joiner.on("\n").join(
+ "<catalogItem>",
+ " <brooklynVersion>0.12.0-20170901.1331</brooklynVersion>",
+ " <type>org.apache.brooklyn.core:org.apache.brooklyn.core.catalog.internal.CatalogEntityItemDto</type>",
+ " <id>"+itemName.getSymbolicName()+":"+itemName.getVersionString()+"</id>",
+ " <catalogItemId>"+itemName.getSymbolicName()+":"+itemName.getVersionString()+"</catalogItemId>",
+ " <searchPath class=\"ImmutableList\"/>",
+ " <registeredTypeName>"+itemName.getSymbolicName()+"</registeredTypeName>",
+ " <version>"+itemName.getVersionString()+"</version>",
+ " <planYaml>services: [{type: org.apache.brooklyn.entity.stock.BasicApplication}]</planYaml>",
+ " <libraries class=\"ImmutableList\" reference=\"../searchPath\"/>",
+ " <catalogItemType>ENTITY</catalogItemType>",
+ " <catalogItemJavaType>org.apache.brooklyn.api:org.apache.brooklyn.api.entity.Entity</catalogItemJavaType>",
+ " <specType>org.apache.brooklyn.api:org.apache.brooklyn.api.entity.EntitySpec</specType>",
+ " <deprecated>false</deprecated>",
+ " <disabled>false</disabled>",
+ "</catalogItem>");
+ }
+
+ protected String createCatalogYaml(Iterable<URI> libraries, Iterable<VersionedName> entities) {
+ if (Iterables.isEmpty(libraries) && Iterables.isEmpty(entities)) {
+ return "brooklyn.catalog: {}\n";
+ }
+
+ StringBuilder result = new StringBuilder();
+ result.append("brooklyn.catalog:\n");
+ if (!Iterables.isEmpty(libraries)) {
+ result.append(" brooklyn.libraries:\n");
+ }
+ for (URI library : libraries) {
+ result.append(" - " + library+"\n");
+ }
+ if (!Iterables.isEmpty(entities)) {
+ result.append(" items:\n");
+ }
+ for (VersionedName entity : entities) {
+ result.append(" - id: " + entity.getSymbolicName()+"\n");
+ result.append(" version: " + entity.getVersionString()+"\n");
+ result.append(" itemType: entity"+"\n");
+ result.append(" item:"+"\n");
+ result.append(" type: " + BasicEntity.class.getName()+"\n");
+ }
+ return result.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/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 c52fec4..2e9c78e 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherRebindCatalogOsgiTest.java
@@ -18,21 +18,12 @@
*/
package org.apache.brooklyn.launcher;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
import java.io.File;
-import java.net.URI;
import java.nio.charset.StandardCharsets;
-import java.util.LinkedHashSet;
import java.util.Set;
-import org.apache.brooklyn.api.typereg.ManagedBundle;
-import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
import org.apache.brooklyn.util.osgi.OsgiTestResources;
import org.apache.brooklyn.util.osgi.VersionedName;
@@ -40,7 +31,6 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -179,41 +169,4 @@ public class BrooklynLauncherRebindCatalogOsgiTest extends AbstractBrooklynLaunc
assertCatalogConsistsOfIds(newLauncher, COM_EXAMPLE_BUNDLE_CATALOG_IDS);
assertManagedBundle(newLauncher, COM_EXAMPLE_BUNDLE_ID, COM_EXAMPLE_BUNDLE_CATALOG_IDS);
}
-
- private void assertManagedBundle(BrooklynLauncher launcher, VersionedName bundleId, Set<VersionedName> expectedCatalogItems) {
- ManagementContextInternal mgmt = (ManagementContextInternal)launcher.getManagementContext();
- ManagedBundle bundle = mgmt.getOsgiManager().get().getManagedBundle(bundleId);
- assertNotNull(bundle, bundleId+" not found");
-
- Set<VersionedName> actualCatalogItems = new LinkedHashSet<>();
- Iterable<RegisteredType> types = launcher.getManagementContext().getTypeRegistry().getAll();
- for (RegisteredType type : types) {
- if (Objects.equal(bundleId.toOsgiString(), type.getContainingBundle())) {
- actualCatalogItems.add(type.getVersionedName());
- }
- }
- assertEquals(actualCatalogItems, expectedCatalogItems, "actual="+actualCatalogItems+"; expected="+expectedCatalogItems);
- }
-
- private String createCatalogYaml(Iterable<URI> libraries, Iterable<VersionedName> entities) {
- StringBuilder result = new StringBuilder();
- result.append("brooklyn.catalog:\n");
- if (!Iterables.isEmpty(libraries)) {
- result.append(" brooklyn.libraries:\n");
- }
- for (URI library : libraries) {
- result.append(" - " + library+"\n");
- }
- if (!Iterables.isEmpty(entities)) {
- result.append(" items:\n");
- }
- for (VersionedName entity : entities) {
- result.append(" - id: " + entity.getSymbolicName()+"\n");
- result.append(" version: " + entity.getVersionString()+"\n");
- result.append(" itemType: entity"+"\n");
- result.append(" item:"+"\n");
- result.append(" type: " + BasicEntity.class.getName()+"\n");
- }
- return result.toString();
- }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
new file mode 100644
index 0000000..1922d72
--- /dev/null
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.launcher;
+
+import java.io.File;
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
+import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser;
+import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
+import org.apache.brooklyn.util.osgi.VersionedName;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class BrooklynLauncherUpgradeCatalogOsgiTest extends AbstractBrooklynLauncherRebindTest {
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected boolean useOsgi() {
+ return true;
+ }
+
+ @Override
+ protected boolean reuseOsgi() {
+ return false;
+ }
+
+ private BrooklynLauncher newLauncherForTests(String catalogInitial) {
+ CatalogInitialization catalogInitialization = new CatalogInitialization(catalogInitial);
+ return super.newLauncherForTests()
+ .catalogInitialization(catalogInitialization);
+ }
+
+ @Test
+ public void testRemoveLegacyItems() throws Exception {
+ VersionedName one_0_1_0 = VersionedName.fromString("one:0.1.0");
+ VersionedName two_0_1_0 = VersionedName.fromString("two:0.1.0");
+ VersionedName two_1_0_0 = VersionedName.fromString("two:1.0.0");
+ VersionedName three_0_1_0 = VersionedName.fromString("three:0.1.0");
+ VersionedName three_0_2_0 = VersionedName.fromString("three:0.2.0");
+ VersionedName four_0_1_0 = VersionedName.fromString("four:0.1.0");
+
+ initPersistedState(ImmutableMap.<String, String>builder()
+ .put("one_0.1.0", createLegacyPersistenceCatalogItem(one_0_1_0))
+ .put("two_0.1.0", createLegacyPersistenceCatalogItem(two_0_1_0))
+ .put("two_1.0.0", createLegacyPersistenceCatalogItem(two_1_0_0))
+ .put("three_0.1.0", createLegacyPersistenceCatalogItem(three_0_1_0))
+ .put("three_0.2.0", createLegacyPersistenceCatalogItem(three_0_2_0))
+ .put("four_0.1.0", createLegacyPersistenceCatalogItem(four_0_1_0))
+ .build());
+
+ String bundleBom = createCatalogYaml(ImmutableList.<URI>of(), ImmutableSet.<VersionedName>of());
+ VersionedName bundleName = new VersionedName("org.example.testRemoveLegacyItems", "1.0.0");
+ String removedLegacyItems = "\"one:[0,1.0.0)\",\"two:[0,1.0.0)\",\"three:0.1.0\"";
+ Map<String, String> bundleManifest = ImmutableMap.of(BundleUpgradeParser.MANIFEST_HEADER_REMOVE_LEGACY_ITEMS, removedLegacyItems);
+ File bundleFile = newTmpBundle(ImmutableMap.of(BasicBrooklynCatalog.CATALOG_BOM, bundleBom.getBytes(StandardCharsets.UTF_8)), bundleName, bundleManifest);
+ File initialBomFile = newTmpFile(createCatalogYaml(ImmutableList.of(bundleFile.toURI()), ImmutableList.of()));
+
+ BrooklynLauncher launcher = newLauncherForTests(initialBomFile.getAbsolutePath());
+ launcher.start();
+ assertCatalogConsistsOfIds(launcher, ImmutableList.of(two_1_0_0, three_0_2_0, four_0_1_0));
+ assertManagedBundle(launcher, bundleName, ImmutableSet.<VersionedName>of());
+
+ launcher.terminate();
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
index 1e0e698..89262d5 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
@@ -108,6 +108,32 @@ public class BrooklynVersionSyntax {
*/
}
+ /**
+ * See {@link #toValidOsgiVersion(String)}, but takes a version range (in the standard OSGi format).
+ */
+ public static String toValidOsgiVersionRange(String input) {
+ String beginning = "";
+ String ending = "";
+ if (input.startsWith("[") || input.startsWith("(")) {
+ beginning = input.substring(0, 1);
+ }
+ if (input.endsWith("]") || input.endsWith(")")) {
+ ending = input.substring(input.length() - 1, input.length());
+ }
+ String middle = input.substring(beginning.length(), input.length() - ending.length());
+ String[] middleParts = middle.split(",");
+
+ StringBuilder result = new StringBuilder();
+ result.append(beginning);
+ for (int i = 0; i < middleParts.length; i++) {
+ String middlePart = middleParts[i];
+ if (i != 0) result.append(",");
+ result.append(toValidOsgiVersion(middlePart.trim()));
+ }
+ result.append(ending);
+ return result.toString();
+ }
+
/** Creates a string satisfying {@link #isGoodBrooklynVersion(String)} based on the input.
* For input satisfying {@link #isGoodBrooklynVersion(String)} the input will be returned unchanged.
* For input satisfying {@link #isValidOsgiVersion(String)} the qualifier separator will be changed to "-",
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/98731c21/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
index b938935..1bd8e3a 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
@@ -95,4 +95,19 @@ public class BrooklynVersionSyntaxTest {
// potentially surprising, and different to maven (0.0.0.4aug..)
assertOsgiVersion("4aug2000r7-dev", "4.0.0.aug2000r7-dev");
}
+
+ public void testOsgiVersionRanges() {
+ assertOsgiVersionRange("1.0.0", "1.0.0");
+ assertOsgiVersionRange("[1.0.0,2.0.0)", "[1.0.0,2.0.0)");
+ assertOsgiVersionRange("[1.0.0, 2.0.0)", "[1.0.0,2.0.0)");
+ assertOsgiVersionRange("1.0.0-SNAPSHOT", "1.0.0.SNAPSHOT");
+ assertOsgiVersionRange("[1.0.0-SNAPSHOT]", "[1.0.0.SNAPSHOT]");
+ assertOsgiVersionRange("[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT]", "[1.0.0.SNAPSHOT,2.0.0.SNAPSHOT]");
+ assertOsgiVersionRange("[1.0.0-SNAPSHOT,2.0.0-SNAPSHOT)", "[1.0.0.SNAPSHOT,2.0.0.SNAPSHOT)");
+ assertOsgiVersionRange("(1.0.0-SNAPSHOT,2.0.0-SNAPSHOT]", "(1.0.0.SNAPSHOT,2.0.0.SNAPSHOT]");
+ }
+
+ private void assertOsgiVersionRange(String input, String osgi) {
+ Assert.assertEquals(BrooklynVersionSyntax.toValidOsgiVersionRange(input), osgi, "conversion to valid osgi range");
+ }
}
[3/7] brooklyn-server git commit: Add support for
`force-remove-bundles: *`
Posted by he...@apache.org.
Add support for `force-remove-bundles: *`
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/54ecbf96
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/54ecbf96
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/54ecbf96
Branch: refs/heads/master
Commit: 54ecbf9605154e6f134a73578b6300bcba614a65
Parents: 22fda0d
Author: Aled Sage <al...@gmail.com>
Authored: Wed Oct 25 08:32:50 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Oct 25 08:37:58 2017 +0100
----------------------------------------------------------------------
.../core/typereg/BundleUpgradeParser.java | 30 ++++++++++--
.../core/typereg/BundleUpgradeParserTest.java | 51 ++++++++++++++++----
.../util/text/BrooklynVersionSyntax.java | 14 ++++++
.../util/text/BrooklynVersionSyntaxTest.java | 23 +++++++++
4 files changed, 104 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/54ecbf96/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 96cd2b6..9766514 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
@@ -213,18 +213,33 @@ public class BundleUpgradeParser {
}
public static CatalogUpgrades parseBundleManifestForCatalogUpgrades(Bundle bundle) {
- // TODO Add support for "*" for "force-remove-bundles", to indicate all lower-versioned
- // bundles with the same symbolic name as this bundle. Also add support for the other
- // options described in the proposal:
+ // TODO Add support for the other options described in the proposal:
// https://docs.google.com/document/d/1Lm47Kx-cXPLe8BO34-qrL3ZMPosuUHJILYVQUswEH6Y/edit#
// section "Bundle Upgrade Metadata"
Dictionary<String, String> headers = bundle.getHeaders();
return CatalogUpgrades.builder()
.removedLegacyItems(parseVersionRangedNameList(headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS), false))
- .removedBundles(parseVersionRangedNameList(headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES), false))
+ .removedBundles(parseForceRemoveBundlesHeader(bundle, headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES)))
.build();
}
+
+ @VisibleForTesting
+ static List<VersionRangedName> parseForceRemoveBundlesHeader(Bundle context, String input) {
+ if (input == null) return ImmutableList.of();
+ if (stripQuotes(input).equals("*")) {
+ String bundleVersion = context.getVersion().toString();
+ String maxVersion;
+ if (BrooklynVersionSyntax.isSnapshot(bundleVersion)) {
+ maxVersion = BrooklynVersionSyntax.stripSnapshot(bundleVersion);
+ } else {
+ maxVersion = bundleVersion;
+ }
+ return ImmutableList.of(new VersionRangedName(context.getSymbolicName(), "[0,"+maxVersion+")"));
+ } else {
+ return parseVersionRangedNameList(input, false);
+ }
+ }
@VisibleForTesting
static List<VersionRangedName> parseVersionRangedNameList(String input, boolean singleVersionIsOsgiRange) {
@@ -242,4 +257,11 @@ public class BundleUpgradeParser {
}
return versionedItems;
}
+
+ private static String stripQuotes(String input) {
+ String quoteChars = QuotedStringTokenizer.DEFAULT_QUOTE_CHARS;
+ boolean quoted = (input.length() >= 2) && quoteChars.contains(input.substring(0, 1))
+ && quoteChars.contains(input.substring(input.length() - 1));
+ return (quoted ? input.substring(1, input.length() - 1) : input);
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/54ecbf96/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 143649a..7573bee 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
@@ -28,7 +28,6 @@ import java.util.List;
import java.util.Map;
import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.core.typereg.BundleUpgradeParser;
import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.core.typereg.BundleUpgradeParser.VersionRangedName;
import org.apache.brooklyn.test.Asserts;
@@ -46,6 +45,7 @@ import com.google.common.collect.ImmutableMap;
public class BundleUpgradeParserTest {
private VersionRange from0lessThan1 = new VersionRange('[', Version.valueOf("0"), Version.valueOf("1.0.0"), ')');
+ private VersionRange from0lessThan1_2_3 = new VersionRange('[', Version.valueOf("0"), Version.valueOf("1.2.3"), ')');
private VersionRange exactly0dot1 = new VersionRange('[', Version.valueOf("0.1.0"), Version.valueOf("0.1.0"), ']');
private VersionRangedName fooFrom0lessThan1 = new VersionRangedName("foo", from0lessThan1);
private VersionRangedName barFrom0lessThan1 = new VersionRangedName("bar", from0lessThan1);
@@ -82,28 +82,49 @@ public class BundleUpgradeParserTest {
@Test
public void testParseSingleQuotedVal() throws Exception {
String input = "\"foo:[0,1.0.0)\"";
- assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
+ assertParseList(input, ImmutableList.of(fooFrom0lessThan1));
}
@Test
public void testParseSingleQuotedValWithNestedQuotes() throws Exception {
String input = "\"foo:[0,\"1.0.0\")\"";
- assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
+ assertParseList(input, ImmutableList.of(fooFrom0lessThan1));
}
@Test
public void testParseMultipleVals() throws Exception {
String input = "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"";
- assertParsed(input, ImmutableList.of(fooFrom0lessThan1, barFrom0lessThan1));
+ assertParseList(input, ImmutableList.of(fooFrom0lessThan1, barFrom0lessThan1));
}
@Test
public void testParseValWithExactVersion() throws Exception {
String input = "\"foo:0.1.0\"";
- assertParsed(input, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
+ assertParseList(input, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
}
@Test
+ public void testParseForceRemoveBundlesHeader() throws Exception {
+ Bundle bundle = Mockito.mock(Bundle.class);
+ Mockito.when(bundle.getSymbolicName()).thenReturn("foo.bar");
+ Mockito.when(bundle.getVersion()).thenReturn(Version.valueOf("1.2.3"));
+
+ assertParseForceRemoveBundlesHeader(bundle, "\"foo:0.1.0\"", ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
+ assertParseForceRemoveBundlesHeader(bundle, "\"*\"", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ assertParseForceRemoveBundlesHeader(bundle, "*", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ }
+
+ @Test
+ public void testParseForceRemoveBundlesHeaderWithSnapshot() throws Exception {
+ Bundle bundle = Mockito.mock(Bundle.class);
+ Mockito.when(bundle.getSymbolicName()).thenReturn("foo.bar");
+ Mockito.when(bundle.getVersion()).thenReturn(Version.valueOf("1.2.3.SNAPSHOT"));
+
+ assertParseForceRemoveBundlesHeader(bundle, "\"*\"", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ assertParseForceRemoveBundlesHeader(bundle, "*", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ }
+
+ @Test
public void testParseBundleEmptyManifest() throws Exception {
Bundle bundle = newMockBundle(ImmutableMap.of());
@@ -147,15 +168,25 @@ public class BundleUpgradeParserTest {
return result;
}
- private void assertParsed(String input, List<VersionRangedName> expected) throws Exception {
+ private void assertParseList(String input, List<VersionRangedName> expected) throws Exception {
List<VersionRangedName> actual = BundleUpgradeParser.parseVersionRangedNameList(input, false);
- assertEquals(actual.size(), expected.size(), "actual="+actual);
+ assertListsEqual(actual, expected);
+ }
+
+ private void assertParseForceRemoveBundlesHeader(Bundle bundle, String input, List<VersionRangedName> expected) throws Exception {
+ List<VersionRangedName> actual = BundleUpgradeParser.parseForceRemoveBundlesHeader(bundle, input);
+ assertListsEqual(actual, expected);
+ }
+
+ private void assertListsEqual(List<VersionRangedName> actual, List<VersionRangedName> expected) throws Exception {
+ String errMsg = "actual="+actual;
+ assertEquals(actual.size(), expected.size(), errMsg);
for (int i = 0; i < actual.size(); i++) {
- assertEquals(actual.get(i).getSymbolicName(), expected.get(i).getSymbolicName());
- assertEquals(actual.get(i).getOsgiVersionRange(), expected.get(i).getOsgiVersionRange());
+ assertEquals(actual.get(i).getSymbolicName(), expected.get(i).getSymbolicName(), errMsg);
+ assertEquals(actual.get(i).getOsgiVersionRange(), expected.get(i).getOsgiVersionRange(), errMsg);
}
}
-
+
private void assertVersionRangedNameFails(String input, String expectedFailure, String... optionalOtherExpectedFailures) {
try {
VersionRangedName.fromString(input, false);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/54ecbf96/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java b/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
index 89262d5..6f23489 100644
--- a/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
+++ b/utils/common/src/main/java/org/apache/brooklyn/util/text/BrooklynVersionSyntax.java
@@ -225,4 +225,18 @@ public class BrooklynVersionSyntax {
return version.toUpperCase().contains(SNAPSHOT);
}
+ /**
+ * Returns the version without "SNAPSHOT" (normally this will return the next expected release version).
+ * For example, "1.0.0.SNAPSHOT" or "1.0.0-SNAPSHOT" becomes "1.0.0".
+ */
+ public static String stripSnapshot(String input) {
+ if (input==null) return input;
+ int stripIndex = input.toUpperCase().indexOf(SNAPSHOT);
+ if (stripIndex <= 0) return input;
+ char charBeforeSnapshot = input.charAt(stripIndex - 1);
+ if (charBeforeSnapshot == '.' || charBeforeSnapshot == '_' || charBeforeSnapshot == '-') {
+ stripIndex--;
+ }
+ return (stripIndex <= 0) ? input : input.substring(0, stripIndex);
+ }
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/54ecbf96/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java b/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
index 1bd8e3a..4fa02d6 100644
--- a/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
+++ b/utils/common/src/test/java/org/apache/brooklyn/util/text/BrooklynVersionSyntaxTest.java
@@ -107,6 +107,29 @@ public class BrooklynVersionSyntaxTest {
assertOsgiVersionRange("(1.0.0-SNAPSHOT,2.0.0-SNAPSHOT]", "(1.0.0.SNAPSHOT,2.0.0.SNAPSHOT]");
}
+ public void testIsSnapshot() {
+ Assert.assertTrue(BrooklynVersionSyntax.isSnapshot("1.0.0.SNAPSHOT"));
+ Assert.assertTrue(BrooklynVersionSyntax.isSnapshot("1.0.0.20171025_SNAPSHOT"));
+ Assert.assertTrue(BrooklynVersionSyntax.isSnapshot("1.0.0-SNAPSHOT"));
+ Assert.assertFalse(BrooklynVersionSyntax.isSnapshot("1.0.0"));
+ }
+
+ public void testStripSnapshot() {
+ assertStripSnapshot("1.0.0.SNAPSHOT", "1.0.0");
+ assertStripSnapshot("1.0.0-SNAPSHOT", "1.0.0");
+ assertStripSnapshot("1-SNAPSHOT", "1");
+ assertStripSnapshot("1.0.0.20171025_SNAPSHOT", "1.0.0.20171025");
+ assertStripSnapshot("1.0.0", "1.0.0");
+
+ // for weird things, don't make them even weirder!
+ assertStripSnapshot("SNAPSHOT", "SNAPSHOT");
+ assertStripSnapshot("_SNAPSHOT", "_SNAPSHOT");
+ }
+
+ private void assertStripSnapshot(String input, String expected) {
+ Assert.assertEquals(BrooklynVersionSyntax.stripSnapshot(input), expected, "conversion to strip snapshot");
+ }
+
private void assertOsgiVersionRange(String input, String osgi) {
Assert.assertEquals(BrooklynVersionSyntax.toValidOsgiVersionRange(input), osgi, "conversion to valid osgi range");
}
[5/7] brooklyn-server git commit: Add support for
`force-remove-legacy-items: *`
Posted by he...@apache.org.
Add support for `force-remove-legacy-items: *`
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/2cd4e087
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/2cd4e087
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/2cd4e087
Branch: refs/heads/master
Commit: 2cd4e0879201586bd406e3f21e4ce95dd3de64d8
Parents: 54ecbf9
Author: Aled Sage <al...@gmail.com>
Authored: Wed Oct 25 16:31:07 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Oct 25 16:31:07 2017 +0100
----------------------------------------------------------------------
.../catalog/internal/CatalogInitialization.java | 25 ++++++-
.../core/typereg/BundleUpgradeParser.java | 61 +++++++++++++---
.../core/typereg/BundleUpgradeParserTest.java | 74 ++++++++++++++++----
3 files changed, 134 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2cd4e087/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
index 107a6b2..225e3fd 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
import org.apache.brooklyn.api.mgmt.rebind.RebindExceptionHandler;
import org.apache.brooklyn.api.objs.BrooklynObjectType;
+import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
import org.apache.brooklyn.api.typereg.ManagedBundle;
import org.apache.brooklyn.api.typereg.RegisteredType;
@@ -49,9 +50,9 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
import org.apache.brooklyn.core.typereg.BundleUpgradeParser;
+import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
-import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
@@ -75,6 +76,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Stopwatch;
+import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -576,7 +578,10 @@ public class CatalogInitialization implements ManagementContextInjectable {
for (ManagedBundle managedBundle : managedBundles) {
Maybe<Bundle> bundle = osgiManager.get().findBundle(managedBundle);
if (bundle.isPresent()) {
- catalogUpgradesBuilder.addAll(BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle.get()));
+ CatalogUpgrades catalogUpgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(
+ bundle.get(),
+ new RegisteredTypesSupplier(managementContext, managedBundle));
+ catalogUpgradesBuilder.addAll(catalogUpgrades);
} else {
rebindLogger.info("Managed bundle "+managedBundle.getId()+" not found by OSGi Manager; "
+ "ignoring when calculating persisted state catalog upgrades");
@@ -584,7 +589,21 @@ public class CatalogInitialization implements ManagementContextInjectable {
}
return catalogUpgradesBuilder.build();
}
-
+
+ private static class RegisteredTypesSupplier implements Supplier<Iterable<RegisteredType>> {
+ private final BrooklynTypeRegistry typeRegistry;
+ private final ManagedBundle bundle;
+
+ RegisteredTypesSupplier(ManagementContext mgmt, ManagedBundle bundle) {
+ this.typeRegistry = mgmt.getTypeRegistry();
+ this.bundle = bundle;
+ }
+ @Override
+ public Iterable<RegisteredType> get() {
+ return typeRegistry.getMatching(RegisteredTypePredicates.containingBundle(bundle));
+ }
+ }
+
public interface RebindLogger {
void debug(String message, Object... args);
void info(String message, Object... args);
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2cd4e087/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 9766514..69bd583 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
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Set;
import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.util.osgi.VersionedName;
import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
import org.apache.brooklyn.util.text.QuotedStringTokenizer;
@@ -38,6 +39,7 @@ import org.osgi.framework.VersionRange;
import com.google.common.annotations.Beta;
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.ImmutableSet;
@@ -50,6 +52,19 @@ public class BundleUpgradeParser {
* A header in a bundle's manifest, indicating that this bundle will force the removal of the
* given legacy catalog items. Here "legacy" means those in the `/catalog` persisted state,
* rather than items added in bundles.
+ *
+ * The format for the value is one of:
+ * <ul>
+ * <li>Quoted {@code name:versionRange}, where version range follows the OSGi conventions
+ * (except that a single version number means exactly that version rather than greater
+ * than or equal to that verison). For example, {@code "my-tomcat:[0,1)"}
+ * <li>Comma-separated list of quoted {@code name:versionRange}. For example,
+ * {@code "my-tomcat:[0,1)","my-nginx:[0,1)"}
+ * <li>{@code "*"} means all legacy items for things defined in this bundle, with version
+ * numbers older than the version of the bundle. For example, if the bundle is
+ * version 1.0.0 and its catalog.bom contains items "foo" and "bar", then it is equivalent
+ * to writing {@code "foo:[0,1.0.0)","bar:[0,1.0.0)"}
+ * </ul>
*/
@Beta
public static final String MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS = "brooklyn-catalog-force-remove-legacy-items";
@@ -57,6 +72,19 @@ public class BundleUpgradeParser {
/**
* A header in a bundle's manifest, indicating that this bundle will force the removal of matching
* bundle(s) that are in the `/bundles` persisted state.
+ *
+ * The format for the value is one of:
+ * <ul>
+ * <li>Quoted {@code name:versionRange}, where version range follows the OSGi conventions
+ * (except that a single version number means exactly that version rather than greater
+ * than or equal to that verison). For example, {@code "org.example.mybundle:[0,1)"}
+ * <li>Comma-separated list of quoted {@code name:versionRange}. For example,
+ * {@code "org.example.mybundle:[0,1)","org.example.myotherbundle:[0,1)"} (useful for
+ * when this bundle merges the contents of two previous bundles).
+ * <li>{@code "*"} means all older versions of this bundle. For example, if the bundle is
+ * {@code org.example.mybundle:1.0.0}, then it is equivalent to writing
+ * {@code "org.example.mybundle:[0,1.0.0)"}
+ * </ul>
*/
@Beta
public static final String MANIFEST_HEADER_FORCE_REMOVE_BUNDLES = "brooklyn-catalog-force-remove-bundles";
@@ -212,30 +240,46 @@ public class BundleUpgradeParser {
}
}
- public static CatalogUpgrades parseBundleManifestForCatalogUpgrades(Bundle bundle) {
+ public static CatalogUpgrades parseBundleManifestForCatalogUpgrades(Bundle bundle, Supplier<? extends Iterable<? extends RegisteredType>> typeSupplier) {
// TODO Add support for the other options described in the proposal:
// https://docs.google.com/document/d/1Lm47Kx-cXPLe8BO34-qrL3ZMPosuUHJILYVQUswEH6Y/edit#
// section "Bundle Upgrade Metadata"
Dictionary<String, String> headers = bundle.getHeaders();
return CatalogUpgrades.builder()
- .removedLegacyItems(parseVersionRangedNameList(headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS), false))
- .removedBundles(parseForceRemoveBundlesHeader(bundle, headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES)))
+ .removedLegacyItems(parseForceRemoveLegacyItemsHeader(headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS), bundle, typeSupplier))
+ .removedBundles(parseForceRemoveBundlesHeader(headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES), bundle))
.build();
}
@VisibleForTesting
- static List<VersionRangedName> parseForceRemoveBundlesHeader(Bundle context, String input) {
+ static List<VersionRangedName> parseForceRemoveLegacyItemsHeader(String input, Bundle bundle, Supplier<? extends Iterable<? extends RegisteredType>> typeSupplier) {
+ if (input == null) return ImmutableList.of();
+ if (stripQuotes(input.trim()).equals("*")) {
+ VersionRange versionRange = VersionRange.valueOf("[0,"+bundle.getVersion()+")");
+ List<VersionRangedName> result = new ArrayList<>();
+ for (RegisteredType item : typeSupplier.get()) {
+ result.add(new VersionRangedName(item.getSymbolicName(), versionRange));
+ }
+ return result;
+ } else {
+ return parseVersionRangedNameList(input, false);
+ }
+ }
+
+
+ @VisibleForTesting
+ static List<VersionRangedName> parseForceRemoveBundlesHeader(String input, Bundle bundle) {
if (input == null) return ImmutableList.of();
- if (stripQuotes(input).equals("*")) {
- String bundleVersion = context.getVersion().toString();
+ if (stripQuotes(input.trim()).equals("*")) {
+ String bundleVersion = bundle.getVersion().toString();
String maxVersion;
if (BrooklynVersionSyntax.isSnapshot(bundleVersion)) {
maxVersion = BrooklynVersionSyntax.stripSnapshot(bundleVersion);
} else {
maxVersion = bundleVersion;
}
- return ImmutableList.of(new VersionRangedName(context.getSymbolicName(), "[0,"+maxVersion+")"));
+ return ImmutableList.of(new VersionRangedName(bundle.getSymbolicName(), "[0,"+maxVersion+")"));
} else {
return parseVersionRangedNameList(input, false);
}
@@ -258,7 +302,8 @@ public class BundleUpgradeParser {
return versionedItems;
}
- private static String stripQuotes(String input) {
+ @VisibleForTesting
+ static String stripQuotes(String input) {
String quoteChars = QuotedStringTokenizer.DEFAULT_QUOTE_CHARS;
boolean quoted = (input.length() >= 2) && quoteChars.contains(input.substring(0, 1))
&& quoteChars.contains(input.substring(input.length() - 1));
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2cd4e087/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 7573bee..341cccb 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
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.core.typereg.BundleUpgradeParser.VersionRangedName;
import org.apache.brooklyn.test.Asserts;
@@ -39,6 +40,8 @@ import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
import org.testng.annotations.Test;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -105,30 +108,39 @@ public class BundleUpgradeParserTest {
@Test
public void testParseForceRemoveBundlesHeader() throws Exception {
- Bundle bundle = Mockito.mock(Bundle.class);
- Mockito.when(bundle.getSymbolicName()).thenReturn("foo.bar");
- Mockito.when(bundle.getVersion()).thenReturn(Version.valueOf("1.2.3"));
+ Bundle bundle = newMockBundle(new VersionedName("foo.bar", "1.2.3"));
- assertParseForceRemoveBundlesHeader(bundle, "\"foo:0.1.0\"", ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
- assertParseForceRemoveBundlesHeader(bundle, "\"*\"", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
- assertParseForceRemoveBundlesHeader(bundle, "*", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ assertParseForceRemoveBundlesHeader("\"foo:0.1.0\"", bundle, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
+ assertParseForceRemoveBundlesHeader("\"*\"", bundle, ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ assertParseForceRemoveBundlesHeader("*", bundle, ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
}
@Test
public void testParseForceRemoveBundlesHeaderWithSnapshot() throws Exception {
- Bundle bundle = Mockito.mock(Bundle.class);
- Mockito.when(bundle.getSymbolicName()).thenReturn("foo.bar");
- Mockito.when(bundle.getVersion()).thenReturn(Version.valueOf("1.2.3.SNAPSHOT"));
+ Bundle bundle = newMockBundle(new VersionedName("foo.bar", "1.2.3.SNAPSHOT"));
- assertParseForceRemoveBundlesHeader(bundle, "\"*\"", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
- assertParseForceRemoveBundlesHeader(bundle, "*", ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ assertParseForceRemoveBundlesHeader("\"*\"", bundle, ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ assertParseForceRemoveBundlesHeader("*", bundle, ImmutableList.of(new VersionRangedName("foo.bar", from0lessThan1_2_3)));
+ }
+
+ @Test
+ public void testParseForceRemoveLegacyItemsHeader() throws Exception {
+ Bundle bundle = newMockBundle(new VersionedName("mybundle", "1.0.0"));
+ Supplier<Iterable<RegisteredType>> typeSupplier = Suppliers.ofInstance(ImmutableList.of(
+ newMockRegisteredType("foo", "1.0.0"),
+ newMockRegisteredType("bar", "1.0.0")));
+
+ assertParseForceRemoveLegacyItemsHeader("\"foo:0.1.0\"", bundle, typeSupplier, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
+ assertParseForceRemoveLegacyItemsHeader("\"*\"", bundle, typeSupplier, ImmutableList.of(new VersionRangedName("foo", from0lessThan1), new VersionRangedName("bar", from0lessThan1)));
+ assertParseForceRemoveLegacyItemsHeader("*", bundle, typeSupplier, ImmutableList.of(new VersionRangedName("foo", from0lessThan1), new VersionRangedName("bar", from0lessThan1)));
}
@Test
public void testParseBundleEmptyManifest() throws Exception {
Bundle bundle = newMockBundle(ImmutableMap.of());
+ Supplier<Iterable<RegisteredType>> typeSupplier = Suppliers.ofInstance(ImmutableList.of());
- CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
+ CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, typeSupplier);
assertTrue(upgrades.isEmpty());
assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
@@ -139,8 +151,9 @@ public class BundleUpgradeParserTest {
Bundle bundle = newMockBundle(ImmutableMap.of(
BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"",
BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
+ Supplier<Iterable<RegisteredType>> typeSupplier = Suppliers.ofInstance(ImmutableList.of());
- CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
+ CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle, typeSupplier);
assertFalse(upgrades.isEmpty());
assertTrue(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "1.0.0")));
@@ -152,10 +165,36 @@ public class BundleUpgradeParserTest {
assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("different", "0.1.0")));
}
+ @Test
+ public void testStripQuotes() throws Exception {
+ assertEquals(BundleUpgradeParser.stripQuotes("a"), "a");
+ assertEquals(BundleUpgradeParser.stripQuotes("'a'"), "a");
+ assertEquals(BundleUpgradeParser.stripQuotes("\"\""), "");
+ assertEquals(BundleUpgradeParser.stripQuotes("''"), "");
+ }
+
private Bundle newMockBundle(Map<String, String> rawHeaders) {
+ return newMockBundle(VersionedName.fromString("do.no.care:1.2.3"), rawHeaders);
+ }
+
+ private Bundle newMockBundle(VersionedName name) {
+ return newMockBundle(name, ImmutableMap.of());
+ }
+
+ private Bundle newMockBundle(VersionedName name, Map<String, String> rawHeaders) {
Dictionary<String, String> headers = new Hashtable<>(rawHeaders);
Bundle result = Mockito.mock(Bundle.class);
Mockito.when(result.getHeaders()).thenReturn(headers);
+ Mockito.when(result.getSymbolicName()).thenReturn(name.getSymbolicName());
+ Mockito.when(result.getVersion()).thenReturn(Version.valueOf(name.getOsgiVersionString()));
+ return result;
+ }
+
+ private RegisteredType newMockRegisteredType(String symbolicName, String version) {
+ RegisteredType result = Mockito.mock(RegisteredType.class);
+ Mockito.when(result.getSymbolicName()).thenReturn(symbolicName);
+ Mockito.when(result.getVersion()).thenReturn(version);
+ Mockito.when(result.getVersionedName()).thenReturn(new VersionedName(symbolicName, version));
return result;
}
@@ -173,8 +212,13 @@ public class BundleUpgradeParserTest {
assertListsEqual(actual, expected);
}
- private void assertParseForceRemoveBundlesHeader(Bundle bundle, String input, List<VersionRangedName> expected) throws Exception {
- List<VersionRangedName> actual = BundleUpgradeParser.parseForceRemoveBundlesHeader(bundle, input);
+ private void assertParseForceRemoveBundlesHeader(String input, Bundle bundle, List<VersionRangedName> expected) throws Exception {
+ List<VersionRangedName> actual = BundleUpgradeParser.parseForceRemoveBundlesHeader(input, bundle);
+ assertListsEqual(actual, expected);
+ }
+
+ private void assertParseForceRemoveLegacyItemsHeader(String input, Bundle bundle, Supplier<? extends Iterable<? extends RegisteredType>> typeSupplier, List<VersionRangedName> expected) throws Exception {
+ List<VersionRangedName> actual = BundleUpgradeParser.parseForceRemoveLegacyItemsHeader(input, bundle, typeSupplier);
assertListsEqual(actual, expected);
}
[7/7] brooklyn-server git commit: This closes #866
Posted by he...@apache.org.
This closes #866
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/9045005d
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/9045005d
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/9045005d
Branch: refs/heads/master
Commit: 9045005ddeb89cedebf626d6d6a2b2fef50c27dd
Parents: 05d6ee0 2ecdf6a
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Oct 27 11:56:50 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Oct 27 11:56:50 2017 +0100
----------------------------------------------------------------------
.../catalog/internal/CatalogInitialization.java | 87 +++++-
.../core/mgmt/rebind/RebindIteration.java | 18 +-
.../core/typereg/BundleUpgradeParser.java | 312 +++++++++++++++++++
.../core/typereg/BundleUpgradeParserTest.java | 242 ++++++++++++++
.../AbstractBrooklynLauncherRebindTest.java | 196 +++++++++++-
.../BrooklynLauncherRebindCatalogOsgiTest.java | 47 ---
.../BrooklynLauncherUpgradeCatalogOsgiTest.java | 147 +++++++++
.../util/text/BrooklynVersionSyntax.java | 40 +++
.../util/text/BrooklynVersionSyntaxTest.java | 38 +++
9 files changed, 1064 insertions(+), 63 deletions(-)
----------------------------------------------------------------------
[6/7] brooklyn-server git commit: rebind complete: log how many
catalog bundles
Posted by he...@apache.org.
rebind complete: log how many catalog bundles
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/2ecdf6af
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/2ecdf6af
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/2ecdf6af
Branch: refs/heads/master
Commit: 2ecdf6afa5f79f6edd64d4f02b90dc9dbeeb04dd
Parents: 2cd4e08
Author: Aled Sage <al...@gmail.com>
Authored: Fri Oct 27 09:41:41 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Fri Oct 27 09:41:41 2017 +0100
----------------------------------------------------------------------
.../org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2ecdf6af/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 3038429..755107a 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
@@ -761,14 +761,15 @@ public abstract class RebindIteration {
if (!isEmpty) {
BrooklynLogging.log(LOG, shouldLogRebinding() ? LoggingLevel.INFO : LoggingLevel.DEBUG,
"Rebind complete " + "("+mode+(readOnlyRebindCount.get()>=0 ? ", iteration "+readOnlyRebindCount : "")+")" +
- " in {}: {} app{}, {} entit{}, {} location{}, {} polic{}, {} enricher{}, {} feed{}, {} catalog item{}",
+ " in {}: {} app{}, {} entit{}, {} location{}, {} polic{}, {} enricher{}, {} feed{}, {} catalog item{}, {} catalog bundle{}",
Time.makeTimeStringRounded(timer), applications.size(), Strings.s(applications),
rebindContext.getEntities().size(), Strings.ies(rebindContext.getEntities()),
rebindContext.getLocations().size(), Strings.s(rebindContext.getLocations()),
rebindContext.getPolicies().size(), Strings.ies(rebindContext.getPolicies()),
rebindContext.getEnrichers().size(), Strings.s(rebindContext.getEnrichers()),
rebindContext.getFeeds().size(), Strings.s(rebindContext.getFeeds()),
- rebindContext.getCatalogItems().size(), Strings.s(rebindContext.getCatalogItems())
+ rebindContext.getCatalogItems().size(), Strings.s(rebindContext.getCatalogItems()),
+ rebindContext.getBundles().size(), Strings.s(rebindContext.getBundles())
);
}
[4/7] brooklyn-server git commit: PR #866: incorporate comments for
bundle-upgrade
Posted by he...@apache.org.
PR #866: incorporate comments for bundle-upgrade
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/22fda0dd
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/22fda0dd
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/22fda0dd
Branch: refs/heads/master
Commit: 22fda0dd7980ea3456b3b3e7f5687d9271fdcf32
Parents: dba226f
Author: Aled Sage <al...@gmail.com>
Authored: Wed Oct 25 07:41:54 2017 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Oct 25 08:37:58 2017 +0100
----------------------------------------------------------------------
.../catalog/internal/BundleUpgradeParser.java | 239 ------------------
.../catalog/internal/CatalogInitialization.java | 16 +-
.../core/typereg/BundleUpgradeParser.java | 245 +++++++++++++++++++
.../internal/BundleUpgradeParserTest.java | 148 -----------
.../core/typereg/BundleUpgradeParserTest.java | 167 +++++++++++++
.../BrooklynLauncherUpgradeCatalogOsgiTest.java | 4 +-
6 files changed, 425 insertions(+), 394 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22fda0dd/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
deleted file mode 100644
index 0773014..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParser.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * 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.catalog.internal;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.util.osgi.VersionedName;
-import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
-import org.apache.brooklyn.util.text.QuotedStringTokenizer;
-import org.apache.brooklyn.util.text.Strings;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.VersionRange;
-
-import com.google.common.annotations.Beta;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class BundleUpgradeParser {
-
- @Beta
- public static final String MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS = "brooklyn-catalog-force-remove-legacy-items";
-
- @Beta
- public static final String MANIFEST_HEADER_FORCE_REMOVE_BUNDLES = "brooklyn-catalog-force-remove-bundles";
-
- @Beta
- public static final String MANIFEST_HEADER_UPGRADE_BUNDLES = "brooklyn-catalog-upgrade-for-bundles";
-
- /**
- * The result from parsing bundle(s) to find their upgrade info.
- */
- public static class CatalogUpgrades {
- static final CatalogUpgrades EMPTY = new CatalogUpgrades(builder());
-
- static class Builder {
- private Set<VersionRangedName> removedLegacyItems = new LinkedHashSet<>();
- private Set<VersionRangedName> removedBundles = new LinkedHashSet<>();
-
- public Builder removedLegacyItems(Collection<VersionRangedName> vals) {
- removedLegacyItems.addAll(vals);
- return this;
- }
- public Builder removedBundles(Collection<VersionRangedName> vals) {
- removedBundles.addAll(vals);
- return this;
- }
- public Builder addAll(CatalogUpgrades other) {
- removedLegacyItems.addAll(other.removedLegacyItems);
- removedBundles.addAll(other.removedBundles);
- return this;
- }
- public CatalogUpgrades build() {
- return new CatalogUpgrades(this);
- }
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- private Set<VersionRangedName> removedLegacyItems;
- private Set<VersionRangedName> removedBundles;
-
- public CatalogUpgrades(Builder builder) {
- this.removedLegacyItems = ImmutableSet.copyOf(builder.removedLegacyItems);
- this.removedBundles = ImmutableSet.copyOf(builder.removedBundles);
- }
-
- public boolean isEmpty() {
- return removedLegacyItems.isEmpty() && removedBundles.isEmpty();
- }
-
- public Set<VersionRangedName> getRemovedLegacyItems() {
- return removedLegacyItems;
- }
-
- public Set<VersionRangedName> getRemovedBundles() {
- return removedBundles;
- }
-
- public boolean isLegacyItemRemoved(CatalogItem<?, ?> legacyCatalogItem) {
- VersionedName name = new VersionedName(legacyCatalogItem.getSymbolicName(), legacyCatalogItem.getVersion());
- return contains(removedLegacyItems, name);
- }
-
- public boolean isBundleRemoved(VersionedName bundle) {
- return contains(removedBundles, bundle);
- }
-
- public boolean contains(Iterable<VersionRangedName> names, VersionedName name) {
- for (VersionRangedName contender : names) {
- if (contender.getSymbolicName().equals(name.getSymbolicName()) && contender.getOsgiVersionRange().includes(name.getOsgiVersion())) {
- return true;
- }
- }
- return false;
- }
- }
-
- /**
- * Records a name (string) and version range (string),
- * with conveniences for pretty-printing and converting to OSGi format.
- *
- * Implementation-wise, this is similar to {@link VersionedName}, but is intended
- * as internal-only so is cut down to only what is needed.
- */
- public static class VersionRangedName {
- private final String name;
- private final String v;
- private transient volatile VersionRange cachedOsgiVersionRange;
-
- public static VersionRangedName fromString(String val, boolean singleVersionIsOsgiRange) {
- if (Strings.isBlank(val)) {
- throw new IllegalArgumentException("Must not be blank");
- }
- String[] parts = val.split(":");
- if (parts.length > 2) {
- throw new IllegalArgumentException("Identifier '"+val+"' has too many parts; max one ':' symbol");
- }
- if (parts.length == 1 || Strings.isBlank(parts[1])) {
- throw new IllegalArgumentException("Identifier '"+val+"' must be of 'name:versionRange' syntax");
- } else if (singleVersionIsOsgiRange || (parts[1].startsWith("(") || parts[1].startsWith("["))) {
- return new VersionRangedName(parts[0], parts[1]);
- } else {
- return new VersionRangedName(parts[0], "["+parts[1]+","+parts[1]+"]");
- }
- }
-
- public VersionRangedName(String name, VersionRange v) {
- this.name = checkNotNull(name, "name").toString();
- this.v = checkNotNull(v, "versionRange").toString();
- }
-
- private VersionRangedName(String name, String v) {
- this.name = checkNotNull(name, "name");
- this.v = checkNotNull(v, "versionRange");
- }
-
- @Override
- public String toString() {
- return name + ":" + v;
- }
-
- public String toOsgiString() {
- return name + ":" + getOsgiVersionRange();
- }
-
- public String getSymbolicName() {
- return name;
- }
-
- public VersionRange getOsgiVersionRange() {
- if (cachedOsgiVersionRange == null) {
- cachedOsgiVersionRange = VersionRange.valueOf(BrooklynVersionSyntax.toValidOsgiVersionRange(v));
- }
- return cachedOsgiVersionRange;
- }
-
- public String getVersionString() {
- return v;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(name, v);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof VersionRangedName)) {
- return false;
- }
- VersionRangedName o = (VersionRangedName) other;
- return Objects.equal(name, o.name) && Objects.equal(v, o.v);
- }
- }
-
- public static CatalogUpgrades parseBundleManifestForCatalogUpgrades(Bundle bundle) {
- Dictionary<String, String> headers = bundle.getHeaders();
- String removedLegacyItemsHeader = headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS);
- String removedBundlesHeader = headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES);
- List<VersionRangedName> removedLegacyItems = ImmutableList.of();
- List<VersionRangedName> removedBundles = ImmutableList.of();
- if (removedLegacyItemsHeader == null && removedBundlesHeader == null) {
- return CatalogUpgrades.EMPTY;
- }
- if (removedLegacyItemsHeader != null) {
- removedLegacyItems = parseVersionRangedNameList(removedLegacyItemsHeader, false);
- }
- if (removedBundlesHeader != null) {
- removedBundles = parseVersionRangedNameList(removedBundlesHeader, false);
- }
- return CatalogUpgrades.builder()
- .removedLegacyItems(removedLegacyItems)
- .removedBundles(removedBundles)
- .build();
- }
-
- @VisibleForTesting
- static List<VersionRangedName> parseVersionRangedNameList(String input, boolean singleVersionIsOsgiRange) {
- List<String> vals = QuotedStringTokenizer.builder()
- .delimiterChars(",")
- .includeQuotes(false)
- .includeDelimiters(false)
- .buildList(input);
-
- List<VersionRangedName> versionedItems = new ArrayList<>();
- for (String val : vals) {
- versionedItems.add(VersionRangedName.fromString(val, singleVersionIsOsgiRange));
- }
- return versionedItems;
- }
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22fda0dd/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
index 9f9da67..107a6b2 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogInitialization.java
@@ -42,15 +42,16 @@ import org.apache.brooklyn.api.objs.BrooklynObjectType;
import org.apache.brooklyn.api.typereg.BrooklynTypeRegistry.RegisteredTypeKind;
import org.apache.brooklyn.api.typereg.ManagedBundle;
import org.apache.brooklyn.api.typereg.RegisteredType;
-import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult;
import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.core.typereg.BundleUpgradeParser;
import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
+import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
@@ -236,7 +237,7 @@ public class CatalogInitialization implements ManagementContextInjectable {
populateInitialCatalogImpl(true);
- PersistedCatalogState filteredPersistedState = filterPersistedState(persistedState, rebindLogger);
+ PersistedCatalogState filteredPersistedState = filterBundlesAndCatalogInPersistedState(persistedState, rebindLogger);
addPersistedCatalogImpl(filteredPersistedState, exceptionHandler, rebindLogger);
if (mode == ManagementNodeState.MASTER) {
@@ -528,8 +529,13 @@ public class CatalogInitialization implements ManagementContextInjectable {
}
}
- private PersistedCatalogState filterPersistedState(PersistedCatalogState persistedState, RebindLogger rebindLogger) {
- CatalogUpgrades catalogUpgrades = findCatalogUpgrades(rebindLogger);
+ private PersistedCatalogState filterBundlesAndCatalogInPersistedState(PersistedCatalogState persistedState, RebindLogger rebindLogger) {
+ // TODO Will need to share the results of `findCatalogUpgrades` when we support
+ // other options, such as, `brooklyn-catalog-upgrade-for-bundles`, described in the proposal:
+ // https://docs.google.com/document/d/1Lm47Kx-cXPLe8BO34-qrL3ZMPosuUHJILYVQUswEH6Y/edit#
+ // section "Bundle Upgrade Metadata"
+
+ CatalogUpgrades catalogUpgrades = findCatalogUpgradesInstructions(rebindLogger);
if (catalogUpgrades.isEmpty()) {
return persistedState;
@@ -558,7 +564,7 @@ public class CatalogInitialization implements ManagementContextInjectable {
return new PersistedCatalogState(bundles, legacyCatalogItems);
}
- private CatalogUpgrades findCatalogUpgrades(RebindLogger rebindLogger) {
+ private CatalogUpgrades findCatalogUpgradesInstructions(RebindLogger rebindLogger) {
Maybe<OsgiManager> osgiManager = ((ManagementContextInternal)managementContext).getOsgiManager();
if (osgiManager.isAbsent()) {
// Can't find any bundles to tell if there are upgrades. Could be running tests; do no filtering.
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22fda0dd/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
new file mode 100644
index 0000000..96cd2b6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BundleUpgradeParser.java
@@ -0,0 +1,245 @@
+/*
+ * 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.typereg;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.util.osgi.VersionedName;
+import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
+import org.apache.brooklyn.util.text.QuotedStringTokenizer;
+import org.apache.brooklyn.util.text.Strings;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.VersionRange;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Internal class for parsing bundle manifests to extract their upgrade instructions.
+ */
+public class BundleUpgradeParser {
+
+ /**
+ * A header in a bundle's manifest, indicating that this bundle will force the removal of the
+ * given legacy catalog items. Here "legacy" means those in the `/catalog` persisted state,
+ * rather than items added in bundles.
+ */
+ @Beta
+ public static final String MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS = "brooklyn-catalog-force-remove-legacy-items";
+
+ /**
+ * A header in a bundle's manifest, indicating that this bundle will force the removal of matching
+ * bundle(s) that are in the `/bundles` persisted state.
+ */
+ @Beta
+ public static final String MANIFEST_HEADER_FORCE_REMOVE_BUNDLES = "brooklyn-catalog-force-remove-bundles";
+
+ /**
+ * The result from parsing bundle(s) to find their upgrade info.
+ */
+ public static class CatalogUpgrades {
+ public static final CatalogUpgrades EMPTY = new CatalogUpgrades(builder());
+
+ public static class Builder {
+ private Set<VersionRangedName> removedLegacyItems = new LinkedHashSet<>();
+ private Set<VersionRangedName> removedBundles = new LinkedHashSet<>();
+
+ public Builder removedLegacyItems(Collection<VersionRangedName> vals) {
+ removedLegacyItems.addAll(vals);
+ return this;
+ }
+ public Builder removedBundles(Collection<VersionRangedName> vals) {
+ removedBundles.addAll(vals);
+ return this;
+ }
+ public Builder addAll(CatalogUpgrades other) {
+ removedLegacyItems.addAll(other.removedLegacyItems);
+ removedBundles.addAll(other.removedBundles);
+ return this;
+ }
+ public CatalogUpgrades build() {
+ return new CatalogUpgrades(this);
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ private final Set<VersionRangedName> removedLegacyItems;
+ private final Set<VersionRangedName> removedBundles;
+
+ public CatalogUpgrades(Builder builder) {
+ this.removedLegacyItems = ImmutableSet.copyOf(builder.removedLegacyItems);
+ this.removedBundles = ImmutableSet.copyOf(builder.removedBundles);
+ }
+
+ public boolean isEmpty() {
+ return removedLegacyItems.isEmpty() && removedBundles.isEmpty();
+ }
+
+ public Set<VersionRangedName> getRemovedLegacyItems() {
+ return removedLegacyItems;
+ }
+
+ public Set<VersionRangedName> getRemovedBundles() {
+ return removedBundles;
+ }
+
+ public boolean isLegacyItemRemoved(CatalogItem<?, ?> legacyCatalogItem) {
+ VersionedName name = new VersionedName(legacyCatalogItem.getSymbolicName(), legacyCatalogItem.getVersion());
+ return contains(removedLegacyItems, name);
+ }
+
+ public boolean isBundleRemoved(VersionedName bundle) {
+ return contains(removedBundles, bundle);
+ }
+
+ public boolean contains(Iterable<VersionRangedName> names, VersionedName name) {
+ for (VersionRangedName contender : names) {
+ if (contender.getSymbolicName().equals(name.getSymbolicName()) && contender.getOsgiVersionRange().includes(name.getOsgiVersion())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ /**
+ * Records a name (string) and version range (string),
+ * with conveniences for pretty-printing and converting to OSGi format.
+ *
+ * Implementation-wise, this is similar to {@link VersionedName}, but is intended
+ * as internal-only so is cut down to only what is needed.
+ *
+ * Both the name and the version range are required.
+ */
+ public static class VersionRangedName {
+ private final String name;
+ private final String v;
+ private transient volatile VersionRange cachedOsgiVersionRange;
+
+ public static VersionRangedName fromString(String val, boolean singleVersionIsOsgiRange) {
+ if (Strings.isBlank(val)) {
+ throw new IllegalArgumentException("Must not be blank");
+ }
+ String[] parts = val.split(":");
+ if (parts.length > 2) {
+ throw new IllegalArgumentException("Identifier '"+val+"' has too many parts; max one ':' symbol");
+ }
+ if (parts.length == 1 || Strings.isBlank(parts[1])) {
+ throw new IllegalArgumentException("Identifier '"+val+"' must be of 'name:versionRange' syntax");
+ } else if (singleVersionIsOsgiRange || (parts[1].startsWith("(") || parts[1].startsWith("["))) {
+ return new VersionRangedName(parts[0], parts[1]);
+ } else {
+ return new VersionRangedName(parts[0], "["+parts[1]+","+parts[1]+"]");
+ }
+ }
+
+ public VersionRangedName(String name, VersionRange v) {
+ this.name = checkNotNull(name, "name").toString();
+ this.v = checkNotNull(v, "versionRange").toString();
+ }
+
+ private VersionRangedName(String name, String v) {
+ this.name = checkNotNull(name, "name");
+ this.v = checkNotNull(v, "versionRange");
+ }
+
+ @Override
+ public String toString() {
+ return name + ":" + v;
+ }
+
+ public String toOsgiString() {
+ return name + ":" + getOsgiVersionRange();
+ }
+
+ public String getSymbolicName() {
+ return name;
+ }
+
+ public VersionRange getOsgiVersionRange() {
+ if (cachedOsgiVersionRange == null) {
+ cachedOsgiVersionRange = VersionRange.valueOf(BrooklynVersionSyntax.toValidOsgiVersionRange(v));
+ }
+ return cachedOsgiVersionRange;
+ }
+
+ public String getVersionString() {
+ return v;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, v);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof VersionRangedName)) {
+ return false;
+ }
+ VersionRangedName o = (VersionRangedName) other;
+ return Objects.equal(name, o.name) && Objects.equal(v, o.v);
+ }
+ }
+
+ public static CatalogUpgrades parseBundleManifestForCatalogUpgrades(Bundle bundle) {
+ // TODO Add support for "*" for "force-remove-bundles", to indicate all lower-versioned
+ // bundles with the same symbolic name as this bundle. Also add support for the other
+ // options described in the proposal:
+ // https://docs.google.com/document/d/1Lm47Kx-cXPLe8BO34-qrL3ZMPosuUHJILYVQUswEH6Y/edit#
+ // section "Bundle Upgrade Metadata"
+
+ Dictionary<String, String> headers = bundle.getHeaders();
+ return CatalogUpgrades.builder()
+ .removedLegacyItems(parseVersionRangedNameList(headers.get(MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS), false))
+ .removedBundles(parseVersionRangedNameList(headers.get(MANIFEST_HEADER_FORCE_REMOVE_BUNDLES), false))
+ .build();
+ }
+
+ @VisibleForTesting
+ static List<VersionRangedName> parseVersionRangedNameList(String input, boolean singleVersionIsOsgiRange) {
+ if (input == null) return ImmutableList.of();
+
+ List<String> vals = QuotedStringTokenizer.builder()
+ .delimiterChars(",")
+ .includeQuotes(false)
+ .includeDelimiters(false)
+ .buildList(input);
+
+ List<VersionRangedName> versionedItems = new ArrayList<>();
+ for (String val : vals) {
+ versionedItems.add(VersionRangedName.fromString(val, singleVersionIsOsgiRange));
+ }
+ return versionedItems;
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22fda0dd/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java b/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
deleted file mode 100644
index a409eaf..0000000
--- a/core/src/test/java/org/apache/brooklyn/core/catalog/internal/BundleUpgradeParserTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * 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.catalog.internal;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.catalog.CatalogItem;
-import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.CatalogUpgrades;
-import org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.VersionRangedName;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.osgi.VersionedName;
-import org.mockito.Mockito;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
-import org.osgi.framework.VersionRange;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class BundleUpgradeParserTest {
-
- private VersionRange from0lessThan1 = new VersionRange('[', Version.valueOf("0"), Version.valueOf("1.0.0"), ')');
- private VersionRange exactly0dot1 = new VersionRange('[', Version.valueOf("0.1.0"), Version.valueOf("0.1.0"), ']');
- private VersionRangedName fooFrom0lessThan1 = new VersionRangedName("foo", from0lessThan1);
- private VersionRangedName barFrom0lessThan1 = new VersionRangedName("bar", from0lessThan1);
-
- @Test
- public void testVersionRangedName() throws Exception {
- assertEquals(VersionRangedName.fromString("foo:0.1.0", true).toOsgiString(), "foo:0.1.0");
- assertEquals(VersionRangedName.fromString("foo:0.1.0", false).toOsgiString(), "foo:[0.1.0,0.1.0]");
- assertEquals(VersionRangedName.fromString("foo:[0,1)", false).toOsgiString(), "foo:[0.0.0,1.0.0)");
-
- assertVersionRangedNameFails("foo", "'foo' must be of 'name:versionRange' syntax");
- assertVersionRangedNameFails("foo:bar:0.1.0", "has too many parts");
- assertVersionRangedNameFails("", "Must not be blank");
- assertVersionRangedNameFails(null, "Must not be blank");
- }
-
- @Test
- public void testParseSingleQuotedVal() throws Exception {
- String input = "\"foo:[0,1.0.0)\"";
- assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
- }
-
- @Test
- public void testParseSingleQuotedValWithNestedQuotes() throws Exception {
- String input = "\"foo:[0,\"1.0.0\")\"";
- assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
- }
-
- @Test
- public void testParseMultipleVals() throws Exception {
- String input = "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"";
- assertParsed(input, ImmutableList.of(fooFrom0lessThan1, barFrom0lessThan1));
- }
-
- @Test
- public void testParseValWithExactVersion() throws Exception {
- String input = "\"foo:0.1.0\"";
- assertParsed(input, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
- }
-
- @Test
- public void testParseBundleEmptyManifest() throws Exception {
- Bundle bundle = newMockBundle(ImmutableMap.of());
-
- CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
- assertTrue(upgrades.isEmpty());
- assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
- assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
- }
-
- @Test
- public void testParseBundleManifest() throws Exception {
- Bundle bundle = newMockBundle(ImmutableMap.of(
- BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"",
- BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
-
- CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
- assertFalse(upgrades.isEmpty());
- assertTrue(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
- assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "1.0.0")));
-
- assertTrue(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
- assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "1.0.0")));
- assertTrue(upgrades.isLegacyItemRemoved(newMockCatalogItem("bar", "0.1.0")));
- assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("bar", "1.0.0")));
- assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("different", "0.1.0")));
- }
-
- private Bundle newMockBundle(Map<String, String> rawHeaders) {
- Dictionary<String, String> headers = new Hashtable<>(rawHeaders);
- Bundle result = Mockito.mock(Bundle.class);
- Mockito.when(result.getHeaders()).thenReturn(headers);
- return result;
- }
-
- private CatalogItem<?,?> newMockCatalogItem(String symbolicName, String version) {
- CatalogItem<?,?> result = Mockito.mock(CatalogItem.class);
- Mockito.when(result.getSymbolicName()).thenReturn(symbolicName);
- Mockito.when(result.getVersion()).thenReturn(version);
- Mockito.when(result.getId()).thenReturn(symbolicName+":"+version);
- Mockito.when(result.getCatalogItemId()).thenReturn(symbolicName+":"+version);
- return result;
- }
-
- private void assertParsed(String input, List<VersionRangedName> expected) throws Exception {
- List<VersionRangedName> actual = BundleUpgradeParser.parseVersionRangedNameList(input, false);
- assertEquals(actual.size(), expected.size(), "actual="+actual);
- for (int i = 0; i < actual.size(); i++) {
- assertEquals(actual.get(i).getSymbolicName(), expected.get(i).getSymbolicName());
- assertEquals(actual.get(i).getOsgiVersionRange(), expected.get(i).getOsgiVersionRange());
- }
- }
-
- private void assertVersionRangedNameFails(String input, String expectedFailure, String... optionalOtherExpectedFailures) {
- try {
- VersionRangedName.fromString(input, false);
- Asserts.shouldHaveFailedPreviously();
- } catch (IllegalArgumentException e) {
- Asserts.expectedFailureContains(e, expectedFailure, optionalOtherExpectedFailures);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22fda0dd/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
new file mode 100644
index 0000000..143649a
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/typereg/BundleUpgradeParserTest.java
@@ -0,0 +1,167 @@
+/*
+ * 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.typereg;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.catalog.CatalogItem;
+import org.apache.brooklyn.core.typereg.BundleUpgradeParser;
+import org.apache.brooklyn.core.typereg.BundleUpgradeParser.CatalogUpgrades;
+import org.apache.brooklyn.core.typereg.BundleUpgradeParser.VersionRangedName;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.osgi.VersionedName;
+import org.apache.brooklyn.util.text.BrooklynVersionSyntax;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class BundleUpgradeParserTest {
+
+ private VersionRange from0lessThan1 = new VersionRange('[', Version.valueOf("0"), Version.valueOf("1.0.0"), ')');
+ private VersionRange exactly0dot1 = new VersionRange('[', Version.valueOf("0.1.0"), Version.valueOf("0.1.0"), ']');
+ private VersionRangedName fooFrom0lessThan1 = new VersionRangedName("foo", from0lessThan1);
+ private VersionRangedName barFrom0lessThan1 = new VersionRangedName("bar", from0lessThan1);
+
+ @Test
+ public void testVersionRangedName() throws Exception {
+ assertEquals(VersionRangedName.fromString("foo:0.1.0", true).toOsgiString(), "foo:0.1.0");
+ assertEquals(VersionRangedName.fromString("foo:0.1.0", false).toOsgiString(), "foo:[0.1.0,0.1.0]");
+ assertEquals(VersionRangedName.fromString("foo:[0,1)", false).toOsgiString(), "foo:[0.0.0,1.0.0)");
+
+ assertVersionRangedNameFails("foo", "'foo' must be of 'name:versionRange' syntax");
+ assertVersionRangedNameFails("foo:bar:0.1.0", "has too many parts");
+ assertVersionRangedNameFails("", "Must not be blank");
+ assertVersionRangedNameFails(null, "Must not be blank");
+ }
+
+ @Test
+ public void testVersionRangesWithSnapshots() throws Exception {
+ VersionRange from0lessThan1 = VersionRangedName.fromString("foo:[0,1)", false).getOsgiVersionRange();
+ assertTrue(from0lessThan1.includes(Version.valueOf("0.1.0.SNAPSHOT")));
+ assertTrue(from0lessThan1.includes(Version.valueOf(BrooklynVersionSyntax.toValidOsgiVersion("0.1.0-SNAPSHOT"))));
+ assertTrue(from0lessThan1.includes(Version.valueOf("0.0.0.SNAPSHOT")));
+ assertTrue(from0lessThan1.includes(Version.valueOf(BrooklynVersionSyntax.toValidOsgiVersion("0.0.0-SNAPSHOT"))));
+ assertFalse(from0lessThan1.includes(Version.valueOf("1.0.0.SNAPSHOT")));
+ assertFalse(from0lessThan1.includes(Version.valueOf(BrooklynVersionSyntax.toValidOsgiVersion("1.0.0-SNAPSHOT"))));
+
+ VersionRange from1 = VersionRangedName.fromString("foo:[1,9999)", false).getOsgiVersionRange();
+ assertTrue(from1.includes(Version.valueOf("1.0.0.SNAPSHOT")));
+ assertTrue(from1.includes(Version.valueOf(BrooklynVersionSyntax.toValidOsgiVersion("1.SNAPSHOT"))));
+ assertFalse(from1.includes(Version.valueOf("0.0.0.SNAPSHOT")));
+ assertFalse(from1.includes(Version.valueOf("0.1.0.SNAPSHOT")));
+ }
+
+ @Test
+ public void testParseSingleQuotedVal() throws Exception {
+ String input = "\"foo:[0,1.0.0)\"";
+ assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
+ }
+
+ @Test
+ public void testParseSingleQuotedValWithNestedQuotes() throws Exception {
+ String input = "\"foo:[0,\"1.0.0\")\"";
+ assertParsed(input, ImmutableList.of(fooFrom0lessThan1));
+ }
+
+ @Test
+ public void testParseMultipleVals() throws Exception {
+ String input = "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"";
+ assertParsed(input, ImmutableList.of(fooFrom0lessThan1, barFrom0lessThan1));
+ }
+
+ @Test
+ public void testParseValWithExactVersion() throws Exception {
+ String input = "\"foo:0.1.0\"";
+ assertParsed(input, ImmutableList.of(new VersionRangedName("foo", exactly0dot1)));
+ }
+
+ @Test
+ public void testParseBundleEmptyManifest() throws Exception {
+ Bundle bundle = newMockBundle(ImmutableMap.of());
+
+ CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
+ assertTrue(upgrades.isEmpty());
+ assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
+ }
+
+ @Test
+ public void testParseBundleManifest() throws Exception {
+ Bundle bundle = newMockBundle(ImmutableMap.of(
+ BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS, "\"foo:[0,1.0.0)\",\"bar:[0,1.0.0)\"",
+ BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES, "\"org.example.brooklyn.mybundle:[0,1.0.0)\""));
+
+ CatalogUpgrades upgrades = BundleUpgradeParser.parseBundleManifestForCatalogUpgrades(bundle);
+ assertFalse(upgrades.isEmpty());
+ assertTrue(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "0.1.0")));
+ assertFalse(upgrades.isBundleRemoved(new VersionedName("org.example.brooklyn.mybundle", "1.0.0")));
+
+ assertTrue(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "0.1.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("foo", "1.0.0")));
+ assertTrue(upgrades.isLegacyItemRemoved(newMockCatalogItem("bar", "0.1.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("bar", "1.0.0")));
+ assertFalse(upgrades.isLegacyItemRemoved(newMockCatalogItem("different", "0.1.0")));
+ }
+
+ private Bundle newMockBundle(Map<String, String> rawHeaders) {
+ Dictionary<String, String> headers = new Hashtable<>(rawHeaders);
+ Bundle result = Mockito.mock(Bundle.class);
+ Mockito.when(result.getHeaders()).thenReturn(headers);
+ return result;
+ }
+
+ private CatalogItem<?,?> newMockCatalogItem(String symbolicName, String version) {
+ CatalogItem<?,?> result = Mockito.mock(CatalogItem.class);
+ Mockito.when(result.getSymbolicName()).thenReturn(symbolicName);
+ Mockito.when(result.getVersion()).thenReturn(version);
+ Mockito.when(result.getId()).thenReturn(symbolicName+":"+version);
+ Mockito.when(result.getCatalogItemId()).thenReturn(symbolicName+":"+version);
+ return result;
+ }
+
+ private void assertParsed(String input, List<VersionRangedName> expected) throws Exception {
+ List<VersionRangedName> actual = BundleUpgradeParser.parseVersionRangedNameList(input, false);
+ assertEquals(actual.size(), expected.size(), "actual="+actual);
+ for (int i = 0; i < actual.size(); i++) {
+ assertEquals(actual.get(i).getSymbolicName(), expected.get(i).getSymbolicName());
+ assertEquals(actual.get(i).getOsgiVersionRange(), expected.get(i).getOsgiVersionRange());
+ }
+ }
+
+ private void assertVersionRangedNameFails(String input, String expectedFailure, String... optionalOtherExpectedFailures) {
+ try {
+ VersionRangedName.fromString(input, false);
+ Asserts.shouldHaveFailedPreviously();
+ } catch (IllegalArgumentException e) {
+ Asserts.expectedFailureContains(e, expectedFailure, optionalOtherExpectedFailures);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/22fda0dd/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
----------------------------------------------------------------------
diff --git a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
index 8ef3466..a6f5129 100644
--- a/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
+++ b/launcher/src/test/java/org/apache/brooklyn/launcher/BrooklynLauncherUpgradeCatalogOsgiTest.java
@@ -19,8 +19,8 @@
package org.apache.brooklyn.launcher;
import static org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.CATALOG_BOM;
-import static org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES;
-import static org.apache.brooklyn.core.catalog.internal.BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS;
+import static org.apache.brooklyn.core.typereg.BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_BUNDLES;
+import static org.apache.brooklyn.core.typereg.BundleUpgradeParser.MANIFEST_HEADER_FORCE_REMOVE_LEGACY_ITEMS;
import java.io.File;
import java.net.URI;