remaining PR comments move /bundles and /types under /catalog, remove subtype, remove autodetect create in 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/05ad45e7 Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/05ad45e7 Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/05ad45e7 Branch: refs/heads/master Commit: 05ad45e7ff1f78f655d7d3aa03aae557e70b8fb5 Parents: 206f744 Author: Alex Heneveld <[email protected]> Authored: Fri Sep 22 13:07:19 2017 +0100 Committer: Alex Heneveld <[email protected]> Committed: Fri Sep 22 13:28:43 2017 +0100 ---------------------------------------------------------------------- .../org/apache/brooklyn/rest/api/BundleApi.java | 23 +- .../apache/brooklyn/rest/api/CatalogApi.java | 56 +- .../apache/brooklyn/rest/api/SubtypeApi.java | 96 -- .../org/apache/brooklyn/rest/api/TypeApi.java | 9 +- .../apache/brooklyn/rest/BrooklynRestApi.java | 2 - .../brooklyn/rest/resources/BundleResource.java | 20 - .../rest/resources/SubtypeResource.java | 82 -- .../brooklyn/rest/resources/TypeResource.java | 21 +- .../BundleAndTypeAndSubtypeResourcesTest.java | 1093 ----------------- .../resources/BundleAndTypeResourcesTest.java | 1098 ++++++++++++++++++ 10 files changed, 1179 insertions(+), 1321 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/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 6bf46ea..2eb5ed8 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 @@ -42,8 +42,8 @@ import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -@Path("/bundles") -@Api("Bundles") +@Path("/catalog/bundles") +@Api("Catalog Bundles") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public interface BundleApi { @@ -144,23 +144,4 @@ public interface BundleApi { @QueryParam("force") @DefaultValue("false") Boolean force); - @POST - @Consumes // anything (if doesn't match other methods with specific content types - @ApiOperation( - value = "Adds types to the registry from the given item, autodetecting type as ZIP/JAR or BOM YAML", - response = BundleInstallationRestResult.class - ) - @ApiResponses(value = { - @ApiResponse(code = 400, message = "Error processing the given archive, or the catalog.bom is invalid"), - @ApiResponse(code = 201, message = "Catalog items added successfully") - }) - public Response createAutodetecting( - @ApiParam( - name = "item", - value = "Item to install, as JAR/ZIP or Catalog YAML (autodetected)", - required = true) - byte[] item, - @ApiParam(name = "force", value = "Whether to forcibly remove it, even if in use and/or errors", required = false, defaultValue = "false") - @QueryParam("force") @DefaultValue("false") - Boolean force); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java index 3cbae5b..cb4298f 100644 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java +++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java @@ -47,9 +47,6 @@ import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -/** @deprecated since 0.12.0 use /bundle, /type, and /subtype */ -// but we will probably keep this around for a while as many places use it -@Deprecated @Path("/catalog") @Api("Catalog") @Consumes(MediaType.APPLICATION_JSON) @@ -156,6 +153,9 @@ public interface CatalogApi { @QueryParam("forceUpdate") @DefaultValue("false") boolean forceUpdate); + /** @deprecated since 0.12.0 delete the bundle via DELETE /catalog/bundles/xxx */ + // but we will probably keep this around for a while as many places use it + @Deprecated @DELETE @Path("/applications/{symbolicName}/{version}") @ApiOperation( @@ -173,6 +173,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the application or template to delete", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 delete the bundle via DELETE /catalog/bundles/xxx */ + // but we will probably keep this around for a while as many places use it + @Deprecated @DELETE @Path("/entities/{symbolicName}/{version}") @ApiOperation( @@ -190,6 +193,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the entity or template to delete", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 delete the bundle via DELETE /catalog/bundles/xxx */ + // but we will probably keep this around for a while as many places use it + @Deprecated @DELETE @Path("/policies/{policyId}/{version}") @ApiOperation( @@ -206,6 +212,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the policy to delete", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 delete the bundle via DELETE /catalog/bundles/xxx */ + // but we will probably keep this around for a while as many places use it + @Deprecated @DELETE @Path("/locations/{locationId}/{version}") @ApiOperation( @@ -223,6 +232,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the location to delete", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/entities") @ApiOperation(value = "List available entity types optionally matching a query", @@ -237,6 +249,9 @@ public interface CatalogApi { @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions); // bad name - it is just templates + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/applications") @ApiOperation(value = "Fetch a list of templates (for applications) optionally matching a query", @@ -250,6 +265,9 @@ public interface CatalogApi { @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)") @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/entities/{symbolicName}/{version}") @ApiOperation( @@ -268,6 +286,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the entity or template to retrieve", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/applications/{symbolicName}/{version}") @ApiOperation( @@ -286,6 +307,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/policies") @ApiOperation(value = "List available policies optionally matching a query", @@ -299,6 +323,9 @@ public interface CatalogApi { @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)") @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/policies/{policyId}/{version}") @ApiOperation( @@ -316,6 +343,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/locations") @ApiOperation(value = "List available locations optionally matching a query", @@ -329,6 +359,9 @@ public interface CatalogApi { @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)") @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/locations/{locationId}/{version}") @ApiOperation( @@ -364,6 +397,10 @@ public interface CatalogApi { @ApiParam(name = "version", value = "version identifier of catalog item (application, entity, policy, location)", required=true) @PathParam("version") String version); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=...; + * deprecation/disabling needs to be done in the bundle, and we might support deprecating/disabling bundles */ + // but we will probably keep this around for a while as many places use it + @Deprecated @POST @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN}) @ApiResponses(value = { @@ -376,6 +413,10 @@ public interface CatalogApi { @ApiParam(name = "deprecated", value = "Whether or not the catalog item is deprecated", required = true) boolean deprecated); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=...; + * deprecation/disabling needs to be done in the bundle, and we might support deprecating/disabling bundles */ + // but we will probably keep this around for a while as many places use it + @Deprecated @POST @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM, MediaType.TEXT_PLAIN}) @ApiResponses(value = { @@ -388,6 +429,9 @@ public interface CatalogApi { @ApiParam(name = "disabled", value = "Whether or not the catalog item is disabled", required = true) boolean disabled); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/enrichers") @ApiOperation(value = "List available enrichers types optionally matching a query", @@ -401,6 +445,9 @@ public interface CatalogApi { @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)") @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions); + /** @deprecated since 0.12.0 use /catalog/bundles and /catalog/types?supertype=... */ + // but we will probably keep this around for a while as many places use it + @Deprecated @GET @Path("/enrichers/{enricherId}/{version}") @ApiOperation(value = "Fetch an enricher's definition from the catalog", @@ -415,6 +462,9 @@ public interface CatalogApi { @ApiParam(name = "version", value = "The version identifier of the enricher to retrieve", required = true) @PathParam("version") String version) throws Exception; + /** @deprecated since 0.12.0 delete the bundle via DELETE /catalog/bundles/xxx */ + // but we will probably keep this around for a while as many places use it + @Deprecated @DELETE @Path("/enrichers/{enricherId}/{version}") @ApiOperation(value = "Deletes a specific version of an enricher's definition from the catalog") http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/SubtypeApi.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/SubtypeApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/SubtypeApi.java deleted file mode 100644 index 01890c5..0000000 --- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/SubtypeApi.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.brooklyn.rest.api; - -import java.util.List; - -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; - -import org.apache.brooklyn.rest.domain.TypeSummary; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; - -@Path("/subtypes") -@Api("Subtypes") -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public interface SubtypeApi { - - @Path("/{supertype}") - @GET - @ApiOperation(value = "Get all known types which declare the given argument as a supertype", - response = TypeSummary.class, responseContainer = "List") - public List<TypeSummary> list( - @ApiParam(name = "supertype", value = "Supertype to query", required = true) - @PathParam("supertype") - String supertype, - @ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", required = false, defaultValue = "latest") - @QueryParam("versions") - String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") - @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") - @QueryParam("fragment") @DefaultValue("") String fragment); - - // conveniences for common items where internally it uses java class name - // caller can of course use /subtypes/org.apache.brooklyn.api.Entity - - @GET @Path("/application") - @ApiOperation(value = "Get all applications", response = TypeSummary.class, responseContainer = "List") - public List<TypeSummary> listApplications(@ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", required = false, defaultValue = "latest") @QueryParam("versions") String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") @QueryParam("fragment") @DefaultValue("") String fragment); - - @GET @Path("/entity") - @ApiOperation(value = "Get all entities", response = TypeSummary.class, responseContainer = "List") - public List<TypeSummary> listEntities(@ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", required = false, defaultValue = "latest") @QueryParam("versions") String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") @QueryParam("fragment") @DefaultValue("") String fragment); - - @GET @Path("/policy") - @ApiOperation(value = "Get all policies", response = TypeSummary.class, responseContainer = "List") - public List<TypeSummary> listPolicies(@ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", required = false, defaultValue = "latest") @QueryParam("versions") String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") @QueryParam("fragment") @DefaultValue("") String fragment); - - @GET @Path("/enricher") - @ApiOperation(value = "Get all enrichers", response = TypeSummary.class, responseContainer = "List") - public List<TypeSummary> listEnrichers(@ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", required = false, defaultValue = "latest") @QueryParam("versions") String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") @QueryParam("fragment") @DefaultValue("") String fragment); - - @GET @Path("/location") - // note some (deprecated) locations are only available on location manager - @ApiOperation(value = "Get all locations stored in the registry", response = TypeSummary.class, responseContainer = "List") - public List<TypeSummary> listLocations(@ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", required = false, defaultValue = "latest") @QueryParam("versions") String versions, - @ApiParam(name = "regex", value = "Regular expression to search for") @QueryParam("regex") @DefaultValue("") String regex, - @ApiParam(name = "fragment", value = "Substring case-insensitive to search for") @QueryParam("fragment") @DefaultValue("") String fragment); - - // in future could have others, eg: tasks, feeds, etc - -} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/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 f8167b5..914dce2 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 @@ -39,8 +39,8 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; -@Path("/types") -@Api("Types") +@Path("/catalog/types") +@Api("Catalog Types") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Beta @@ -51,8 +51,11 @@ public interface TypeApi { response = TypeSummary.class, responseContainer = "List") public List<TypeSummary> list( + @ApiParam(name = "supertype", value = "Supertype to require (beta, currently intended only for 'entity', 'policy', 'enricher', and 'location')", required = false) + @QueryParam("supertype") + String supertype, @ApiParam(name = "versions", value = "Whether to list 'latest' of each symbolic-name or 'all' versions", - required = false, defaultValue = "latest") + required = false, defaultValue = "latest") @QueryParam("versions") String versions, @ApiParam(name = "regex", value = "Regular expression to search for (in name and description)") http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java index b3eb4e4..e172127 100644 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java @@ -38,7 +38,6 @@ import org.apache.brooklyn.rest.resources.PolicyResource; import org.apache.brooklyn.rest.resources.ScriptResource; import org.apache.brooklyn.rest.resources.SensorResource; import org.apache.brooklyn.rest.resources.ServerResource; -import org.apache.brooklyn.rest.resources.SubtypeResource; import org.apache.brooklyn.rest.resources.TypeResource; import org.apache.brooklyn.rest.resources.UsageResource; import org.apache.brooklyn.rest.util.DefaultExceptionMapper; @@ -56,7 +55,6 @@ public class BrooklynRestApi { resources.add(new LocationResource()); resources.add(new CatalogResource()); resources.add(new TypeResource()); - resources.add(new SubtypeResource()); resources.add(new BundleResource()); resources.add(new ApplicationResource()); resources.add(new EntityResource()); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/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 b4664ea..24fe3ca 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 @@ -19,7 +19,6 @@ package org.apache.brooklyn.rest.resources; import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -44,7 +43,6 @@ import org.apache.brooklyn.util.exceptions.Exceptions; import org.apache.brooklyn.util.exceptions.ReferenceWithError; import org.apache.brooklyn.util.osgi.VersionedName; import org.apache.brooklyn.util.osgi.VersionedName.VersionedNameComparator; -import org.apache.brooklyn.util.yaml.Yamls; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -168,22 +166,4 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund return Response.status(Status.CREATED).entity( resultR ).build(); } - @Override - public Response createAutodetecting(byte[] item, Boolean force) { - Throwable yamlException = null; - try { - MutableList.copyOf( Yamls.parseAll(new InputStreamReader(new ByteArrayInputStream(item))) ); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - yamlException = e; - } - - if (yamlException==null) { - // treat as yaml if it parsed - return createFromYaml(new String(item), force); - } - - return createFromArchive(item, force); - } } - http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SubtypeResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SubtypeResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SubtypeResource.java deleted file mode 100644 index 12716b3..0000000 --- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SubtypeResource.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.brooklyn.rest.resources; - -import java.util.List; - -import org.apache.brooklyn.api.entity.Application; -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.location.Location; -import org.apache.brooklyn.api.policy.Policy; -import org.apache.brooklyn.api.sensor.Enricher; -import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.core.typereg.RegisteredTypePredicates; -import org.apache.brooklyn.core.typereg.RegisteredTypes; -import org.apache.brooklyn.rest.api.SubtypeApi; -import org.apache.brooklyn.rest.domain.TypeSummary; -import org.apache.brooklyn.rest.filter.HaHotStateRequired; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.text.StringPredicates; -import org.apache.brooklyn.util.text.Strings; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; - -@HaHotStateRequired -public class SubtypeResource extends AbstractBrooklynRestResource implements SubtypeApi { - - @SuppressWarnings("unused") - private static final Logger log = LoggerFactory.getLogger(SubtypeResource.class); - - @Override - public List<TypeSummary> list(String supertype, String versions, String regex, String fragment) { - List<Predicate<RegisteredType>> filters = MutableList.<Predicate<RegisteredType>>of() - .append(RegisteredTypePredicates.entitledToSee(mgmt())) - .append(RegisteredTypePredicates.subtypeOf(supertype)); - if (TypeResource.isLatestOnly(versions, true)) { - // TODO inefficient - does n^2 comparisons where n is sufficient - // create RegisteredTypes.filterBestVersions to do a list after the initial parse - // (and javadoc in predicate method below) - filters.add(RegisteredTypePredicates.isBestVersion(mgmt())); - } - if (Strings.isNonEmpty(regex)) { - filters.add(RegisteredTypePredicates.nameOrAlias(StringPredicates.containsRegex(regex))); - } - if (Strings.isNonEmpty(fragment)) { - filters.add(RegisteredTypePredicates.nameOrAlias(StringPredicates.containsLiteralIgnoreCase(fragment))); - } - Predicate<RegisteredType> filter = Predicates.and(filters); - ImmutableList<RegisteredType> sortedItems = - FluentIterable.from(brooklyn().getTypeRegistry().getMatching(filter)) - .toSortedList(RegisteredTypes.RegisteredTypeNameThenBestFirstComparator.INSTANCE); - return TypeResource.toTypeSummary(brooklyn(), sortedItems, ui.getBaseUriBuilder()); - } - - @Override public List<TypeSummary> listApplications(String versions, String regex, String fragment) { return list(Application.class.getName(), versions, regex, fragment); } - @Override public List<TypeSummary> listEntities(String versions, String regex, String fragment) { return list(Entity.class.getName(), versions, regex, fragment); } - @Override public List<TypeSummary> listPolicies(String versions, String regex, String fragment) { return list(Policy.class.getName(), versions, regex, fragment); } - @Override public List<TypeSummary> listEnrichers(String versions, String regex, String fragment) { return list(Enricher.class.getName(), versions, regex, fragment); } - @Override public List<TypeSummary> listLocations(String versions, String regex, String fragment) { return list(Location.class.getName(), versions, regex, fragment); } - -} - http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/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 52627e3..cf9f40f 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 @@ -27,6 +27,11 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriBuilder; +import org.apache.brooklyn.api.entity.Application; +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.location.Location; +import org.apache.brooklyn.api.policy.Policy; +import org.apache.brooklyn.api.sensor.Enricher; import org.apache.brooklyn.api.typereg.RegisteredType; import org.apache.brooklyn.core.catalog.internal.CatalogUtils; import org.apache.brooklyn.core.mgmt.entitlement.Entitlements; @@ -75,9 +80,23 @@ public class TypeResource extends AbstractBrooklynRestResource implements TypeAp } @Override - public List<TypeSummary> list(String versions, String regex, String fragment) { + public List<TypeSummary> list(String supertype, String versions, String regex, String fragment) { List<Predicate<RegisteredType>> filters = MutableList.<Predicate<RegisteredType>>of() .append(RegisteredTypePredicates.entitledToSee(mgmt())); + if (Strings.isNonBlank(supertype)) { + // rewrite certain well known ones + // (in future this should happen automatically as Entity.class should be known as user-friendly name 'entity') + if ("entity".equals(supertype)) supertype = Entity.class.getName(); + else if ("enricher".equals(supertype)) supertype = Enricher.class.getName(); + else if ("policy".equals(supertype)) supertype = Policy.class.getName(); + else if ("location".equals(supertype)) supertype = Location.class.getName(); + // TODO application probably isn't at all interesting; keep it for backward compatibility, + // and meanwhile sort out things like "template" vs "quick launch" + // (probably adding tags on the API) + else if ("application".equals(supertype)) supertype = Application.class.getName(); + + filters.add(RegisteredTypePredicates.subtypeOf(supertype)); + } if (TypeResource.isLatestOnly(versions, true)) { // TODO inefficient - does n^2 comparisons where n is sufficient // create RegisteredTypes.filterBestVersions to do a list after the initial parse http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/05ad45e7/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeAndSubtypeResourcesTest.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeAndSubtypeResourcesTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeAndSubtypeResourcesTest.java deleted file mode 100644 index 03578f1..0000000 --- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeAndSubtypeResourcesTest.java +++ /dev/null @@ -1,1093 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.brooklyn.rest.resources; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - -import java.awt.Image; -import java.awt.Toolkit; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import javax.ws.rs.core.GenericType; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.brooklyn.api.entity.Entity; -import org.apache.brooklyn.api.objs.BrooklynObject; -import org.apache.brooklyn.api.objs.Configurable; -import org.apache.brooklyn.api.objs.Identifiable; -import org.apache.brooklyn.api.policy.Policy; -import org.apache.brooklyn.api.typereg.ManagedBundle; -import org.apache.brooklyn.api.typereg.OsgiBundleWithUrl; -import org.apache.brooklyn.api.typereg.RegisteredType; -import org.apache.brooklyn.core.entity.EntityPredicates; -import org.apache.brooklyn.core.mgmt.ha.OsgiManager; -import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; -import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest; -import org.apache.brooklyn.core.test.entity.TestEntity; -import org.apache.brooklyn.enricher.stock.Aggregator; -import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy; -import org.apache.brooklyn.rest.domain.BundleInstallationRestResult; -import org.apache.brooklyn.rest.domain.BundleSummary; -import org.apache.brooklyn.rest.domain.TypeDetail; -import org.apache.brooklyn.rest.domain.TypeSummary; -import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest; -import org.apache.brooklyn.test.Asserts; -import org.apache.brooklyn.test.support.TestResourceUnavailableException; -import org.apache.brooklyn.util.collections.MutableList; -import org.apache.brooklyn.util.collections.MutableMap; -import org.apache.brooklyn.util.collections.MutableSet; -import org.apache.brooklyn.util.core.ResourceUtils; -import org.apache.brooklyn.util.core.osgi.BundleMaker; -import org.apache.brooklyn.util.javalang.JavaClassNames; -import org.apache.brooklyn.util.javalang.Reflections; -import org.apache.brooklyn.util.os.Os; -import org.apache.brooklyn.util.osgi.OsgiTestResources; -import org.apache.brooklyn.util.stream.Streams; -import org.apache.http.HttpHeaders; -import org.eclipse.jetty.http.HttpStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.Assert; -import org.testng.annotations.Test; -import org.testng.reporters.Files; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; - -public class BundleAndTypeAndSubtypeResourcesTest extends BrooklynRestResourceTest { - - private static final Logger log = LoggerFactory.getLogger(BundleAndTypeAndSubtypeResourcesTest.class); - - private static String TEST_VERSION = "0.1.2"; - private static String TEST_LASTEST_VERSION = "0.1.3"; - - private Collection<ManagedBundle> initialBundles; - - @Override - protected boolean useLocalScannedCatalog() { - return true; - } - - @Override - protected void initClass() throws Exception { - super.initClass(); - // cache initially installed bundles - OsgiManager osgi = ((ManagementContextInternal)getManagementContext()).getOsgiManager().get(); - initialBundles = osgi.getManagedBundles().values(); - } - - protected void initMethod() throws Exception { - super.initMethod(); - - // and reset OSGi container - OsgiManager osgi = ((ManagementContextInternal)getManagementContext()).getOsgiManager().get(); - for (ManagedBundle b: osgi.getManagedBundles().values()) { - if (!initialBundles.contains(b)) { - osgi.uninstallUploadedBundle(b); - } - } - } - - @Test - /** based on CampYamlLiteTest */ - public void testRegisterCustomEntityTopLevelSyntaxWithBundleWhereEntityIsFromCoreAndIconFromBundle() { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - String symbolicName = "my.catalog.entity.id"; - String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL; - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " libraries:", - " - url: " + bundleUrl, - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"); - - Response response = client().path("/bundles") - .post(yaml); - - assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode()); - BundleInstallationRestResult installed = response.readEntity(BundleInstallationRestResult.class); - Asserts.assertSize(installed.getTypes().values(), 1); - TypeSummary installedItem = installed.getTypes().get(symbolicName+":"+TEST_VERSION); - Assert.assertNotNull(installedItem, ""+installed.getTypes()); - - TypeDetail entityItem = client().path("/types/"+symbolicName + "/" + TEST_VERSION) - .get(TypeDetail.class); - - Assert.assertEquals(new TypeSummary(entityItem), installedItem); - Assert.assertNotNull(entityItem.getPlan()); - Assert.assertTrue(((String)entityItem.getPlan().getData()).contains("org.apache.brooklyn.core.test.entity.TestEntity")); - - assertEquals(entityItem.getSymbolicName(), symbolicName); - assertEquals(entityItem.getVersion(), TEST_VERSION); - - // also check it's included in various lists - List<TypeSummary> list1 = client().path("/types/"+symbolicName).get(new GenericType<List<TypeSummary>>() {}); - assertEquals(list1, MutableList.of(installedItem)); - List<TypeSummary> list2 = client().path("/types").get(new GenericType<List<TypeSummary>>() {}); - Assert.assertTrue(list2.contains(installedItem), ""+list2); - List<TypeSummary> list3 = client().path("/subtypes/entity").get(new GenericType<List<TypeSummary>>() {}); - Assert.assertTrue(list3.contains(installedItem), ""+list3); - - // and internally let's check we have libraries - RegisteredType item = getManagementContext().getTypeRegistry().get(symbolicName, TEST_VERSION); - Assert.assertNotNull(item); - Collection<OsgiBundleWithUrl> libs = item.getLibraries(); - assertEquals(libs.size(), 1); - assertEquals(Iterables.getOnlyElement(libs).getUrl(), bundleUrl); - - // now let's check other things on the item - URI expectedIconUrl = URI.create(getEndpointAddress() + "/types/" + symbolicName + "/" + entityItem.getVersion()+"/icon").normalize(); - assertEquals(entityItem.getDisplayName(), "My Catalog App"); - assertEquals(entityItem.getDescription(), "My description"); - assertEquals(entityItem.getIconUrl(), expectedIconUrl.getPath()); - assertEquals(item.getIconUrl(), "classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif"); - - // an InterfacesTag should be created for every catalog item - if (checkTraits(false)) { - @SuppressWarnings("unchecked") - Map<String, List<String>> traitsMapTag = Iterables.getOnlyElement(Iterables.filter(entityItem.getTags(), Map.class)); - List<String> actualInterfaces = traitsMapTag.get("traits"); - List<Class<?>> expectedInterfaces = Reflections.getAllInterfaces(TestEntity.class); - assertEquals(actualInterfaces.size(), expectedInterfaces.size()); - for (Class<?> expectedInterface : expectedInterfaces) { - assertTrue(actualInterfaces.contains(expectedInterface.getName())); - } - } - - byte[] iconData = client().path("/types/" + symbolicName + "/" + TEST_VERSION+"/icon").get(byte[].class); - assertEquals(iconData.length, 43); - } - - @Test - public void testRegisterOsgiPolicyTopLevelSyntax() { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - String symbolicName = "my.catalog.entity.id."+JavaClassNames.niceClassAndMethod(); - String policyType = "org.apache.brooklyn.test.osgi.entities.SimplePolicy"; - String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL; - - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: policy", - " name: My Catalog App", - " description: My description", - " libraries:", - " - url: " + bundleUrl, - " item:", - " type: " + policyType); - - TypeSummary installedItem = Iterables.getOnlyElement( client().path("/bundles") - .post(yaml, BundleInstallationRestResult.class).getTypes().values() ); - - assertEquals(installedItem.getSymbolicName(), symbolicName); - assertEquals(installedItem.getVersion(), TEST_VERSION); - Assert.assertTrue(installedItem.getSupertypes().contains(Policy.class.getName()), ""+installedItem.getSupertypes()); - } - - @Test - public void testFilterListOfEntitiesByName() { - List<TypeSummary> entities = client().path("/types") - .query("fragment", "vaNIllasOFTWAREpROCESS").get(new GenericType<List<TypeSummary>>() {}); - log.info("Matching entities: " + entities); - assertEquals(entities.size(), 1); - - entities = client().path("/subtypes/entity") - .query("fragment", "vaNIllasOFTWAREpROCESS").get(new GenericType<List<TypeSummary>>() {}); - log.info("Matching entities: " + entities); - assertEquals(entities.size(), 1); - - List<TypeSummary> entities2 = client().path("/types") - .query("regex", "[Vv]an.[alS]+oftware\\w+").get(new GenericType<List<TypeSummary>>() {}); - assertEquals(entities2.size(), 1); - - assertEquals(entities, entities2); - - entities = client().path("/subtypes/entity") - .query("fragment", "bweqQzZ").get(new GenericType<List<TypeSummary>>() {}); - Asserts.assertSize(entities, 0); - - entities = client().path("/subtypes/entity") - .query("regex", "bweq+z+").get(new GenericType<List<TypeSummary>>() {}); - Asserts.assertSize(entities, 0); - } - - @Test - public void testGetCatalogEntityIconDetails() throws IOException { - String catalogItemId = "testGetCatalogEntityIconDetails"; - addTestCatalogItemAsEntity(catalogItemId); - Response response = client().path(URI.create("/types/" + catalogItemId + "/" + TEST_VERSION + "/icon")) - .get(); - response.bufferEntity(); - Assert.assertEquals(response.getStatus(), 200); - Assert.assertEquals(response.getMediaType(), MediaType.valueOf("image/png")); - Image image = Toolkit.getDefaultToolkit().createImage(Files.readFile(response.readEntity(InputStream.class))); - Assert.assertNotNull(image); - } - - private void addTestCatalogItemAsEntity(String catalogItemId) { - addTestCatalogItem(catalogItemId, "entity", TEST_VERSION, "org.apache.brooklyn.rest.resources.DummyIconEntity"); - } - - private void addTestCatalogItem(String catalogItemId, String itemType, String version, String service) { - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + catalogItemId, - " version: " + TEST_VERSION, - " itemType: " + checkNotNull(itemType), - " name: My Catalog App", - " description: My description", - " icon_url: classpath:///bridge-small.png", - " version: " + version, - " item:", - " type: " + service); - - client().path("/bundles").post(yaml); - } - - @Test - public void testListPolicies() { - Set<TypeSummary> policies = client().path("/subtypes/policy") - .get(new GenericType<Set<TypeSummary>>() {}); - - assertTrue(policies.size() > 0); - TypeSummary asp = null; - for (TypeSummary p : policies) { - if (AutoScalerPolicy.class.getName().equals(p.getSymbolicName())) - asp = p; - } - Assert.assertNotNull(asp, "didn't find AutoScalerPolicy"); - } - - @Test - public void testLocationAddGetAndRemove() { - String symbolicName = "my.catalog.location.id"; - String locationType = "localhost"; - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: location", - " name: My Catalog Location", - " description: My description", - " item:", - " type: " + locationType); - - // Create location item - Map<String, TypeSummary> items = client().path("/bundles") - .post(yaml, BundleInstallationRestResult.class).getTypes(); - TypeSummary locationItem = Iterables.getOnlyElement(items.values()); - - assertEquals(locationItem.getSymbolicName(), symbolicName); - assertEquals(locationItem.getVersion(), TEST_VERSION); - - // Retrieve location item - TypeDetail location = client().path("/types/"+symbolicName+"/"+TEST_VERSION).get(TypeDetail.class); - assertEquals(location.getSymbolicName(), symbolicName); - - // Retrieve all locations - Set<TypeSummary> locations = client().path("/subtypes/location") - .get(new GenericType<Set<TypeSummary>>() {}); - boolean found = false; - for (TypeSummary contender : locations) { - if (contender.getSymbolicName().equals(symbolicName)) { - found = true; - break; - } - } - Assert.assertTrue(found, "contenders="+locations); - - // Delete - Response deleteResponse = client().path("/bundles/"+locationItem.getContainingBundle().replaceAll(":", "/")) - .delete(); - assertEquals(deleteResponse.getStatus(), Response.Status.OK.getStatusCode()); - BundleInstallationRestResult deletionResponse = deleteResponse.readEntity(BundleInstallationRestResult.class); - Assert.assertEquals(deletionResponse.getBundle(), symbolicName+":"+TEST_VERSION); - Assert.assertEquals(deletionResponse.getTypes().keySet(), MutableSet.of(symbolicName+":"+TEST_VERSION)); - - Response getPostDeleteResponse = client().path("/types/"+symbolicName+"/"+TEST_VERSION) - .get(); - assertEquals(getPostDeleteResponse.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); - } - - @Test - public void testListEnrichers() { - Set<TypeSummary> enrichers = client().path("/subtypes/enricher") - .get(new GenericType<Set<TypeSummary>>() {}); - - assertTrue(enrichers.size() > 0); - TypeSummary asp = null; - for (TypeSummary p : enrichers) { - if (Aggregator.class.getName().equals(p.getSymbolicName())) - asp = p; - } - Assert.assertNotNull(asp, "didn't find Aggregator"); - } - - @Test - public void testEnricherAddGet() { - String symbolicName = "my.catalog.enricher.id"; - String enricherType = "org.apache.brooklyn.enricher.stock.Aggregator"; - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: enricher", - " name: My Catalog Enricher", - " description: My description", - " item:", - " type: " + enricherType); - - // Create location item - Map<String, TypeSummary> items = client().path("/bundles") - .post(yaml, BundleInstallationRestResult.class).getTypes(); - TypeSummary enricherItem = Iterables.getOnlyElement(items.values()); - - assertEquals(enricherItem.getSymbolicName(), symbolicName); - assertEquals(enricherItem.getVersion(), TEST_VERSION); - - // Retrieve location item - TypeSummary enricher = client().path("/types/"+symbolicName+"/"+TEST_VERSION) - .get(TypeSummary.class); - assertEquals(enricher.getSymbolicName(), symbolicName); - - // Retrieve all locations - Set<TypeSummary> enrichers = client().path("/subtypes/enricher") - .get(new GenericType<Set<TypeSummary>>() {}); - boolean found = false; - for (TypeSummary contender : enrichers) { - if (contender.getSymbolicName().equals(symbolicName)) { - found = true; - break; - } - } - Assert.assertTrue(found, "contenders="+enrichers); - } - - @Test - // osgi may fail in IDE, typically works on mvn CLI though - public void testRegisterOsgiEnricherTopLevelSyntax() { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - - String symbolicName = "my.catalog.enricher.id"; - String enricherType = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_SIMPLE_ENRICHER; - String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL; - - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: enricher", - " name: My Catalog Enricher", - " description: My description", - " libraries:", - " - url: " + bundleUrl, - " item:", - " type: " + enricherType); - - TypeSummary installedItem = Iterables.getOnlyElement( client().path("/bundles") - .post(yaml, BundleInstallationRestResult.class).getTypes().values() ); - - assertEquals(installedItem.getSymbolicName(), symbolicName); - assertEquals(installedItem.getVersion(), TEST_VERSION); - } - - @Test - public void testDeleteCustomEntityFromCatalog() { - String symbolicName = "my.catalog.app.id.to.subsequently.delete"; - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: entity", - " name: My Catalog App To Be Deleted", - " description: My description", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"); - - client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/yaml") - .post(yaml); - - BundleSummary getInstalledBundle = client().path("/bundles/"+symbolicName+"/"+TEST_VERSION) - .get(BundleSummary.class); - assertEquals(getInstalledBundle.getSymbolicName(), symbolicName); - assertEquals(getInstalledBundle.getVersion(), TEST_VERSION); - Asserts.assertNotNull(getInstalledBundle.getTypes(), "expected 'types' in: "+getInstalledBundle.getExtraFields()); - Asserts.assertStringContains(""+getInstalledBundle.getTypes(), "My Catalog App"); - - Response deleteResponse = client().path("/bundles/"+symbolicName+"/"+TEST_VERSION) - .delete(); - - assertEquals(deleteResponse.getStatus(), Response.Status.OK.getStatusCode()); - // contents of delete tested in delete location method - - Response getPostDeleteResponse = client().path("/bundles/"+symbolicName+"/"+TEST_VERSION) - .get(); - assertEquals(getPostDeleteResponse.getStatus(), Response.Status.NOT_FOUND.getStatusCode()); - } - - private void addCatalogItemWithInvalidBundleUrl(String bundleUrl) { - String symbolicName = "my.catalog.entity.id"; - String yaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " libraries:", - " - url: " + bundleUrl, - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-yaml") - .post(yaml); - - assertEquals(response.getStatus(), HttpStatus.BAD_REQUEST_400); - } - - @Test - public void testAddUnreachableItem() { - addCatalogItemWithInvalidBundleUrl("http://0.0.0.0/can-not-connect"); - } - - @Test - public void testAddInvalidItem() { - //equivalent to HTTP response 200 text/html - addCatalogItemWithInvalidBundleUrl("classpath://not-a-jar-file.txt"); - } - - @Test - public void testAddMissingItem() { - //equivalent to HTTP response 404 text/html - addCatalogItemWithInvalidBundleUrl("classpath://missing-jar-file.txt"); - } - - @Test - public void testInvalidArchive() throws Exception { - File f = Os.newTempFile("osgi", "zip"); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), "zip file is empty"); - } - - @Test - public void testArchiveWithoutBom() throws Exception { - File f = createZip(ImmutableMap.<String, String>of()); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), "Missing bundle symbolic name in BOM or MANIFEST"); - } - - @Test - public void testArchiveWithoutBundleAndVersion() throws Exception { - File f = createZip(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), "Missing bundle symbolic name in BOM or MANIFEST"); - } - - @Test - public void testArchiveWithoutBundle() throws Exception { - File f = createZip(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " version: 0.1.0", - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), - "Missing bundle symbolic name in BOM or MANIFEST"); - } - - @Test - public void testArchiveWithoutVersion() throws Exception { - File f = createZip(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: org.apache.brooklyn.test", - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), "Catalog BOM must define version"); - } - - @Test - public void testJarWithoutMatchingBundle() throws Exception { - String name = "My Catalog App"; - String bundle = "org.apache.brooklyn.test"; - String version = "0.1.0"; - String wrongBundleName = "org.apache.brooklyn.test2"; - File f = createJar(ImmutableMap.<String, String>of( - "catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + bundle, - " version: " + version, - " itemType: entity", - " name: " + name, - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"), - "META-INF/MANIFEST.MF", Joiner.on("\n").join( - "Manifest-Version: 1.0", - "Bundle-Name: " + name, - "Bundle-SymbolicName: "+wrongBundleName, - "Bundle-Version: " + version, - "Bundle-ManifestVersion: " + version))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-jar") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), - "symbolic name mismatch", - wrongBundleName, bundle); - } - - @Test - public void testJarWithoutMatchingVersion() throws Exception { - String name = "My Catalog App"; - String bundle = "org.apache.brooklyn.test"; - String version = "0.1.0"; - String wrongVersion = "0.3.0"; - File f = createJar(ImmutableMap.<String, String>of( - "catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + bundle, - " version: " + version, - " itemType: entity", - " name: " + name, - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"), - "META-INF/MANIFEST.MF", Joiner.on("\n").join( - "Manifest-Version: 1.0", - "Bundle-Name: " + name, - "Bundle-SymbolicName: " + bundle, - "Bundle-Version: " + wrongVersion, - "Bundle-ManifestVersion: " + wrongVersion))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-jar") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - Asserts.assertStringContainsIgnoreCase(response.readEntity(String.class), - "version mismatch", - wrongVersion, version); - } - - @Test - public void testOsgiBundleWithBom() throws Exception { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_PATH); - final String symbolicName = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_SYMBOLIC_NAME_FULL; - final String version = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_VERSION; - final String bundleUrl = OsgiStandaloneTest.BROOKLYN_TEST_OSGI_ENTITIES_URL; - BundleMaker bm = new BundleMaker(manager); - File f = Os.newTempFile("osgi", "jar"); - Files.copyFile(ResourceUtils.create(this).getResourceFromUrl(bundleUrl), f); - - String bom = Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + symbolicName, - " version: " + version, - " id: " + symbolicName, - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"); - - f = bm.copyAdding(f, MutableMap.of(new ZipEntry("catalog.bom"), (InputStream) new ByteArrayInputStream(bom.getBytes()))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-jar") - .post(Streams.readFully(new FileInputStream(f))); - - assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode()); - - TypeSummary entityItem = client().path("/types/"+symbolicName + "/" + version) - .get(TypeSummary.class); - - assertEquals(entityItem.getSymbolicName(), symbolicName); - assertEquals(entityItem.getVersion(), version); - - // and internally let's check we have libraries - RegisteredType item = getManagementContext().getTypeRegistry().get(symbolicName, version); - Assert.assertNotNull(item); - Collection<OsgiBundleWithUrl> libs = item.getLibraries(); - assertEquals(libs.size(), 1); - OsgiBundleWithUrl lib = Iterables.getOnlyElement(libs); - Assert.assertNull(lib.getUrl()); - - assertEquals(lib.getSymbolicName(), "org.apache.brooklyn.test.resources.osgi.brooklyn-test-osgi-entities"); - assertEquals(lib.getSuppliedVersionString(), version); - - // now let's check other things on the item - URI expectedIconUrl = URI.create(getEndpointAddress() + "/types/" + symbolicName + "/" + entityItem.getVersion()+"/icon").normalize(); - assertEquals(entityItem.getDisplayName(), "My Catalog App"); - assertEquals(entityItem.getDescription(), "My description"); - assertEquals(entityItem.getIconUrl(), expectedIconUrl.getPath()); - assertEquals(item.getIconUrl(), "classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif"); - - if (checkTraits(false)) { - // an InterfacesTag should be created for every catalog item - @SuppressWarnings("unchecked") - Map<String, List<String>> traitsMapTag = Iterables.getOnlyElement(Iterables.filter(entityItem.getTags(), Map.class)); - List<String> actualInterfaces = traitsMapTag.get("traits"); - List<Class<?>> expectedInterfaces = Reflections.getAllInterfaces(TestEntity.class); - assertEquals(actualInterfaces.size(), expectedInterfaces.size()); - for (Class<?> expectedInterface : expectedInterfaces) { - assertTrue(actualInterfaces.contains(expectedInterface.getName())); - } - } - - byte[] iconData = client().path("/types/" + symbolicName + "/" + version + "/icon").get(byte[].class); - assertEquals(iconData.length, 43); - } - - @Test - public void testOsgiBundleWithBomNotInBrooklynNamespace() throws Exception { - TestResourceUnavailableException.throwIfResourceUnavailable(getClass(), OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_PATH); - final String symbolicName = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_SYMBOLIC_NAME_FULL; - final String version = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_VERSION; - final String bundleUrl = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_URL; - final String entityType = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_ENTITY; - final String iconPath = OsgiTestResources.BROOKLYN_TEST_OSGI_ENTITIES_COM_EXAMPLE_ICON_PATH; - BundleMaker bm = new BundleMaker(manager); - File f = Os.newTempFile("osgi", "jar"); - Files.copyFile(ResourceUtils.create(this).getResourceFromUrl(bundleUrl), f); - - String bom = Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + symbolicName, - " version: " + version, - " id: " + symbolicName, - " itemType: entity", - " name: My Catalog App", - " description: My description", - " icon_url: classpath:" + iconPath, - " item:", - " type: " + entityType); - - f = bm.copyAdding(f, MutableMap.of(new ZipEntry("catalog.bom"), (InputStream) new ByteArrayInputStream(bom.getBytes()))); - - Response response = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(f))); - - - assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode()); - - TypeDetail entityItem = client().path("/types/"+symbolicName + "/" + version) - .get(TypeDetail.class); - - Assert.assertNotNull(entityItem.getPlan().getData()); - Assert.assertTrue(entityItem.getPlan().getData().toString().contains(entityType)); - - assertEquals(entityItem.getSymbolicName(), symbolicName); - assertEquals(entityItem.getVersion(), version); - - // and internally let's check we have libraries - RegisteredType item = getManagementContext().getTypeRegistry().get(symbolicName, version); - Assert.assertNotNull(item); - Collection<OsgiBundleWithUrl> libs = item.getLibraries(); - assertEquals(libs.size(), 1); - OsgiBundleWithUrl lib = Iterables.getOnlyElement(libs); - Assert.assertNull(lib.getUrl()); - - assertEquals(lib.getSymbolicName(), symbolicName); - assertEquals(lib.getSuppliedVersionString(), version); - - // now let's check other things on the item - assertEquals(entityItem.getDescription(), "My description"); - URI expectedIconUrl = URI.create(getEndpointAddress() + "/types/" + symbolicName + "/" + entityItem.getVersion() + "/icon").normalize(); - assertEquals(entityItem.getIconUrl(), expectedIconUrl.getPath()); - assertEquals(item.getIconUrl(), "classpath:" + iconPath); - - if (checkTraits(false)) { - // an InterfacesTag should be created for every catalog item - @SuppressWarnings("unchecked") - Map<String, List<String>> traitsMapTag = Iterables.getOnlyElement(Iterables.filter(entityItem.getTags(), Map.class)); - List<String> actualInterfaces = traitsMapTag.get("traits"); - List<String> expectedInterfaces = ImmutableList.of(Entity.class.getName(), BrooklynObject.class.getName(), Identifiable.class.getName(), Configurable.class.getName()); - assertTrue(actualInterfaces.containsAll(expectedInterfaces), "actual="+actualInterfaces); - } - - byte[] iconData = client().path("/types/" + symbolicName + "/" + version + "/icon").get(byte[].class); - assertEquals(iconData.length, 43); - - // Check that the catalog item is useable (i.e. can deploy the entity) - String appYaml = Joiner.on("\n").join( - "services:", - "- type: " + symbolicName + ":" + version, - " name: myEntityName"); - - Response appResponse = client().path("/applications") - .header(HttpHeaders.CONTENT_TYPE, "application/x-yaml") - .post(appYaml); - - assertEquals(appResponse.getStatus(), Response.Status.CREATED.getStatusCode()); - - Entity entity = Iterables.tryFind(getManagementContext().getEntityManager().getEntities(), EntityPredicates.displayNameEqualTo("myEntityName")).get(); - assertEquals(entity.getEntityType().getName(), entityType); - } - - private static File createZip(Map<String, String> files) throws Exception { - File f = Os.newTempFile("osgi", "zip"); - - ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(f)); - - for (Map.Entry<String, String> entry : files.entrySet()) { - ZipEntry ze = new ZipEntry(entry.getKey()); - zip.putNextEntry(ze); - zip.write(entry.getValue().getBytes()); - } - - zip.closeEntry(); - zip.flush(); - zip.close(); - - return f; - } - - private static File createJar(Map<String, String> files) throws Exception { - File f = Os.newTempFile("osgi", "jar"); - - JarOutputStream zip = new JarOutputStream(new FileOutputStream(f)); - - for (Map.Entry<String, String> entry : files.entrySet()) { - JarEntry ze = new JarEntry(entry.getKey()); - zip.putNextEntry(ze); - zip.write(entry.getValue().getBytes()); - } - - zip.closeEntry(); - zip.flush(); - zip.close(); - - return f; - } - - @Test - public void testGetOnlyLatestApplication() { - String symbolicName = "latest.catalog.application.id"; - String itemType = "template"; - String serviceType = "org.apache.brooklyn.core.test.entity.TestEntity"; - - addTestCatalogItem(symbolicName, itemType, TEST_VERSION, serviceType); - addTestCatalogItem(symbolicName, itemType, TEST_LASTEST_VERSION, serviceType); - - TypeSummary application = client().path("/types/" + symbolicName + "/latest") - .get(TypeSummary.class); - assertEquals(application.getVersion(), TEST_LASTEST_VERSION); - } - - @Test - public void testGetOnlyLatestDifferentCases() { - // depends on installation of this - testGetOnlyLatestApplication(); - - String symbolicName = "latest.catalog.application.id"; - - TypeSummary application = client().path("/types/" + symbolicName + "/LaTeSt") - .get(TypeSummary.class); - assertEquals(application.getVersion(), TEST_LASTEST_VERSION); - - application = client().path("/types/" + symbolicName + "/LATEST") - .get(TypeSummary.class); - assertEquals(application.getVersion(), TEST_LASTEST_VERSION); - } - - @Test - public void testGetOnlyLatestEntity() { - String symbolicName = "latest.catalog.entity.id"; - String itemType = "entity"; - String serviceType = "org.apache.brooklyn.core.test.entity.TestEntity"; - - addTestCatalogItem(symbolicName, itemType, TEST_VERSION, serviceType); - addTestCatalogItem(symbolicName, itemType, TEST_LASTEST_VERSION, serviceType); - - TypeSummary application = client().path("/types/" + symbolicName + "/latest") - .get(TypeSummary.class); - assertEquals(application.getVersion(), TEST_LASTEST_VERSION); - } - - @Test - public void testGetOnlyLatestLocation() { - String symbolicName = "latest.catalog.location.id"; - String itemType = "location"; - String serviceType = "localhost"; - - addTestCatalogItem(symbolicName, itemType, TEST_VERSION, serviceType); - addTestCatalogItem(symbolicName, itemType, TEST_LASTEST_VERSION, serviceType); - - TypeSummary application = client().path("/types/" + symbolicName + "/latest") - .get(TypeSummary.class); - assertEquals(application.getVersion(), TEST_LASTEST_VERSION); - } - - - @Test - public void testForceUpdateForYAML() { - String symbolicName = "force.update.catalog.application.id"; - String itemType = "template"; - String initialName = "My Catalog App"; - String initialDescription = "My description"; - String updatedName = initialName + " 2"; - String updatedDescription = initialDescription + " 2"; - - String initialYaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: " + itemType, - " name: " + initialName, - " description: " + initialDescription, - " icon_url: classpath:///bridge-small.png", - " version: " + TEST_VERSION, - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"); - String updatedYaml = Joiner.on("\n").join( - "brooklyn.catalog:", - " id: " + symbolicName, - " version: " + TEST_VERSION, - " itemType: " + itemType, - " name: " + updatedName, - " description: " + updatedDescription, - " icon_url: classpath:///bridge-small.png", - " version: " + TEST_VERSION, - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"); - - client().path("/bundles").post(initialYaml); - - TypeDetail initialApplication = client().path("/types/" + symbolicName + "/" + TEST_VERSION) - .get(TypeDetail.class); - assertEquals(initialApplication.getDisplayName(), initialName); - assertEquals(initialApplication.getDescription(), initialDescription); - - Response invalidResponse = client().path("/bundles").post(updatedYaml); - - assertEquals(invalidResponse.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - - Response validResponse = client().path("/bundles").query("force", true).post(updatedYaml); - - assertEquals(validResponse.getStatus(), Response.Status.CREATED.getStatusCode()); - - TypeSummary application = client().path("/types/" + symbolicName + "/" + TEST_VERSION) - .get(TypeSummary.class); - assertEquals(application.getDisplayName(), updatedName); - assertEquals(application.getDescription(), updatedDescription); - } - - @Test - public void testForceUpdateForZip() throws Exception { - final String symbolicName = "force.update.zip.catalog.application.id"; - final String initialName = "My Catalog App"; - final String initialDescription = "My Description"; - final String updatedName = initialName + " 2"; - final String updatedDescription = initialDescription +" 2"; - - File initialZip = createZip(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + symbolicName, - " version: " + TEST_VERSION, - " id: " + symbolicName, - " itemType: entity", - " name: " + initialName, - " description: " + initialDescription, - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - File updatedZip = createZip(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + symbolicName, - " version: " + TEST_VERSION, - " id: " + symbolicName, - " itemType: entity", - " name: " + updatedName, - " description: " + updatedDescription, - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - - client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(initialZip))); - - TypeSummary initialEntity = client().path("/types/" + symbolicName + "/" + TEST_VERSION) - .get(TypeSummary.class); - assertEquals(initialEntity.getDisplayName(), initialName); - assertEquals(initialEntity.getDescription(), initialDescription); - - Response invalidResponse = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .post(Streams.readFully(new FileInputStream(updatedZip))); - - assertEquals(invalidResponse.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - - Response validResponse = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-zip") - .query("force", true) - .post(Streams.readFully(new FileInputStream(updatedZip))); - - assertEquals(validResponse.getStatus(), Response.Status.CREATED.getStatusCode()); - - TypeSummary entity = client().path("/types/" + symbolicName + "/" + TEST_VERSION) - .get(TypeSummary.class); - assertEquals(entity.getDisplayName(), updatedName); - assertEquals(entity.getDescription(), updatedDescription); - } - - @Test - public void testForceUpdateForJar() throws Exception { - final String symbolicName = "force.update.jar.catalog.application.id"; - final String initialName = "My Catalog App"; - final String initialDescription = "My Description"; - final String updatedName = initialName + " 2"; - final String updatedDescription = initialDescription +" 2"; - - File initialJar = createJar(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + symbolicName, - " version: " + TEST_VERSION, - " id: " + symbolicName, - " itemType: entity", - " name: " + initialName, - " description: " + initialDescription, - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - File updatedJar = createJar(ImmutableMap.<String, String>of("catalog.bom", Joiner.on("\n").join( - "brooklyn.catalog:", - " bundle: " + symbolicName, - " version: " + TEST_VERSION, - " id: " + symbolicName, - " itemType: entity", - " name: " + updatedName, - " description: " + updatedDescription, - " icon_url: classpath:/org/apache/brooklyn/test/osgi/entities/icon.gif", - " item:", - " type: org.apache.brooklyn.core.test.entity.TestEntity"))); - - client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-jar") - .post(Streams.readFully(new FileInputStream(initialJar))); - - TypeSummary initialEntity = client().path("/types/" + symbolicName + "/" + TEST_VERSION) - .get(TypeSummary.class); - assertEquals(initialEntity.getDisplayName(), initialName); - assertEquals(initialEntity.getDescription(), initialDescription); - - Response invalidResponse = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-jar") - .post(Streams.readFully(new FileInputStream(updatedJar))); - - assertEquals(invalidResponse.getStatus(), Response.Status.BAD_REQUEST.getStatusCode()); - - Response validResponse = client().path("/bundles") - .header(HttpHeaders.CONTENT_TYPE, "application/x-jar") - .query("force", true) - .post(Streams.readFully(new FileInputStream(updatedJar))); - - assertEquals(validResponse.getStatus(), Response.Status.CREATED.getStatusCode()); - - TypeSummary entity = client().path("/types/" + symbolicName + "/" + TEST_VERSION) - .get(TypeSummary.class); - assertEquals(entity.getDisplayName(), updatedName); - assertEquals(entity.getDescription(), updatedDescription); - } - - // TODO traits no longer always set - we have supertypes so not needed, we should investigate when they are and when they aren't - // and switch those to setting and using the supertypes - private boolean checkTraits(boolean currentExpectedToBeWorking) { - return currentExpectedToBeWorking; - } - -}
