Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id D9858200C53 for ; Mon, 27 Mar 2017 12:35:23 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id D83AB160B5D; Mon, 27 Mar 2017 10:35:23 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 3AC4C160BA1 for ; Mon, 27 Mar 2017 12:35:22 +0200 (CEST) Received: (qmail 59480 invoked by uid 500); 27 Mar 2017 10:35:21 -0000 Mailing-List: contact commits-help@brooklyn.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@brooklyn.apache.org Delivered-To: mailing list commits@brooklyn.apache.org Received: (qmail 59234 invoked by uid 99); 27 Mar 2017 10:35:21 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Mar 2017 10:35:21 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id CE33DE00FF; Mon, 27 Mar 2017 10:35:20 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: geomacy@apache.org To: commits@brooklyn.apache.org Date: Mon, 27 Mar 2017 10:35:24 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [05/12] brooklyn-server git commit: Split out internal classes into their own class (for CatalogBundleTracker and CatalogBundleLoader) archived-at: Mon, 27 Mar 2017 10:35:24 -0000 Split out internal classes into their own class (for CatalogBundleTracker and CatalogBundleLoader) Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/e8cc8d22 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/e8cc8d22 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/e8cc8d22 Branch: refs/heads/master Commit: e8cc8d224b1285ca6bbdb6ba8784e39a3b344c79 Parents: e2fa077 Author: Thomas Bouron Authored: Fri Mar 24 11:34:04 2017 +0000 Committer: Thomas Bouron Committed: Fri Mar 24 11:34:04 2017 +0000 ---------------------------------------------------------------------- .../catalog/internal/CatalogBomScanner.java | 261 +------------------ .../catalog/internal/CatalogBundleLoader.java | 191 ++++++++++++++ .../catalog/internal/CatalogBundleTracker.java | 104 ++++++++ .../rest/resources/CatalogResource.java | 4 +- 4 files changed, 303 insertions(+), 257 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8cc8d22/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java index 1348886..78e7d54 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBomScanner.java @@ -18,37 +18,18 @@ */ package org.apache.brooklyn.core.catalog.internal; -import static org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType.TEMPLATE; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; import java.util.List; -import java.util.Map; -import org.apache.brooklyn.api.catalog.CatalogItem; import org.apache.brooklyn.api.mgmt.ManagementContext; import org.apache.brooklyn.core.BrooklynFeatureEnablement; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.exceptions.Exceptions; -import org.apache.brooklyn.util.stream.Streams; import org.apache.brooklyn.util.text.Strings; -import org.apache.brooklyn.util.yaml.Yamls; import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.BundleEvent; import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.BundleTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; import com.google.common.annotations.Beta; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; /** Scans bundles being added, filtered by a whitelist and blacklist, and adds catalog.bom files to the catalog. * See karaf blueprint.xml for configuration, and tests in dist project. */ @@ -58,30 +39,27 @@ public class CatalogBomScanner { private final String ACCEPT_ALL_BY_DEFAULT = ".*"; private static final Logger LOG = LoggerFactory.getLogger(CatalogBomScanner.class); - private static final String CATALOG_BOM_URL = "catalog.bom"; - private static final String BROOKLYN_CATALOG = "brooklyn.catalog"; - private static final String BROOKLYN_LIBRARIES = "brooklyn.libraries"; private List whiteList = ImmutableList.of(ACCEPT_ALL_BY_DEFAULT); private List blackList = ImmutableList.of(); - private CatalogPopulator catalogTracker; + private CatalogBundleTracker catalogBundleTracker; public void bind(ServiceReference managementContext) throws Exception { if (isEnabled()) { LOG.debug("Binding management context with whiteList [{}] and blacklist [{}]", Strings.join(getWhiteList(), "; "), Strings.join(getBlackList(), "; ")); - catalogTracker = new CatalogPopulator(managementContext); + catalogBundleTracker = new CatalogBundleTracker(this, managementContext); } } public void unbind(ServiceReference managementContext) throws Exception { if (isEnabled()) { LOG.debug("Unbinding management context"); - if (null != catalogTracker) { - CatalogPopulator temp = catalogTracker; - catalogTracker = null; + if (null != catalogBundleTracker) { + CatalogBundleTracker temp = catalogBundleTracker; + catalogBundleTracker = null; temp.close(); } } @@ -91,7 +69,7 @@ public class CatalogBomScanner { return BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_LOAD_BUNDLE_CATALOG_BOM); } - private String[] bundleIds(Bundle bundle) { + public String[] bundleIds(Bundle bundle) { return new String[] { String.valueOf(bundle.getBundleId()), bundle.getSymbolicName(), bundle.getVersion().toString() }; @@ -123,231 +101,4 @@ public class CatalogBomScanner { this.blackList = Strings.parseCsv(blackListText); } - public class CatalogPopulator extends BundleTracker>> { - - private ServiceReference mgmtContextReference; - private BundleContext bundleContext; - private ManagementContext managementContext; - private CatalogBundleLoader catalogBundleLoader; - - public CatalogPopulator(ServiceReference serviceReference) { - super(serviceReference.getBundle().getBundleContext(), Bundle.ACTIVE, null); - this.mgmtContextReference = serviceReference; - open(); - } - - public CatalogPopulator(BundleContext bundleContext, ManagementContext managementContext) { - super(Preconditions.checkNotNull(bundleContext, "bundleContext required; is OSGi running?"), Bundle.ACTIVE, null); - this.bundleContext = bundleContext; - this.managementContext = managementContext; - open(); - } - - @Override - public void open() { - if (mgmtContextReference != null) { - bundleContext = getBundleContext(); - managementContext = getManagementContext(); - catalogBundleLoader = new CatalogBundleLoader(managementContext); - } - super.open(); - } - - @Override - public void close() { - super.close(); - if (mgmtContextReference != null) { - managementContext = null; - getBundleContext().ungetService(mgmtContextReference); - bundleContext = null; - catalogBundleLoader = null; - } - } - - public BundleContext getBundleContext() { - if (bundleContext != null) return bundleContext; - if (mgmtContextReference != null) return mgmtContextReference.getBundle().getBundleContext(); - throw new IllegalStateException("Bundle context or management context reference must be supplied"); - } - - public ManagementContext getManagementContext() { - if (managementContext != null) return managementContext; - if (mgmtContextReference != null) return getBundleContext().getService(mgmtContextReference); - throw new IllegalStateException("Bundle context or management context reference must be supplied"); - } - - /** - * Scans the bundle being added for a catalog.bom file and adds any entries in it to the catalog. - * - * @param bundle The bundle being added to the bundle context. - * @param bundleEvent The event of the addition. - * - * @return The items added to the catalog; these will be tracked by the {@link BundleTracker} mechanism - * and supplied to the {@link #removedBundle(Bundle, BundleEvent, Iterable)} method. - * - * @throws RuntimeException if the catalog items failed to be added to the catalog - */ - @Override - public Iterable> addingBundle(Bundle bundle, BundleEvent bundleEvent) { - return catalogBundleLoader.scanForCatalog(bundle); - } - - /** - * Remove the given entries from the catalog, related to the given bundle. - * - * @param bundle The bundle being removed to the bundle context. - * @param bundleEvent The event of the removal. - * @param items The items being removed - * - * @throws RuntimeException if the catalog items failed to be added to the catalog - */ - @Override - public void removedBundle(Bundle bundle, BundleEvent bundleEvent, Iterable> items) { - if (!items.iterator().hasNext()) { - return; - } - LOG.debug("Unloading catalog BOM entries from {} {} {}", bundleIds(bundle)); - for (CatalogItem item : items) { - LOG.debug("Unloading {} {} from catalog", item.getSymbolicName(), item.getVersion()); - - catalogBundleLoader.removeFromCatalog(item); - } - } - } - - @Beta - public class CatalogBundleLoader { - - private ManagementContext managementContext; - - public CatalogBundleLoader(ManagementContext managementContext) { - this.managementContext = managementContext; - } - - /** - * Scan the given bundle for a catalog.bom and adds it to the catalog. - * - * @param bundle The bundle to add - * @return A list of items added to the catalog - * - * @throws RuntimeException if the catalog items failed to be added to the catalog - */ - public Iterable> scanForCatalog(Bundle bundle) { - - Iterable> catalogItems = MutableList.of(); - - final URL bom = bundle.getResource(CATALOG_BOM_URL); - if (null != bom) { - LOG.debug("Found catalog BOM in {} {} {}", bundleIds(bundle)); - String bomText = readBom(bom); - String bomWithLibraryPath = addLibraryDetails(bundle, bomText); - catalogItems = this.managementContext.getCatalog().addItems(bomWithLibraryPath); - for (CatalogItem item : catalogItems) { - LOG.debug("Added to catalog: {}, {}", item.getSymbolicName(), item.getVersion()); - } - } else { - LOG.debug("No BOM found in {} {} {}", bundleIds(bundle)); - } - - if (!passesWhiteAndBlacklists(bundle)) { - catalogItems = removeAnyApplications(catalogItems); - } - - return catalogItems; - } - - private String readBom(URL bom) { - try (final InputStream ins = bom.openStream()) { - return Streams.readFullyString(ins); - } catch (IOException e) { - throw Exceptions.propagate("Error loading Catalog BOM from " + bom, e); - } - } - - private String addLibraryDetails(Bundle bundle, String bomText) { - @SuppressWarnings("unchecked") - final Map bom = (Map)Iterables.getOnlyElement(Yamls.parseAll(bomText)); - final Object catalog = bom.get(BROOKLYN_CATALOG); - if (null != catalog) { - if (catalog instanceof Map) { - @SuppressWarnings("unchecked") - Map catalogMap = (Map) catalog; - addLibraryDetails(bundle, catalogMap); - } else { - LOG.warn("Unexpected syntax for {} (expected Map, but got {}), ignoring", BROOKLYN_CATALOG, catalog.getClass().getName()); - } - } - final String updatedBom = backToYaml(bom); - LOG.trace("Updated catalog bom:\n{}", updatedBom); - return updatedBom; - } - - private void addLibraryDetails(Bundle bundle, Map catalog) { - if (!catalog.containsKey(BROOKLYN_LIBRARIES)) { - catalog.put(BROOKLYN_LIBRARIES, MutableList.of()); - } - final Object librarySpec = catalog.get(BROOKLYN_LIBRARIES); - if (!(librarySpec instanceof List)) { - throw new RuntimeException("expected " + BROOKLYN_LIBRARIES + " to be a list, but got " - + (librarySpec == null ? "null" : librarySpec.getClass().getName())); - } - @SuppressWarnings("unchecked") - List> libraries = (List>)librarySpec; - if (bundle.getSymbolicName() == null || bundle.getVersion() == null) { - throw new IllegalStateException("Cannot scan "+bundle+" for catalog files: name or version is null"); - } - libraries.add(ImmutableMap.of( - "name", bundle.getSymbolicName(), - "version", bundle.getVersion().toString())); - LOG.debug("library spec is {}", librarySpec); - } - - private String backToYaml(Map bom) { - final DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - options.setPrettyFlow(true); - return new Yaml(options).dump(bom); - } - - private Iterable> removeAnyApplications( - Iterable> catalogItems) { - - List> result = MutableList.of(); - - for (CatalogItem item: catalogItems) { - if (TEMPLATE.equals(item.getCatalogItemType())) { - removeFromCatalog(item); - } else { - result.add(item); - } - } - return result; - } - - private boolean passesWhiteAndBlacklists(Bundle bundle) { - return on(bundle, getWhiteList()) && !on(bundle, getBlackList()); - } - - private boolean on(Bundle bundle, List list) { - for (String candidate : list) { - final String symbolicName = bundle.getSymbolicName(); - if (symbolicName.matches(candidate.trim())) { - return true; - } - } - return false; - } - - private void removeFromCatalog(CatalogItem item) { - try { - this.managementContext.getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion()); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - LOG.warn(Strings.join(new String[] { - "Failed to remove", item.getSymbolicName(), item.getVersion(), "from catalog" - }, " "), e); - } - } - } - } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8cc8d22/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleLoader.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleLoader.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleLoader.java new file mode 100644 index 0000000..20fe5e2 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleLoader.java @@ -0,0 +1,191 @@ +/* + * 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.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType.TEMPLATE; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.Map; + +import org.apache.brooklyn.api.catalog.CatalogItem; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.util.collections.MutableList; +import org.apache.brooklyn.util.exceptions.Exceptions; +import org.apache.brooklyn.util.stream.Streams; +import org.apache.brooklyn.util.text.Strings; +import org.apache.brooklyn.util.yaml.Yamls; +import org.osgi.framework.Bundle; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; + +import com.google.common.annotations.Beta; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; + +@Beta +public class CatalogBundleLoader { + + private static final Logger LOG = LoggerFactory.getLogger(CatalogBundleLoader.class); + private static final String CATALOG_BOM_URL = "catalog.bom"; + private static final String BROOKLYN_CATALOG = "brooklyn.catalog"; + private static final String BROOKLYN_LIBRARIES = "brooklyn.libraries"; + + private CatalogBomScanner catalogBomScanner; + private ManagementContext managementContext; + + public CatalogBundleLoader(CatalogBomScanner catalogBomScanner, ManagementContext managementContext) { + this.catalogBomScanner = catalogBomScanner; + this.managementContext = managementContext; + } + + /** + * Scan the given bundle for a catalog.bom and adds it to the catalog. + * + * @param bundle The bundle to add + * @return A list of items added to the catalog + * @throws RuntimeException if the catalog items failed to be added to the catalog + */ + public Iterable> scanForCatalog(Bundle bundle) { + + Iterable> catalogItems = MutableList.of(); + + final URL bom = bundle.getResource(CatalogBundleLoader.CATALOG_BOM_URL); + if (null != bom) { + LOG.debug("Found catalog BOM in {} {} {}", catalogBomScanner.bundleIds(bundle)); + String bomText = readBom(bom); + String bomWithLibraryPath = addLibraryDetails(bundle, bomText); + catalogItems = this.managementContext.getCatalog().addItems(bomWithLibraryPath); + for (CatalogItem item : catalogItems) { + LOG.debug("Added to catalog: {}, {}", item.getSymbolicName(), item.getVersion()); + } + } else { + LOG.debug("No BOM found in {} {} {}", catalogBomScanner.bundleIds(bundle)); + } + + if (!passesWhiteAndBlacklists(bundle)) { + catalogItems = removeAnyApplications(catalogItems); + } + + return catalogItems; + } + + /** + * Remove the given items from the catalog. + * + * @param item Catalog items to remove + */ + public void removeFromCatalog(CatalogItem item) { + try { + this.managementContext.getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion()); + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + LOG.warn(Strings.join(new String[]{ + "Failed to remove", item.getSymbolicName(), item.getVersion(), "from catalog" + }, " "), e); + } + } + + private String readBom(URL bom) { + try (final InputStream ins = bom.openStream()) { + return Streams.readFullyString(ins); + } catch (IOException e) { + throw Exceptions.propagate("Error loading Catalog BOM from " + bom, e); + } + } + + private String addLibraryDetails(Bundle bundle, String bomText) { + @SuppressWarnings("unchecked") + final Map bom = (Map) Iterables.getOnlyElement(Yamls.parseAll(bomText)); + final Object catalog = bom.get(CatalogBundleLoader.BROOKLYN_CATALOG); + if (null != catalog) { + if (catalog instanceof Map) { + @SuppressWarnings("unchecked") + Map catalogMap = (Map) catalog; + addLibraryDetails(bundle, catalogMap); + } else { + LOG.warn("Unexpected syntax for {} (expected Map, but got {}), ignoring", CatalogBundleLoader.BROOKLYN_CATALOG, catalog.getClass().getName()); + } + } + final String updatedBom = backToYaml(bom); + LOG.trace("Updated catalog bom:\n{}", updatedBom); + return updatedBom; + } + + private void addLibraryDetails(Bundle bundle, Map catalog) { + if (!catalog.containsKey(CatalogBundleLoader.BROOKLYN_LIBRARIES)) { + catalog.put(CatalogBundleLoader.BROOKLYN_LIBRARIES, MutableList.of()); + } + final Object librarySpec = catalog.get(CatalogBundleLoader.BROOKLYN_LIBRARIES); + if (!(librarySpec instanceof List)) { + throw new RuntimeException("expected " + CatalogBundleLoader.BROOKLYN_LIBRARIES + " to be a list, but got " + + (librarySpec == null ? "null" : librarySpec.getClass().getName())); + } + @SuppressWarnings("unchecked") + List> libraries = (List>) librarySpec; + if (bundle.getSymbolicName() == null || bundle.getVersion() == null) { + throw new IllegalStateException("Cannot scan " + bundle + " for catalog files: name or version is null"); + } + libraries.add(ImmutableMap.of( + "name", bundle.getSymbolicName(), + "version", bundle.getVersion().toString())); + LOG.debug("library spec is {}", librarySpec); + } + + private String backToYaml(Map bom) { + final DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + options.setPrettyFlow(true); + return new Yaml(options).dump(bom); + } + + private Iterable> removeAnyApplications( + Iterable> catalogItems) { + + List> result = MutableList.of(); + + for (CatalogItem item : catalogItems) { + if (TEMPLATE.equals(item.getCatalogItemType())) { + removeFromCatalog(item); + } else { + result.add(item); + } + } + return result; + } + + private boolean passesWhiteAndBlacklists(Bundle bundle) { + return on(bundle, catalogBomScanner.getWhiteList()) && !on(bundle, catalogBomScanner.getBlackList()); + } + + private boolean on(Bundle bundle, List list) { + for (String candidate : list) { + final String symbolicName = bundle.getSymbolicName(); + if (symbolicName.matches(candidate.trim())) { + return true; + } + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8cc8d22/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleTracker.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleTracker.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleTracker.java new file mode 100644 index 0000000..4cb2470 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleTracker.java @@ -0,0 +1,104 @@ +/* + * 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 org.apache.brooklyn.api.catalog.CatalogItem; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.ServiceReference; +import org.osgi.util.tracker.BundleTracker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.Beta; + +@Beta +public class CatalogBundleTracker extends BundleTracker>> { + + private static final Logger LOG = LoggerFactory.getLogger(CatalogBundleTracker.class); + + private ServiceReference mgmtContextReference; + private ManagementContext managementContext; + + private CatalogBomScanner catalogBomScanner; + private CatalogBundleLoader catalogBundleLoader; + + public CatalogBundleTracker(CatalogBomScanner catalogBomScanner, ServiceReference serviceReference) { + super(serviceReference.getBundle().getBundleContext(), Bundle.ACTIVE, null); + this.mgmtContextReference = serviceReference; + this.catalogBomScanner = catalogBomScanner; + open(); + } + + @Override + public void open() { + managementContext = mgmtContextReference.getBundle().getBundleContext().getService(mgmtContextReference); + catalogBundleLoader = new CatalogBundleLoader(catalogBomScanner, managementContext); + super.open(); + } + + @Override + public void close() { + super.close(); + managementContext = null; + mgmtContextReference.getBundle().getBundleContext().ungetService(mgmtContextReference); + catalogBundleLoader = null; + } + + public ManagementContext getManagementContext() { + return managementContext; + } + + /** + * Scans the bundle being added for a catalog.bom file and adds any entries in it to the catalog. + * + * @param bundle The bundle being added to the bundle context. + * @param bundleEvent The event of the addition. + * @return The items added to the catalog; these will be tracked by the {@link BundleTracker} mechanism + * and supplied to the {@link #removedBundle(Bundle, BundleEvent, Iterable)} method. + * @throws RuntimeException if the catalog items failed to be added to the catalog + */ + @Override + public Iterable> addingBundle(Bundle bundle, BundleEvent bundleEvent) { + return catalogBundleLoader.scanForCatalog(bundle); + } + + /** + * Remove the given entries from the catalog, related to the given bundle. + * + * @param bundle The bundle being removed to the bundle context. + * @param bundleEvent The event of the removal. + * @param items The items being removed + * @throws RuntimeException if the catalog items failed to be added to the catalog + */ + @Override + public void removedBundle(Bundle bundle, BundleEvent bundleEvent, Iterable> items) { + if (!items.iterator().hasNext()) { + return; + } + LOG.debug("Unloading catalog BOM entries from {} {} {}", catalogBomScanner.bundleIds(bundle)); + for (CatalogItem item : items) { + LOG.debug("Unloading {} {} from catalog", item.getSymbolicName(), item.getVersion()); + + catalogBundleLoader.removeFromCatalog(item); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e8cc8d22/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java index 8cf4d01..a5cdfe4 100644 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/CatalogResource.java @@ -51,12 +51,12 @@ import org.apache.brooklyn.core.BrooklynFeatureEnablement; import org.apache.brooklyn.core.catalog.CatalogPredicates; import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog; import org.apache.brooklyn.core.catalog.internal.CatalogBomScanner; +import org.apache.brooklyn.core.catalog.internal.CatalogBundleLoader; import org.apache.brooklyn.core.catalog.internal.CatalogDto; import org.apache.brooklyn.core.catalog.internal.CatalogItemComparator; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; import org.apache.brooklyn.core.mgmt.entitlement.Entitlements; import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.StringAndArgument; -import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext; import org.apache.brooklyn.core.typereg.RegisteredTypeLoadingContexts; import org.apache.brooklyn.core.typereg.RegisteredTypePredicates; import org.apache.brooklyn.core.typereg.RegisteredTypes; @@ -247,7 +247,7 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat if (!BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_LOAD_BUNDLE_CATALOG_BOM)) { // if the above feature is not enabled, let's do it manually (as a contract of this method) try { - new CatalogBomScanner().new CatalogBundleLoader(mgmt()).scanForCatalog(bundle); + new CatalogBundleLoader(new CatalogBomScanner(), mgmt()).scanForCatalog(bundle); } catch (RuntimeException ex) { try { bundle.uninstall();