address most PR comments still to do: supertypes as query param, and restructure to hang both of catalog (remove POST /catalog/bundles)
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/206f744a Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/206f744a Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/206f744a Branch: refs/heads/master Commit: 206f744a84e93b364fbd912927ca6849a29873a3 Parents: 831db4a Author: Alex Heneveld <[email protected]> Authored: Fri Sep 22 11:42:02 2017 +0100 Committer: Alex Heneveld <[email protected]> Committed: Fri Sep 22 11:42:02 2017 +0100 ---------------------------------------------------------------------- .../core/mgmt/entitlement/Entitlements.java | 1 + .../org/apache/brooklyn/rest/api/BundleApi.java | 14 +++++++-- .../org/apache/brooklyn/rest/api/TypeApi.java | 7 +++-- .../brooklyn/rest/domain/BundleSummary.java | 7 +++++ .../apache/brooklyn/rest/domain/TypeDetail.java | 3 +- .../brooklyn/rest/domain/TypeSummary.java | 12 ++++++-- .../brooklyn/rest/resources/BundleResource.java | 25 +++++++++------- .../brooklyn/rest/resources/TypeResource.java | 2 ++ .../rest/transform/TypeTransformer.java | 31 +++++++++++--------- 9 files changed, 68 insertions(+), 34 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java index 60d998e..f7b5f72 100644 --- a/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java +++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/entitlement/Entitlements.java @@ -60,6 +60,7 @@ public class Entitlements { // ------------------- individual permissions + // TODO applies to bundles and registered types; should pass object or probably better add more entitlements? public static EntitlementClass<String> SEE_CATALOG_ITEM = new BasicEntitlementClassDefinition<String>("catalog.see", String.class); public static EntitlementClass<Object> ADD_CATALOG_ITEM = new BasicEntitlementClassDefinition<Object>("catalog.add", Object.class); public static EntitlementClass<StringAndArgument> MODIFY_CATALOG_ITEM = new BasicEntitlementClassDefinition<StringAndArgument>("catalog.modify", StringAndArgument.class); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/BundleApi.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/BundleApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/BundleApi.java index 2c2eeae..6bf46ea 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/BundleApi.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/BundleApi.java @@ -54,9 +54,13 @@ public interface BundleApi { responseContainer = "List") public List<BundleSummary> list( @ApiParam(name = "versions", value = "Whether to list 'latest' for each symbolic-name or 'all' versions", - required = false, defaultValue = "latest") + required = false, defaultValue = "latest") @QueryParam("versions") - String versions); + String versions, + @ApiParam(name = "detail", value = "Whether to include types and other detail info, default 'false'", + required = false, defaultValue = "false") + @QueryParam("detail") + boolean detail); @Path("/{symbolicName}") @GET @@ -66,7 +70,11 @@ public interface BundleApi { public List<BundleSummary> listVersions( @ApiParam(name = "symbolicName", value = "Bundle name to query", required = true) @PathParam("symbolicName") - String symbolicName); + String symbolicName, + @ApiParam(name = "detail", value = "Whether to include types and other detail info, default 'false'", + required = false, defaultValue = "false") + @QueryParam("detail") + boolean detail); @Path("/{symbolicName}/{version}") @GET http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/TypeApi.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/TypeApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/TypeApi.java index c39d5ef..f8167b5 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/TypeApi.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/TypeApi.java @@ -33,6 +33,8 @@ import javax.ws.rs.core.Response; import org.apache.brooklyn.rest.domain.TypeDetail; import org.apache.brooklyn.rest.domain.TypeSummary; +import com.google.common.annotations.Beta; + import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -41,6 +43,7 @@ import io.swagger.annotations.ApiParam; @Api("Types") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) +@Beta public interface TypeApi { @GET @@ -52,9 +55,9 @@ public interface TypeApi { required = false, defaultValue = "latest") @QueryParam("versions") String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") + @ApiParam(name = "regex", value = "Regular expression to search for (in name and description)") @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") + @ApiParam(name = "fragment", value = "Substring case-insensitive to search for (in name and description)") @QueryParam("fragment") @DefaultValue("") String fragment); @Path("/{nameOrAlias}") http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/BundleSummary.java ---------------------------------------------------------------------- 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 f14ee07..c8f442b 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 @@ -21,6 +21,7 @@ package org.apache.brooklyn.rest.domain; import java.util.List; import java.util.Map; +import org.apache.brooklyn.api.typereg.ManagedBundle; import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl; import org.apache.brooklyn.util.collections.MutableList; import org.apache.brooklyn.util.collections.MutableMap; @@ -35,6 +36,12 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.google.common.collect.ComparisonChain; +/** Summary info of {@link ManagedBundle} bundles in the catalog providing types, + * essentially the symbolic name and version. + * Extra fields listing the types may be added. + * <p> + * These are comparable in alpha-then-version order with most recent preferring non-snapshot versions first, + * as per {@link VersionComparator}. */ public class BundleSummary implements Comparable<BundleSummary> { private final String symbolicName; http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeDetail.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeDetail.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeDetail.java index 2f9e32f..0fafcbe 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeDetail.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeDetail.java @@ -24,6 +24,7 @@ import org.apache.brooklyn.api.typereg.RegisteredType.TypeImplementationPlan; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +/** As {@link TypeSummary} but including plan information. */ public class TypeDetail extends TypeSummary { public static class TypeImplementationPlanSummary { @@ -42,7 +43,7 @@ public class TypeDetail extends TypeSummary { return data; } } - private final TypeImplementationPlanSummary plan; + private TypeImplementationPlanSummary plan; /** Constructor for JSON deserialization use only. */ TypeDetail() { http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeSummary.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeSummary.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeSummary.java index 0a045d4..70942cf 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeSummary.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/domain/TypeSummary.java @@ -34,7 +34,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.google.common.collect.ComparisonChain; +import com.google.common.collect.ImmutableSet; +/** Summary info of {@link RegisteredType} items in the catalog. + * See {@link TypeDetail} for further information. */ public class TypeSummary implements Comparable<TypeSummary> { private final String symbolicName; @@ -52,7 +55,7 @@ public class TypeSummary implements Comparable<TypeSummary> { @JsonInclude(value=Include.NON_EMPTY) private Set<String> aliases; @JsonInclude(value=Include.NON_EMPTY) - private Set<Object> supertypes; + private Set<String> supertypes; @JsonInclude(value=Include.NON_EMPTY) private Set<Object> tags; @@ -88,7 +91,10 @@ public class TypeSummary implements Comparable<TypeSummary> { iconUrl = t.getIconUrl(); aliases = t.getAliases(); - supertypes = t.getSuperTypes(); + supertypes = ImmutableSet.copyOf(t.getSuperTypes().stream().map(s -> + s instanceof Class ? ((Class<?>)s).getName() : + s instanceof RegisteredType ? ((RegisteredType)s).getId() : + s.toString()).iterator()); tags = t.getTags(); deprecated = t.isDeprecated(); @@ -172,7 +178,7 @@ public class TypeSummary implements Comparable<TypeSummary> { return aliases; } - public Set<Object> getSupertypes() { + public Set<String> getSupertypes() { return supertypes; } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/BundleResource.java ---------------------------------------------------------------------- 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 a2a6532..b4664ea 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 @@ -58,16 +58,18 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund private static final String LATEST = "latest"; @Override - public List<BundleSummary> list(String versions) { - return list(TypeResource.isLatestOnly(versions, true), Predicates.alwaysTrue()); + public List<BundleSummary> list(String versions, boolean detail) { + return list(Predicates.alwaysTrue(), TypeResource.isLatestOnly(versions, true), detail); } - private List<BundleSummary> list(boolean onlyLatest, Predicate<String> symbolicNameFilter) { + private List<BundleSummary> list(Predicate<String> symbolicNameFilter, boolean onlyLatest, boolean detail) { Map<VersionedName,ManagedBundle> bundles = new TreeMap<>(VersionedNameComparator.INSTANCE); for (ManagedBundle b: ((ManagementContextInternal)mgmt()).getOsgiManager().get().getManagedBundles().values()) { + if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, b.getId())) { + continue; + } if (symbolicNameFilter.apply(b.getSymbolicName())) { - // TODO entitlements for bundles VersionedName key = onlyLatest ? new VersionedName(b.getSymbolicName(), LATEST) : b.getVersionedName(); ManagedBundle oldBundle = bundles.get(key); if (oldBundle==null || oldBundle.getVersionedName().compareTo(b.getVersionedName()) > 0) { @@ -75,20 +77,20 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund } } } - return toBundleSummary(bundles.values()); + return toBundleSummary(bundles.values(), detail); } - private List<BundleSummary> toBundleSummary(Iterable<ManagedBundle> sortedItems) { + private List<BundleSummary> toBundleSummary(Iterable<ManagedBundle> sortedItems, boolean detail) { List<BundleSummary> result = MutableList.of(); for (ManagedBundle t: sortedItems) { - result.add(TypeTransformer.bundleSummary(brooklyn(), t, ui.getBaseUriBuilder(), mgmt())); + result.add(TypeTransformer.bundleSummary(brooklyn(), t, ui.getBaseUriBuilder(), mgmt(), detail)); } return result; } @Override - public List<BundleSummary> listVersions(String symbolicName) { - return list(false, Predicates.equalTo(symbolicName)); + public List<BundleSummary> listVersions(String symbolicName, boolean detail) { + return list(Predicates.equalTo(symbolicName), false, detail); } @Override @@ -98,12 +100,13 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund } protected ManagedBundle lookup(String symbolicName, String version) { - // TODO entitlements for bundles - ManagedBundle b = ((ManagementContextInternal)mgmt()).getOsgiManager().get().getManagedBundle(new VersionedName(symbolicName, version)); if (b==null) { throw WebResourceUtils.notFound("Bundle with id '%s:%s' not found", symbolicName, version); } + if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, b.getId())) { + throw WebResourceUtils.notFound("Bundle with id '%s:%s' not found", symbolicName, version); + } return b; } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/TypeResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/TypeResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/TypeResource.java index 86de57d..52627e3 100644 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/TypeResource.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/TypeResource.java @@ -48,6 +48,7 @@ import org.apache.brooklyn.util.text.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.annotations.Beta; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; @@ -55,6 +56,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.io.Files; @HaHotStateRequired +@Beta public class TypeResource extends AbstractBrooklynRestResource implements TypeApi { private static final Logger log = LoggerFactory.getLogger(TypeResource.class); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/206f744a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java index fb3fdd3..4c9ccb2 100644 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/transform/TypeTransformer.java @@ -79,10 +79,10 @@ public class TypeTransformer { } private static <T extends TypeSummary> T embellish(T result, RegisteredType item, boolean detail, BrooklynRestResourceUtils b, UriBuilder ub) { - result.getExtraFields().put("links", makeLinks(item, ub)); + result.setExtraField("links", makeLinks(item, ub)); if (RegisteredTypes.isTemplate(item)) { - result.getExtraFields().put("template", true); + result.setExtraField("template", true); } if (item.getIconUrl()!=null) { result.setIconUrl(tidyIconLink(b, item, item.getIconUrl(), ub)); @@ -103,7 +103,7 @@ public class TypeTransformer { config.add(EntityTransformer.adjunctConfigSummary(input)); } - result.getExtraFields().put("config", config); + result.setExtraField("config", config); } catch (Exception e) { Exceptions.propagateIfFatal(e); log.trace("Unable to create spec for "+item+": "+e, e); @@ -111,7 +111,7 @@ public class TypeTransformer { } else if (RegisteredTypes.isSubtypeOf(item, Location.class)) { // TODO include config on location specs? (wasn't done previously so not needed, but good for completeness) - result.getExtraFields().put("config", Collections.emptyMap()); + result.setExtraField("config", Collections.emptyMap()); } } return result; @@ -135,9 +135,9 @@ public class TypeTransformer { for (Effector<?> x: type.getEffectors()) effectors.add(EffectorTransformer.effectorSummaryForCatalog(x)); - result.getExtraFields().put("config", config); - result.getExtraFields().put("sensors", sensors); - result.getExtraFields().put("effectors", effectors); + result.setExtraField("config", config); + result.setExtraField("sensors", sensors); + result.setExtraField("effectors", effectors); } catch (Exception e) { Exceptions.propagateIfFatal(e); @@ -152,19 +152,22 @@ public class TypeTransformer { } } - public static BundleSummary bundleSummary(BrooklynRestResourceUtils brooklyn, ManagedBundle b, UriBuilder baseUriBuilder, ManagementContext mgmt) { + public static BundleSummary bundleSummary(BrooklynRestResourceUtils brooklyn, ManagedBundle b, UriBuilder baseUriBuilder, ManagementContext mgmt, boolean detail) { BundleSummary result = new BundleSummary(b); - for (RegisteredType t: mgmt.getTypeRegistry().getMatching(RegisteredTypePredicates.containingBundle(b))) { - result.addType(summary(brooklyn, t, baseUriBuilder)); + if (detail) { + result.setExtraField("osgiVersion", b.getOsgiVersionString()); + result.setExtraField("checksum", b.getChecksum()); + } + if (detail) { + for (RegisteredType t: mgmt.getTypeRegistry().getMatching(RegisteredTypePredicates.containingBundle(b))) { + result.addType(summary(brooklyn, t, baseUriBuilder)); + } } return result; } public static BundleSummary bundleDetails(BrooklynRestResourceUtils brooklyn, ManagedBundle b, UriBuilder baseUriBuilder, ManagementContext mgmt) { - BundleSummary result = bundleSummary(brooklyn, b, baseUriBuilder, mgmt); - result.getExtraFields().put("osgiVersion", b.getOsgiVersionString()); - result.getExtraFields().put("checksum", b.getChecksum()); - return result; + return bundleSummary(brooklyn, b, baseUriBuilder, mgmt, true); } public static BundleInstallationRestResult bundleInstallationResult(OsgiBundleInstallationResult in, ManagementContext mgmt, BrooklynRestResourceUtils brooklynU, UriInfo ui) {
