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 d198f6381517842ca766be7dcc83ea943e5ab1ee
Author: Alex Heneveld <[email protected]>
AuthorDate: Wed Jul 13 12:20:42 2022 +0100

    share catalog init / persist/rebind logic for installing bundles via API 
import
    
    fixes test failing in previous commit
---
 .../catalog/internal/CatalogInitialization.java    | 74 ++++++++++++----------
 .../brooklyn/core/mgmt/rebind/RebindIteration.java | 73 +++++++++++----------
 .../brooklyn/rest/resources/ServerResource.java    | 45 +++++++------
 3 files changed, 103 insertions(+), 89 deletions(-)

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 ed116dc4ec..14f95d2bab 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
@@ -254,39 +254,12 @@ public class CatalogInitialization implements 
ManagementContextInjectable {
                 throw new IllegalStateException("Catalog initialization 
already run for initial catalog by mechanism other than populating persisted 
state; mode="+mode);      
             }
 
-            // Always install the bundles from persisted state; installed (but 
not started) prior to catalog,
-            // so that OSGi unique IDs might be picked up when initial catalog 
is populated
-            Map<InstallableManagedBundle, OsgiBundleInstallationResult> 
persistenceInstalls = 
installPersistedBundlesDontStart(persistedState.getBundles(), exceptionHandler, 
rebindLogger);
-
-            // now we install and start the bundles from the catalog;
-            // 2021-12-03 now this only will look for classes in active 
bundles, so it won't resolve persisted bundles
-            // and we can safely filter them out later
-            populateInitialCatalogImpl(true);
-
-            final Maybe<OsgiManager> maybesOsgiManager = 
managementContext.getOsgiManager();
-            if (maybesOsgiManager.isAbsent()) {
-                // Can't find any bundles to tell if there are upgrades. Could 
be running tests; do no filtering.
-                
CatalogUpgrades.storeInManagementContext(CatalogUpgrades.EMPTY, 
managementContext);
-            } else {
-                final OsgiManager osgiManager = maybesOsgiManager.get();
-                final BundleContext bundleContext = 
osgiManager.getFramework().getBundleContext();
-                final CatalogUpgrades catalogUpgrades =
-                        catalogUpgradeScanner.scan(osgiManager, bundleContext, 
rebindLogger);
-                CatalogUpgrades.storeInManagementContext(catalogUpgrades, 
managementContext);
-            }
-
-            PersistedCatalogState filteredPersistedState = 
filterBundlesAndCatalogInPersistedState(persistedState, rebindLogger);
-
-            // 2021-09-14 previously we effectively installed here, after 
populating; but now we do it earlier and then uninstall if needed, to preserve 
IDs
-//            Map<InstallableManagedBundle, OsgiBundleInstallationResult> 
persistenceInstalls = 
installPersistedBundlesDontStart(filteredPersistedState.getBundles(), 
exceptionHandler, rebindLogger);
-
-            try {
-                startPersistedBundles(filteredPersistedState, 
persistenceInstalls, exceptionHandler, rebindLogger);
-                BrooklynCatalog catalog = managementContext.getCatalog();
-                
catalog.addCatalogLegacyItemsOnRebind(filteredPersistedState.getLegacyCatalogItems());
-            } finally {
-                hasRunPersistenceInitialization = true;
-            }
+            installPersistedBundles(persistedState, () -> {
+                // now we install and start the bundles from the catalog;
+                // 2021-12-03 now this only will look for classes in active 
bundles, so it won't resolve persisted bundles
+                // and we can safely filter them out later
+                populateInitialCatalogImpl(true);
+            }, exceptionHandler, rebindLogger);
 
             if (mode == ManagementNodeState.MASTER) {
                 // TODO ideally this would remain false until it has 
*persisted* the changed catalog;
@@ -303,6 +276,41 @@ public class CatalogInitialization implements 
ManagementContextInjectable {
         }
     }
 
+    /** shared routine between above "normal" initialization, and special 
addition via ServerResource.import */
+    @Beta
+    public void installPersistedBundles(PersistedCatalogState persistedState, 
Runnable beforeDeferredStartAndSetRunPersistence, RebindExceptionHandler 
exceptionHandler, RebindLogger rebindLogger) {
+        // Always install the bundles from persisted state; installed (but not 
started) prior to catalog,
+        // so that OSGi unique IDs might be picked up when initial catalog is 
populated
+        Map<InstallableManagedBundle, OsgiBundleInstallationResult> 
persistenceInstalls = 
installPersistedBundlesDontStart(persistedState.getBundles(), exceptionHandler, 
rebindLogger);
+
+        if (beforeDeferredStartAndSetRunPersistence!=null) 
beforeDeferredStartAndSetRunPersistence.run();
+
+        final Maybe<OsgiManager> maybesOsgiManager = 
managementContext.getOsgiManager();
+        if (maybesOsgiManager.isAbsent()) {
+            // Can't find any bundles to tell if there are upgrades. Could be 
running tests; do no filtering.
+            CatalogUpgrades.storeInManagementContext(CatalogUpgrades.EMPTY, 
managementContext);
+        } else {
+            final OsgiManager osgiManager = maybesOsgiManager.get();
+            final BundleContext bundleContext = 
osgiManager.getFramework().getBundleContext();
+            final CatalogUpgrades catalogUpgrades =
+                    catalogUpgradeScanner.scan(osgiManager, bundleContext, 
rebindLogger);
+            CatalogUpgrades.storeInManagementContext(catalogUpgrades, 
managementContext);
+        }
+
+        PersistedCatalogState filteredPersistedState = 
filterBundlesAndCatalogInPersistedState(persistedState, rebindLogger);
+
+        // 2021-09-14 previously we effectively installed here, after 
populating; but now we do it earlier and then uninstall if needed, to preserve 
IDs
+//            Map<InstallableManagedBundle, OsgiBundleInstallationResult> 
persistenceInstalls = 
installPersistedBundlesDontStart(filteredPersistedState.getBundles(), 
exceptionHandler, rebindLogger);
+
+        try {
+            startPersistedBundles(filteredPersistedState, persistenceInstalls, 
exceptionHandler, rebindLogger);
+            BrooklynCatalog catalog = managementContext.getCatalog();
+            
catalog.addCatalogLegacyItemsOnRebind(filteredPersistedState.getLegacyCatalogItems());
+        } finally {
+            if (beforeDeferredStartAndSetRunPersistence!=null) 
hasRunPersistenceInitialization = true;
+        }
+    }
+
     /**
      * Populates the initial catalog, but not via an official code-path.
      * 
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 9e5aa1c4a9..a3f609ab35 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
@@ -32,6 +32,7 @@ import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import com.google.common.annotations.Beta;
 import org.apache.brooklyn.api.catalog.BrooklynCatalog;
 import org.apache.brooklyn.api.catalog.CatalogItem;
 import org.apache.brooklyn.api.entity.Application;
@@ -333,6 +334,33 @@ public abstract class RebindIteration {
         isEmpty = mementoManifest.isEmpty();
     }
 
+    @Beta
+    public static class InstallableManagedBundleImpl implements 
CatalogInitialization.InstallableManagedBundle {
+        private final ManagedBundleMemento memento;
+        private final ManagedBundle managedBundle;
+
+        public InstallableManagedBundleImpl(ManagedBundleMemento memento, 
ManagedBundle managedBundle) {
+            this.memento = memento;
+            this.managedBundle = managedBundle;
+        }
+
+        @Override
+        public ManagedBundle getManagedBundle() {
+            return managedBundle;
+        }
+
+        @Override
+        public Supplier<InputStream> getInputStreamSource() throws IOException 
{
+            return InputStreamSource.ofRenewableSupplier("JAR for " + memento, 
() -> {
+                try {
+                    return memento.getJarContent().openStream();
+                } catch (IOException e) {
+                    throw Exceptions.propagate(e);
+                }
+            });
+        }
+    }
+
     protected void installBundlesAndRebuildCatalog() {
         // Build catalog early so we can load other things.
         // Reads the persisted catalog contents, and passes it all to 
CatalogInitialization, which decides what to do with it.
@@ -350,32 +378,6 @@ public abstract class RebindIteration {
             }
         };
 
-        class InstallableManagedBundleImpl implements 
CatalogInitialization.InstallableManagedBundle {
-            private final ManagedBundleMemento memento;
-            private final ManagedBundle managedBundle;
-
-            InstallableManagedBundleImpl(ManagedBundleMemento memento, 
ManagedBundle managedBundle) {
-                this.memento = memento;
-                this.managedBundle = managedBundle;
-            }
-
-            @Override
-            public ManagedBundle getManagedBundle() {
-                return managedBundle;
-            }
-
-            @Override
-            public Supplier<InputStream> getInputStreamSource() throws 
IOException {
-                return InputStreamSource.ofRenewableSupplier("JAR for " + 
memento, () -> {
-                    try {
-                        return memento.getJarContent().openStream();
-                    } catch (IOException e) {
-                        throw Exceptions.propagate(e);
-                    }
-                });
-            }
-        }
-
         Map<VersionedName, InstallableManagedBundle> bundles = new 
LinkedHashMap<>();
         Collection<CatalogItem<?, ?>> legacyCatalogItems = new ArrayList<>();
 
@@ -1411,13 +1413,6 @@ public abstract class RebindIteration {
             return invokeConstructor(reflections, clazz, new Object[]{});
         }
 
-        protected ManagedBundle newManagedBundle(ManagedBundleMemento memento) 
{
-            ManagedBundle result = new 
BasicManagedBundle(memento.getSymbolicName(), memento.getVersion(), 
memento.getUrl(),
-                    memento.getFormat(), null, memento.getChecksum(), 
memento.getDeleteable());
-            FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", 
memento.getId()), result);
-            return result;
-        }
-
         protected <T> T invokeConstructor(Reflections reflections, Class<T> 
clazz, Object[]... possibleArgs) {
             for (Object[] args : possibleArgs) {
                 try {
@@ -1442,6 +1437,10 @@ public abstract class RebindIteration {
             throw new IllegalStateException("Cannot instantiate instance of 
type " + clazz +
                     "; expected constructor signature not found (" + args + 
")");
         }
+
+        protected ManagedBundle newManagedBundle(ManagedBundleMemento 
bundleMemento) {
+            return RebindIteration.newManagedBundle(bundleMemento);
+        }
     }
 
     protected BrooklynMementoPersister getPersister() {
@@ -1489,4 +1488,12 @@ public abstract class RebindIteration {
         return (readOnlyRebindCount.get() < 5) || (readOnlyRebindCount.get() % 
1000 == 0);
     }
 
+    @Beta
+    public static ManagedBundle newManagedBundle(ManagedBundleMemento memento) 
{
+        ManagedBundle result = new 
BasicManagedBundle(memento.getSymbolicName(), memento.getVersion(), 
memento.getUrl(),
+                memento.getFormat(), null, memento.getChecksum(), 
memento.getDeleteable());
+        FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", memento.getId()), 
result);
+        return result;
+    }
+
 }
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
index 812ede244d..d183670265 100644
--- 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
@@ -47,8 +47,10 @@ import org.apache.brooklyn.api.mgmt.rebind.RebindManager;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoManifest;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.BrooklynMementoRawData;
 import org.apache.brooklyn.api.mgmt.rebind.mementos.ManagedBundleMemento;
+import org.apache.brooklyn.api.typereg.ManagedBundle;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.BrooklynVersion;
+import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.config.Sanitizer;
 import org.apache.brooklyn.core.entity.Attributes;
@@ -64,6 +66,7 @@ import 
org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
 import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
 import org.apache.brooklyn.core.mgmt.persist.*;
 import org.apache.brooklyn.core.mgmt.rebind.PersistenceExceptionHandlerImpl;
+import org.apache.brooklyn.core.mgmt.rebind.RebindIteration;
 import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl;
 import org.apache.brooklyn.core.server.BrooklynServerPaths;
 import org.apache.brooklyn.rest.api.ServerApi;
@@ -83,6 +86,7 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.ReferenceWithError;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.os.Os;
+import org.apache.brooklyn.util.osgi.VersionedName;
 import org.apache.brooklyn.util.stream.InputStreamSource;
 import org.apache.brooklyn.util.text.Identifiers;
 import org.apache.brooklyn.util.text.Strings;
@@ -96,6 +100,8 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.FluentIterable;
 
+import static org.apache.brooklyn.api.mgmt.ha.ManagementNodeState.INITIALIZING;
+
 public class ServerResource extends AbstractBrooklynRestResource implements 
ServerApi {
 
     private static final int SHUTDOWN_TIMEOUT_CHECK_INTERVAL = 200;
@@ -436,7 +442,7 @@ public class ServerResource extends 
AbstractBrooklynRestResource implements Serv
             throw 
WebResourceUtils.forbidden(USER_OPERATION_NOT_AUTHORIZED_MSG, 
Entitlements.getEntitlementContext().user());
         
         Maybe<ManagementContext> mm = mgmtMaybe();
-        if (mm.isAbsent()) return ManagementNodeState.INITIALIZING;
+        if (mm.isAbsent()) return INITIALIZING;
         return mm.get().getHighAvailabilityManager().getNodeState();
     }
 
@@ -609,30 +615,23 @@ public class ServerResource extends 
AbstractBrooklynRestResource implements Serv
                     ((RebindManagerImpl)rebindManager).newExceptionHandler());
 
             // install bundles to active management context
-            for (Map.Entry<String, ByteSource> bundleJar : 
newMementoRawData.getBundleJars().entrySet()){
-                ManagedBundleMemento memento = 
mementoManifest.getBundle(bundleJar.getKey());
-                log.debug("Installing "+memento+" as part of persisted state 
import");
-                ReferenceWithError<OsgiBundleInstallationResult> 
bundleInstallResult = ((ManagementContextInternal)mgmt()).getOsgiManager().get()
-                        .install(InputStreamSource.of("Persistence import - 
bundle install - "+memento, bundleJar.getValue().read()), "", false, 
memento.getDeleteable());
-
-                if (bundleInstallResult.hasError()) {
-                    log.debug("Unable to create "+memento+", format '', 
throwing: "+bundleInstallResult.getError().getMessage(), 
bundleInstallResult.getError());
-                    String errorMsg = "";
-                    if (bundleInstallResult.getWithoutError()!=null) {
-                        errorMsg = 
bundleInstallResult.getWithoutError().getMessage();
-                    } else {
-                        errorMsg = 
Strings.isNonBlank(bundleInstallResult.getError().getMessage()) ? 
bundleInstallResult.getError().getMessage() : 
bundleInstallResult.getError().toString();
-                    }
-                    throw new Exception(errorMsg);
+            Map<VersionedName, CatalogInitialization.InstallableManagedBundle> 
bundles = new LinkedHashMap<>();
+            for (Map.Entry<String, ByteSource> bundleJar : 
newMementoRawData.getBundleJars().entrySet()) {
+                ManagedBundleMemento bundleMemento = 
mementoManifest.getBundle(bundleJar.getKey());
+                ManagedBundle b = 
RebindIteration.newManagedBundle(bundleMemento);
+                bundles.put(b.getVersionedName(), new 
RebindIteration.InstallableManagedBundleImpl(bundleMemento, b));
+                log.debug("Installing "+bundleMemento+" for "+b+" as part of 
persisted state import");
+            }
+            CatalogInitialization.PersistedCatalogState persistedCatalogState 
= new CatalogInitialization.PersistedCatalogState(bundles, 
Collections.emptySet());
+            CatalogInitialization.RebindLogger rebindLogger = new 
CatalogInitialization.RebindLogger() {
+                @Override public void debug(String message, Object... args) {
+                    log.debug(message, args);
                 }
-                if 
(!OsgiBundleInstallationResult.ResultCode.IGNORING_BUNDLE_AREADY_INSTALLED.equals(bundleInstallResult.get().getCode())
 && 
!OsgiBundleInstallationResult.ResultCode.UPDATED_EXISTING_BUNDLE.equals(bundleInstallResult.get().getCode()))
 {
-                    BundleInstallationRestResult result = 
TypeTransformer.bundleInstallationResult(bundleInstallResult.get(), mgmt(), 
brooklyn(), ui);
-                    log.debug("Installed "+memento+" as part of persisted 
state import: "+result);
-                } else {
-                    log.debug("Installation of " + memento + " reported: " + 
bundleInstallResult.get());
+                @Override public void info(String message, Object... args) {
+                    log.warn(message, args);
                 }
-            }
-
+            };
+            
mgmtInternal().getCatalogInitialization().installPersistedBundles(persistedCatalogState,
 null, ((RebindManagerImpl)mgmt().getRebindManager()).newExceptionHandler(), 
rebindLogger);
 
             // store persisted items and rebind to load applications
             BrooklynMementoRawData.Builder result = 
BrooklynMementoRawData.builder();

Reply via email to