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/09/26 12:17:08 UTC
[3/9] brooklyn-server git commit: handle edge cases where importing
OSGi-already-managed bundles to Brooklyn mgmt
handle edge cases where importing OSGi-already-managed bundles to Brooklyn mgmt
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/69ea9844
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/69ea9844
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/69ea9844
Branch: refs/heads/master
Commit: 69ea984467e79dc3554d0079a662648c5e9bd922
Parents: 3816fb7
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Sep 21 13:07:07 2017 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Sep 21 13:17:07 2017 +0100
----------------------------------------------------------------------
.../catalog/internal/BasicBrooklynCatalog.java | 3 +-
.../core/catalog/internal/CatalogUtils.java | 27 ++++---
.../core/mgmt/ha/OsgiArchiveInstaller.java | 85 ++++++++++++++++----
.../brooklyn/core/mgmt/ha/OsgiManager.java | 36 +++++----
4 files changed, 109 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/69ea9844/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
index f42c0a2..c358cef 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/BasicBrooklynCatalog.java
@@ -1782,7 +1782,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
//assume forceUpdate for backwards compatibility
log.debug("Adding manual catalog item to "+mgmt+": "+item);
checkNotNull(item, "item");
- CatalogUtils.installLibraries(mgmt, item.getLibraries());
+ //don't activate bundles; only intended for legacy tests where that might not work
+ CatalogUtils.installLibraries(mgmt, item.getLibraries(), false);
if (manualAdditionsCatalog==null) loadManualAdditionsCatalog();
manualAdditionsCatalog.addEntry(getAbstractCatalogItem(item));
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/69ea9844/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
index 471ce64..5621588 100644
--- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogUtils.java
@@ -168,6 +168,11 @@ public class CatalogUtils {
* Registers all bundles with the management context's OSGi framework.
*/
public static void installLibraries(ManagementContext managementContext, @Nullable Collection<CatalogBundle> libraries) {
+ installLibraries(managementContext, libraries, true);
+ }
+ /** As {@link #installLibraries(ManagementContext, Collection)} but letting caller suppress the deferred start/install
+ * (for use in tests where bundles' BOMs aren't resolvable). */
+ public static void installLibraries(ManagementContext managementContext, @Nullable Collection<CatalogBundle> libraries, boolean startBundlesAndInstallToBrooklyn) {
if (libraries == null) return;
ManagementContextInternal mgmt = (ManagementContextInternal) managementContext;
@@ -190,16 +195,18 @@ public class CatalogUtils {
results.add(result);
}
Map<String, Throwable> errors = MutableMap.of();
- for (OsgiBundleInstallationResult r: results) {
- if (r.getDeferredStart()!=null) {
- try {
- r.getDeferredStart().run();
- } catch (Throwable t) {
- Exceptions.propagateIfFatal(t);
- // above will done rollback for the failed item, but we need consistent behaviour for all libraries;
- // for simplicity we simply have each bundle either fully installed or fully rolled back
- // (alternative would be to roll back everything)
- errors.put(r.getVersionedName().toString(), t);
+ if (startBundlesAndInstallToBrooklyn) {
+ for (OsgiBundleInstallationResult r: results) {
+ if (r.getDeferredStart()!=null) {
+ try {
+ r.getDeferredStart().run();
+ } catch (Throwable t) {
+ Exceptions.propagateIfFatal(t);
+ // above will done rollback for the failed item, but we need consistent behaviour for all libraries;
+ // for simplicity we simply have each bundle either fully installed or fully rolled back
+ // (alternative would be to roll back everything)
+ errors.put(r.getVersionedName().toString(), t);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/69ea9844/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiArchiveInstaller.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiArchiveInstaller.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiArchiveInstaller.java
index f00b96f..5f053e5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiArchiveInstaller.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiArchiveInstaller.java
@@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
@@ -81,6 +82,7 @@ class OsgiArchiveInstaller {
private boolean validateTypes = true;
private File zipFile;
+ private boolean isBringingExistingOsgiInstalledBundleUnderBrooklynManagement = false;
private Manifest discoveredManifest;
private VersionedName discoveredBomVersionedName;
OsgiBundleInstallationResult result;
@@ -178,8 +180,9 @@ class OsgiArchiveInstaller {
}
try {
// do this in special try block, not below, so we can give a better error
- // (the user won't understnad the URL)
+ // (the user won't understand the URL)
zipIn = ResourceUtils.create(mgmt()).getResourceFromUrl(candidateUrl);
+ isBringingExistingOsgiInstalledBundleUnderBrooklynManagement = true;
} catch (Exception e) {
Exceptions.propagateIfFatal(e);
throw new IllegalArgumentException("Could not find binary for already installed OSGi bundle "+existingOsgiInstalledBundle.get()+" (location "+candidateUrl+") when trying to promote "+suppliedKnownBundleMetadata+" to Brooklyn management", e);
@@ -360,19 +363,61 @@ class OsgiArchiveInstaller {
}
} else {
result.metadata = inferredMetadata;
- // no such managed bundle
+ // no such Brooklyn-managed bundle
Maybe<Bundle> b = Osgis.bundleFinder(osgiManager.framework).symbolicName(result.getMetadata().getSymbolicName()).version(result.getMetadata().getSuppliedVersionString()).find();
if (b.isPresent()) {
// bundle already installed to OSGi subsystem but brooklyn not aware of it;
- // this will often happen on a karaf restart so don't be too strict!
- // in this case let's uninstall it to make sure we have the right bundle and checksum
- // (in case where user has replaced a JAR file in persisted state,
- // or where they osgi installed something and are now uploading it or something else)
- // but let's just assume it's the same; worst case if not user will
- // have to uninstall it then reinstall it to do the replacement
- // (means you can't just replace a JAR in persisted state however)
- log.debug("Brooklyn install of "+result.getMetadata().getVersionedName()+" detected already loaded in OSGi; uninstalling that to reinstall as Brooklyn-managed");
- b.get().uninstall();
+ // this will often happen on a karaf restart where bundle was cached by karaf,
+ // so we need to allow it. can also happen if brooklyn.libraries references an existing bundle.
+
+ // determine if we are simply bringing existing installed under Brooklyn management (because url or binary content identical and not forced)
+ // or if the bundle should be reinstalled/updated
+ if (!force) {
+ if (!isBringingExistingOsgiInstalledBundleUnderBrooklynManagement) {
+ if (Objects.equal(b.get().getLocation(), suppliedKnownBundleMetadata.getUrl())) {
+ // installation request was for identical location, so assume we are simply bringing under mgmt
+ log.debug("Request to install "+inferredMetadata+" from same location "+b.get().getLocation()+
+ " as existing OSGi installed (but not Brooklyn-managed) bundle "+b.get()+", so skipping reinstall");
+ isBringingExistingOsgiInstalledBundleUnderBrooklynManagement = true;
+ } else {
+ // different locations, but see if we can compare input stream contents
+ // (prevents needless uninstall/reinstall of already installed bundles)
+ try {
+ if (Streams.compare(new FileInputStream(zipFile), new URL(b.get().getLocation()).openStream())) {
+ log.debug("Request to install "+inferredMetadata+" has same contents"+
+ " as existing OSGi installed (but not Brooklyn-managed) bundle "+b.get()+", so skipping reinstall");
+ isBringingExistingOsgiInstalledBundleUnderBrooklynManagement = true;
+ } else {
+ log.debug("Request to install "+inferredMetadata+" has different contents"+
+ " as existing OSGi installed (but not Brooklyn-managed) bundle "+b.get()+", so will do reinstall");
+ }
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ // probably an invalid URL on installed bundle; that's allowed
+ log.debug("Request to install "+inferredMetadata+" could not compare contents"+
+ " with existing OSGi installed (but not Brooklyn-managed) bundle "+b.get()+", so will do reinstall (error "+e+" loading from "+b.get().getLocation()+")");
+ }
+ }
+ }
+ } else {
+ if (isBringingExistingOsgiInstalledBundleUnderBrooklynManagement) {
+ log.debug("Request to install "+inferredMetadata+" was forced, so forcing reinstallation "
+ + "of existing OSGi installed (but not Brooklyn-managed) bundle "+b.get());
+ isBringingExistingOsgiInstalledBundleUnderBrooklynManagement = false;
+ }
+ }
+
+ if (isBringingExistingOsgiInstalledBundleUnderBrooklynManagement) {
+ result.bundle = b.get();
+
+ } else {
+ // needs reinstallation
+ // we could update instead of uninstall/reinstall
+ // note however either way we won't be able to rollback if there is a failure
+ log.debug("Brooklyn install of "+result.getMetadata().getVersionedName()+" detected already loaded in OSGi; uninstalling that to reinstall as Brooklyn-managed");
+ b.get().uninstall();
+ result.bundle = null;
+ }
}
// normal install
updating = false;
@@ -381,8 +426,13 @@ class OsgiArchiveInstaller {
startedInstallation = true;
try (InputStream fin = new FileInputStream(zipFile)) {
if (!updating) {
- assert result.getBundle()==null;
- result.bundle = osgiManager.framework.getBundleContext().installBundle(result.getMetadata().getOsgiUniqueUrl(), fin);
+ if (isBringingExistingOsgiInstalledBundleUnderBrooklynManagement) {
+ assert result.getBundle()!=null;
+ log.debug("Brooklyn install of "+result.getMetadata().getVersionedName()+" detected already loaded "+result.getBundle()+" in OSGi can be re-used, skipping OSGi install");
+ } else {
+ assert result.getBundle()==null;
+ result.bundle = osgiManager.framework.getBundleContext().installBundle(result.getMetadata().getOsgiUniqueUrl(), fin);
+ }
} else {
result.bundle.update(fin);
}
@@ -440,9 +490,12 @@ class OsgiArchiveInstaller {
((BasicManagedBundle)result.getMetadata()).setPersistenceNeeded(true);
mgmt().getRebindManager().getChangeListener().onChanged(result.getMetadata());
} else {
- log.debug("Uninstalling bundle "+result.getVersionedName()+" (roll back of failed fresh install, no previous version to revert to)");
- osgiManager.uninstallUploadedBundle(result.getMetadata());
-
+ if (isBringingExistingOsgiInstalledBundleUnderBrooklynManagement) {
+ log.debug("Uninstalling bundle "+result.getVersionedName()+" from Brooklyn management only (rollback needed but it was already installed to OSGi)");
+ } else {
+ log.debug("Uninstalling bundle "+result.getVersionedName()+" (roll back of failed fresh install, no previous version to revert to)");
+ }
+ osgiManager.uninstallUploadedBundle(result.getMetadata(), false, isBringingExistingOsgiInstalledBundleUnderBrooklynManagement);
((BasicManagedBundle)result.getMetadata()).setPersistenceNeeded(true);
mgmt().getRebindManager().getChangeListener().onUnmanaged(result.getMetadata());
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/69ea9844/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
index 603927a..995f7ed 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/OsgiManager.java
@@ -393,6 +393,10 @@ public class OsgiManager {
* This does not throw but returns a reference containing errors and result for caller to inspect and handle.
*/
public ReferenceWithError<OsgiBundleInstallationResult> uninstallUploadedBundle(ManagedBundle bundleMetadata, boolean force) {
+ return uninstallUploadedBundle(bundleMetadata, force, false);
+ }
+
+ public ReferenceWithError<OsgiBundleInstallationResult> uninstallUploadedBundle(ManagedBundle bundleMetadata, boolean force, boolean leaveInOsgi) {
OsgiBundleInstallationResult result = new OsgiBundleInstallationResult();
result.metadata = bundleMetadata;
List<Throwable> errors = MutableList.of();
@@ -425,22 +429,24 @@ public class OsgiManager {
errors.add(e);
}
- Bundle bundle = framework.getBundleContext().getBundle(bundleMetadata.getOsgiUniqueUrl());
- result.bundle = bundle;
- if (bundle==null) {
- Exception e = new IllegalStateException("No such bundle installed in OSGi when uninstalling: "+bundleMetadata);
- if (!force) Exceptions.propagate(e);
- log.warn(e.getMessage());
- errors.add(e);
- } else {
- try {
- bundle.stop();
- bundle.uninstall();
- } catch (BundleException e) {
- Exceptions.propagateIfFatal(e);
+ if (!leaveInOsgi) {
+ Bundle bundle = framework.getBundleContext().getBundle(bundleMetadata.getOsgiUniqueUrl());
+ result.bundle = bundle;
+ if (bundle==null) {
+ Exception e = new IllegalStateException("No such bundle installed in OSGi when uninstalling: "+bundleMetadata);
if (!force) Exceptions.propagate(e);
- log.warn("Error stopping and uninstalling "+bundleMetadata+": "+e);
- errors.add(e);
+ log.warn(e.getMessage());
+ errors.add(e);
+ } else {
+ try {
+ bundle.stop();
+ bundle.uninstall();
+ } catch (BundleException e) {
+ Exceptions.propagateIfFatal(e);
+ if (!force) Exceptions.propagate(e);
+ log.warn("Error stopping and uninstalling "+bundleMetadata+": "+e);
+ errors.add(e);
+ }
}
}
} catch (Exception e) {