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 f689b8196f8fa90e90d347e322d4aee470456dad Author: Alex Heneveld <[email protected]> AuthorDate: Fri Oct 1 17:24:52 2021 +0100 record that user-installed bundles are deleteable this saves it in persisted state and returns it via the rest api --- .../mgmt/rebind/mementos/ManagedBundleMemento.java | 4 +++ .../brooklyn/api/typereg/OsgiBundleWithUrl.java | 4 +++ .../brooklyn/camp/brooklyn/AbstractYamlTest.java | 2 +- .../camp/brooklyn/test/lite/CampYamlLiteTest.java | 2 +- .../core/catalog/internal/CatalogBundleDto.java | 14 ++++++++- .../catalog/internal/CatalogItemDtoAbstract.java | 3 +- .../apache/brooklyn/core/mgmt/ha/OsgiManager.java | 5 ++++ .../brooklyn/core/mgmt/rebind/RebindIteration.java | 2 +- .../core/mgmt/rebind/RebindManagerImpl.java | 33 ++++++++++------------ .../mgmt/rebind/dto/BasicManagedBundleMemento.java | 19 +++++++++++-- .../core/mgmt/rebind/dto/MementosGenerators.java | 2 ++ .../core/typereg/BasicBrooklynTypeRegistry.java | 2 +- .../brooklyn/core/typereg/BasicManagedBundle.java | 27 +++++++++++++----- .../core/typereg/BasicOsgiBundleWithUrl.java | 16 +++++++++-- .../BrooklynBomYamlCatalogBundleResolver.java | 4 +-- .../typereg/BrooklynCatalogBundleResolver.java | 7 +++++ .../apache/brooklyn/rest/domain/BundleSummary.java | 11 ++++++-- .../brooklyn/rest/resources/BundleResource.java | 2 +- .../brooklyn/rest/resources/CatalogResource.java | 2 +- .../brooklyn/rest/resources/ServerResource.java | 25 +++++++++++----- 20 files changed, 136 insertions(+), 50 deletions(-) diff --git a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/ManagedBundleMemento.java b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/ManagedBundleMemento.java index dba3c1c..e608608 100644 --- a/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/ManagedBundleMemento.java +++ b/api/src/main/java/org/apache/brooklyn/api/mgmt/rebind/mementos/ManagedBundleMemento.java @@ -37,4 +37,8 @@ public interface ManagedBundleMemento extends Memento { ByteSource getJarContent(); void setJarContent(ByteSource byteSource); + @Nullable + /** whether the bundle is known to be able to be permanently deleteable (eg it was installed by a user) */ + Boolean getDeleteable(); + } diff --git a/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java b/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java index 8e245c1..9080c74 100644 --- a/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java +++ b/api/src/main/java/org/apache/brooklyn/api/typereg/OsgiBundleWithUrl.java @@ -44,6 +44,10 @@ public interface OsgiBundleWithUrl { /** @return true if we have a name and version for this bundle; * false if not, e.g. if we only know the URL and we haven't loaded it yet */ public boolean isNameResolved(); + + /** @return whether this is known to be deleteable (eg installed by user) or known not to be (eg installed at boot and will be reinstalled) + * or unknown (null, probably installed at boot or before this info was kept) */ + public Boolean getDeleteable(); /** @return the {@link VersionedName} for this bundle, or null if not available */ public VersionedName getVersionedName(); diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java index 34e18d1..9f4d7f5 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/AbstractYamlTest.java @@ -269,7 +269,7 @@ public abstract class AbstractYamlTest { File bf = bundleMaker.createTempZip("test", MutableMap.of( new ZipEntry(BasicBrooklynCatalog.CATALOG_BOM), new ByteArrayInputStream(catalogYaml.getBytes()))); ReferenceWithError<OsgiBundleInstallationResult> b = ((ManagementContextInternal)mgmt).getOsgiManager().get().installDeferredStart( - new BasicManagedBundle(bundleName.getSymbolicName(), bundleName.getVersionString(), null, null, null, null), + new BasicManagedBundle(bundleName.getSymbolicName(), bundleName.getVersionString(), null, null, null, null, true), InputStreamSource.of("tests:"+bundleName+":"+bf, bf), false); diff --git a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java index 299b200..32114eb 100644 --- a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java +++ b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java @@ -213,7 +213,7 @@ public class CampYamlLiteTest { // install bundle for class access but without loading its catalog.bom, // since we only have mock matchers here // (if we don't do this, the default routines install it and try to process the catalog.bom, failing) - ((ManagementContextInternal)mgmt).getOsgiManager().get().installDeferredStart(new BasicManagedBundle(null, null, bundleUrl, null, null, null), null, false).get(); + ((ManagementContextInternal)mgmt).getOsgiManager().get().installDeferredStart(new BasicManagedBundle(null, null, bundleUrl, null, null, null, true), null, false).get(); } private void assertMgmtHasSampleMyCatalogApp(String symbolicName, String bundleUrl) { diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java index 654a3f0..296a367 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogBundleDto.java @@ -39,14 +39,20 @@ public class CatalogBundleDto implements CatalogBundle { private String version; private String url; private Credentials credential; + private Boolean deleteable; public CatalogBundleDto() {} + @Deprecated /** @deprecated since 1.1 use larger constructor */ public CatalogBundleDto(String name, String version, String url) { this(name, version, url, null); } + @Deprecated /** @deprecated since 1.1 use larger constructor */ public CatalogBundleDto(String name, String version, String url, @Nullable Credentials credential) { + this(name, version, url, credential, null); + } + public CatalogBundleDto(String name, String version, String url, @Nullable Credentials credential, @Nullable Boolean deleteable) { if (name == null && version == null) { Preconditions.checkNotNull(url, "url to an OSGi bundle is required"); } else { @@ -58,6 +64,7 @@ public class CatalogBundleDto implements CatalogBundle { this.version = version==null ? null : BrooklynVersionSyntax.toValidOsgiVersion(version); this.url = url; this.credential = credential; + this.deleteable = deleteable; } @Override @@ -97,6 +104,11 @@ public class CatalogBundleDto implements CatalogBundle { } @Override + public Boolean getDeleteable() { + return deleteable; + } + + @Override public String toString() { return MoreObjects.toStringHelper(this) .add("symbolicName", symbolicName) @@ -128,7 +140,7 @@ public class CatalogBundleDto implements CatalogBundle { if (osgi==null) return Maybe.absent("No OSGi manager"); Maybe<Bundle> b2 = osgi.findBundle(b); if (b2.isAbsent()) return Maybe.absent("Nothing installed for "+b); - return Maybe.of(new CatalogBundleDto(b2.get().getSymbolicName(), b2.get().getVersion().toString(), b.getUrl())); + return Maybe.of(new CatalogBundleDto(b2.get().getSymbolicName(), b2.get().getVersion().toString(), b.getUrl(), b.getUrlCredential(), b.getDeleteable())); } } diff --git a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java index 99c43a5..7292bc4 100644 --- a/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java +++ b/core/src/main/java/org/apache/brooklyn/core/catalog/internal/CatalogItemDtoAbstract.java @@ -441,7 +441,8 @@ public abstract class CatalogItemDtoAbstract<T, SpecT> extends AbstractBrooklynO bwu.getSymbolicName(), bwu.getSuppliedVersionString(), bwu.getUrl(), - bwu.getUrlCredential())); + bwu.getUrlCredential(), + bwu.getDeleteable())); } else if (object instanceof VersionedName) { dto.add(new CatalogBundleDto(((VersionedName) object).getSymbolicName(), ((VersionedName) object).getVersionString(), null)); } else { 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 5fe3eec..273cdb0 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 @@ -443,10 +443,15 @@ public class OsgiManager { return BrooklynCatalogBundleResolvers.install(getManagementContext(), zipIn, options); } + @Deprecated /** @deprecated since 1.1 use larger variant of method */ public ReferenceWithError<OsgiBundleInstallationResult> install(Supplier<InputStream> input, String format, boolean force) { + return install(input, format, force, null); + } + public ReferenceWithError<OsgiBundleInstallationResult> install(Supplier<InputStream> input, String format, boolean force, Boolean deleteable) { BundleInstallationOptions options = new BundleInstallationOptions(); options.setFormat(format); options.setForceUpdateOfNonSnapshots(force); + options.setDeleteable(deleteable); return BrooklynCatalogBundleResolvers.install(getManagementContext(), input, options); } 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 cf96700..367e5ff 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 @@ -1379,7 +1379,7 @@ public abstract class RebindIteration { protected ManagedBundle newManagedBundle(ManagedBundleMemento memento) { ManagedBundle result = new BasicManagedBundle(memento.getSymbolicName(), memento.getVersion(), memento.getUrl(), - memento.getFormat(), null, memento.getChecksum()); + memento.getFormat(), null, memento.getChecksum(), memento.getDeleteable()); FlagUtils.setFieldsFromFlags(ImmutableMap.of("id", memento.getId()), result); return result; } diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java index c45c96f..81c254e 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java @@ -504,15 +504,7 @@ public class RebindManagerImpl implements RebindManager { // failure at various points should leave proxies in a sensible state, // either pointing at old or at new, though this is relatively untested, // and some things e.g. policies might not be properly started - final RebindExceptionHandler exceptionHandler = - RebindExceptionHandlerImpl.builder() - .danglingRefFailureMode(danglingRefFailureMode) - .danglingRefQuorumRequiredHealthy(danglingRefsQuorumRequiredHealthy) - .rebindFailureMode(rebindFailureMode) - .addConfigFailureMode(addConfigFailureMode) - .addPolicyFailureMode(addPolicyFailureMode) - .loadPolicyFailureMode(loadPolicyFailureMode) - .build(); + final RebindExceptionHandler exceptionHandler = newExceptionHandler(); final ManagementNodeState mode = getRebindMode(); ActivePartialRebindIteration iteration = new ActivePartialRebindIteration(this, mode, classLoader, exceptionHandler, @@ -597,14 +589,7 @@ public class RebindManagerImpl implements RebindManager { final ClassLoader classLoader = classLoaderO!=null ? classLoaderO : managementContext.getCatalogClassLoader(); final RebindExceptionHandler exceptionHandler = exceptionHandlerO!=null ? exceptionHandlerO : - RebindExceptionHandlerImpl.builder() - .danglingRefFailureMode(danglingRefFailureMode) - .danglingRefQuorumRequiredHealthy(danglingRefsQuorumRequiredHealthy) - .rebindFailureMode(rebindFailureMode) - .addConfigFailureMode(addConfigFailureMode) - .addPolicyFailureMode(addPolicyFailureMode) - .loadPolicyFailureMode(loadPolicyFailureMode) - .build(); + newExceptionHandler(); final ManagementNodeState mode = modeO!=null ? modeO : getRebindMode(); if (mode!=ManagementNodeState.MASTER && mode!=ManagementNodeState.HOT_STANDBY && mode!=ManagementNodeState.HOT_BACKUP) @@ -619,7 +604,19 @@ public class RebindManagerImpl implements RebindManager { return rebindImpl(classLoader, exceptionHandler, mode); } } - + + @Beta + public RebindExceptionHandler newExceptionHandler() { + return RebindExceptionHandlerImpl.builder() + .danglingRefFailureMode(danglingRefFailureMode) + .danglingRefQuorumRequiredHealthy(danglingRefsQuorumRequiredHealthy) + .rebindFailureMode(rebindFailureMode) + .addConfigFailureMode(addConfigFailureMode) + .addPolicyFailureMode(addPolicyFailureMode) + .loadPolicyFailureMode(loadPolicyFailureMode) + .build(); + } + @Override public BrooklynMementoRawData retrieveMementoRawData() { RebindExceptionHandler exceptionHandler = RebindExceptionHandlerImpl.builder() diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicManagedBundleMemento.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicManagedBundleMemento.java index 6d74587..a1d7d7f 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicManagedBundleMemento.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicManagedBundleMemento.java @@ -44,7 +44,8 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage protected String format; protected String url; protected String checksum; - + protected Boolean deleteable; + public Builder symbolicName(String symbolicName) { this.symbolicName = symbolicName; return self(); @@ -70,6 +71,11 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage return self(); } + public Builder deleteable(Boolean deleteable) { + this.deleteable = deleteable; + return self(); + } + public Builder from(ManagedBundleMemento other) { super.from(other); symbolicName = other.getSymbolicName(); @@ -77,6 +83,7 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage format = other.getFormat(); url = other.getUrl(); checksum = other.getChecksum(); + deleteable = other.getDeleteable(); return self(); } @@ -90,6 +97,7 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage private String format; private String url; private String checksum; + private Boolean deleteable; transient private ByteSource jarContent; @SuppressWarnings("unused") // For deserialisation @@ -102,6 +110,7 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage this.format = builder.format; this.url = builder.url; this.checksum = builder.checksum; + this.deleteable = builder.deleteable; } @Override @@ -130,10 +139,13 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage } @Override + public Boolean getDeleteable() { return deleteable; } + + @Override public ByteSource getJarContent() { return jarContent; } - + @Override public void setJarContent(ByteSource byteSource) { this.jarContent = byteSource; @@ -159,7 +171,8 @@ public class BasicManagedBundleMemento extends AbstractMemento implements Manage .add("version", getVersion()) .add("format", getFormat()) .add("url", getUrl()) - .add("checksum", getChecksum()); + .add("checksum", getChecksum()) + .add("deleteable", getDeleteable()); } @Override diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java index 51e3e6f..187c1ac 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java @@ -355,6 +355,8 @@ public class MementosGenerators { builder.url(bundle.getUrl()) .symbolicName(bundle.getSymbolicName()) .version(bundle.getSuppliedVersionString()) + .checksum(bundle.getChecksum()) + .deleteable(bundle.getDeleteable()) .format(bundle.getFormat()); return builder.build(); } diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java index c47f808..0e8431a 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicBrooklynTypeRegistry.java @@ -515,7 +515,7 @@ public class BasicBrooklynTypeRegistry implements BrooklynTypeRegistry { // if not osgi, everything is treated as a wrapper bundle if (osgi.isAbsent()) return true; VersionedName vn = VersionedName.fromString(bundleNameVersion); - Maybe<Bundle> b = osgi.get().findBundle(new BasicOsgiBundleWithUrl(vn.getSymbolicName(), vn.getOsgiVersionString(), null)); + Maybe<Bundle> b = osgi.get().findBundle(new BasicOsgiBundleWithUrl(vn.getSymbolicName(), vn.getOsgiVersionString(), null, null, null)); // if bundle not found it is an error or a race; we don't fail, but we shouldn't treat it as a wrapper if (b.isAbsent()) return false; 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 c921a31..826db9a 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 Boolean deleteable; private String osgiUniqueUrl; private String format; private String url; @@ -60,11 +61,16 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage this(name, version, url, null, credentials, checksum); } + /** @deprecated since 1.1 use larger constructor */ @Deprecated public BasicManagedBundle(String name, String version, String url, String format, Credentials credentials, @Nullable String checksum) { - init(name, version, url, format, credentials, checksum); + init(name, version, url, format, credentials, checksum, null); + } + + public BasicManagedBundle(String name, String version, String url, String format, Credentials credentials, @Nullable String checksum, @Nullable Boolean deleteable) { + init(name, version, url, format, credentials, checksum, deleteable); } - private void init(String name, String version, String url, String format, Credentials credentials, @Nullable String checksum) { + private void init(String name, String version, String url, String format, Credentials credentials, @Nullable String checksum, @Nullable Boolean deleteable) { if (name == null && version == null) { Preconditions.checkNotNull(url, "Either a URL or both name and version are required"); } else { @@ -77,18 +83,19 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage this.format = format; this.credentials = credentials; this.checksum = checksum; + this.deleteable = deleteable; } - private BasicManagedBundle(String id, String name, String version, String url, String format, Credentials credentials, @Nullable String checksum) { + private BasicManagedBundle(String id, String name, String version, String url, String format, Credentials credentials, @Nullable String checksum, @Nullable Boolean deleteable) { super(id); - init(name, version, url, format, credentials, checksum); + init(name, version, url, format, credentials, checksum, deleteable); } /** 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()); + BasicManagedBundle result = new BasicManagedBundle(oldOneForCoordinates.getId(), update.getSymbolicName(), update.getSuppliedVersionString(), update.getUrl(), update.getFormat(), update.getUrlCredential(), update.getChecksum(), update.getDeleteable()); // we have secondary logic which should accept a change in the OSGi unique URL, // but more efficient if we use the original URL result.osgiUniqueUrl = oldOneForCoordinates.getOsgiUniqueUrl(); @@ -99,7 +106,12 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage public boolean isNameResolved() { return symbolicName != null && version != null; } - + + @Override + public Boolean getDeleteable() { + return deleteable; + } + @Override public String getSymbolicName() { return symbolicName; @@ -264,7 +276,8 @@ public class BasicManagedBundle extends AbstractBrooklynObject implements Manage bundle.getUrl(), null, bundle.getUrlCredential(), - checksum); + checksum, + bundle instanceof ManagedBundle ? ((ManagedBundle)bundle).getDeleteable() : null); } public void setPersistenceNeeded(boolean val) { diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java index a644224..e218fdd 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BasicOsgiBundleWithUrl.java @@ -34,17 +34,23 @@ public class BasicOsgiBundleWithUrl implements CatalogBundle, OsgiBundleWithUrl private String symbolicName; private String version; private String url; + private Boolean deleteable; private Credentials credential; // for deserializing (not sure if needed?) @SuppressWarnings("unused") private BasicOsgiBundleWithUrl() {} + @Deprecated /** @deprecated since 1.1 use larger constructor */ public BasicOsgiBundleWithUrl(String name, String version, String url) { this(name, version, url, null); } - + @Deprecated /** @deprecated since 1.1 use larger constructor */ public BasicOsgiBundleWithUrl(String name, String version, String url, @Nullable Credentials cred) { + this(name, version, url, cred, null); + } + + public BasicOsgiBundleWithUrl(String name, String version, String url, @Nullable Credentials cred, @Nullable Boolean deleteable) { if (name == null && version == null) { Preconditions.checkNotNull(url, "Either a URL or both name and version are required"); } else { @@ -56,10 +62,11 @@ public class BasicOsgiBundleWithUrl implements CatalogBundle, OsgiBundleWithUrl this.version = version; this.url = url; this.credential = cred; + this.deleteable = deleteable; } public BasicOsgiBundleWithUrl(OsgiBundleWithUrl b) { - this(b.getSymbolicName(), b.getSuppliedVersionString(), b.getUrl()); + this(b.getSymbolicName(), b.getSuppliedVersionString(), b.getUrl(), b.getUrlCredential(), b.getDeleteable()); } @Override @@ -99,6 +106,11 @@ public class BasicOsgiBundleWithUrl implements CatalogBundle, OsgiBundleWithUrl } @Override + public Boolean getDeleteable() { + return deleteable; + } + + @Override public String toString() { return MoreObjects.toStringHelper(this) .add("symbolicName", symbolicName) diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java index f7203d2..110533c 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynBomYamlCatalogBundleResolver.java @@ -31,9 +31,7 @@ import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult; import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; import org.apache.brooklyn.util.collections.MutableMap; import org.apache.brooklyn.util.core.osgi.BundleMaker; -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.osgi.VersionedName; import org.apache.brooklyn.util.stream.InputStreamSource; import org.apache.brooklyn.util.stream.Streams; @@ -118,7 +116,7 @@ public class BrooklynBomYamlCatalogBundleResolver extends AbstractCatalogBundleR BasicManagedBundle basicManagedBundle = new BasicManagedBundle(vn.getSymbolicName(), vn.getVersionString(), null, BrooklynBomBundleCatalogBundleResolver.FORMAT, - null, null); + null, null, options.getDeleteable()); // if the submitted blueprint contains tags, we set them on the bundle, so they can be picked up and used to tag the plan. if( cm.containsKey("tags") && cm.get("tags") instanceof Iterable) { basicManagedBundle.tags().addTags((Iterable<?>)cm.get("tags")); diff --git a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynCatalogBundleResolver.java b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynCatalogBundleResolver.java index 685037b..5ee5286 100644 --- a/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynCatalogBundleResolver.java +++ b/core/src/main/java/org/apache/brooklyn/core/typereg/BrooklynCatalogBundleResolver.java @@ -99,6 +99,7 @@ public interface BrooklynCatalogBundleResolver extends ManagementContextInjectab protected boolean deferredStart = false; protected boolean start = true; protected boolean loadCatalogBom = true; + protected Boolean deleteable = null; protected ManagedBundle knownBundleMetadata = null; public void setFormat(String format) { @@ -156,6 +157,12 @@ public interface BrooklynCatalogBundleResolver extends ManagementContextInjectab public boolean isValidateTypes() { return validateTypes; } + + public Boolean getDeleteable() { return deleteable; } + + public void setDeleteable(Boolean deleteable) { + this.deleteable = deleteable; + } } } diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/BundleSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/BundleSummary.java index c8f442b..bb93fb0 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/BundleSummary.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/BundleSummary.java @@ -49,7 +49,10 @@ public class BundleSummary implements Comparable<BundleSummary> { @JsonInclude(value=Include.ALWAYS) private final List<TypeSummary> types = MutableList.of(); - + + @JsonInclude(value=Include.NON_NULL) + private final Boolean deleteable; + // not exported directly, but used to provide other top-level json fields // for specific types @JsonIgnore @@ -59,11 +62,13 @@ public class BundleSummary implements Comparable<BundleSummary> { BundleSummary() { symbolicName = null; version = null; + deleteable = null; } public BundleSummary(OsgiBundleWithUrl bundle) { symbolicName = bundle.getSymbolicName(); version = bundle.getSuppliedVersionString(); + deleteable = bundle.getDeleteable(); } /** Mutable map of other top-level metadata included on this DTO (eg listing config keys or effectors) */ @@ -98,7 +103,9 @@ public class BundleSummary implements Comparable<BundleSummary> { public List<TypeSummary> getTypes() { return types; } - + + public Boolean getDeleteable() { return deleteable; } + @Override public String toString() { return JavaClassNames.cleanSimpleClassName(this)+"["+symbolicName+":"+version+"]"; diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/BundleResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/BundleResource.java index 04bfbca..1b8cd13 100644 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/BundleResource.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/BundleResource.java @@ -222,7 +222,7 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund if (force==null) force = false; ReferenceWithError<OsgiBundleInstallationResult> result = ((ManagementContextInternal)mgmt()).getOsgiManager().get() - .install(source, format, force); + .install(source, format, force, true); if (result.hasError()) { // (rollback already done as part of install, if necessary) 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 7fc43d7..f3187c1 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 @@ -153,7 +153,7 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat } ReferenceWithError<OsgiBundleInstallationResult> result = ((ManagementContextInternal)mgmt()).getOsgiManager().get() - .install(source, format, forceUpdate); + .install(source, format, forceUpdate, true); if (result.hasError()) { // (rollback already done as part of install, if necessary) 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 1706b80..33f4ef3 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 @@ -44,7 +44,9 @@ import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecord; import org.apache.brooklyn.api.mgmt.ha.MementoCopyMode; import org.apache.brooklyn.api.mgmt.rebind.PersistenceExceptionHandler; 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.config.ConfigKey; import org.apache.brooklyn.core.BrooklynVersion; import org.apache.brooklyn.core.config.ConfigKeys; @@ -61,6 +63,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.RebindManagerImpl; import org.apache.brooklyn.core.server.BrooklynServerPaths; import org.apache.brooklyn.rest.api.ServerApi; import org.apache.brooklyn.rest.domain.*; @@ -588,16 +591,18 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv // create raw memento of persisted state to be imported BrooklynMementoRawData newMementoRawData = tempMgmt.getRebindManager().retrieveMementoRawData(); + BrooklynMementoManifest mementoManifest = persister.loadMementoManifest(newMementoRawData, + ((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", bundleJar.getValue().read()), "", false); + .install(InputStreamSource.of("Persistence import - bundle install - "+memento, bundleJar.getValue().read()), "", false, memento.getDeleteable()); if (bundleInstallResult.hasError()) { - if (log.isTraceEnabled()) { - log.trace("Unable to create, format '', returning 400: "+bundleInstallResult.getError().getMessage(), bundleInstallResult.getError()); - } + log.debug("Unable to create "+memento+", format '', throwing: "+bundleInstallResult.getError().getMessage(), bundleInstallResult.getError()); String errorMsg = ""; if (bundleInstallResult.getWithoutError()!=null) { errorMsg = bundleInstallResult.getWithoutError().getMessage(); @@ -607,20 +612,26 @@ public class ServerResource extends AbstractBrooklynRestResource implements Serv throw new Exception(errorMsg); } if (!OsgiBundleInstallationResult.ResultCode.IGNORING_BUNDLE_AREADY_INSTALLED.equals(bundleInstallResult.get().getCode()) && !OsgiBundleInstallationResult.ResultCode.UPDATED_EXISTING_BUNDLE.equals(bundleInstallResult.get().getCode())) { - TypeTransformer.bundleInstallationResult(bundleInstallResult.get(), mgmt(), brooklyn(), ui); + 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()); } } - // write persisted items and rebind to load applications + // store persisted items and rebind to load applications BrooklynMementoRawData.Builder result = BrooklynMementoRawData.builder(); + + // bundles already initialized +// result.bundles(newMementoRawData.getBundles()); + result.planeId(mgmt().getManagementPlaneIdMaybe().orNull()); result.entities(newMementoRawData.getEntities()); result.locations(newMementoRawData.getLocations()); result.policies(newMementoRawData.getPolicies()); result.enrichers(newMementoRawData.getEnrichers()); result.feeds(newMementoRawData.getFeeds()); - result.feeds(newMementoRawData.getFeeds()); result.catalogItems(newMementoRawData.getCatalogItems()); PersistenceObjectStore currentPersistenceStore = ((BrooklynMementoPersisterToObjectStore) mgmt().getRebindManager().getPersister()).getObjectStore();
