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 2015/02/06 13:48:17 UTC

[05/11] incubator-brooklyn git commit: make effector arguments available to entitlements checks

make effector arguments available to entitlements checks


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

Branch: refs/heads/master
Commit: 3ff0e799313f086e31346104f8600a6d0ed048b7
Parents: ddf0a44
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Mon Dec 22 17:08:37 2014 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Thu Feb 5 11:56:08 2015 +0000

----------------------------------------------------------------------
 .../entitlement/EntitlementManagerAdapter.java  |  5 +--
 .../management/entitlement/Entitlements.java    | 34 ++++++++++++--------
 .../management/internal/EffectorUtils.java      |  4 +--
 .../internal/EntityChangeListener.java          |  4 +--
 .../internal/EntityManagementSupport.java       |  5 +--
 .../entitlement/AcmeEntitlementManagerTest.java |  3 +-
 .../AcmeEntitlementManagerTestFixture.java      |  7 ++--
 .../entitlement/EntitlementsTest.java           |  8 +++--
 .../entitlement/EntityEntitlementTest.java      |  9 +++---
 .../rest/resources/ApplicationResource.java     |  7 ++--
 .../rest/resources/EffectorResource.java        |  5 +--
 .../rest/util/BrooklynRestResourceUtils.java    |  4 ++-
 12 files changed, 57 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/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 6a62e36..e1c6be8 100644
--- a/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
+++ b/core/src/main/java/brooklyn/management/entitlement/EntitlementManagerAdapter.java
@@ -25,6 +25,7 @@ import com.google.common.annotations.Beta;
 
 import brooklyn.entity.Entity;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 
 /**
  * provides an easy entry point to supplying entitlements, by providing the dispatch and defining the additional methods
@@ -56,7 +57,7 @@ public abstract class EntitlementManagerAdapter implements EntitlementManager {
             return isEntitledToSeeSensor( context, (EntityAndItem<String>)entitlementClassArgument );
             
         case ENTITLEMENT_INVOKE_EFFECTOR:
-            return isEntitledToInvokeEffector( context, (EntityAndItem<String>)entitlementClassArgument );
+            return isEntitledToInvokeEffector( context, (EntityAndItem<StringAndArgument>)entitlementClassArgument );
             
         case ENTITLEMENT_DEPLOY_APPLICATION:
             return isEntitledToDeploy( context, entitlementClassArgument );
@@ -72,7 +73,7 @@ public abstract class EntitlementManagerAdapter implements EntitlementManager {
 
     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 isEntitledToInvokeEffector(EntitlementContext context, EntityAndItem<StringAndArgument> 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/3ff0e799/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 5d61e4f..67fb3c7 100644
--- a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
+++ b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
@@ -54,7 +54,8 @@ public class Entitlements {
     
     public static EntitlementClass<Entity> SEE_ENTITY = new BasicEntitlementClassDefinition<Entity>("entity.see", Entity.class);
     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));
+    // string is effector name; argument may be a map or a list, depending how the args were supplied
+    public static EntitlementClass<EntityAndItem<StringAndArgument>> INVOKE_EFFECTOR = new BasicEntitlementClassDefinition<EntityAndItem<StringAndArgument>>("effector.invoke", EntityAndItem.typeToken(StringAndArgument.class));
     public static EntitlementClass<Entity> MODIFY_ENTITY = new BasicEntitlementClassDefinition<Entity>("entity.modify", Entity.class);
     
     /** the permission to deploy an application, where parameter is some representation of the app to be deployed (spec instance or yaml plan) */
@@ -100,28 +101,33 @@ public class Entitlements {
         }
     }
     
-    public static class EntityAndItem<T> {
-        final Entity entity;
-        final T item;
+    protected static class Pair<T1,T2> {
+        protected final T1 p1;
+        protected final T2 p2;
+        protected Pair(T1 p1, T2 p2) { this.p1 = p1; this.p2 = p2; }
+    }
+    public static class EntityAndItem<T> extends Pair<Entity,T> {
         public static <TT> TypeToken<EntityAndItem<TT>> typeToken(Class<TT> type) {
             return new TypeToken<Entitlements.EntityAndItem<TT>>() {
                 private static final long serialVersionUID = -738154831809025407L;
             };
         }
-        public EntityAndItem(Entity entity, T item) {
-            this.entity = entity;
-            this.item = item;
-        }
-        public Entity getEntity() {
-            return entity;
-        }
-        public T getItem() {
-            return item;
-        }
+        public EntityAndItem(Entity entity, T item) { super (entity, item); }
+        public Entity getEntity() { return p1; }
+        public T getItem() { return p2; }
         public static <T> EntityAndItem<T> of(Entity entity, T item) {
             return new EntityAndItem<T>(entity, item);
         }
     }
+    
+    public static class StringAndArgument extends Pair<String,Object> {
+        public StringAndArgument(String string, Object argument) { super(string, argument); }
+        public String getString() { return p1; }
+        public Object getArgument() { return p2; }
+        public static StringAndArgument of(String string, Object argument) {
+            return new StringAndArgument(string, argument);
+        }
+    }
 
     /** 
      * These lifecycle operations are currently treated as effectors. This may change in the future.

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/core/src/main/java/brooklyn/management/internal/EffectorUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EffectorUtils.java b/core/src/main/java/brooklyn/management/internal/EffectorUtils.java
index d55f3a8..c14b98c 100644
--- a/core/src/main/java/brooklyn/management/internal/EffectorUtils.java
+++ b/core/src/main/java/brooklyn/management/internal/EffectorUtils.java
@@ -245,7 +245,7 @@ public class EffectorUtils {
             }
             ManagementContextInternal mgmtContext = (ManagementContextInternal) ((EntityInternal) entity).getManagementContext();
 
-            mgmtSupport.getEntityChangeListener().onEffectorStarting(eff);
+            mgmtSupport.getEntityChangeListener().onEffectorStarting(eff, args);
             try {
                 return mgmtContext.invokeEffectorMethodSync(entity, eff, args);
             } finally {
@@ -276,7 +276,7 @@ public class EffectorUtils {
 
         // FIXME seems brittle to have the listeners in the Utils method; better to move into the context.invokeEff
         // (or whatever the last mile before invoking the effector is - though currently there is not such a canonical place!)
-        mgmtSupport.getEntityChangeListener().onEffectorStarting(eff);
+        mgmtSupport.getEntityChangeListener().onEffectorStarting(eff, parameters);
         try {
             return mgmtContext.invokeEffector(entity, eff, parameters);
         } finally {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/core/src/main/java/brooklyn/management/internal/EntityChangeListener.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/EntityChangeListener.java b/core/src/main/java/brooklyn/management/internal/EntityChangeListener.java
index 811092a..9828844 100644
--- a/core/src/main/java/brooklyn/management/internal/EntityChangeListener.java
+++ b/core/src/main/java/brooklyn/management/internal/EntityChangeListener.java
@@ -42,7 +42,7 @@ public interface EntityChangeListener {
         @Override public void onEnricherRemoved(Enricher enricher) {}
         @Override public void onFeedAdded(Feed feed) {}
         @Override public void onFeedRemoved(Feed feed) {}
-        @Override public void onEffectorStarting(Effector<?> effector) {}
+        @Override public void onEffectorStarting(Effector<?> effector, Object parameters) {}
         @Override public void onEffectorCompleted(Effector<?> effector) {}
     };
     
@@ -72,7 +72,7 @@ public interface EntityChangeListener {
 
     void onFeedRemoved(Feed feed);
 
-    void onEffectorStarting(Effector<?> effector);
+    void onEffectorStarting(Effector<?> effector, Object parameters);
     
     void onEffectorCompleted(Effector<?> effector);
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/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 026cf49..fa5de94 100644
--- a/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
+++ b/core/src/main/java/brooklyn/management/internal/EntityManagementSupport.java
@@ -41,6 +41,7 @@ import brooklyn.management.SubscriptionContext;
 import brooklyn.management.entitlement.EntitlementManager;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.management.internal.NonDeploymentManagementContext.NonDeploymentManagementContextMode;
 import brooklyn.policy.Enricher;
 import brooklyn.policy.Policy;
@@ -456,8 +457,8 @@ public class EntityManagementSupport {
             getManagementContext().getRebindManager().getChangeListener().onChanged(entity);
         }
         @Override
-        public void onEffectorStarting(Effector<?> effector) {
-            Entitlements.checkEntitled(getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(entity, effector.getName()));
+        public void onEffectorStarting(Effector<?> effector, Object parameters) {
+            Entitlements.checkEntitled(getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(entity, StringAndArgument.of(effector.getName(), parameters)));
         }
         @Override
         public void onEffectorCompleted(Effector<?> effector) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
index 1927f4d..e43fe4a 100644
--- a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
+++ b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
@@ -24,6 +24,7 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 
 public class AcmeEntitlementManagerTest extends AcmeEntitlementManagerTestFixture {
 
@@ -48,7 +49,7 @@ public class AcmeEntitlementManagerTest extends AcmeEntitlementManagerTestFixtur
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
-        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         // and cannot invoke methods
         confirmEffectorEntitlement(false);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
index 24f1e52..a0fd135 100644
--- a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
+++ b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTestFixture.java
@@ -40,6 +40,7 @@ import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.NotEntitledException;
 import brooklyn.management.entitlement.WebEntitlementContext;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.test.entity.LocalManagementContextForTests;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
@@ -84,7 +85,7 @@ public abstract class AcmeEntitlementManagerTestFixture {
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
-        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         // and can invoke methods
         confirmEffectorEntitlement(false);
@@ -101,7 +102,7 @@ public abstract class AcmeEntitlementManagerTestFixture {
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
-        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         // and cannot invoke methods
         confirmEffectorEntitlement(false);
@@ -118,7 +119,7 @@ public abstract class AcmeEntitlementManagerTestFixture {
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
-        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         // and can invoke methods
         confirmEffectorEntitlement(true);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/core/src/test/java/brooklyn/management/entitlement/EntitlementsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/EntitlementsTest.java b/core/src/test/java/brooklyn/management/entitlement/EntitlementsTest.java
index a4f23de..3e6b207 100644
--- a/core/src/test/java/brooklyn/management/entitlement/EntitlementsTest.java
+++ b/core/src/test/java/brooklyn/management/entitlement/EntitlementsTest.java
@@ -32,6 +32,8 @@ import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.management.ManagementContext;
+import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.test.entity.LocalManagementContextForTests;
 
 @Test
@@ -156,7 +158,7 @@ public class EntitlementsTest {
     public void testAppSpecificRootEntitlement() {
         EntitlementManager root = Entitlements.root();
         assertTrue(root.isEntitled(null, Entitlements.SEE_ENTITY, app));
-        assertTrue(root.isEntitled(null, Entitlements.INVOKE_EFFECTOR, Entitlements.EntityAndItem.of(app, "any-eff")));
+        assertTrue(root.isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         assertTrue(root.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
         assertTrue(root.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
         assertTrue(root.isEntitled(null, Entitlements.DEPLOY_APPLICATION, Entitlements.EntityAndItem.of(app, null)));
@@ -176,7 +178,7 @@ public class EntitlementsTest {
     public void testAppSpecificMinimalEntitlement() {
         EntitlementManager minimal = Entitlements.minimal();
         assertFalse(minimal.isEntitled(null, Entitlements.SEE_ENTITY, app));
-        assertFalse(minimal.isEntitled(null, Entitlements.INVOKE_EFFECTOR, Entitlements.EntityAndItem.of(app, "any-eff")));
+        assertFalse(minimal.isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         assertFalse(minimal.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
         assertFalse(minimal.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
         assertFalse(minimal.isEntitled(null, Entitlements.DEPLOY_APPLICATION, Entitlements.EntityAndItem.of(app, null)));
@@ -196,7 +198,7 @@ public class EntitlementsTest {
     public void testAppSpecificReadOnlyEntitlement() {
         EntitlementManager readOnly = Entitlements.readOnly();
         assertTrue(readOnly.isEntitled(null, Entitlements.SEE_ENTITY, app));
-        assertFalse(readOnly.isEntitled(null, Entitlements.INVOKE_EFFECTOR, Entitlements.EntityAndItem.of(app, "any-eff")));
+        assertFalse(readOnly.isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         assertTrue(readOnly.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "any-sensor")));
         assertFalse(readOnly.isEntitled(null, Entitlements.SEE_SENSOR, Entitlements.EntityAndItem.of(app, "password")));
         assertFalse(readOnly.isEntitled(null, Entitlements.DEPLOY_APPLICATION, Entitlements.EntityAndItem.of(app, null)));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java b/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
index c13fe31..d380e6f 100644
--- a/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
+++ b/core/src/test/java/brooklyn/management/entitlement/EntityEntitlementTest.java
@@ -35,6 +35,7 @@ import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.location.Location;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.management.internal.LocalManagementContext;
 import brooklyn.test.entity.LocalManagementContextForTests;
 import brooklyn.util.config.ConfigBag;
@@ -66,7 +67,7 @@ public class EntityEntitlementTest {
         // default "root" access allows ROOT permission, and invoke effector, etc
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
-        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         // and can invoke methods, without any user/login registered
         confirmEffectorEntitlement(true);
@@ -79,7 +80,7 @@ public class EntityEntitlementTest {
         
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
-        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         
         confirmEffectorEntitlement(true);
@@ -117,7 +118,7 @@ public class EntityEntitlementTest {
         
         Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
-        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertTrue(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         
         confirmEffectorEntitlement(false);
@@ -130,7 +131,7 @@ public class EntityEntitlementTest {
         
         Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.ROOT, null));
         Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_ENTITY, app));
-        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, "any-eff")));
+        Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, StringAndArgument.of("any-eff", null))));
         Assert.assertFalse(mgmt.getEntitlementManager().isEntitled(null, Entitlements.SEE_SENSOR, EntityAndItem.of(app, "any-sensor")));
         
         confirmEffectorEntitlement(false);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/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 9511ebe..c9f42ae 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
@@ -60,6 +60,7 @@ import brooklyn.management.Task;
 import brooklyn.management.entitlement.EntitlementPredicates;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.management.entitlement.Entitlements.EntityAndItem;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.management.internal.EntityManagementUtils;
 import brooklyn.management.internal.EntityManagementUtils.CreationResult;
 import brooklyn.rest.api.ApplicationApi;
@@ -281,7 +282,8 @@ public class ApplicationResource extends AbstractBrooklynRestResource implements
             CreationResult<? extends Application, Void> result = EntityManagementUtils.createStarting(mgmt(), at);
             
             Application app = result.get();
-            if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, Startable.START.getName()))) {
+            if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, EntityAndItem.of(app, 
+                StringAndArgument.of(Startable.START.getName(), null)))) {
                 throw WebResourceUtils.unauthorized("User '%s' is not authorized to start application %s",
                     Entitlements.getEntitlementContext().user(), at.getType());
             }
@@ -358,7 +360,8 @@ 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, Entitlements.LifecycleEffectors.DELETE))) {
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR, Entitlements.EntityAndItem.of(app, 
+            StringAndArgument.of(Entitlements.LifecycleEffectors.DELETE, null)))) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to delete application %s",
                 Entitlements.getEntitlementContext().user(), app);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
index dc76de4..1ee4cf4 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
@@ -37,6 +37,7 @@ import brooklyn.entity.Effector;
 import brooklyn.entity.basic.EntityLocal;
 import brooklyn.management.Task;
 import brooklyn.management.entitlement.Entitlements;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.management.internal.EffectorUtils;
 import brooklyn.rest.api.EffectorApi;
 import brooklyn.rest.domain.EffectorSummary;
@@ -61,7 +62,7 @@ public class EffectorResource extends AbstractBrooklynRestResource implements Ef
                     @Override
                     public boolean apply(@Nullable Effector<?> input) {
                         return Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
-                                Entitlements.EntityAndItem.of(entity, input.getName()));
+                                Entitlements.EntityAndItem.of(entity, StringAndArgument.of(input.getName(), null)));
                     }
                 })
                 .transform(new Function<Effector<?>, EffectorSummary>() {
@@ -83,7 +84,7 @@ public class EffectorResource extends AbstractBrooklynRestResource implements Ef
         if (effector.isAbsentOrNull()) {
             throw WebResourceUtils.notFound("Entity '%s' has no effector with name '%s'", entityToken, effectorName);
         } else if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.INVOKE_EFFECTOR,
-                Entitlements.EntityAndItem.of(entity, effector.get().getName()))) {
+                Entitlements.EntityAndItem.of(entity, StringAndArgument.of(effector.get().getName(), null)))) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to invoke effector %s on entity %s",
                     Entitlements.getEntitlementContext().user(), effector.get().getName(), entity);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3ff0e799/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 5ddf037..b2fd4a5 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
@@ -59,6 +59,7 @@ import brooklyn.location.LocationRegistry;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.Task;
 import brooklyn.management.entitlement.Entitlements;
+import brooklyn.management.entitlement.Entitlements.StringAndArgument;
 import brooklyn.policy.Policy;
 import brooklyn.policy.basic.AbstractPolicy;
 import brooklyn.rest.domain.ApplicationSpec;
@@ -438,7 +439,8 @@ public class BrooklynRestResourceUtils {
     
     public Task<?> expunge(final Entity entity, final boolean release) {
         if (mgmt.getEntitlementManager().isEntitled(Entitlements.getEntitlementContext(),
-                Entitlements.INVOKE_EFFECTOR, Entitlements.EntityAndItem.of(entity, "expunge"))) {
+                Entitlements.INVOKE_EFFECTOR, Entitlements.EntityAndItem.of(entity, 
+                    StringAndArgument.of("expunge", MutableMap.of("release", release))))) {
             return mgmt.getExecutionManager().submit(
                     MutableMap.of("displayName", "expunging " + entity, "description", "REST call to expunge entity "
                             + entity.getDisplayName() + " (" + entity + ")"), new Runnable() {