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:07 UTC

[5/7] brooklyn-server git commit: Add support for `force-remove-legacy-items: *`

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);
     }