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 2022/07/14 10:16:33 UTC
[brooklyn-server] 02/05: share catalog init / persist/rebind logic for installing bundles via API import
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 <al...@cloudsoft.io>
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();