Rename DslCallable to DslFunctionSource and some cleanup

Addresses review comments.


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

Branch: refs/heads/master
Commit: 60c5c6fa97ae3bd33548832123e5f50c5532b128
Parents: b75b45c
Author: Svetoslav Neykov <svetoslav.ney...@cloudsoftcorp.com>
Authored: Tue Dec 13 16:42:57 2016 +0200
Committer: Svetoslav Neykov <svetoslav.ney...@cloudsoftcorp.com>
Committed: Tue Dec 13 16:42:57 2016 +0200

----------------------------------------------------------------------
 .../spi/dsl/BrooklynDslInterpreter.java         |  7 +-
 .../camp/brooklyn/spi/dsl/DslCallable.java      | 26 ------
 .../spi/dsl/DslDeferredFunctionCall.java        | 95 ++++++++++----------
 .../brooklyn/spi/dsl/DslFunctionSource.java     | 26 ++++++
 .../brooklyn/spi/dsl/methods/DslComponent.java  |  4 +-
 .../camp/brooklyn/spi/dsl/DslYamlTest.java      | 32 ++++++-
 .../spi/dsl/methods/DslTestObjects.java         |  7 +-
 .../brooklyn/util/core/task/ValueResolver.java  |  1 -
 8 files changed, 115 insertions(+), 83 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
index 16d5c5a..ab20c3b 100644
--- 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
+++ 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java
@@ -33,7 +33,6 @@ import 
org.apache.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
 import 
org.apache.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode.Role;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.javalang.Reflections;
 import org.apache.brooklyn.util.text.Strings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -170,12 +169,14 @@ public class BrooklynDslInterpreter extends 
PlanInterpreterAdapter {
             args.add( deepEvaluation ? evaluate(arg, true) : arg );
         }
         try {
-            if (o instanceof BrooklynDslDeferredSupplier && !(o instanceof 
DslCallable)) {
+            // TODO Could move argument resolve in DslDeferredFunctionCall 
freeing each Deffered implementation
+            // having to handle it separately. The shortcoming is that will 
lose the eager evaluation we have here.
+            if (o instanceof BrooklynDslDeferredSupplier && !(o instanceof 
DslFunctionSource)) {
                 return new 
DslDeferredFunctionCall((BrooklynDslDeferredSupplier<?>) o, fn, args);
             } else {
                 // Would prefer to keep the invocation logic encapsulated in 
DslDeferredFunctionCall, but
                 // for backwards compatibility will evaluate as much as 
possible eagerly (though it shouldn't matter in theory).
-                return DslDeferredFunctionCall.invokeOn(o, fn, args);
+                return DslDeferredFunctionCall.invokeOn(o, fn, args).get();
             }
         } catch (Exception e) {
             Exceptions.propagateIfFatal(e);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslCallable.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslCallable.java
 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslCallable.java
deleted file mode 100644
index 4eeddb7..0000000
--- 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslCallable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2016 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.brooklyn.camp.brooklyn.spi.dsl;
-
-import org.apache.brooklyn.util.core.task.DeferredSupplier;
-
-/**
- * Marker interface so the evaluator can tell apart objects which are {@link 
DeferredSupplier}
- * but which expect DSL methods called on them instead of the value they 
supply.
- */
-public interface DslCallable {
-
-}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java
 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java
index ad8c4b1..638f36f 100644
--- 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java
+++ 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslDeferredFunctionCall.java
@@ -37,12 +37,11 @@ public class DslDeferredFunctionCall extends 
BrooklynDslDeferredSupplier<Object>
 
     private static final long serialVersionUID = 3243262633795112155L;
 
-    // TODO should this be some of the super types?
-    private BrooklynDslDeferredSupplier<?> object;
+    private Object object;
     private String fnName;
     private List<?> args;
 
-    public DslDeferredFunctionCall(BrooklynDslDeferredSupplier<?> o, String 
fn, List<Object> args) {
+    public DslDeferredFunctionCall(Object o, String fn, List<Object> args) {
         this.object = o;
         this.fnName = fn;
         this.args = args;
@@ -50,15 +49,7 @@ public class DslDeferredFunctionCall extends 
BrooklynDslDeferredSupplier<Object>
 
     @Override
     public Maybe<Object> getImmediately() {
-        Maybe<?> obj = resolveImmediate(object);
-        if (obj.isPresent()) {
-            if (obj.isNull()) {
-                throw new IllegalArgumentException("Deferred function call, " 
+ object + 
-                        " evaluates to null (when calling " + fnName + "(" + 
toString(args) + "))");
-            }
-            return Maybe.of(invokeOn(obj.get()));
-        }
-        return Maybe.absent("Could not evaluate immediately " + object);
+        return invokeOnDeferred(object, true);
     }
 
     @Override
@@ -70,52 +61,37 @@ public class DslDeferredFunctionCall extends 
BrooklynDslDeferredSupplier<Object>
                 .body(new Callable<Object>() {
                     @Override
                     public Object call() throws Exception {
-                        Object obj = 
DslDeferredFunctionCall.this.resolveBlocking(object).orNull();
-                        if (obj == null) {
-                            throw new IllegalArgumentException("Deferred 
function call, " + object + 
-                                    " evaluates to null (when calling " + 
fnName + "(" + DslDeferredFunctionCall.toString(args) + "))");
-                        }
-                        return invokeOn(obj);
+                        return invokeOnDeferred(object, false).get();
                     }
 
                 }).build();
     }
 
-    protected Maybe<?> resolveImmediate(Object object) {
-        return resolve(object, true);
-    }
-    protected Maybe<?> resolveBlocking(Object object) {
-        return resolve(object, false);
-    }
-    protected Maybe<?> resolve(Object object, boolean immediate) {
-        if (object instanceof DslCallable || object == null) {
-            return Maybe.of(object);
-        }
-        Maybe<?> resultMaybe = Tasks.resolving(object, Object.class)
-                .context(((EntityInternal)entity()).getExecutionContext())
-                .deep(true)
-                .immediately(immediate)
-                .recursive(false)
-                .getMaybe();
-        if (resultMaybe.isAbsent()) {
-            return resultMaybe;
+    protected Maybe<Object> invokeOnDeferred(Object obj, boolean immediate) {
+        Maybe<?> resolvedMaybe = resolve(obj, immediate);
+        if (resolvedMaybe.isPresent()) {
+            Object instance = resolvedMaybe.get();
+
+            if (instance == null) {
+                throw new IllegalArgumentException("Deferred function call, " 
+ object + 
+                        " evaluates to null (when calling " + fnName + "(" + 
toString(args) + "))");
+            }
+
+            return invokeOn(instance);
         } else {
-            // No nice way to figure out whether the object is deferred. Try 
to resolve it
-            // until it matches the input value as a poor man's replacement.
-            Object result = resultMaybe.get();
-            if (result == object) {
-                return resultMaybe;
+            if (immediate) {
+                return Maybe.absent("Could not evaluate immediately " + obj);
             } else {
-                return resolve(result, immediate);
+                return Maybe.absent(Maybe.getException(resolvedMaybe));
             }
         }
     }
 
-    protected Object invokeOn(Object obj) {
+    protected Maybe<Object> invokeOn(Object obj) {
         return invokeOn(obj, fnName, args);
     }
 
-    protected static Object invokeOn(Object obj, String fnName, List<?> args) {
+    protected static Maybe<Object> invokeOn(Object obj, String fnName, List<?> 
args) {
         Object instance = obj;
         List<?> instanceArgs = args;
         Maybe<Method> method = Reflections.getMethodFromArgs(instance, fnName, 
instanceArgs);
@@ -148,12 +124,39 @@ public class DslDeferredFunctionCall extends 
BrooklynDslDeferredSupplier<Object>
 
             try {
                 // Value is most likely another BrooklynDslDeferredSupplier - 
let the caller handle it,
-                return Reflections.invokeMethodFromArgs(instance, m, 
instanceArgs);
+                return Maybe.of(Reflections.invokeMethodFromArgs(instance, m, 
instanceArgs));
             } catch (IllegalArgumentException | IllegalAccessException | 
InvocationTargetException e) {
+                // If the method is there but not executable for whatever 
reason fail with a fatal error, don't return an absent.
                 throw Exceptions.propagate(new InvocationTargetException(e, 
"Error invoking '"+fnName+"("+toString(instanceArgs)+")' on '"+instance+"'"));
             }
         } else {
-            throw new IllegalArgumentException("No such function 
'"+fnName+"("+toString(args)+")' on "+obj);
+            return Maybe.absent(new IllegalArgumentException("No such function 
'"+fnName+"("+toString(args)+")' on "+obj));
+        }
+    }
+
+    protected Maybe<?> resolve(Object object, boolean immediate) {
+        if (object instanceof DslFunctionSource || object == null) {
+            return Maybe.of(object);
+        }
+
+        Maybe<?> resultMaybe = Tasks.resolving(object, Object.class)
+                .context(((EntityInternal)entity()).getExecutionContext())
+                .deep(true)
+                .immediately(immediate)
+                .recursive(false)
+                .getMaybe();
+
+        if (resultMaybe.isPresent()) {
+            // No nice way to figure out whether the object is deferred. Try 
to resolve it
+            // until it matches the input value as a poor man's replacement.
+            Object result = resultMaybe.get();
+            if (result == object) {
+                return resultMaybe;
+            } else {
+                return resolve(result, immediate);
+            }
+        } else {
+            return resultMaybe;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslFunctionSource.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslFunctionSource.java
 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslFunctionSource.java
new file mode 100644
index 0000000..ac85603
--- /dev/null
+++ 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslFunctionSource.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.brooklyn.camp.brooklyn.spi.dsl;
+
+import org.apache.brooklyn.util.core.task.DeferredSupplier;
+
+/**
+ * Marker interface so the evaluator can tell apart objects which are {@link 
DeferredSupplier}
+ * but which expect DSL methods called on them instead of the value they 
supply.
+ */
+public interface DslFunctionSource {
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
index d6859fa..37b9c59 100644
--- 
a/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
+++ 
b/camp/camp-brooklyn/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
 import org.apache.brooklyn.api.sensor.Sensor;
 import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
 import org.apache.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier;
-import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslCallable;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslFunctionSource;
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
 import org.apache.brooklyn.core.entity.Entities;
@@ -63,7 +63,7 @@ import com.google.common.base.Predicates;
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.Callables;
 
-public class DslComponent extends BrooklynDslDeferredSupplier<Entity> 
implements DslCallable {
+public class DslComponent extends BrooklynDslDeferredSupplier<Entity> 
implements DslFunctionSource {
 
     private static final long serialVersionUID = -7715984495268724954L;
     

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java
 
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java
index 65fd66d..aca1aba 100644
--- 
a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java
+++ 
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/DslYamlTest.java
@@ -38,6 +38,7 @@ import org.apache.brooklyn.core.test.entity.TestApplication;
 import org.apache.brooklyn.entity.stock.BasicApplication;
 import org.apache.brooklyn.entity.stock.BasicEntity;
 import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.testng.annotations.Test;
 
@@ -351,7 +352,7 @@ public class DslYamlTest extends AbstractYamlTest {
         assertEquals(getConfigEventually(app, DEST), "myvalue");
     }
 
-    @Test(groups="WIP") // config accepts strings only, no suppliers
+    @Test(groups="WIP") // attributeWhenReady accepts strings only, no 
suppliers
     public void testDslAttributeWhenReadyWithDeferredArg() throws Exception {
         final Entity app = createAndStartApplication(
                 "services:",
@@ -367,7 +368,7 @@ public class DslYamlTest extends AbstractYamlTest {
         assertEquals(getConfigEventually(app, DEST), "myvalue");
     }
 
-    @Test(groups="WIP") // config accepts strings only, no suppliers
+    @Test(groups="WIP") // attributeWhenReady accepts strings only, no 
suppliers
     public void testDslAttributeWhenReadyOnEntityWithDeferredArg() throws 
Exception {
         final Entity app = createAndStartApplication(
                 "services:",
@@ -505,6 +506,20 @@ public class DslYamlTest extends AbstractYamlTest {
         assertEquals(replacementFn.apply("Broooklyn"), "Brooklyn");
     }
 
+    @Test
+    public void testDslNonDeferredInvalidMethod() throws Exception {
+        try {
+            createAndStartApplication(
+                    "services:",
+                    "- type: " + BasicApplication.class.getName(),
+                    "  brooklyn.config:",
+                    "    dest: $brooklyn:self().invalidMethod()");
+            Asserts.shouldHaveFailedPreviously("Non-existing non-deferred 
method should fail deployment");
+        } catch (CompoundRuntimeException e) {
+            Asserts.expectedFailureContains(e, "No such function 
'invalidMethod()'");
+        }
+    }
+
     public static class InaccessibleType {
         public static void isEvaluated() {}
     }
@@ -548,6 +563,17 @@ public class DslYamlTest extends AbstractYamlTest {
     }
 
     @Test
+    public void testDeferredDslChainingDslComponent() throws Exception {
+        final Entity app = createAndStartApplication(
+                "services:",
+                "- type: " + BasicApplication.class.getName(),
+                "  brooklyn.config:",
+                "    dest: 
$brooklyn:config(\"targetValue\").self().attributeWhenReady(\"entity.id\")");
+        app.config().set(ConfigKeys.newConfigKey(TestDslSupplierValue.class, 
"targetValue"), new TestDslSupplierValue());
+        assertEquals(getConfigEventually(app, DEST), app.getId());
+    }
+
+    @Test
     public void testDeferredDslChainingOnConfigNoFunction() throws Exception {
         final Entity app = createAndStartApplication(
                 "services:",
@@ -710,7 +736,7 @@ public class DslYamlTest extends AbstractYamlTest {
         Task<T> result = 
((EntityInternal)entity).getExecutionContext().submit(new Callable<T>() {
             @Override
             public T call() throws Exception {
-                // TODO Move the getNonBlocking call out of the task after 
#280 is merged.
+                // TODO Move the getNonBlocking call out of the task after 
#480 is merged.
                 // Currently doesn't work because no execution context 
available.
                 Maybe<T> immediateValue = 
((EntityInternal)entity).config().getNonBlocking(configKey);
                 T blockingValue = entity.config().get(configKey);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslTestObjects.java
----------------------------------------------------------------------
diff --git 
a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslTestObjects.java
 
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslTestObjects.java
index 9cd1dbd..60225af 100644
--- 
a/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslTestObjects.java
+++ 
b/camp/camp-brooklyn/src/test/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslTestObjects.java
@@ -15,7 +15,7 @@
  */
 package org.apache.brooklyn.camp.brooklyn.spi.dsl.methods;
 
-import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslCallable;
+import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslFunctionSource;
 import org.apache.brooklyn.util.core.task.DeferredSupplier;
 import org.apache.brooklyn.util.core.task.ImmediateSupplier;
 import org.apache.brooklyn.util.guava.Maybe;
@@ -38,6 +38,9 @@ public class DslTestObjects {
         public boolean isSupplierEvaluated() {
             return true;
         }
+        public DslComponent self() {
+            return BrooklynDslCommon.self();
+        }
     }
 
     public static class TestDslSupplier implements DeferredSupplier<Object>, 
ImmediateSupplier<Object> {
@@ -58,7 +61,7 @@ public class DslTestObjects {
         }
     }
 
-    public static class DslTestCallable implements DslCallable, 
DeferredSupplier<TestDslSupplier>, ImmediateSupplier<TestDslSupplier> {
+    public static class DslTestCallable implements DslFunctionSource, 
DeferredSupplier<TestDslSupplier>, ImmediateSupplier<TestDslSupplier> {
 
         @Override
         public Maybe<TestDslSupplier> getImmediately() {

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/60c5c6fa/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
----------------------------------------------------------------------
diff --git 
a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java 
b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
index 4dcf5be..3b00252 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ValueResolver.java
@@ -31,7 +31,6 @@ import org.apache.brooklyn.api.mgmt.Task;
 import org.apache.brooklyn.api.mgmt.TaskAdaptable;
 import org.apache.brooklyn.core.entity.EntityInternal;
 import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.rebind.ImmediateDeltaChangeListener;
 import org.apache.brooklyn.util.core.flags.TypeCoercions;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;

Reply via email to