You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by tb...@apache.org on 2018/01/08 12:10:50 UTC
[2/3] brooklyn-server git commit: adds bundle-specific type endpoint
adds bundle-specific type endpoint
and fixes test for self link distinguishing between same type id in different 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/93b2b99a
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/93b2b99a
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/93b2b99a
Branch: refs/heads/master
Commit: 93b2b99a0cd1806e511a79eb479c92118a6b71a4
Parents: 2b5e55a
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jan 5 13:12:10 2018 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jan 5 13:17:15 2018 +0000
----------------------------------------------------------------------
.../org/apache/brooklyn/rest/api/BundleApi.java | 47 ++++++++++++++++++++
.../apache/brooklyn/rest/domain/TypeDetail.java | 16 +++++++
.../brooklyn/rest/resources/BundleResource.java | 43 ++++++++++++++++++
.../rest/transform/TypeTransformer.java | 11 ++++-
.../resources/BundleAndTypeResourcesTest.java | 24 +++++++---
5 files changed, 133 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/93b2b99a/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 2eb5ed8..2296fe3 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
@@ -35,6 +35,8 @@ import javax.ws.rs.core.Response;
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 io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -88,6 +90,51 @@ public interface BundleApi {
@PathParam("version")
String version);
+
+ @Path("/{symbolicName}/{version}/types")
+ @GET
+ @ApiOperation(value = "Get all types declared in a given bundle",
+ response = TypeDetail.class)
+ public List<TypeSummary> getTypes(
+ @ApiParam(name = "symbolicName", value = "Bundle name to query", required = true)
+ @PathParam("symbolicName")
+ String symbolicName,
+ @ApiParam(name = "version", value = "Version of bundle and of type to query", required = true)
+ @PathParam("version")
+ String version);
+
+ @Path("/{symbolicName}/{version}/types/{typeSymbolicName}")
+ @GET
+ @ApiOperation(value = "Get detail on a given type in a given bundle",
+ response = TypeDetail.class)
+ public TypeDetail getType(
+ @ApiParam(name = "symbolicName", value = "Bundle name to query", required = true)
+ @PathParam("symbolicName")
+ String symbolicName,
+ @ApiParam(name = "version", value = "Version of bundle and of type to query", required = true)
+ @PathParam("version")
+ String version,
+ @ApiParam(name = "typeSymbolicName", value = "Type name to query", required = true)
+ @PathParam("typeSymbolicName")
+ String typeSymbolicName);
+
+ @Path("/{symbolicName}/{version}/types/{typeSymbolicName}/{typeVersion}")
+ @GET
+ @ApiOperation(value = "Get detail on a given type and version in a bundle (special method for unusual cases where type has different version)",
+ response = TypeDetail.class)
+ public TypeDetail getTypeExplicitVersion(
+ @ApiParam(name = "symbolicName", value = "Bundle name to query", required = true)
+ @PathParam("symbolicName")
+ String symbolicName,
+ @ApiParam(name = "version", value = "Bundle version to query", required = true)
+ @PathParam("version")
+ String version,
+ @ApiParam(name = "typeSymbolicName", value = "Type name to query", required = true)
+ @PathParam("typeSymbolicName")
+ String typeSymbolicName,
+ @ApiParam(name = "typeVersion", value = "Version to query (if different to bundle version)", required = true)
+ @PathParam("typeVersion")
+ String typeVersion);
@Path("/{symbolicName}/{version}")
@DELETE
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/93b2b99a/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 0fafcbe..4b84d60 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
@@ -23,6 +23,7 @@ import org.apache.brooklyn.api.typereg.RegisteredType.TypeImplementationPlan;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.google.common.base.Objects;
/** As {@link TypeSummary} but including plan information. */
public class TypeDetail extends TypeSummary {
@@ -42,7 +43,22 @@ public class TypeDetail extends TypeSummary {
public Object getData() {
return data;
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(format, data);
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ TypeImplementationPlanSummary other = (TypeImplementationPlanSummary) obj;
+ if (!Objects.equal(data, other.data)) return false;
+ if (!Objects.equal(format, other.format)) return false;
+ return true;
+ }
}
+
private TypeImplementationPlanSummary plan;
/** Constructor for JSON deserialization use only. */
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/93b2b99a/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 64cd6ed..433d833 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
@@ -27,14 +27,19 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.brooklyn.api.typereg.ManagedBundle;
+import org.apache.brooklyn.api.typereg.RegisteredType;
import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
+import org.apache.brooklyn.core.typereg.RegisteredTypes;
import org.apache.brooklyn.rest.api.BundleApi;
import org.apache.brooklyn.rest.domain.ApiError;
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.filter.HaHotStateRequired;
import org.apache.brooklyn.rest.transform.TypeTransformer;
import org.apache.brooklyn.rest.util.WebResourceUtils;
@@ -48,6 +53,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
@HaHotStateRequired
public class BundleResource extends AbstractBrooklynRestResource implements BundleApi {
@@ -107,6 +113,42 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund
}
return b;
}
+
+
+ @Override
+ public List<TypeSummary> getTypes(String symbolicName, String version) {
+ ManagedBundle b = lookup(symbolicName, version);
+ return TypeTransformer.bundleDetails(brooklyn(), b, ui.getBaseUriBuilder(), mgmt()).getTypes();
+ }
+
+ @Override
+ public TypeDetail getType(String symbolicName, String version, String typeSymbolicName) {
+ return getTypeExplicitVersion(symbolicName, version, typeSymbolicName, version);
+ }
+
+ @Override
+ public TypeDetail getTypeExplicitVersion(String symbolicName, String version, String typeSymbolicName, String typeVersion) {
+ ManagedBundle b = lookup(symbolicName, version);
+ if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, typeSymbolicName+":"+typeVersion)) {
+ // TODO best to default to "not found" - unless maybe they have permission to "see null"
+ throw WebResourceUtils.forbidden("User '%s' not permitted to see info on this type (including whether or not installed)",
+ Entitlements.getEntitlementContext().user());
+ }
+
+ Predicate<RegisteredType> pred = RegisteredTypePredicates.nameOrAlias(typeSymbolicName);
+ pred = Predicates.and(pred, RegisteredTypePredicates.containingBundle(b.getVersionedName()));
+ if (!LATEST.equalsIgnoreCase(typeVersion)) {
+ pred = Predicates.and(pred, RegisteredTypePredicates.version(typeVersion));
+ }
+ Iterable<RegisteredType> items = mgmt().getTypeRegistry().getMatching(pred);
+
+ if (Iterables.isEmpty(items)) {
+ throw WebResourceUtils.notFound("Entity with id '%s:%s' not found", typeSymbolicName, typeVersion);
+ }
+
+ RegisteredType item = RegisteredTypes.getBestVersion(items);
+ return TypeTransformer.detail(brooklyn(), item, ui.getBaseUriBuilder());
+ }
@Override
public BundleInstallationRestResult remove(String symbolicName, String version, Boolean force) {
@@ -170,4 +212,5 @@ public class BundleResource extends AbstractBrooklynRestResource implements Bund
}
return Response.status(status).entity(resultR).build();
}
+
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/93b2b99a/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 736ee83..e8bfb50 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
@@ -49,6 +49,7 @@ import org.apache.brooklyn.core.mgmt.ha.OsgiBundleInstallationResult;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.core.typereg.RegisteredTypePredicates;
import org.apache.brooklyn.core.typereg.RegisteredTypes;
+import org.apache.brooklyn.rest.api.BundleApi;
import org.apache.brooklyn.rest.api.TypeApi;
import org.apache.brooklyn.rest.domain.BundleInstallationRestResult;
import org.apache.brooklyn.rest.domain.BundleSummary;
@@ -61,6 +62,8 @@ import org.apache.brooklyn.rest.domain.TypeSummary;
import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.osgi.VersionedName;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
@@ -185,7 +188,13 @@ public class TypeTransformer {
}
private static URI getSelfLink(RegisteredType item, UriBuilder ub) {
- return serviceUriBuilder(ub, TypeApi.class, "detail").build(item.getSymbolicName(), item.getVersion());
+ Maybe<VersionedName> bundleM = VersionedName.parseMaybe(item.getContainingBundle(), true);
+ if (bundleM.isPresent()) {
+ return serviceUriBuilder(ub, BundleApi.class, "getTypeExplicitVersion").build(bundleM.get().getSymbolicName(), bundleM.get().getVersionString(),
+ item.getSymbolicName(), item.getVersion());
+ } else {
+ return serviceUriBuilder(ub, TypeApi.class, "detail").build(item.getSymbolicName(), item.getVersion());
+ }
}
private static String tidyIconLink(BrooklynRestResourceUtils b, RegisteredType item, String iconUrl, UriBuilder ub) {
if (b.isUrlServerSideAndSafe(iconUrl)) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/93b2b99a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeResourcesTest.java
----------------------------------------------------------------------
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeResourcesTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeResourcesTest.java
index 3672a7a..a15b04a 100644
--- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeResourcesTest.java
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/BundleAndTypeResourcesTest.java
@@ -698,12 +698,25 @@ public class BundleAndTypeResourcesTest extends BrooklynRestResourceTest {
assertEquals(response.getStatus(), Response.Status.CREATED.getStatusCode());
- TypeSummary entityItem = client().path("/catalog/types/"+symbolicName + "/" + version)
- .get(TypeSummary.class);
-
+ TypeDetail entityItem = client().path("/catalog/types/"+symbolicName + "/" + version)
+ .get(TypeDetail.class);
assertEquals(entityItem.getSymbolicName(), symbolicName);
assertEquals(entityItem.getVersion(), version);
+ // assert we can cast it as summary
+ TypeSummary entityItemSummary = client().path("/catalog/types/"+symbolicName + "/" + version)
+ .get(TypeSummary.class);
+ assertEquals(entityItemSummary.getSymbolicName(), symbolicName);
+ assertEquals(entityItemSummary.getVersion(), version);
+
+ List<TypeSummary> typesInBundle = client().path("/catalog/bundles/" + symbolicName + "/" + version + "/types")
+ .get(new GenericType<List<TypeSummary>>() {});
+ assertEquals(Iterables.getOnlyElement(typesInBundle), entityItemSummary);
+
+ TypeDetail entityItemFromBundle = client().path("/catalog/bundles/" + symbolicName + "/" + version + "/types/" + symbolicName + "/" + version)
+ .get(TypeDetail.class);
+ assertEquals(entityItemFromBundle, entityItem);
+
// and internally let's check we have libraries
RegisteredType item = getManagementContext().getTypeRegistry().get(symbolicName, version);
Assert.assertNotNull(item);
@@ -1283,9 +1296,6 @@ public class BundleAndTypeResourcesTest extends BrooklynRestResourceTest {
}
@Test
- // TODO fails as there is NOT a link to a specific type in a specific bundle currently - API assumes type name+id unique
- // but they may differ in the containing bundle (and maybe in future differ in more things)
- // ==> bug about to be fixed!
public void testAddSameTypeTwiceInDifferentBundleSameDefinition_AllowedAndApiMakesTheDifferentOnesClear() throws Exception {
final String symbolicName1 = "test.duplicate.type."+JavaClassNames.niceClassAndMethod()+".1";
final String symbolicName2 = "test.duplicate.type."+JavaClassNames.niceClassAndMethod()+".2";
@@ -1359,7 +1369,7 @@ public class BundleAndTypeResourcesTest extends BrooklynRestResourceTest {
Assert.assertNotEquals(self1, self2);
TypeSummary entity1r = client().path(self1).get(TypeSummary.class);
- TypeSummary entity2r = client().path(self1).get(TypeSummary.class);
+ TypeSummary entity2r = client().path(self2).get(TypeSummary.class);
Assert.assertEquals(entity1r, entity1);
Assert.assertEquals(entity2r, entity2);
}