brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henev...@apache.org
Subject [4/5] git commit: address @aledsage comments from #23 and review @andreaturli in #30: - mark things beta - ensure more checks (many done by delegate messages) - better javadoc and things renamed
Date Mon, 30 Jun 2014 22:24:42 GMT
address @aledsage comments from #23 and review @andreaturli in #30:
- mark things beta
- ensure more checks (many done by delegate messages)
- better javadoc and things renamed


Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ff7ff7b2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ff7ff7b2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ff7ff7b2

Branch: refs/heads/master
Commit: ff7ff7b29b04b2aafe213ccf6ec4abfee858d7ba
Parents: f150725
Author: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Authored: Mon Jun 30 21:27:54 2014 +0100
Committer: Alex Heneveld <alex.heneveld@cloudsoftcorp.com>
Committed: Mon Jun 30 21:27:54 2014 +0100

----------------------------------------------------------------------
 .../entitlement/EntitlementManager.java         |  7 ++-
 .../entitlement/EntitlementManagerAdapter.java  | 11 ++++
 .../management/entitlement/Entitlements.java    | 41 +++++++++----
 .../internal/EntityManagementSupport.java       |  2 +-
 .../rest/resources/ApplicationResource.java     | 64 ++++++++++++--------
 .../rest/util/BrooklynRestResourceUtils.java    | 31 +++++++---
 6 files changed, 108 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ff7ff7b2/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java b/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java
index 3035344..b8f2090 100644
--- a/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java
+++ b/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java
@@ -3,6 +3,8 @@ package brooklyn.management.entitlement;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import com.google.common.annotations.Beta;
+
 /** 
  * Entitlement lookup relies on:
  * <li>an "entitlement context", consisting of at minimum a string identifier of the
user/actor for which entitlement is being requested
@@ -13,8 +15,11 @@ import javax.annotation.Nullable;
  * (configuration injected by the Brooklyn framework)
  * or a 0-arg constructor (if no external configuration is needed).
  * <p>
+ * An EntitlementManagerAdapter class is available to do dispatch to common methods.
+ * <p>
  * Instantiation is done e.g. by Entitlements.newManager.  
- */
+ * @since 0.7.0 */
+@Beta
 public interface EntitlementManager {
 
     public <T> boolean isEntitled(@Nullable EntitlementContext context, @Nonnull EntitlementClass<T>
entitlementClass, @Nullable T entitlementClassArgument);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ff7ff7b2/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
b/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
index 7b4196d..c6ff1cb 100644
--- a/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
+++ b/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
@@ -3,9 +3,20 @@ package brooklyn.management.entitlement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.Beta;
+
 import brooklyn.entity.Entity;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
 
+/**
+ * provides an easy entry point to supplying entitlements, by providing the dispatch and
defining the additional methods
+ * which have to be supplied.
+ * <p>
+ * note that this class may change as versions change, deliberately breaking backwards compatibility
+ * to ensure all permissions are used.
+ * <p>
+ * @since 0.7.0 */
+@Beta
 public abstract class EntitlementManagerAdapter implements EntitlementManager {
 
     private static final Logger log = LoggerFactory.getLogger(EntitlementManagerAdapter.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ff7ff7b2/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
index 667bb3b..509f947 100644
--- a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
+++ b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
@@ -18,7 +18,9 @@ package brooklyn.management.entitlement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
+import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.reflect.TypeToken;
@@ -30,8 +32,11 @@ import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Entities;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.javalang.Reflections;
 import brooklyn.util.text.Strings;
 
+/** @since 0.7.0 */
+@Beta
 public class Entitlements {
 
     private static final Logger log = LoggerFactory.getLogger(Entitlements.class);
@@ -42,10 +47,10 @@ public class Entitlements {
     
     public static EntitlementClass<EntityAndItem<String>> SEE_SENSOR = new BasicEntitlementClassDefinition<EntityAndItem<String>>("sensor.see",
EntityAndItem. typeToken(String.class));
     
-    public static EntitlementClass<EntityAndItem<String>> INVOKE_EFFECTOR = new
BasicEntitlementClassDefinition<EntityAndItem<String>>("effector.invoke", EntityAndItem.
typeToken(String.class));
+    public static EntitlementClass<EntityAndItem<String>> INVOKE_EFFECTOR = new
BasicEntitlementClassDefinition<EntityAndItem<String>>("effector.invoke", EntityAndItem.typeToken(String.class));
     
     /** the permission to deploy an application, where parameter is some representation of
the app to be deployed (spec instance or yaml plan) */
-    public static EntitlementClass<EntityAndItem<Object>> DEPLOY_APPLICATION
= new BasicEntitlementClassDefinition<EntityAndItem<Object>>("app.deploy", EntityAndItem.
typeToken(Object.class));
+    public static EntitlementClass<Object> DEPLOY_APPLICATION = new BasicEntitlementClassDefinition<Object>("app.deploy",
Object.class);
 
     /** catch-all for catalog, locations, scripting, usage, etc; 
      * NB1: all users can see HA status;
@@ -105,6 +110,14 @@ public class Entitlements {
         }
     }
 
+    /** 
+     * These lifecycle operations are currently treated as effectors. This may change in
the future.
+     * @since 0.7.0 */
+    @Beta
+    public static class LifecycleEffectors {
+        public static final String DELETE = "delete";
+    }
+    
     // ------------- permission sets -------------
     
     /** always ALLOW access to everything */
@@ -129,7 +142,7 @@ public class Entitlements {
 
     public static class FineGrainedEntitlements {
     
-        public static EntitlementManager anyOf(final EntitlementManager ...checkers) {
+        public static EntitlementManager anyOf(final EntitlementManager... checkers) {
             return new EntitlementManager() {
                 @Override
                 public <T> boolean isEntitled(EntitlementContext context, EntitlementClass<T>
permission, T typeArgument) {
@@ -141,7 +154,7 @@ public class Entitlements {
             };
         }
         
-        public static EntitlementManager allOf(final EntitlementManager ...checkers) {
+        public static EntitlementManager allOf(final EntitlementManager... checkers) {
             return new EntitlementManager() {
                 @Override
                 public <T> boolean isEntitled(EntitlementContext context, EntitlementClass<T>
permission, T typeArgument) {
@@ -224,12 +237,20 @@ public class Entitlements {
         return checker.isEntitled(getEntitlementContext(), permission, typeArgument);
     }
 
-    public static <T> void requireEntitled(EntitlementManager checker, EntitlementClass<T>
permission, T typeArgument) {
+    /** throws {@link NotEntitledException} if entitlement not available for current {@link
#getEntitlementContext()} */
+    public static <T> void checkEntitled(EntitlementManager checker, EntitlementClass<T>
permission, T typeArgument) {
         if (!isEntitled(checker, permission, typeArgument)) {
             throw new NotEntitledException(getEntitlementContext(), permission, typeArgument);
         }
     }
-
+    /** throws {@link NotEntitledException} if entitlement not available for current {@link
#getEntitlementContext()} 
+     * @since 0.7.0
+     * @deprecated since 0.7.0, use {@link #checkEntitled(EntitlementManager, EntitlementClass,
Object)};
+     * kept briefly because there is some downstream usage*/
+    public static <T> void requireEntitled(EntitlementManager checker, EntitlementClass<T>
permission, T typeArgument) {
+        checkEntitled(checker, permission, typeArgument);
+    }
+    
     // ----------------- initialization ----------------
 
     public static ConfigKey<String> GLOBAL_ENTITLEMENT_MANAGER = ConfigKeys.newStringConfigKey("brooklyn.entitlements.global",

@@ -251,11 +272,9 @@ public class Entitlements {
         if (Strings.isNonBlank(type)) {
             try {
                 Class<?> clazz = loader.getLoader().loadClass(type);
-                if (clazz.getConstructor(BrooklynProperties.class)!=null) {
-                    return (EntitlementManager) clazz.getConstructor(BrooklynProperties.class).newInstance(brooklynProperties);
-                } else {
-                    return (EntitlementManager) clazz.newInstance();
-                }
+                Optional<?> result = Reflections.invokeConstructorWithArgs(clazz, brooklynProperties);
+                if (result.isPresent()) return (EntitlementManager) result.get();
+                return (EntitlementManager) clazz.newInstance();
             } catch (Exception e) { throw Exceptions.propagate(e); }
         }
         throw new IllegalStateException("Invalid entitlement manager specified: '"+type+"'");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ff7ff7b2/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
b/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
index e87ed3e..a98a993 100644
--- a/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
+++ b/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
@@ -379,7 +379,7 @@ public class EntityManagementSupport {
         }
         @Override
         public void onEffectorStarting(Effector<?> effector) {
-            Entitlements.requireEntitled(getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
EntityAndItem.of(null, effector.getName()));
+            Entitlements.checkEntitled(getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
EntityAndItem.of(entity, effector.getName()));
         }
         @Override
         public void onEffectorCompleted(Effector<?> effector) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ff7ff7b2/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
b/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
index 68e8bcd..75d4f34 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
@@ -1,9 +1,13 @@
 package brooklyn.rest.resources;
 
 import static com.google.common.base.Preconditions.checkNotNull;
-import static javax.ws.rs.core.Response.Status.ACCEPTED;
 import static javax.ws.rs.core.Response.created;
 import static javax.ws.rs.core.Response.status;
+import static javax.ws.rs.core.Response.Status.ACCEPTED;
+import io.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
+import io.brooklyn.camp.spi.Assembly;
+import io.brooklyn.camp.spi.AssemblyTemplate;
+import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
 
 import java.io.Reader;
 import java.io.StringReader;
@@ -26,10 +30,6 @@ import org.codehaus.jackson.node.ObjectNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Throwables;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.Iterables;
-
 import brooklyn.entity.Application;
 import brooklyn.entity.Entity;
 import brooklyn.entity.Group;
@@ -45,6 +45,7 @@ import brooklyn.location.Location;
 import brooklyn.management.Task;
 import brooklyn.management.entitlement.EntitlementPredicates;
 import brooklyn.management.entitlement.Entitlements;
+import brooklyn.management.entitlement.Entitlements.EntityAndItem;
 import brooklyn.rest.api.ApplicationApi;
 import brooklyn.rest.domain.ApplicationSpec;
 import brooklyn.rest.domain.ApplicationSummary;
@@ -60,10 +61,10 @@ import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableList;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.exceptions.Exceptions;
-import io.brooklyn.camp.brooklyn.spi.creation.BrooklynAssemblyTemplateInstantiator;
-import io.brooklyn.camp.spi.Assembly;
-import io.brooklyn.camp.spi.AssemblyTemplate;
-import io.brooklyn.camp.spi.instantiate.AssemblyTemplateInstantiator;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.Iterables;
 
 
 public class ApplicationResource extends AbstractBrooklynRestResource implements ApplicationApi
{
@@ -212,6 +213,11 @@ public class ApplicationResource extends AbstractBrooklynRestResource
implements
 
     /** @deprecated since 0.7.0 see #create */ @Deprecated
     protected Response createFromAppSpec(ApplicationSpec applicationSpec) {
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.DEPLOY_APPLICATION,
applicationSpec)) {
+            throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application
%s",
+                Entitlements.getEntitlementContext().user(), applicationSpec);
+        }
+
         checkApplicationTypesAreValid(applicationSpec);
         checkLocationsAreValid(applicationSpec);
         // TODO duplicate prevention
@@ -244,6 +250,12 @@ public class ApplicationResource extends AbstractBrooklynRestResource
implements
         log.debug("Creating app from yaml:\n{}", yaml);
         Reader input = new StringReader(yaml);
         AssemblyTemplate at = camp().pdp().registerDeploymentPlan(input);
+        
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.DEPLOY_APPLICATION,
at)) {
+            throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application
%s",
+                Entitlements.getEntitlementContext().user(), yaml);
+        }
+
         return launch(at);
     }
 
@@ -264,17 +276,19 @@ public class ApplicationResource extends AbstractBrooklynRestResource
implements
                 assembly = instantiator.instantiate(at, camp());
             }
             Entity app = mgmt().getEntityManager().getEntity(assembly.getId());
-            if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
Entitlements.EntityAndItem.of(app, "createFromAppSpec"))) {
-                log.info("Launched from YAML: " + assembly + " (" + task + ")");
-
-                URI ref = URI.create(app.getApplicationId());
-                ResponseBuilder response = created(ref);
-                if (task != null)
-                    response.entity(TaskTransformer.FROM_TASK.apply(task));
-                return response.build();
-            }
-            throw WebResourceUtils.unauthorized("User '%s' is not authorized to launch application
from %s",
+            
+            if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
EntityAndItem.of(app, Startable.START.getName()))) {
+                throw WebResourceUtils.unauthorized("User '%s' is not authorized to start
application %s",
                     Entitlements.getEntitlementContext().user(), at.getType());
+            }
+
+            log.info("Launched from YAML: " + assembly + " (" + task + ")");
+
+            URI ref = URI.create(app.getApplicationId());
+            ResponseBuilder response = created(ref);
+            if (task != null)
+                response.entity(TaskTransformer.FROM_TASK.apply(task));
+            return response.build();
         } catch (Exception e) {
             throw Exceptions.propagate(e);
         }
@@ -340,13 +354,13 @@ public class ApplicationResource extends AbstractBrooklynRestResource
implements
     @Override
     public Response delete(String application) {
         Application app = brooklyn().getApplication(application);
-        if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
Entitlements.EntityAndItem.of(app, "delete"))) {
-            Task<?> t = brooklyn().destroy(app);
-            TaskSummary ts = TaskTransformer.FROM_TASK.apply(t);
-            return status(ACCEPTED).entity(ts).build();
-        }
-        throw WebResourceUtils.unauthorized("User '%s' is not authorized to delete application
%s",
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
Entitlements.EntityAndItem.of(app, Entitlements.LifecycleEffectors.DELETE))) {
+            throw WebResourceUtils.unauthorized("User '%s' is not authorized to delete application
%s",
                 Entitlements.getEntitlementContext().user(), app);
+        }
+        Task<?> t = brooklyn().destroy(app);
+        TaskSummary ts = TaskTransformer.FROM_TASK.apply(t);
+        return status(ACCEPTED).entity(ts).build();
     }
 
     private void checkApplicationTypesAreValid(ApplicationSpec applicationSpec) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ff7ff7b2/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
b/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
index d6ed824..1d5701f 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -2,7 +2,6 @@ package brooklyn.rest.util;
 
 import static brooklyn.rest.util.WebResourceUtils.notFound;
 import static com.google.common.collect.Iterables.transform;
-
 import brooklyn.management.entitlement.Entitlements;
 import groovy.lang.GroovyClassLoader;
 
@@ -118,13 +117,19 @@ public class BrooklynRestResourceUtils {
         if (entity==null) return null;
         Application app = application!=null ? getApplication(application) : null;
         EntityLocal e = (EntityLocal) mgmt.getEntityManager().getEntity(entity);
+        
         if (e!=null) {
+            if (!Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY,
e)) {
+                throw WebResourceUtils.notFound("Cannot find entity '%s': no known ID and
application not supplied for searching", entity);
+            }
+            
             if (app==null || app.equals(findTopLevelApplication(e))) return e;
             throw WebResourceUtils.preconditionFailed("Application '%s' specified does not
match application '%s' to which entity '%s' (%s) is associated", 
                     application, e.getApplication().getId(), entity, e);
         }
         if (application==null)
             throw WebResourceUtils.notFound("Cannot find entity '%s': no known ID and application
not supplied for searching", entity);
+        
         assert app!=null : "null app should not be returned from getApplication";
         e = searchForEntityNamed(app, entity);
         if (e!=null) return e;
@@ -146,20 +151,21 @@ public class BrooklynRestResourceUtils {
 
     /** looks for the given application instance, first by ID then by name
      * 
-     * @throws 404 if not found
+     * @throws 404 if not found, or not entitled
      */
     public Application getApplication(String application) {
         Entity e = mgmt.getEntityManager().getEntity(application);
-        if (Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY,
e)) {
-            if (e != null && e instanceof Application) return (Application) e;
-            for (Application app : mgmt.getApplications()) {
-                if (app.getId().equals(application)) return app;
-                if (application.equalsIgnoreCase(app.getDisplayName())) return app;
-            }
+        if (!Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY,
e)) {
             throw notFound("Application '%s' not found", application);
         }
-        throw WebResourceUtils.unauthorized("User '%s' is not authorized to get application
'%s'",
-                    Entitlements.getEntitlementContext().user(), e);
+        
+        if (e != null && e instanceof Application) return (Application) e;
+        for (Application app : mgmt.getApplications()) {
+            if (app.getId().equals(application)) return app;
+            if (application.equalsIgnoreCase(app.getDisplayName())) return app;
+        }
+        
+        throw notFound("Application '%s' not found", application);
     }
 
     /** walks the hierarchy (depth-first) at root (often an Application) looking for
@@ -178,6 +184,11 @@ public class BrooklynRestResourceUtils {
     public Application create(ApplicationSpec spec) {
         log.debug("REST creating application instance for {}", spec);
         
+        if (!Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.DEPLOY_APPLICATION,
spec)) {
+            throw WebResourceUtils.unauthorized("User '%s' is not authorized to deploy application
%s",
+                Entitlements.getEntitlementContext().user(), spec);
+        }
+        
         final String type = spec.getType();
         final String name = spec.getName();
         final Map<String,String> configO = spec.getConfig();


Mime
View raw message