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);
     }