You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2014/07/01 00:24:39 UTC

[1/5] git commit: more support for entitlements

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 60a55767c -> b8f1a04df


more support for entitlements


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

Branch: refs/heads/master
Commit: 8958fc14a5a6faaee0234dcac3c5ef0d4c04dee1
Parents: 6a34f38
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jun 27 14:29:00 2014 +0100
Committer: Andrea Turli <an...@gmail.com>
Committed: Mon Jun 30 11:24:56 2014 +0200

----------------------------------------------------------------------
 .../entitlement/EntitlementManager.java         |  8 ++-
 .../entitlement/EntitlementManagerAdapter.java  | 51 ++++++++++++++++++++
 .../management/entitlement/Entitlements.java    | 48 +++++++++++++++---
 .../main/java/brooklyn/util/guava/Maybe.java    |  2 +-
 .../main/java/brooklyn/util/time/Duration.java  |  6 +++
 5 files changed, 105 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8958fc14/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 d9312d0..3035344 100644
--- a/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java
+++ b/api/src/main/java/brooklyn/management/entitlement/EntitlementManager.java
@@ -7,7 +7,13 @@ import javax.annotation.Nullable;
  * 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
  * <li>an "entitlement class", representing the category of activity for which entitlement is being requested
- * <li>an "entitlement class argument", representing the specifics of the activity for which entitlement is being requested 
+ * <li>an "entitlement class argument", representing the specifics of the activity for which entitlement is being requested
+ * <p>
+ * Instances of this class typically have a 1-arg constructor taking a BrooklynProperties object
+ * (configuration injected by the Brooklyn framework)
+ * or a 0-arg constructor (if no external configuration is needed).
+ * <p>
+ * Instantiation is done e.g. by Entitlements.newManager.  
  */
 public interface EntitlementManager {
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8958fc14/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
new file mode 100644
index 0000000..7b4196d
--- /dev/null
+++ b/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
@@ -0,0 +1,51 @@
+package brooklyn.management.entitlement;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.Entity;
+import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+
+public abstract class EntitlementManagerAdapter implements EntitlementManager {
+
+    private static final Logger log = LoggerFactory.getLogger(EntitlementManagerAdapter.class);
+    
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> boolean isEntitled(EntitlementContext context, EntitlementClass<T> entitlementClass, T entitlementClassArgument) {
+        if (log.isTraceEnabled()) {
+            log.trace("Checking entitlement of "+context+" to "+entitlementClass+" "+entitlementClassArgument);
+        }
+        
+        if (isEntitledToRoot( context )) return true;
+        
+        switch (Entitlements.EntitlementClassesEnum.of(entitlementClass)) {
+        case ENTITLEMENT_SEE_ENTITY:
+            return isEntitledToSeeEntity( context, (Entity)entitlementClassArgument );
+            
+        case ENTITLEMENT_SEE_SENSOR:
+            return isEntitledToSeeSensor( context, (EntityAndItem<String>)entitlementClassArgument );
+            
+        case ENTITLEMENT_INVOKE_EFFECTOR:
+            return isEntitledToInvokeEffector( context, (EntityAndItem<String>)entitlementClassArgument );
+            
+        case ENTITLEMENT_DEPLOY_APPLICATION:
+            return isEntitledToDeploy( context, entitlementClassArgument );
+
+        case ENTITLEMENT_SEE_ALL_SERVER_INFO:
+            return isEntitledToSeeAllServerInfo( context );
+
+        default:
+            log.warn("Unsupported permission type: "+entitlementClass+" / "+entitlementClassArgument);
+            return false;
+        }
+    }
+
+    protected abstract boolean isEntitledToSeeSensor(EntitlementContext context, EntityAndItem<String> sensorInfo);
+    protected abstract boolean isEntitledToSeeEntity(EntitlementContext context, Entity entity);
+    protected abstract boolean isEntitledToInvokeEffector(EntitlementContext context, EntityAndItem<String> effectorInfo);
+    protected abstract boolean isEntitledToDeploy(EntitlementContext context, Object app);
+    protected abstract boolean isEntitledToSeeAllServerInfo(EntitlementContext context);
+    protected abstract boolean isEntitledToRoot(EntitlementContext context);
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8958fc14/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 684b0c6..6e3fe71 100644
--- a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
+++ b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
@@ -15,10 +15,6 @@
  */
 package brooklyn.management.entitlement;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.reflect.TypeToken;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -31,6 +27,11 @@ import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.text.Strings;
 
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.reflect.TypeToken;
+
 public class Entitlements {
 
     private static final Logger log = LoggerFactory.getLogger(Entitlements.class);
@@ -55,6 +56,31 @@ public class Entitlements {
      * secondary check required for any operation which could potentially grant root-level access */ 
     public static EntitlementClass<Void> ROOT = new BasicEntitlementClassDefinition<Void>("root", Void.class);
 
+    public static enum EntitlementClassesEnum {
+        ENTITLEMENT_SEE_ENTITY(SEE_ENTITY),
+        ENTITLEMENT_SEE_SENSOR(SEE_SENSOR),
+        ENTITLEMENT_INVOKE_EFFECTOR(INVOKE_EFFECTOR),
+        ENTITLEMENT_DEPLOY_APPLICATION(DEPLOY_APPLICATION),
+        ENTITLEMENT_SEE_ALL_SERVER_INFO(SEE_ALL_SERVER_INFO),
+        ENTITLEMENT_ROOT(ROOT),
+        ;
+        
+        private EntitlementClass<?> entitlementClass;
+
+        private EntitlementClassesEnum(EntitlementClass<?> specificClass) {
+            this.entitlementClass = specificClass;
+        }
+        public EntitlementClass<?> getEntitlementClass() {
+            return entitlementClass;
+        }
+        
+        public static EntitlementClassesEnum of(EntitlementClass<?> entitlementClass) {
+            for (EntitlementClassesEnum x: values()) {
+                if (entitlementClass.equals(x.getEntitlementClass())) return x;
+            }
+            return null;
+        }
+    }
     
     public static class EntityAndItem<T> {
         final Entity entity;
@@ -207,13 +233,14 @@ public class Entitlements {
     // ----------------- initialization ----------------
 
     public static ConfigKey<String> GLOBAL_ENTITLEMENT_MANAGER = ConfigKeys.newStringConfigKey("brooklyn.entitlements.global", 
-        "Class for entitlements in effect globally; many instances accept further per user entitlements; "
-        + "short names 'minimal', 'readonly', or 'root' are permitted here, with the default 'root' giving full access to all declared users",
+        "Class for entitlements in effect globally; "
+        + "short names 'minimal', 'readonly', or 'root' are permitted here, with the default 'root' giving full access to all declared users; "
+        + "or supply the name of an "+EntitlementManager.class+" class to instantiate, taking a 1-arg BrooklynProperties constructor or a 0-arg constructor",
         "root");
     
     public static EntitlementManager newManager(ResourceUtils loader, BrooklynProperties brooklynProperties) {
         EntitlementManager result = newGlobalManager(loader, brooklynProperties);
-        // TODO per user settings
+        // TODO read per user settings from brooklyn.properties, if set there ?
         return result;
     }
     private static EntitlementManager newGlobalManager(ResourceUtils loader, BrooklynProperties brooklynProperties) {
@@ -223,7 +250,12 @@ public class Entitlements {
         if ("minimal".equalsIgnoreCase(type)) return new PerUserEntitlementManagerWithDefault(minimal());
         if (Strings.isNonBlank(type)) {
             try {
-                return (EntitlementManager) loader.getLoader().loadClass(type).newInstance();
+                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();
+                }
             } 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/8958fc14/utils/common/src/main/java/brooklyn/util/guava/Maybe.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/guava/Maybe.java b/utils/common/src/main/java/brooklyn/util/guava/Maybe.java
index dc64349..85f7233 100644
--- a/utils/common/src/main/java/brooklyn/util/guava/Maybe.java
+++ b/utils/common/src/main/java/brooklyn/util/guava/Maybe.java
@@ -15,7 +15,7 @@ import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableSet;
 
 /** Like Guava Optional but permitting null and permitting errors to be thrown. */
-public abstract class Maybe<T> implements Serializable {
+public abstract class Maybe<T> implements Serializable, Supplier<T> {
 
     private static final long serialVersionUID = -6372099069863179019L;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8958fc14/utils/common/src/main/java/brooklyn/util/time/Duration.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/time/Duration.java b/utils/common/src/main/java/brooklyn/util/time/Duration.java
index 2b854fa..1c01f82 100644
--- a/utils/common/src/main/java/brooklyn/util/time/Duration.java
+++ b/utils/common/src/main/java/brooklyn/util/time/Duration.java
@@ -117,7 +117,13 @@ public class Duration implements Comparable<Duration>, Serializable {
 
     /** see {@link #of(Object)} and {@link Time#parseTimeString(String)} */
     public static Duration parse(String textualDescription) {
+        if (textualDescription==null) return null;
         if ("null".equalsIgnoreCase(textualDescription)) return null;
+        
+        if ("forever".equalsIgnoreCase(textualDescription)) return Duration.PRACTICALLY_FOREVER;
+        if ("practicallyforever".equalsIgnoreCase(textualDescription)) return Duration.PRACTICALLY_FOREVER;
+        if ("practically_forever".equalsIgnoreCase(textualDescription)) return Duration.PRACTICALLY_FOREVER;
+        
         return new Duration(Time.parseTimeString(textualDescription), TimeUnit.MILLISECONDS);
     }
 


[2/5] git commit: filter the applicationresource children according to the entitlements

Posted by he...@apache.org.
filter the applicationresource children according to the entitlements


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

Branch: refs/heads/master
Commit: 82136c7a951617be81fc57263dbe1cd35945ec0e
Parents: 8958fc1
Author: Andrea Turli <an...@gmail.com>
Authored: Mon Jun 30 18:58:32 2014 +0200
Committer: Andrea Turli <an...@gmail.com>
Committed: Mon Jun 30 18:58:32 2014 +0200

----------------------------------------------------------------------
 .../management/entitlement/Entitlements.java    | 10 ++++----
 .../rest/resources/ApplicationResource.java     | 26 +++++++++++++-------
 2 files changed, 22 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/82136c7a/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 6e3fe71..667bb3b 100644
--- a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
+++ b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
@@ -18,6 +18,11 @@ package brooklyn.management.entitlement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.reflect.TypeToken;
+
 import brooklyn.config.BrooklynProperties;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.Entity;
@@ -27,11 +32,6 @@ import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.text.Strings;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.reflect.TypeToken;
-
 public class Entitlements {
 
     private static final Logger log = LoggerFactory.getLogger(Entitlements.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/82136c7a/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 95eefb8..68e8bcd 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
@@ -140,26 +140,32 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
     private ArrayNode childEntitiesRecursiveAsArray(Entity entity) {
         ArrayNode node = mapper().createArrayNode();
         for (Entity e : entity.getChildren()) {
-            node.add(recursiveTreeFromEntity(e));
+            if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
+                node.add(recursiveTreeFromEntity(e));
+            }
         }
         return node;
     }
 
     private ArrayNode entitiesIdAndNameAsArray(Collection<? extends Entity> entities) {
         ArrayNode node = mapper().createArrayNode();
-        for (Entity e : entities) {
-            ObjectNode holder = mapper().createObjectNode();
-            holder.put("id", e.getId());
-            holder.put("name", e.getDisplayName());
-            node.add(holder);
+        for (Entity entity : entities) {
+            if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
+                ObjectNode holder = mapper().createObjectNode();
+                holder.put("id", entity.getId());
+                holder.put("name", entity.getDisplayName());
+                node.add(holder);
+            }
         }
         return node;
     }
 
     private ArrayNode entitiesIdAsArray(Collection<? extends Entity> entities) {
         ArrayNode node = mapper().createArrayNode();
-        for (Entity e : entities) {
-            node.add(e.getId());
+        for (Entity entity : entities) {
+            if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
+                node.add(entity.getId());
+            }
         }
         return node;
     }
@@ -173,7 +179,9 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
             for (String entityId: entityIds.split(",")) {
                 Entity entity = mgmt().getEntityManager().getEntity(entityId.trim());
                 while (entity != null && entity.getParent() != null) {
-                    jsonEntitiesById.put(entity.getId(), fromEntity(entity));
+                    if (Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
+                        jsonEntitiesById.put(entity.getId(), fromEntity(entity));
+                    }
                     entity = entity.getParent();
                 }
             }


[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

Posted by he...@apache.org.
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 <al...@cloudsoftcorp.com>
Authored: Mon Jun 30 21:27:54 2014 +0100
Committer: Alex Heneveld <al...@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();


[5/5] git commit: This closes #27

Posted by he...@apache.org.
This closes #27


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

Branch: refs/heads/master
Commit: b8f1a04dfe53868651be7e05a5f9ebd68065b4ee
Parents: 60a5576 ff7ff7b
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Jun 30 23:23:54 2014 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Jun 30 23:23:54 2014 +0100

----------------------------------------------------------------------
 .../entitlement/EntitlementManager.java         | 15 +++-
 .../entitlement/EntitlementManagerAdapter.java  | 62 ++++++++++++++
 .../management/entitlement/Entitlements.java    | 75 +++++++++++++---
 .../internal/EntityManagementSupport.java       |  2 +-
 .../rest/resources/ApplicationResource.java     | 90 ++++++++++++--------
 .../rest/util/BrooklynRestResourceUtils.java    | 31 ++++---
 .../main/java/brooklyn/util/guava/Maybe.java    |  2 +-
 .../main/java/brooklyn/util/time/Duration.java  |  6 ++
 8 files changed, 223 insertions(+), 60 deletions(-)
----------------------------------------------------------------------



[3/5] git commit: Merge remote-tracking branch 'andreaturli/more-entitlements' into more-entitlements

Posted by he...@apache.org.
Merge remote-tracking branch 'andreaturli/more-entitlements' into more-entitlements


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

Branch: refs/heads/master
Commit: f150725ea9c214ad65319d73c83a9df5a77ceac8
Parents: 79c8c40 82136c7
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Jun 30 21:01:14 2014 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Mon Jun 30 21:01:14 2014 +0100

----------------------------------------------------------------------
 .../entitlement/EntitlementManager.java         |  8 ++-
 .../entitlement/EntitlementManagerAdapter.java  | 51 ++++++++++++++++++++
 .../management/entitlement/Entitlements.java    | 44 ++++++++++++++---
 .../rest/resources/ApplicationResource.java     | 26 ++++++----
 .../main/java/brooklyn/util/guava/Maybe.java    |  2 +-
 .../main/java/brooklyn/util/time/Duration.java  |  6 +++
 6 files changed, 120 insertions(+), 17 deletions(-)
----------------------------------------------------------------------