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 2021/05/26 22:52:27 UTC

[brooklyn-server] 02/06: preserve original ID and OSGi URL for bundles so update logic is correct

This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 473495368711eb09f85cebecdb093bf67b1f9f79
Author: Alex Heneveld <al...@cloudsoftcorp.com>
AuthorDate: Wed May 26 20:19:07 2021 +0100

    preserve original ID and OSGi URL for bundles so update logic is correct
---
 .../camp/brooklyn/catalog/CatalogScanOsgiTest.java |  2 +-
 .../mgmt/ha/BrooklynBomOsgiArchiveInstaller.java   | 15 ++++++++--
 .../apache/brooklyn/core/mgmt/ha/OsgiManager.java  |  8 ++++--
 .../brooklyn/core/objs/AbstractBrooklynObject.java |  4 +++
 .../brooklyn/core/typereg/BasicManagedBundle.java  | 33 ++++++++++++++++++----
 5 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java
index 8dc74c5..9798651 100644
--- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java
+++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/catalog/CatalogScanOsgiTest.java
@@ -220,7 +220,7 @@ public class CatalogScanOsgiTest extends AbstractYamlTest {
             Streams.closeQuietly(out);
 
             OsgiBundleInstallationResult result = ((ManagementContextInternal) mgmt()).getOsgiManager().get().install(InputStreamSource.of("test:" + f, f)).getWithError();
-            LOG.info("Installed "+result.getVersionedName()+": "+result.getCode()+" - "+result.getMessage());
+            LOG.info("Installed "+result.getVersionedName()+": "+result.getCode()+" - "+result.getMessage() + " ("+result.getMetadata().getChecksum()+")");
             if (expectedResultCode!=null) Asserts.assertEquals(result.getCode(), expectedResultCode);
         } catch (Exception e) {
             throw Exceptions.propagate(e);
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/BrooklynBomOsgiArchiveInstaller.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/BrooklynBomOsgiArchiveInstaller.java
index bbdd21f..253c46d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/BrooklynBomOsgiArchiveInstaller.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/ha/BrooklynBomOsgiArchiveInstaller.java
@@ -498,9 +498,13 @@ public class BrooklynBomOsgiArchiveInstaller {
 
                 result.bundle = osgiManager.getFramework().getBundleContext().getBundle(result.getMetadata().getOsgiUniqueUrl());
 
+                log.debug("Request to install "+inferredMetadata.getVersionedName()+" (checksum "+inferredMetadata.getChecksum()+", OSGi URL "+inferredMetadata.getOsgiUniqueUrl()+") in the presence of "+result.getMetadata().getVersionedName()+" (checksum "+result.getMetadata().getChecksum()+", OSGi URL "+result.getMetadata().getOsgiUniqueUrl()+")");
+
                 // Check if exactly this bundle is already installed
-                if (result.bundle != null && !VersionComparator.isSnapshot(inferredMetadata.getSuppliedVersionString()) &&
-                        checksumsMatch(result.getMetadata(), inferredMetadata)) {
+                if (result.bundle != null && checksumsMatch(result.getMetadata(), inferredMetadata)) {
+
+                    isEquivalentBundleAlreadyOsgiInstalled(osgiManager, inferredMetadata, zipFile);
+
                     // e.g. repeatedly installing the same bundle
                     log.trace("Bundle "+inferredMetadata+" matches already installed managed bundle "+result.getMetadata()
                             +"; install is no-op");
@@ -540,6 +544,11 @@ public class BrooklynBomOsgiArchiveInstaller {
                                 + "will not re-install without use of 'force'");
                     }
                 }
+
+                // if proceeding with install, use the new metadata but the old id and osgi url
+                // (the osgi url must match because we use "getBundle(...)" to update it)
+                result.metadata = BasicManagedBundle.copyFirstWithCoordsOfSecond(inferredMetadata, result.metadata);
+
             } else {
                 // No such Brooklyn-managed bundle.
 
@@ -635,7 +644,7 @@ public class BrooklynBomOsgiArchiveInstaller {
                     mgmt().getRebindManager().getChangeListener().onManaged(result.getMetadata());
                 }
             } else {
-                oldZipFile = osgiManager.managedBundlesRecord.updateManagedBundleFile(result, zipFile);
+                oldZipFile = osgiManager.managedBundlesRecord.updateManagedBundleFileAndMetadata(result, zipFile);
 
                 result.code = OsgiBundleInstallationResult.ResultCode.UPDATED_EXISTING_BUNDLE;
                 result.message = "Updated Brooklyn catalog bundle "+result.getMetadata().getVersionedName()+" as existing ID "+result.getMetadata().getId()+" ["+result.bundle.getBundleId()+"]";
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 0d9772d..44065ab 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
@@ -141,8 +141,7 @@ public class OsgiManager {
         }
         
         synchronized void addManagedBundle(OsgiBundleInstallationResult result, File f) {
-            updateManagedBundleFile(result, f);
-            managedBundlesByUid.put(result.getMetadata().getId(), result.getMetadata());
+            updateManagedBundleFileAndMetadata(result, f);
             managedBundlesUidByVersionedName.put(VersionedName.toOsgiVersionedName(result.getMetadata().getVersionedName()), 
                 result.getMetadata().getId());
             if (Strings.isNonBlank(result.getMetadata().getUrl())) {
@@ -174,7 +173,7 @@ public class OsgiManager {
         }
 
         /** Updates the bundle file associated with the given record, creating and returning a backup if there was already such a file */ 
-        synchronized File updateManagedBundleFile(OsgiBundleInstallationResult result, File fNew) {
+        synchronized File updateManagedBundleFileAndMetadata(OsgiBundleInstallationResult result, File fNew) {
             File fCached = fileFor(result.getMetadata());
             File fBak = new File(fCached.getAbsolutePath()+".bak");
             if (fBak.equals(fNew)) {
@@ -192,6 +191,9 @@ public class OsgiManager {
             } catch (IOException e) {
                 throw Exceptions.propagate(e);
             }
+
+            managedBundlesByUid.put(result.getMetadata().getId(), result.getMetadata());
+
             return fBak;
         }
         
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractBrooklynObject.java b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractBrooklynObject.java
index 3d7b552..a725633 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractBrooklynObject.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractBrooklynObject.java
@@ -73,6 +73,10 @@ public abstract class AbstractBrooklynObject implements BrooklynObjectInternal {
         this(Maps.newLinkedHashMap());
     }
 
+    protected AbstractBrooklynObject(String id) {
+        this.id = id;
+    }
+
     public AbstractBrooklynObject(Map<?, ?> properties) {
         _legacyConstruction = !InternalFactory.FactoryConstructionTracker.isConstructing();
 
diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
index e722d83..367d106 100644
--- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
+++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicManagedBundle.java
@@ -42,6 +42,7 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage
     private String symbolicName;
     private String version;
     private String checksum;
+    private String osgiUniqueUrl;
     private String format;
     private String url;
     private Credentials credentials;
@@ -60,6 +61,10 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage
     }
 
     public BasicManagedBundle(String name, String version, String url, String format, Credentials credentials, @Nullable String checksum) {
+        init(name, version, url, format, credentials, checksum);
+    }
+
+    private void init(String name, String version, String url, String format, Credentials credentials, @Nullable String checksum) {
         if (name == null && version == null) {
             Preconditions.checkNotNull(url, "Either a URL or both name and version are required");
         } else {
@@ -68,10 +73,24 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage
         }
         this.symbolicName = name;
         this.version = version;
-        this.format = format;
         this.url = url;
-        this.checksum = checksum;
+        this.format = format;
         this.credentials = credentials;
+        this.checksum = checksum;
+    }
+
+    private BasicManagedBundle(String id, String name, String version, String url, String format, Credentials credentials, @Nullable String checksum) {
+        super(id);
+        init(name, version, url, format, credentials, checksum);
+    }
+
+    /** used when updating a persisted bundle, we want to use the coords (ID and OSGI unique URL) of the second with the checksum of the former;
+     * the other fields should be the same between the two but if in doubt use the first argument
+     */
+    public static BasicManagedBundle copyFirstWithCoordsOfSecond(ManagedBundle update, ManagedBundle oldOneForCoordinates) {
+        BasicManagedBundle result = new BasicManagedBundle(oldOneForCoordinates.getId(), update.getSymbolicName(), update.getSuppliedVersionString(), update.getUrl(), update.getFormat(), update.getUrlCredential(), update.getChecksum());
+        result.osgiUniqueUrl = oldOneForCoordinates.getOsgiUniqueUrl();
+        return result;
     }
     
     @Override
@@ -133,14 +152,18 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage
 
     /**
      * Gets the (internal) value to be used as the location in bundleContext.install(location). 
-     * It thus allows us to tell if a cached OSGi bundle is the same as a bundle we are about to 
-     * install (e.g. one we get from persisted state), or have retrieved from the initial catalog.
+     * It thus allows us to tell if a cached OSGi bundle should be considered as replacement
+     * for the one we are about to install (e.g. one we get from persisted state),
+     * or have retrieved from the initial catalog.
      * 
      * Care should be taken to set the checksum <em>before</em> using the OSGi unique url.
      */
     @Override
     public String getOsgiUniqueUrl() {
-        return "brooklyn:" + (checksum != null ? checksum : getId());
+        if (osgiUniqueUrl==null) {
+            osgiUniqueUrl = "brooklyn:" + (checksum != null ? checksum : getId());
+        }
+        return osgiUniqueUrl;
     }
     
     @Override