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/08/20 00:53:49 UTC
[01/36] incubator-brooklyn git commit: Rename
o.a.b.util.groovy.internal to o.a.b.util.groovy
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master dbf621a84 -> 147f9ec44
Rename o.a.b.util.groovy.internal to o.a.b.util.groovy
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0eab0fa0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0eab0fa0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0eab0fa0
Branch: refs/heads/master
Commit: 0eab0fa05e4b9f700cef855e974971faf494116c
Parents: dbf621a
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 22:31:05 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 19 22:31:24 2015 +0100
----------------------------------------------------------------------
.../util/core/BrooklynLanguageExtensions.java | 2 +-
.../brooklyn/util/core/internal/Repeater.java | 2 +-
.../util/core/internal/RepeaterTest.groovy | 4 +-
.../Infinispan5ServerIntegrationTest.groovy | 2 +-
.../nosql/couchdb/AbstractCouchDBNodeTest.java | 2 +-
.../webapp/WebAppLiveIntegrationTest.groovy | 2 +-
...namicWebAppClusterRebindIntegrationTest.java | 2 +-
.../brooklyn/util/groovy/JavadocDummy.java | 30 ++
.../brooklyn/util/groovy/LanguageUtils.groovy | 383 +++++++++++++++++++
.../brooklyn/util/groovy/TimeExtras.groovy | 83 ++++
.../util/groovy/internal/JavadocDummy.java | 30 --
.../util/groovy/internal/LanguageUtils.groovy | 383 -------------------
.../util/groovy/internal/TimeExtras.groovy | 83 ----
.../util/groovy/LanguageUtilsTest.groovy | 152 ++++++++
.../brooklyn/util/groovy/PojoTestingFields.java | 28 ++
.../brooklyn/util/groovy/TimeExtrasTest.groovy | 49 +++
.../groovy/internal/LanguageUtilsTest.groovy | 153 --------
.../util/groovy/internal/PojoTestingFields.java | 28 --
.../util/groovy/internal/TimeExtrasTest.groovy | 51 ---
19 files changed, 733 insertions(+), 736 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/core/src/main/java/org/apache/brooklyn/util/core/BrooklynLanguageExtensions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/BrooklynLanguageExtensions.java b/core/src/main/java/org/apache/brooklyn/util/core/BrooklynLanguageExtensions.java
index 5e7f0a6..afad73f 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/BrooklynLanguageExtensions.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/BrooklynLanguageExtensions.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.util.core;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.brooklyn.core.internal.BrooklynInitialization;
-import org.apache.brooklyn.util.groovy.internal.TimeExtras;
+import org.apache.brooklyn.util.groovy.TimeExtras;
/** @deprecated since 0.7.0 use {@link BrooklynInitialization} */
public class BrooklynLanguageExtensions {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/core/src/main/java/org/apache/brooklyn/util/core/internal/Repeater.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/internal/Repeater.java b/core/src/main/java/org/apache/brooklyn/util/core/internal/Repeater.java
index bc54b6e..77d15c7 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/internal/Repeater.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/internal/Repeater.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.FlagUtils;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.groovy.internal.TimeExtras;
+import org.apache.brooklyn.util.groovy.TimeExtras;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/core/src/test/java/org/apache/brooklyn/util/core/internal/RepeaterTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/internal/RepeaterTest.groovy b/core/src/test/java/org/apache/brooklyn/util/core/internal/RepeaterTest.groovy
index 5888aa0..5eae3c9 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/internal/RepeaterTest.groovy
+++ b/core/src/test/java/org/apache/brooklyn/util/core/internal/RepeaterTest.groovy
@@ -25,8 +25,8 @@ import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit
import org.testng.annotations.Test
-import org.apache.brooklyn.util.core.internal.Repeater;
-import org.apache.brooklyn.util.groovy.internal.TimeExtras;
+import org.apache.brooklyn.util.core.internal.Repeater
+import org.apache.brooklyn.util.groovy.TimeExtras;
import org.apache.brooklyn.util.time.Duration;
import com.google.common.base.Stopwatch
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
index b283f2f..1e68c27 100644
--- a/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
+++ b/sandbox/nosql/src/test/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5ServerIntegrationTest.groovy
@@ -35,7 +35,7 @@ import org.apache.brooklyn.api.entity.Application
import org.apache.brooklyn.core.entity.Entities
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation
import org.apache.brooklyn.core.test.entity.TestApplicationImpl
-import org.apache.brooklyn.util.groovy.internal.TimeExtras
+import org.apache.brooklyn.util.groovy.TimeExtras;
import org.apache.brooklyn.util.net.Networking
import org.apache.brooklyn.util.repeat.Repeater
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
index a4382ce..2ecfac8 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/couchdb/AbstractCouchDBNodeTest.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.util.groovy.internal.TimeExtras;
+import org.apache.brooklyn.util.groovy.TimeExtras;
/**
* CouchDB test framework for integration and live tests.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
index 6bb41cf..c8747fa 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/WebAppLiveIntegrationTest.groovy
@@ -37,7 +37,7 @@ import org.apache.brooklyn.entity.webapp.jboss.JBoss7ServerImpl
import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer
import org.apache.brooklyn.entity.webapp.tomcat.TomcatServerImpl
import org.apache.brooklyn.test.TestUtils
-import org.apache.brooklyn.util.groovy.internal.TimeExtras
+import org.apache.brooklyn.util.groovy.TimeExtras;
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.testng.annotations.AfterMethod
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
index a4dec8c..b05a747 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/webapp/jboss/ControlledDynamicWebAppClusterRebindIntegrationTest.java
@@ -41,7 +41,7 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.test.WebAppMonitor;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
-import org.apache.brooklyn.util.groovy.internal.TimeExtras;
+import org.apache.brooklyn.util.groovy.TimeExtras;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/JavadocDummy.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/JavadocDummy.java b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/JavadocDummy.java
new file mode 100644
index 0000000..c9a51b5
--- /dev/null
+++ b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/JavadocDummy.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.groovy;
+
+/** Maven Central requires javadoc to promote as a release. This seemed to happen when this was built by maven as a bundle,
+ * but now that it is built as a jar it does not. This class exists only to provide that javadoc.
+ * <p>
+ * Note the groovy code does javadoc but the maven build is not picking it up. It *is* generated as part of the site build.
+ */
+public class JavadocDummy {
+
+ private JavadocDummy() {}
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/LanguageUtils.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/LanguageUtils.groovy b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/LanguageUtils.groovy
new file mode 100644
index 0000000..d4fe86c
--- /dev/null
+++ b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/LanguageUtils.groovy
@@ -0,0 +1,383 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.groovy
+
+import java.lang.reflect.Field
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicLong
+
+import org.apache.brooklyn.util.javalang.Reflections;
+import org.apache.brooklyn.util.text.Identifiers
+
+import com.google.common.annotations.Beta
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+/**
+ * Useful Groovy utility methods.
+ *
+ * @deprecated since 0.5; requires thorough review for what will be kept.
+ * e.g. consider instead using guava's {@link com.google.common.collect.Multimap} instead of addToMapOfSets etc
+ */
+@Deprecated
+@Beta
+public class LanguageUtils {
+ // For unique identifiers
+ private static final AtomicLong seed = new AtomicLong(0L)
+
+ public static <T> T getRequiredField(String name, Map<?,?> m) {
+ if (!m.containsKey(name))
+ throw new IllegalArgumentException("a parameter '"+name+"' was required in the argument to this function")
+ m.get name
+ }
+
+ public static <T> T getOptionalField(String name, Map<?,?> m, T defaultValue=null) {
+ m.get(name) ?: defaultValue
+ }
+
+ public static <T> T getPropertySafe(Object target, String name, T defaultValue=null) {
+ target.hasProperty(name)?.getProperty(target) ?: defaultValue
+ }
+
+ //TODO find with annotation
+
+ public static byte[] serialize(Object orig) {
+ if (orig == null) return null;
+
+ // Write the object out to a byte array
+ ByteArrayOutputStream fbos = []
+ ObjectOutputStream out = new ObjectOutputStream(fbos);
+ out.writeObject(orig);
+ out.flush();
+ out.close();
+ return fbos.toByteArray();
+ }
+
+ public static <T> T deserialize(byte[] bytes, ClassLoader classLoader) {
+ if (bytes == null) return null;
+
+ ObjectInputStream ins =
+ //new ObjectInputStreamWithLoader(new FastByteArrayInputStream(bytes, bytes.length), classLoader);
+ new ObjectInputStream(new ByteArrayInputStream(bytes));
+ (T) ins.readObject();
+ }
+
+ /**
+ * @deprecated use Identifiers.makeRandomId(8)
+ */
+ @Deprecated
+ public static String newUid() { Identifiers.makeRandomId(8) }
+
+ public static Map setFieldsFromMap(Object target, Map fieldValues) {
+ Map unused = [:]
+ fieldValues.each {
+ // println "looking for "+it.key+" in "+target+": "+target.metaClass.hasProperty(it.key)
+ target.hasProperty(it.key) ? target.(it.key) = it.value : unused << it
+ }
+ unused
+ }
+
+ /**
+ * Adds the given value to a collection in the map under the key.
+ *
+ * A collection (as {@link LinkedHashMap}) will be created if necessary,
+ * synchronized on map for map access/change and set for addition there
+ *
+ * @return the updated set (instance, not copy)
+ *
+ * @deprecated since 0.5; use {@link HashMultimap}, and {@link Multimaps#synchronizedSetMultimap(com.google.common.collect.SetMultimap)}
+ */
+ @Deprecated
+ public static <K,V> Set<V> addToMapOfSets(Map<K,Set<V>> map, K key, V valueInCollection) {
+ Set<V> coll;
+ synchronized (map) {
+ coll = map.get(key)
+ if (coll==null) {
+ coll = new LinkedHashSet<V>()
+ map.put(key, coll)
+ }
+ if (coll.isEmpty()) {
+ synchronized (coll) {
+ coll.add(valueInCollection)
+ }
+ //if collection was empty then add to the collection while holding the map lock, to prevent removal
+ return coll
+ }
+ }
+ synchronized (coll) {
+ if (!coll.isEmpty()) {
+ coll.add(valueInCollection)
+ return coll;
+ }
+ }
+ //if was empty, recurse, because someone else might be removing the collection
+ return addToMapOfSets(map, key, valueInCollection);
+ }
+
+ /**
+ * as {@link #addToMapOfSets(Map, Object, Object)} but for {@link ArrayList}
+ *
+ * @deprecated since 0.5; use {@link ArrayListMultimap}, and {@link Multimaps#synchronizedListMultimap(com.google.common.collect.ListMultimap)}
+ */
+ @Deprecated
+ public static <K,V> List<V> addToMapOfLists(Map<K,List<V>> map, K key, V valueInCollection) {
+ List<V> coll;
+ synchronized (map) {
+ coll = map.get(key)
+ if (coll==null) {
+ coll = new ArrayList<V>()
+ map.put(key, coll)
+ }
+ if (coll.isEmpty()) {
+ synchronized (coll) {
+ coll.add(valueInCollection)
+ }
+ //if collection was empty then add to the collection while holding the map lock, to prevent removal
+ return coll
+ }
+ }
+ synchronized (coll) {
+ if (!coll.isEmpty()) {
+ coll.add(valueInCollection)
+ return coll;
+ }
+ }
+ //if was empty, recurse, because someone else might be removing the collection
+ return addToMapOfLists(map, key, valueInCollection);
+ }
+
+ /**
+ * Removes the given value from a collection in the map under the key.
+ *
+ * @return the updated set (instance, not copy)
+ *
+ * @deprecated since 0.5; use {@link ArrayListMultimap} or {@link HashMultimap}, and {@link Multimaps#synchronizedListMultimap(com.google.common.collect.ListMultimap)} etc
+ */
+ @Deprecated
+ public static <K,V> boolean removeFromMapOfCollections(Map<K,? extends Collection<V>> map, K key, V valueInCollection) {
+ Collection<V> coll;
+ synchronized (map) {
+ coll = map.get(key)
+ if (coll==null) return false;
+ }
+ boolean result;
+ synchronized (coll) {
+ result = coll.remove(valueInCollection)
+ }
+ if (coll.isEmpty()) {
+ synchronized (map) {
+ synchronized (coll) {
+ if (coll.isEmpty()) {
+ //only remove from the map if no one is adding to the collection or to the map, and the collection is still in the map
+ if (map.get(key)==coll) {
+ map.remove(key)
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Visits all fields of a given object, recursively.
+ *
+ * For collections, arrays, and maps it visits the items within, passing null for keys where it isn't a map.
+ */
+ public static void visitFields(Object o, FieldVisitor fv, Collection<Object> objectsToSkip=([] as Set)) {
+ if (o == null || objectsToSkip.contains(o)) return
+ objectsToSkip << o
+ if (o in String) return
+ if (o in Map) {
+ o.each { key, value ->
+ fv.visit(o, key.toString(), value)
+ visitFields(value, fv, objectsToSkip)
+ }
+ } else if ((o in Collection) || (o.getClass().isArray())) {
+ o.each {
+ entry ->
+ fv.visit(o, null, entry)
+ visitFields(entry, fv, objectsToSkip)
+ }
+ } else {
+ o.getClass().getDeclaredFields().each {
+ Field field ->
+ if ((field.getModifiers() & Modifier.STATIC) || field.isSynthetic()) return; //skip static
+ field.setAccessible true
+ def v = field.get(o);
+ fv.visit(o, field.name, v)
+ visitFields(v, fv, objectsToSkip)
+ }
+ }
+ }
+
+ public interface FieldVisitor {
+ /** Invoked by visitFields; fieldName will be null for collections */
+ public void visit(Object parent, String fieldName, Object value)
+ }
+
+ /**
+ * Iterates through two collections simultaneously, passing both args to code.
+ *
+ * <pre>
+ * a = ['a','b']; b=[1,2];
+ * assert ['a1','b2'] == forboth(a,b) { x,y -> x+y }
+ * </pre>
+ */
+ public static Collection forBoth(Collection l1, Collection l2, Closure code) {
+ def result=[]
+ l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i]) ) }
+ result
+ }
+
+ public static Collection forBothWithIndex(Collection l1, Collection l2, Closure code) {
+ def result=[]
+ l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i], i) ) }
+ result
+ }
+
+ public static Collection forBoth(Object[] l1, Object[] l2, Closure code) {
+ def result=[]
+ l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i]) ) }
+ result
+ }
+
+ public static Collection forBothWithIndex(Object[] l1, Object[] l2, Closure code) {
+ def result=[]
+ l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i], i) ) }
+ result
+ }
+
+ /** return value used to indicate that there is no such field */
+ public static final Object NO_SUCH_FIELD = new Object();
+
+ /**
+ * Default field getter.
+ *
+ * Delegates to {@code object[field]} (which will invoke a getter if one exists, in groovy),
+ * unless field starts with {@literal @} in which case it looks up the actual java field (bypassing getter).
+ * <p>
+ * Can be extended as needed when passed to {@link #equals(Object, Object, Class, String[])}
+ */
+ public static final Closure DEFAULT_FIELD_GETTER = { Object object, Object field ->
+ try {
+ if ((field in String) && field.startsWith("@")) {
+ return object.@"${field.substring(1)}"
+ }
+ return object[field]
+ } catch (Exception e) {
+ return NO_SUCH_FIELD
+ }
+ }
+
+ /**
+ * Checks equality of o1 and o2 with respect to the named fields, optionally enforcing a common superclass
+ * and using a custom field-getter.
+ *
+ * Other types can be supplied if they are supported by {@code object[field]} (what the {@link #DEFAULT_FIELD_GETTER} does)
+ * or if the {@literal optionalGetter} handles it. Note that {@code object[field]} causes invocation of {@code object.getAt(field)}
+ * (which can be provided on the object for non-strings - this is preferred to an optionalGetter, generally)
+ * looking for {@code object.getXxx()}, where field is a string {@literal xxx}, then {@code object.xxx}.
+ * <p>
+ * One exception is that field names which start with {@literal @} get the field directly according to {@link #DEFAULT_FIELD_GETTER},
+ * but use with care on private fields, as they must be on the object and not a superclass, and with groovy properties
+ * (formerly known as package-private, i.e. with no access modifiers) because they become private fields.
+ * <p>
+ * For example
+ * <pre>
+ * public class Foo {
+ * Object bar;
+ * public boolean equals(Object other) { LangaugeUtils.equals(this, other, Foo.class, ["bar"]); }
+ * public int hashCode() { LangaugeUtils.hashCode(this, ["bar"]); }
+ * }
+ * </pre>
+ *
+ * @param o1 one object to compare
+ * @param o2 other object to compare
+ * @param optionalCommonSuperClass if supplied, returns false unless both objects are instances of the given type;
+ * (if not supplied it effectively does duck typing, returning false if any field is not present)
+ * @param optionalGetter if supplied, a closure which takes (object, field) and returns the value of field on object;
+ * should return static {@link #NO_SUCH_FIELD} if none found;
+ * recommended to delegate to {@link #DEFAULT_FIELD_GETTER} at least for strings (or for anything)
+ * @param fields typically a list of strings being names of fields on the class to compare
+ * @return true if the two objects are equal in all indicated fields, and conform to the optionalCommonSuperClass if supplied
+ */
+ public static boolean equals(Object o1, Object o2, Class<?> optionalCommonSuperClass=null, Closure optionalGetter=null, Iterable<Object> fieldNames) {
+ if (o1==null) return o2==null;
+ if (o2==null) return false;
+ if (optionalCommonSuperClass) {
+ if (!(o1 in optionalCommonSuperClass) || !(o2 in optionalCommonSuperClass)) return false
+ }
+ Closure get = optionalGetter ?: DEFAULT_FIELD_GETTER
+ for (it in fieldNames) {
+ def v1 = get.call(o1, it)
+ if (v1==NO_SUCH_FIELD) return false
+ if (v1!=get.call(o2, it)) return false
+ }
+ return true
+ }
+
+ public static boolean equals(Object o1, Object o2, Class<?> optionalCommonSuperClass=null, Closure optionalGetter=null, Object[] fieldNames) {
+ return equals(o1, o2, optionalCommonSuperClass, optionalGetter, Arrays.asList(fieldNames) )
+ }
+
+ /**
+ * Generates a hashcode for an object.
+ *
+ * Similar to {@link com.google.common.base.Objects#hashCode()} but taking field <em>names</em> and an optional getter,
+ * with the same rich groovy semantics as described in {@link #equals(Object, Object, Class)}.
+ */
+ public static int hashCode(Object o, Closure optionalGetter=null, Collection<Object> fieldNames) {
+ if (o==null) return 0;
+ Closure get = optionalGetter ?: DEFAULT_FIELD_GETTER
+ int result = 1;
+ for (it in fieldNames) {
+ def v1 = get.call(o, it)
+ if (v1==NO_SUCH_FIELD)
+ throw new NoSuchFieldError("Cannot access $it on "+o.getClass());
+ result = 31 * result + (it == null ? 0 : it.hashCode());
+ }
+ result
+ }
+
+ public static int hashCode(Object o, Closure optionalGetter=null, Object[] fieldNames) {
+ hashCode(o, optionalGetter, Arrays.asList(fieldNames))
+ }
+
+ /** Default String representation is simplified name of class, together with selected fields. */
+ public static String toString(Object o, Closure optionalGetter=null, Collection<? extends CharSequence> fieldNames) {
+ if (o==null) return null;
+ Closure get = optionalGetter ?: DEFAULT_FIELD_GETTER
+
+ StringBuilder result = new StringBuilder();
+ result.append(o.getClass().getSimpleName());
+ if (result.length() == 0) result.append(o.getClass().getName());
+ List<Object> fieldVals = fieldNames.collect {
+ Object v = get.call(o, it);
+ return (v != null) ? it+"="+v : null;
+ }
+ result.append("[").append(Joiner.on(",").skipNulls().join(fieldVals)).append("]");
+ return result.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/TimeExtras.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/TimeExtras.groovy b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/TimeExtras.groovy
new file mode 100644
index 0000000..4bca76f
--- /dev/null
+++ b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/TimeExtras.groovy
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.groovy
+
+import groovy.time.TimeDuration
+
+import java.util.concurrent.TimeUnit
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+import org.apache.brooklyn.util.time.Time
+
+
+/**
+ * Classloading this class will cause multiply/add to be made available on TimeDuration.
+ * For example, I could write: 2*TimeUnit.MINUTES+5*TimeUnit.SECONDS.
+ *
+ * That is why nothing seems to use this class, because the methods it defines are not
+ * on this class!
+ *
+ * @author alex
+ *
+ * @deprecated since 0.6.0 - just use brooklyn.util.time.Duration, simpler and easier to configure, and avoids language problems
+ */
+@Deprecated
+class TimeExtras {
+ public static final Logger log = LoggerFactory.getLogger(TimeExtras.class);
+
+ public static void init() {
+ Number.metaClass.multiply << { TimeUnit t -> new TimeDuration(t.toMillis(intValue())) }
+ Number.metaClass.multiply << { TimeDuration t -> t.multiply(doubleValue()) }
+ Integer.metaClass.multiply << { TimeUnit t -> new TimeDuration(t.toMillis(intValue())) }
+
+ TimeDuration.metaClass.multiply << { Number n -> new TimeDuration( (int)(toMilliseconds()*n) ) }
+ TimeDuration.metaClass.constructor << { long millis ->
+ def shift = { int modulus -> int v=millis%modulus; millis/=modulus; v }
+ def l = [shift(1000), shift(60), shift(60), shift(24), (int)millis]
+ Collections.reverse(l)
+ l as TimeDuration
+ }
+ }
+
+ static { init(); }
+
+ /** creates a duration object
+ * <p>
+ * fix for irritating classloading/metaclass order
+ * where an int may get constructed too early and not have the multiply syntax available
+ * (because grail is invoked?; if e.g. 5*SECONDS throws an error, try duration(5, SECONDS) */
+ public static TimeDuration duration(int value, TimeUnit unit) {
+ return new TimeDuration(0, 0, 0, (int)unit.toMillis(value));
+ }
+
+ public static final TimeDuration ONE_SECOND = duration(1, TimeUnit.SECONDS);
+ public static final TimeDuration FIVE_SECONDS = duration(5, TimeUnit.SECONDS);
+ public static final TimeDuration TEN_SECONDS = duration(10, TimeUnit.SECONDS);
+ public static final TimeDuration THIRTY_SECONDS = duration(30, TimeUnit.SECONDS);
+ public static final TimeDuration ONE_MINUTE = duration(1, TimeUnit.MINUTES);
+ public static final TimeDuration TWO_MINUTES = duration(2, TimeUnit.MINUTES);
+ public static final TimeDuration FIVE_MINUTES = duration(5, TimeUnit.MINUTES);
+
+ public static void sleep(TimeDuration duration) {
+ Time.sleep(duration.toMilliseconds());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/JavadocDummy.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/JavadocDummy.java b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/JavadocDummy.java
deleted file mode 100644
index aceef9c..0000000
--- a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/JavadocDummy.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.groovy.internal;
-
-/** Maven Central requires javadoc to promote as a release. This seemed to happen when this was built by maven as a bundle,
- * but now that it is built as a jar it does not. This class exists only to provide that javadoc.
- * <p>
- * Note the groovy code does javadoc but the maven build is not picking it up. It *is* generated as part of the site build.
- */
-public class JavadocDummy {
-
- private JavadocDummy() {}
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/LanguageUtils.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/LanguageUtils.groovy b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/LanguageUtils.groovy
deleted file mode 100644
index 08bc2fe..0000000
--- a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/LanguageUtils.groovy
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.groovy.internal
-
-import java.lang.reflect.Field
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier
-import java.util.Collection;
-import java.util.concurrent.atomic.AtomicLong
-
-import org.apache.brooklyn.util.javalang.Reflections;
-import org.apache.brooklyn.util.text.Identifiers
-
-import com.google.common.annotations.Beta
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-/**
- * Useful Groovy utility methods.
- *
- * @deprecated since 0.5; requires thorough review for what will be kept.
- * e.g. consider instead using guava's {@link com.google.common.collect.Multimap} instead of addToMapOfSets etc
- */
-@Deprecated
-@Beta
-public class LanguageUtils {
- // For unique identifiers
- private static final AtomicLong seed = new AtomicLong(0L)
-
- public static <T> T getRequiredField(String name, Map<?,?> m) {
- if (!m.containsKey(name))
- throw new IllegalArgumentException("a parameter '"+name+"' was required in the argument to this function")
- m.get name
- }
-
- public static <T> T getOptionalField(String name, Map<?,?> m, T defaultValue=null) {
- m.get(name) ?: defaultValue
- }
-
- public static <T> T getPropertySafe(Object target, String name, T defaultValue=null) {
- target.hasProperty(name)?.getProperty(target) ?: defaultValue
- }
-
- //TODO find with annotation
-
- public static byte[] serialize(Object orig) {
- if (orig == null) return null;
-
- // Write the object out to a byte array
- ByteArrayOutputStream fbos = []
- ObjectOutputStream out = new ObjectOutputStream(fbos);
- out.writeObject(orig);
- out.flush();
- out.close();
- return fbos.toByteArray();
- }
-
- public static <T> T deserialize(byte[] bytes, ClassLoader classLoader) {
- if (bytes == null) return null;
-
- ObjectInputStream ins =
- //new ObjectInputStreamWithLoader(new FastByteArrayInputStream(bytes, bytes.length), classLoader);
- new ObjectInputStream(new ByteArrayInputStream(bytes));
- (T) ins.readObject();
- }
-
- /**
- * @deprecated use Identifiers.makeRandomId(8)
- */
- @Deprecated
- public static String newUid() { Identifiers.makeRandomId(8) }
-
- public static Map setFieldsFromMap(Object target, Map fieldValues) {
- Map unused = [:]
- fieldValues.each {
- // println "looking for "+it.key+" in "+target+": "+target.metaClass.hasProperty(it.key)
- target.hasProperty(it.key) ? target.(it.key) = it.value : unused << it
- }
- unused
- }
-
- /**
- * Adds the given value to a collection in the map under the key.
- *
- * A collection (as {@link LinkedHashMap}) will be created if necessary,
- * synchronized on map for map access/change and set for addition there
- *
- * @return the updated set (instance, not copy)
- *
- * @deprecated since 0.5; use {@link HashMultimap}, and {@link Multimaps#synchronizedSetMultimap(com.google.common.collect.SetMultimap)}
- */
- @Deprecated
- public static <K,V> Set<V> addToMapOfSets(Map<K,Set<V>> map, K key, V valueInCollection) {
- Set<V> coll;
- synchronized (map) {
- coll = map.get(key)
- if (coll==null) {
- coll = new LinkedHashSet<V>()
- map.put(key, coll)
- }
- if (coll.isEmpty()) {
- synchronized (coll) {
- coll.add(valueInCollection)
- }
- //if collection was empty then add to the collection while holding the map lock, to prevent removal
- return coll
- }
- }
- synchronized (coll) {
- if (!coll.isEmpty()) {
- coll.add(valueInCollection)
- return coll;
- }
- }
- //if was empty, recurse, because someone else might be removing the collection
- return addToMapOfSets(map, key, valueInCollection);
- }
-
- /**
- * as {@link #addToMapOfSets(Map, Object, Object)} but for {@link ArrayList}
- *
- * @deprecated since 0.5; use {@link ArrayListMultimap}, and {@link Multimaps#synchronizedListMultimap(com.google.common.collect.ListMultimap)}
- */
- @Deprecated
- public static <K,V> List<V> addToMapOfLists(Map<K,List<V>> map, K key, V valueInCollection) {
- List<V> coll;
- synchronized (map) {
- coll = map.get(key)
- if (coll==null) {
- coll = new ArrayList<V>()
- map.put(key, coll)
- }
- if (coll.isEmpty()) {
- synchronized (coll) {
- coll.add(valueInCollection)
- }
- //if collection was empty then add to the collection while holding the map lock, to prevent removal
- return coll
- }
- }
- synchronized (coll) {
- if (!coll.isEmpty()) {
- coll.add(valueInCollection)
- return coll;
- }
- }
- //if was empty, recurse, because someone else might be removing the collection
- return addToMapOfLists(map, key, valueInCollection);
- }
-
- /**
- * Removes the given value from a collection in the map under the key.
- *
- * @return the updated set (instance, not copy)
- *
- * @deprecated since 0.5; use {@link ArrayListMultimap} or {@link HashMultimap}, and {@link Multimaps#synchronizedListMultimap(com.google.common.collect.ListMultimap)} etc
- */
- @Deprecated
- public static <K,V> boolean removeFromMapOfCollections(Map<K,? extends Collection<V>> map, K key, V valueInCollection) {
- Collection<V> coll;
- synchronized (map) {
- coll = map.get(key)
- if (coll==null) return false;
- }
- boolean result;
- synchronized (coll) {
- result = coll.remove(valueInCollection)
- }
- if (coll.isEmpty()) {
- synchronized (map) {
- synchronized (coll) {
- if (coll.isEmpty()) {
- //only remove from the map if no one is adding to the collection or to the map, and the collection is still in the map
- if (map.get(key)==coll) {
- map.remove(key)
- }
- }
- }
- }
- }
- return result;
- }
-
- /**
- * Visits all fields of a given object, recursively.
- *
- * For collections, arrays, and maps it visits the items within, passing null for keys where it isn't a map.
- */
- public static void visitFields(Object o, FieldVisitor fv, Collection<Object> objectsToSkip=([] as Set)) {
- if (o == null || objectsToSkip.contains(o)) return
- objectsToSkip << o
- if (o in String) return
- if (o in Map) {
- o.each { key, value ->
- fv.visit(o, key.toString(), value)
- visitFields(value, fv, objectsToSkip)
- }
- } else if ((o in Collection) || (o.getClass().isArray())) {
- o.each {
- entry ->
- fv.visit(o, null, entry)
- visitFields(entry, fv, objectsToSkip)
- }
- } else {
- o.getClass().getDeclaredFields().each {
- Field field ->
- if ((field.getModifiers() & Modifier.STATIC) || field.isSynthetic()) return; //skip static
- field.setAccessible true
- def v = field.get(o);
- fv.visit(o, field.name, v)
- visitFields(v, fv, objectsToSkip)
- }
- }
- }
-
- public interface FieldVisitor {
- /** Invoked by visitFields; fieldName will be null for collections */
- public void visit(Object parent, String fieldName, Object value)
- }
-
- /**
- * Iterates through two collections simultaneously, passing both args to code.
- *
- * <pre>
- * a = ['a','b']; b=[1,2];
- * assert ['a1','b2'] == forboth(a,b) { x,y -> x+y }
- * </pre>
- */
- public static Collection forBoth(Collection l1, Collection l2, Closure code) {
- def result=[]
- l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i]) ) }
- result
- }
-
- public static Collection forBothWithIndex(Collection l1, Collection l2, Closure code) {
- def result=[]
- l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i], i) ) }
- result
- }
-
- public static Collection forBoth(Object[] l1, Object[] l2, Closure code) {
- def result=[]
- l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i]) ) }
- result
- }
-
- public static Collection forBothWithIndex(Object[] l1, Object[] l2, Closure code) {
- def result=[]
- l1.eachWithIndex { a, i -> result.add( code.call(a, l2[i], i) ) }
- result
- }
-
- /** return value used to indicate that there is no such field */
- public static final Object NO_SUCH_FIELD = new Object();
-
- /**
- * Default field getter.
- *
- * Delegates to {@code object[field]} (which will invoke a getter if one exists, in groovy),
- * unless field starts with {@literal @} in which case it looks up the actual java field (bypassing getter).
- * <p>
- * Can be extended as needed when passed to {@link #equals(Object, Object, Class, String[])}
- */
- public static final Closure DEFAULT_FIELD_GETTER = { Object object, Object field ->
- try {
- if ((field in String) && field.startsWith("@")) {
- return object.@"${field.substring(1)}"
- }
- return object[field]
- } catch (Exception e) {
- return NO_SUCH_FIELD
- }
- }
-
- /**
- * Checks equality of o1 and o2 with respect to the named fields, optionally enforcing a common superclass
- * and using a custom field-getter.
- *
- * Other types can be supplied if they are supported by {@code object[field]} (what the {@link #DEFAULT_FIELD_GETTER} does)
- * or if the {@literal optionalGetter} handles it. Note that {@code object[field]} causes invocation of {@code object.getAt(field)}
- * (which can be provided on the object for non-strings - this is preferred to an optionalGetter, generally)
- * looking for {@code object.getXxx()}, where field is a string {@literal xxx}, then {@code object.xxx}.
- * <p>
- * One exception is that field names which start with {@literal @} get the field directly according to {@link #DEFAULT_FIELD_GETTER},
- * but use with care on private fields, as they must be on the object and not a superclass, and with groovy properties
- * (formerly known as package-private, i.e. with no access modifiers) because they become private fields.
- * <p>
- * For example
- * <pre>
- * public class Foo {
- * Object bar;
- * public boolean equals(Object other) { LangaugeUtils.equals(this, other, Foo.class, ["bar"]); }
- * public int hashCode() { LangaugeUtils.hashCode(this, ["bar"]); }
- * }
- * </pre>
- *
- * @param o1 one object to compare
- * @param o2 other object to compare
- * @param optionalCommonSuperClass if supplied, returns false unless both objects are instances of the given type;
- * (if not supplied it effectively does duck typing, returning false if any field is not present)
- * @param optionalGetter if supplied, a closure which takes (object, field) and returns the value of field on object;
- * should return static {@link #NO_SUCH_FIELD} if none found;
- * recommended to delegate to {@link #DEFAULT_FIELD_GETTER} at least for strings (or for anything)
- * @param fields typically a list of strings being names of fields on the class to compare
- * @return true if the two objects are equal in all indicated fields, and conform to the optionalCommonSuperClass if supplied
- */
- public static boolean equals(Object o1, Object o2, Class<?> optionalCommonSuperClass=null, Closure optionalGetter=null, Iterable<Object> fieldNames) {
- if (o1==null) return o2==null;
- if (o2==null) return false;
- if (optionalCommonSuperClass) {
- if (!(o1 in optionalCommonSuperClass) || !(o2 in optionalCommonSuperClass)) return false
- }
- Closure get = optionalGetter ?: DEFAULT_FIELD_GETTER
- for (it in fieldNames) {
- def v1 = get.call(o1, it)
- if (v1==NO_SUCH_FIELD) return false
- if (v1!=get.call(o2, it)) return false
- }
- return true
- }
-
- public static boolean equals(Object o1, Object o2, Class<?> optionalCommonSuperClass=null, Closure optionalGetter=null, Object[] fieldNames) {
- return equals(o1, o2, optionalCommonSuperClass, optionalGetter, Arrays.asList(fieldNames) )
- }
-
- /**
- * Generates a hashcode for an object.
- *
- * Similar to {@link com.google.common.base.Objects#hashCode()} but taking field <em>names</em> and an optional getter,
- * with the same rich groovy semantics as described in {@link #equals(Object, Object, Class)}.
- */
- public static int hashCode(Object o, Closure optionalGetter=null, Collection<Object> fieldNames) {
- if (o==null) return 0;
- Closure get = optionalGetter ?: DEFAULT_FIELD_GETTER
- int result = 1;
- for (it in fieldNames) {
- def v1 = get.call(o, it)
- if (v1==NO_SUCH_FIELD)
- throw new NoSuchFieldError("Cannot access $it on "+o.getClass());
- result = 31 * result + (it == null ? 0 : it.hashCode());
- }
- result
- }
-
- public static int hashCode(Object o, Closure optionalGetter=null, Object[] fieldNames) {
- hashCode(o, optionalGetter, Arrays.asList(fieldNames))
- }
-
- /** Default String representation is simplified name of class, together with selected fields. */
- public static String toString(Object o, Closure optionalGetter=null, Collection<? extends CharSequence> fieldNames) {
- if (o==null) return null;
- Closure get = optionalGetter ?: DEFAULT_FIELD_GETTER
-
- StringBuilder result = new StringBuilder();
- result.append(o.getClass().getSimpleName());
- if (result.length() == 0) result.append(o.getClass().getName());
- List<Object> fieldVals = fieldNames.collect {
- Object v = get.call(o, it);
- return (v != null) ? it+"="+v : null;
- }
- result.append("[").append(Joiner.on(",").skipNulls().join(fieldVals)).append("]");
- return result.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/TimeExtras.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/TimeExtras.groovy b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/TimeExtras.groovy
deleted file mode 100644
index 9c6cdbd..0000000
--- a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/internal/TimeExtras.groovy
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.groovy.internal
-
-import groovy.time.TimeDuration
-
-import java.util.concurrent.TimeUnit
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-
-import org.apache.brooklyn.util.time.Time
-
-
-/**
- * Classloading this class will cause multiply/add to be made available on TimeDuration.
- * For example, I could write: 2*TimeUnit.MINUTES+5*TimeUnit.SECONDS.
- *
- * That is why nothing seems to use this class, because the methods it defines are not
- * on this class!
- *
- * @author alex
- *
- * @deprecated since 0.6.0 - just use brooklyn.util.time.Duration, simpler and easier to configure, and avoids language problems
- */
-@Deprecated
-class TimeExtras {
- public static final Logger log = LoggerFactory.getLogger(TimeExtras.class);
-
- public static void init() {
- Number.metaClass.multiply << { TimeUnit t -> new TimeDuration(t.toMillis(intValue())) }
- Number.metaClass.multiply << { TimeDuration t -> t.multiply(doubleValue()) }
- Integer.metaClass.multiply << { TimeUnit t -> new TimeDuration(t.toMillis(intValue())) }
-
- TimeDuration.metaClass.multiply << { Number n -> new TimeDuration( (int)(toMilliseconds()*n) ) }
- TimeDuration.metaClass.constructor << { long millis ->
- def shift = { int modulus -> int v=millis%modulus; millis/=modulus; v }
- def l = [shift(1000), shift(60), shift(60), shift(24), (int)millis]
- Collections.reverse(l)
- l as TimeDuration
- }
- }
-
- static { init(); }
-
- /** creates a duration object
- * <p>
- * fix for irritating classloading/metaclass order
- * where an int may get constructed too early and not have the multiply syntax available
- * (because grail is invoked?; if e.g. 5*SECONDS throws an error, try duration(5, SECONDS) */
- public static TimeDuration duration(int value, TimeUnit unit) {
- return new TimeDuration(0, 0, 0, (int)unit.toMillis(value));
- }
-
- public static final TimeDuration ONE_SECOND = duration(1, TimeUnit.SECONDS);
- public static final TimeDuration FIVE_SECONDS = duration(5, TimeUnit.SECONDS);
- public static final TimeDuration TEN_SECONDS = duration(10, TimeUnit.SECONDS);
- public static final TimeDuration THIRTY_SECONDS = duration(30, TimeUnit.SECONDS);
- public static final TimeDuration ONE_MINUTE = duration(1, TimeUnit.MINUTES);
- public static final TimeDuration TWO_MINUTES = duration(2, TimeUnit.MINUTES);
- public static final TimeDuration FIVE_MINUTES = duration(5, TimeUnit.MINUTES);
-
- public static void sleep(TimeDuration duration) {
- Time.sleep(duration.toMilliseconds());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/LanguageUtilsTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/LanguageUtilsTest.groovy b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/LanguageUtilsTest.groovy
new file mode 100644
index 0000000..961db5d
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/LanguageUtilsTest.groovy
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.groovy;
+
+import static org.testng.Assert.*
+
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.annotations.Test
+import org.apache.brooklyn.util.groovy.LanguageUtils.FieldVisitor
+
+
+/**
+ * Test the operation of the {@link LanguageUtils} utilities.
+ */
+public class LanguageUtilsTest {
+ private static final Logger log = LoggerFactory.getLogger(LanguageUtilsTest.class)
+
+ @Test
+ public void testSetFieldsFromMap() {
+ A a = []
+ Map unused = LanguageUtils.setFieldsFromMap(a, [num:1,mun:2])
+ assertEquals(1, a.num);
+ assertEquals([mun:2], unused)
+ }
+
+ @Test
+ public void testVisitingFieldsDeepNonLooping() {
+ BigUn b2 = new BigUn(name:"L'il Guy", num:10, dates:[ new Date() ])
+// b2.dates = [ new Date() ] as Date[]
+ BigUn b1 = new BigUn(name:"Big Guy", num:40)
+ b1.child = b2;
+ b1.children += b2
+ b2.child = b1
+
+ int sum = 0;
+ FieldVisitor numSummer = { parent, name, value -> if ("num"==name) sum+=value } as FieldVisitor
+ LanguageUtils.visitFields(b1, numSummer)
+
+ assertEquals(50, sum)
+ }
+
+ private static class A {
+ int num;
+ }
+
+ private static class BigUn {
+ String name;
+ int num;
+ BigUn child;
+ Set children = []
+ Date[] dates;
+ }
+
+ //test the default getter, and equals
+ static class TestingFieldA {
+ public int a = 6;
+ int getAt(A aa) { return aa.num * a; }
+ static A aa = [num:10];
+ int x = -1;
+ }
+ static class TestingFields extends TestingFieldA {
+ int b = 7;
+ int getB() { -7 }
+ public int c = 8;
+ int getD() { 9 }
+ }
+ @Test
+ public void testSomeGet() {
+ TestingFields tf = []
+ assertEquals( [6, -7, 7, 8, 9, 60],
+ ["a", "b", "@b", "c", "d", TestingFields.aa].collect {
+ LanguageUtils.DEFAULT_FIELD_GETTER.call(tf, it)
+ })
+ }
+
+ @Test
+ public void testEquals() {
+ //basic
+ TestingFields t1 = [], t2 = []
+ assertTrue LanguageUtils.equals(t1, t2, null, ["a", "b"])
+ assertTrue LanguageUtils.equals(t1, t2, TestingFields, ["a", "b"])
+ assertFalse LanguageUtils.equals(t1, t2, String, ["a", "b"])
+ assertFalse LanguageUtils.equals(t1, t2, null, ["z"])
+ assertTrue LanguageUtils.equals(t1, t2, null, (["a", "b"] as String[]))
+
+ //type hierarchy
+ TestingFieldA t1a = []
+ assertTrue LanguageUtils.equals(t1, t1a, null, "a")
+ assertTrue LanguageUtils.equals(t1, t1a, TestingFieldA, "a")
+ assertFalse LanguageUtils.equals(t1, t1a, TestingFields, "a")
+ assertFalse LanguageUtils.equals(t1, t1a, null, "a", "b")
+ t1.b = 0
+ assertTrue LanguageUtils.equals(t1, t1a, null, "a")
+ t1a.a = -6
+ assertFalse LanguageUtils.equals(t1, t1a, null, "a")
+
+ //direct access to field
+ assertTrue LanguageUtils.equals(t1, t2, null, "b")
+ assertFalse LanguageUtils.equals(t1, t2, null, "@b")
+ assertTrue LanguageUtils.equals(t1, t2, null, "@a")
+
+ //and complex field
+ assertTrue LanguageUtils.equals(t1, t2, null, TestingFields.aa)
+ //because we changed t1a.a, and getAt(A) refers to int a
+ assertFalse LanguageUtils.equals(t1, t1a, null, TestingFields.aa)
+
+ //test it works with POJO objects (non-groovy)
+ assertTrue LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(1), null, "privateInt")
+ assertFalse LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(2), null, "privateInt")
+
+ //and a tricky one, because x is a groovy property, it is _private_ so we cannot see it as a field wrt t1
+ assertFalse LanguageUtils.equals(t1, t1a, null, "@x")
+ //but in the context of t1a we can.. in short, be careful with fields
+ assertTrue LanguageUtils.equals(t1a, t1a, null, "@x")
+ }
+
+ @Test
+ public void testHashCode() {
+ //basic
+ TestingFields t1 = [], t2 = []
+ assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
+ assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
+ assertFalse LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
+ t2.b = 0;
+ assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
+ assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
+ assertEquals 0, LanguageUtils.hashCode(null, ["a", "@b"])
+ }
+
+ @Test
+ public void testToString() {
+ TestingFields t1 = [];
+ assertEquals(LanguageUtils.toString(t1, ["a", "b"]), "TestingFields[a=6,b=-7]");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/PojoTestingFields.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/PojoTestingFields.java b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/PojoTestingFields.java
new file mode 100644
index 0000000..9bbc3fb
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/PojoTestingFields.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.groovy;
+
+public class PojoTestingFields {
+ private final int privateInt;
+
+ public PojoTestingFields(int privateInt) {
+ this.privateInt = privateInt;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/TimeExtrasTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/TimeExtrasTest.groovy b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/TimeExtrasTest.groovy
new file mode 100644
index 0000000..11ae3d0
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/TimeExtrasTest.groovy
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.util.groovy;
+
+import static java.util.concurrent.TimeUnit.*
+import static org.testng.Assert.*
+
+import groovy.time.TimeDuration
+
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+/**
+ * Test the operation of the {@link TimeExtras} class.
+ *
+ * TODO clarify test purpose
+ */
+public class TimeExtrasTest {
+ @BeforeMethod
+ public void setUp() throws Exception {
+ TimeExtras.init();
+ }
+
+ @Test
+ public void testMultiplyTimeDurations() {
+ assertEquals(new TimeDuration(6).toMilliseconds(), (new TimeDuration(3)*2).toMilliseconds());
+ }
+
+ @Test
+ public void testAddTimeDurations() {
+ assertEquals(new TimeDuration(0,2,5,0).toMilliseconds(), (5*SECONDS + 2*MINUTES).toMilliseconds());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/LanguageUtilsTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/LanguageUtilsTest.groovy b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/LanguageUtilsTest.groovy
deleted file mode 100644
index 8c8d3d2..0000000
--- a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/LanguageUtilsTest.groovy
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.groovy.internal;
-
-import static org.testng.Assert.*
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.Test
-import org.apache.brooklyn.util.groovy.internal.LanguageUtils;
-import org.apache.brooklyn.util.groovy.internal.LanguageUtils.FieldVisitor
-
-
-/**
- * Test the operation of the {@link LanguageUtils} utilities.
- */
-public class LanguageUtilsTest {
- private static final Logger log = LoggerFactory.getLogger(LanguageUtilsTest.class)
-
- @Test
- public void testSetFieldsFromMap() {
- A a = []
- Map unused = LanguageUtils.setFieldsFromMap(a, [num:1,mun:2])
- assertEquals(1, a.num);
- assertEquals([mun:2], unused)
- }
-
- @Test
- public void testVisitingFieldsDeepNonLooping() {
- BigUn b2 = new BigUn(name:"L'il Guy", num:10, dates:[ new Date() ])
-// b2.dates = [ new Date() ] as Date[]
- BigUn b1 = new BigUn(name:"Big Guy", num:40)
- b1.child = b2;
- b1.children += b2
- b2.child = b1
-
- int sum = 0;
- FieldVisitor numSummer = { parent, name, value -> if ("num"==name) sum+=value } as FieldVisitor
- LanguageUtils.visitFields(b1, numSummer)
-
- assertEquals(50, sum)
- }
-
- private static class A {
- int num;
- }
-
- private static class BigUn {
- String name;
- int num;
- BigUn child;
- Set children = []
- Date[] dates;
- }
-
- //test the default getter, and equals
- static class TestingFieldA {
- public int a = 6;
- int getAt(A aa) { return aa.num * a; }
- static A aa = [num:10];
- int x = -1;
- }
- static class TestingFields extends TestingFieldA {
- int b = 7;
- int getB() { -7 }
- public int c = 8;
- int getD() { 9 }
- }
- @Test
- public void testSomeGet() {
- TestingFields tf = []
- assertEquals( [6, -7, 7, 8, 9, 60],
- ["a", "b", "@b", "c", "d", TestingFields.aa].collect {
- LanguageUtils.DEFAULT_FIELD_GETTER.call(tf, it)
- })
- }
-
- @Test
- public void testEquals() {
- //basic
- TestingFields t1 = [], t2 = []
- assertTrue LanguageUtils.equals(t1, t2, null, ["a", "b"])
- assertTrue LanguageUtils.equals(t1, t2, TestingFields, ["a", "b"])
- assertFalse LanguageUtils.equals(t1, t2, String, ["a", "b"])
- assertFalse LanguageUtils.equals(t1, t2, null, ["z"])
- assertTrue LanguageUtils.equals(t1, t2, null, (["a", "b"] as String[]))
-
- //type hierarchy
- TestingFieldA t1a = []
- assertTrue LanguageUtils.equals(t1, t1a, null, "a")
- assertTrue LanguageUtils.equals(t1, t1a, TestingFieldA, "a")
- assertFalse LanguageUtils.equals(t1, t1a, TestingFields, "a")
- assertFalse LanguageUtils.equals(t1, t1a, null, "a", "b")
- t1.b = 0
- assertTrue LanguageUtils.equals(t1, t1a, null, "a")
- t1a.a = -6
- assertFalse LanguageUtils.equals(t1, t1a, null, "a")
-
- //direct access to field
- assertTrue LanguageUtils.equals(t1, t2, null, "b")
- assertFalse LanguageUtils.equals(t1, t2, null, "@b")
- assertTrue LanguageUtils.equals(t1, t2, null, "@a")
-
- //and complex field
- assertTrue LanguageUtils.equals(t1, t2, null, TestingFields.aa)
- //because we changed t1a.a, and getAt(A) refers to int a
- assertFalse LanguageUtils.equals(t1, t1a, null, TestingFields.aa)
-
- //test it works with POJO objects (non-groovy)
- assertTrue LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(1), null, "privateInt")
- assertFalse LanguageUtils.equals(new PojoTestingFields(1), new PojoTestingFields(2), null, "privateInt")
-
- //and a tricky one, because x is a groovy property, it is _private_ so we cannot see it as a field wrt t1
- assertFalse LanguageUtils.equals(t1, t1a, null, "@x")
- //but in the context of t1a we can.. in short, be careful with fields
- assertTrue LanguageUtils.equals(t1a, t1a, null, "@x")
- }
-
- @Test
- public void testHashCode() {
- //basic
- TestingFields t1 = [], t2 = []
- assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
- assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
- assertFalse LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
- t2.b = 0;
- assertTrue LanguageUtils.hashCode(t1, ["a", "b"]) == LanguageUtils.hashCode(t2, ["a", "b"])
- assertTrue LanguageUtils.hashCode(t1, ["a", "@b"]) == LanguageUtils.hashCode(t2, ["a", "@b"])
- assertEquals 0, LanguageUtils.hashCode(null, ["a", "@b"])
- }
-
- @Test
- public void testToString() {
- TestingFields t1 = [];
- assertEquals(LanguageUtils.toString(t1, ["a", "b"]), "TestingFields[a=6,b=-7]");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/PojoTestingFields.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/PojoTestingFields.java b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/PojoTestingFields.java
deleted file mode 100644
index ae5b5a0..0000000
--- a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/PojoTestingFields.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.groovy.internal;
-
-public class PojoTestingFields {
- private final int privateInt;
-
- public PojoTestingFields(int privateInt) {
- this.privateInt = privateInt;
- }
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0eab0fa0/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/TimeExtrasTest.groovy
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/TimeExtrasTest.groovy b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/TimeExtrasTest.groovy
deleted file mode 100644
index a5aae79..0000000
--- a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/internal/TimeExtrasTest.groovy
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.groovy.internal;
-
-import static java.util.concurrent.TimeUnit.*
-import static org.testng.Assert.*
-
-import org.apache.brooklyn.util.groovy.internal.TimeExtras;
-
-import groovy.time.TimeDuration
-
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-/**
- * Test the operation of the {@link TimeExtras} class.
- *
- * TODO clarify test purpose
- */
-public class TimeExtrasTest {
- @BeforeMethod
- public void setUp() throws Exception {
- TimeExtras.init();
- }
-
- @Test
- public void testMultiplyTimeDurations() {
- assertEquals(new TimeDuration(6).toMilliseconds(), (new TimeDuration(3)*2).toMilliseconds());
- }
-
- @Test
- public void testAddTimeDurations() {
- assertEquals(new TimeDuration(0,2,5,0).toMilliseconds(), (5*SECONDS + 2*MINUTES).toMilliseconds());
- }
-}
[05/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to
o.a.b.core.effector
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiTest.java
deleted file mode 100644
index 828cbd7..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.api.mgmt.ExecutionContext;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.effector.core.MethodEffector;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.BasicTask;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-/**
- * Test the operation of the {@link Effector} implementations.
- *
- * TODO clarify test purpose
- */
-public class EffectorSayHiTest extends BrooklynAppUnitTestSupport {
-
- //TODO test edge/error conditions
- //(missing parameters, wrong number of params, etc)
-
- private static final Logger log = LoggerFactory.getLogger(EffectorSayHiTest.class);
-
- private MyEntity e;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
- }
-
- @Test
- public void testFindEffectorMetaData() {
- assertEquals("sayHi1", e.SAY_HI_1.getName());
- assertEquals("says hello", e.SAY_HI_1.getDescription());
-
- assertEquals(ImmutableList.of("name", "greeting"), getParameterNames(e.SAY_HI_1));
- assertEquals(MutableMap.of("name", null, "greeting", "what to say"), getParameterDescriptions(e.SAY_HI_1));
- }
-
- @Test
- public void testFindTraitEffectors() {
- assertEquals(ImmutableList.of("locations"), getParameterNames(Startable.START));
- }
-
- @Test
- public void testInvokeEffectors1() throws Exception {
- assertEquals("hi Bob", e.sayHi1("Bob", "hi"));
-
- assertEquals("hi Bob", e.SAY_HI_1.call(e, ImmutableMap.of("name", "Bob", "greeting", "hi")) );
- assertEquals("hi Bob", e.invoke(e.SAY_HI_1, ImmutableMap.of("name", "Bob", "greeting", "hi")).get() );
-
- // and with default greeting param value
- assertEquals("hi Bob", e.SAY_HI_1.call(e, ImmutableMap.of("name", "Bob", "greeting", "hi")) );
- assertEquals("hello Bob", e.invoke(e.SAY_HI_1, ImmutableMap.of("name", "Bob")).get() );
- }
-
- @Test
- public void testCanRetrieveTaskForEffector() {
- e.sayHi1("Bob", "hi");
-
- Set<Task<?>> tasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
- BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
- assertEquals(tasks.size(), 1);
- assertTrue(tasks.iterator().next().getDescription().contains("sayHi1"));
- }
-
- @Test
- public void testDelegatedNestedEffectorNotRepresentedAsTask() {
- e.delegateSayHi1("Bob", "hi");
-
- Set<Task<?>> tasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
- BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
- assertEquals(tasks.size(), 1);
- assertTrue(tasks.iterator().next().getDescription().contains("delegateSayHi1"));
- assertFalse(tasks.iterator().next().getDescription().contains("sayHi1"));
- }
-
- @Test
- public void testCanExcludeNonEffectorTasks() throws Exception {
- ExecutionContext executionContext = mgmt.getExecutionContext(e);
- executionContext.submit(new BasicTask<Void>(new Runnable() { public void run() {} }));
-
- Set<Task<?>> effectTasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
- BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
- assertEquals(effectTasks.size(), 0);
- }
-
- public interface CanSayHi {
- static MethodEffector<String> SAY_HI_1 = new MethodEffector<String>(CanSayHi.class, "sayHi1");
- static MethodEffector<String> DELEGATE_SAY_HI_1 = new MethodEffector<String>(CanSayHi.class, "delegateSayHi1");
-
- @org.apache.brooklyn.core.annotation.Effector(description="says hello")
- public String sayHi1(
- @EffectorParam(name="name") String name,
- @EffectorParam(name="greeting", defaultValue="hello", description="what to say") String greeting);
-
- @org.apache.brooklyn.core.annotation.Effector(description="delegate says hello")
- public String delegateSayHi1(
- @EffectorParam(name="name") String name,
- @EffectorParam(name="greeting") String greeting);
- }
-
- @ImplementedBy(MyEntityImpl.class)
- public interface MyEntity extends Entity, CanSayHi {
- }
-
- public static class MyEntityImpl extends AbstractEntity implements MyEntity {
- @Override
- public String sayHi1(String name, String greeting) {
- return greeting+" "+name;
- }
- @Override
- public String delegateSayHi1(String name, String greeting) {
- return sayHi1(name, greeting);
- }
- }
-
- private List<String> getParameterNames(Effector<?> effector) {
- return ImmutableList.copyOf(getParameterDescriptions(effector).keySet());
- }
-
- private Map<String, String> getParameterDescriptions(Effector<?> effector) {
- Map<String,String> result = Maps.newLinkedHashMap();
- for (ParameterType<?> parameter : effector.getParameters()) {
- result.put(parameter.getName(), parameter.getDescription());
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorTaskTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorTaskTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorTaskTest.java
deleted file mode 100644
index 7d8a4f5..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorTaskTest.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.HasTaskChildren;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.EffectorWithBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.TaskBuilder;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class EffectorTaskTest extends BrooklynAppUnitTestSupport {
-
- // ----------- syntax 1 -- effector with body in a class
-
- public static final Effector<Integer> DOUBLE_1 = Effectors.effector(Integer.class, "double")
- .description("doubles the given number")
- .parameter(Integer.class, "numberToDouble")
- .impl(new EffectorBody<Integer>() {
- @Override
- public Integer call(ConfigBag parameters) {
- // do a sanity check
- Assert.assertNotNull(entity());
-
- // finally double the input
- return 2*(Integer)parameters.getStringKey("numberToDouble");
- }
- })
- .build();
-
- public static class DoublingEntity extends AbstractEntity {
- public static final Effector<Integer> DOUBLE = EffectorTaskTest.DOUBLE_1;
- }
-
- @Test
- public void testSyntaxOneDouble1() throws Exception {
- // just use "dynamic" support of effector
- Assert.assertEquals(app.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
- @Test
- public void testSyntaxOneTaggedCorrectly() throws Exception {
- Task<Integer> t = app.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3));
- t.get();
- checkTags(t, app, DOUBLE_1, false);
- }
-
- @Test
- // also assert it works when the effector is defined on an entity
- public void testSimpleEffectorOnEntity() throws Exception {
- Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
-
- Assert.assertEquals(doubler.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
- @Test
- // also assert it works when an abstract effector name is passed in to the entity
- public void testSimpleEffectorNameMatching() throws Exception {
- Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
-
- Assert.assertEquals(doubler.invoke(Effectors.effector(Integer.class, "double").buildAbstract(), MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
-
- // ----------- syntax 2 -- effector with body built with fluent API
-
- public static EffectorTaskFactory<Integer> times(final EffectorTaskFactory<Integer> x, final int y) {
- return new EffectorTaskFactory<Integer>() {
- @Override
- public Task<Integer> newTask(final Entity entity, final Effector<Integer> effector, final ConfigBag parameters) {
- return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() {
- return DynamicTasks.get( x.newTask(entity, effector, parameters) )*y;
- } }).build();
- }
- };
- }
-
- public static final Effector<Integer> DOUBLE_2 = Effectors.effector(Integer.class, "double")
- .description("doubles the given number")
- .parameter(Integer.class, "numberToDouble")
- .impl(times(EffectorTasks.parameter(Integer.class, "numberToDouble"), 2))
- .build();
-
- @Test
- public void testSyntaxTwoDouble2() throws Exception {
- Assert.assertEquals(app.invoke(DOUBLE_2, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
- @Test
- public void testEffectorImplTaggedCorrectly() throws Exception {
- Task<Integer> t = app.invoke(DOUBLE_2, MutableMap.of("numberToDouble", 3));
- t.get();
- checkTags(t, app, DOUBLE_2, true);
- }
-
- public static final Effector<Integer> DOUBLE_CALL_ABSTRACT = Effectors.effector(Integer.class, "double_call")
- .description("doubles the given number")
- .parameter(Integer.class, "numberToDouble")
- .buildAbstract();
- public static final Effector<Integer> DOUBLE_CALL = Effectors.effector(DOUBLE_CALL_ABSTRACT)
- .impl(new EffectorBody<Integer>() {
- @Override
- public Integer call(ConfigBag parameters) {
- final Entity parent = entity();
- final Entity child = Iterables.getOnlyElement(entity().getChildren());
-
- final Effector<Integer> DOUBLE_CHECK_ABSTRACT = Effectors.effector(Integer.class, "double_check")
- .description("doubles the given number and checks tags, assuming double exists as an effector here")
- .parameter(Integer.class, "numberToDouble")
- .buildAbstract();
- Effector<Integer> DOUBLE_CHECK = Effectors.effector(DOUBLE_CHECK_ABSTRACT)
- .impl(new EffectorBody<Integer>() {
- @Override
- public Integer call(ConfigBag parameters) {
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, null, false));
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_CHECK_ABSTRACT, false));
- Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_1, false));
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, true));
- Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, false));
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_CALL_ABSTRACT, true));
- Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_1, true));
-
- return entity().invoke(DOUBLE_1, parameters.getAllConfig()).getUnchecked();
- }
- }).build();
-
- return child.invoke(DOUBLE_CHECK, parameters.getAllConfig()).getUnchecked();
- }
- }).build();
-
-
- @Test
- // also assert it works when the effector is defined on an entity
- public void testNestedEffectorTag() throws Exception {
- app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
- Assert.assertEquals(app.invoke(DOUBLE_CALL, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
-
- private void checkTags(Task<Integer> t, Entity entity, Effector<?> eff, boolean shouldHaveChild) {
- Assert.assertEquals(BrooklynTaskTags.getContextEntity(t), app);
- Assert.assertTrue(t.getTags().contains(BrooklynTaskTags.EFFECTOR_TAG), "missing effector tag; had: "+t.getTags());
- Assert.assertTrue(t.getDescription().contains(eff.getName()), "description missing effector name: "+t.getDescription());
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(t, entity, eff, false));
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(t, null, null, false));
- Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(t, entity, Startable.START, false));
-
- if (shouldHaveChild) {
- Task<?> subtask = ((HasTaskChildren)t).getChildren().iterator().next();
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(subtask, entity, eff, false));
- Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(subtask, null, null, false));
- }
- }
-
- // TEST parameter task missing
-
- // ----------------- syntax for more complex -- an effector using subtasks
-
- public static Task<Integer> add(final int x, final int y) {
- return TaskBuilder.<Integer>builder().name("add").body(new Callable<Integer>() { public Integer call() { return x+y; } }).build();
- }
-
- public static Task<Integer> add(final Task<Integer> x, final int y) {
- return TaskBuilder.<Integer>builder().name("add").body(new Callable<Integer>() { public Integer call() { return DynamicTasks.get(x)+y; } }).build();
- }
-
- public static Task<Integer> addBasic(final Task<Integer> x, final int y) {
- return TaskBuilder.<Integer>builder().name("add (not dynamic)").dynamic(false).body(new Callable<Integer>() { public Integer call() {
- Preconditions.checkState(x.isSubmitted());
- return x.getUnchecked()+y;
- } }).build();
- }
-
- public static Task<Integer> times(final int x, final int y) {
- return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { return x*y; } }).build();
- }
-
- public static Task<Integer> times(final Task<Integer> x, final int y) {
- return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { return DynamicTasks.get(x)*y; } }).build();
- }
-
- public static final Effector<Integer> TWO_X_PLUS_ONE = Effectors.effector(Integer.class, "twoXPlusOne")
- .description("doubles the given number and adds one")
- .parameter(Integer.class, "numberToStartWith")
- .impl(new EffectorBody<Integer>() {
- public Integer call(ConfigBag parameters) {
- int input = (Integer)parameters.getStringKey("numberToStartWith");
- queue( add(times(input, 2), 1) );
- return last(Integer.class);
- }
- })
- .build();
-
- public static final Effector<Integer> TWO_X_PLUS_ONE_BASIC = Effectors.effector(Integer.class, "twoXPlusOne_Basic")
- .description("doubles the given number and adds one, as a basic task")
- .parameter(Integer.class, "numberToStartWith")
- .impl(new EffectorBody<Integer>() {
- public Integer call(ConfigBag parameters) {
- int input = (Integer)parameters.getStringKey("numberToStartWith");
- // note the subtasks must be queued explicitly with a basic task
- // (but with the DynamicSequentialTask they can be resolved by the task itself; see above)
- Task<Integer> product = queue(times(input, 2));
- queue( addBasic(product, 1) );
- return last(Integer.class);
- }
- })
- .build();
-
- // TODO a chaining style approach
-
- public static class Txp1Entity extends AbstractEntity {
- public static final Effector<Integer> TWO_X_P_1 = EffectorTaskTest.TWO_X_PLUS_ONE;
- }
-
- /** the composed effector should allow us to inspect its children */
- @Test
- public void testComposedEffector() throws Exception {
- Entity txp1 = app.createAndManageChild(EntitySpec.create(Entity.class, Txp1Entity.class));
-
- Task<Integer> e = txp1.invoke(TWO_X_PLUS_ONE, MutableMap.of("numberToStartWith", 3));
- Assert.assertTrue(e instanceof DynamicSequentialTask);
- Assert.assertEquals(e.get(), (Integer)7);
- Assert.assertEquals( Iterables.size( ((HasTaskChildren)e).getChildren() ), 1);
- Task<?> child = ((HasTaskChildren)e).getChildren().iterator().next();
- Assert.assertEquals( Iterables.size( ((HasTaskChildren)child).getChildren() ), 1);
- }
-
- /** the composed effector should allow us to inspect its children */
- @Test
- public void testComposedEffectorBasic() throws Exception {
- Entity txp1 = app.createAndManageChild(EntitySpec.create(Entity.class, Txp1Entity.class));
-
- Task<Integer> e = txp1.invoke(TWO_X_PLUS_ONE_BASIC, MutableMap.of("numberToStartWith", 3));
- Assert.assertTrue(e instanceof DynamicSequentialTask);
- Assert.assertEquals(e.get(), (Integer)7);
- Assert.assertEquals( Iterables.size( ((HasTaskChildren)e).getChildren() ), 2);
- }
-
- // --------- defining
-
- @Test
- public void testEffectorWithBodyWorksEvenIfNotOnEntity() throws Exception {
- Entity doubler = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- Assert.assertEquals(doubler.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
- public static final Effector<Integer> DOUBLE_BODYLESS = Effectors.effector(Integer.class, "double")
- .description("doubles the given number")
- .parameter(Integer.class, "numberToDouble")
- .buildAbstract();
-
- @Test
- public void testEffectorWithoutBodyFails() throws Exception {
- Entity doubler = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- boolean failed = false;
- try {
- doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3));
- } catch (Exception e) {
- failed = true;
- }
- if (!failed) Assert.fail("doubling should have failed because it had no body");
- }
-
- @Test
- public void testEffectorBodyAdded() throws Exception {
- EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- // not yet present
- Assert.assertNull( doubler.getEffector("double") );
-
- // add it
- doubler.getMutableEntityType().addEffector(DOUBLE_BODYLESS, new EffectorBody<Integer>() {
- @Override
- public Integer call(ConfigBag parameters) {
- int input = (Integer)parameters.getStringKey("numberToDouble");
- return queue(times(input, 2)).getUnchecked();
- }
- });
- // now it is present
- Assert.assertNotNull( doubler.getEffector("double") );
-
- Assert.assertEquals(doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
- @Test
- public void testEffectorBodyAddedImplicitlyButBodylessSignatureInvoked() throws Exception {
- EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- // add it
- doubler.getMutableEntityType().addEffector(DOUBLE_1);
-
- // invoke it, but using something with equivalent name (and signature -- though only name is used currently)
- // ensures that the call picks up the body by looking in the actual entity
- Assert.assertEquals(doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
- }
-
- @Test(dependsOnMethods={"testEffectorBodyAdded"})
- public void testEntityNotPermanentlyChanged() throws Exception {
- EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
- // ensures that independent creations of the class previously modified do not have this effector
- Assert.assertNull( doubler.getEffector("double") );
- }
-
- // --- overriding by using statics ---------
-
- public static class BadDoublingEntity extends DoublingEntity {
- public static final Effector<Integer> DOUBLE = Effectors.effector(DoublingEntity.DOUBLE).
- impl( ((EffectorWithBody<Integer>)TWO_X_PLUS_ONE).getBody() ).build();
- }
-
- @Test
- // also assert it works when the entity is defined on an entity
- public void testOverriddenEffectorOnEntity() throws Exception {
- Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, BadDoublingEntity.class));
-
- Assert.assertEquals(doubler.invoke(DoublingEntity.DOUBLE, MutableMap.of("numberToDouble", 3, "numberToStartWith", 3)).get(), (Integer)7);
- }
-
- public static final Effector<Void> DUMMY = Effectors.effector(Void.class, "dummy")
- .impl(new EffectorBody<Void>() {
- @Override
- public Void call(ConfigBag parameters) {
- return null;
- }
- })
- .build();
-
- public static final Effector<Void> STALL = Effectors.effector(Void.class, "stall")
- .parameter(AtomicBoolean.class, "lock")
- .impl(new EffectorBody<Void>() {
- @Override
- public Void call(ConfigBag parameters) {
- AtomicBoolean lock = (AtomicBoolean)parameters.getStringKey("lock");
- synchronized(lock) {
- if (!lock.get()) {
- try {
- lock.wait();
- } catch (InterruptedException e) {
- Exceptions.propagate(e);
- }
- }
- }
- return null;
- }
- })
- .build();
-
- public static final Effector<Void> CONTEXT = Effectors.effector(Void.class, "stall_caller")
- .parameter(AtomicBoolean.class, "lock")
- .impl(new EffectorBody<Void>() {
- @Override
- public Void call(ConfigBag parameters) {
- Entity child = Iterables.getOnlyElement(entity().getChildren());
- AtomicBoolean lock = new AtomicBoolean();
- Task<Void> dummyTask = null;
-
- try {
- // Queue a (DST secondary) task which waits until notified, so that tasks queued later will get blocked
- queue(Effectors.invocation(entity(), STALL, ImmutableMap.of("lock", lock)));
-
- // Start a new task - submitted directly to child's ExecutionContext, as well as added as a
- // DST secondary of the current effector.
- dummyTask = child.invoke(DUMMY, ImmutableMap.<String, Object>of());
- dummyTask.getUnchecked();
-
- // Execution completed in the child's ExecutionContext, but still queued as a secondary.
- // Destroy the child entity so that no subsequent tasks can be executed in its context.
- Entities.destroy(child);
- } finally {
- // Let STALL complete
- synchronized(lock) {
- lock.set(true);
- lock.notifyAll();
- }
- // At this point DUMMY will be unblocked and the DST will try to execute it as a secondary.
- // Submission will be ignored because DUMMY already executed.
- // If it's not ignored then submission will fail because entity is already unmanaged.
- }
- return null;
- }
- })
- .build();
-
-
- @Test
- public void testNestedEffectorExecutedAsSecondaryTask() throws Exception {
- app.createAndManageChild(EntitySpec.create(TestEntity.class));
- Task<Void> effTask = app.invoke(CONTEXT, ImmutableMap.<String, Object>of());
- effTask.get();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
deleted file mode 100644
index 597d267..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core.ssh;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
-import org.apache.brooklyn.util.net.Urls;
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-import com.google.common.io.Files;
-
-public class SshEffectorTasksTest {
-
- private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
-
- TestApplication app;
- ManagementContext mgmt;
- SshMachineLocation host;
- File tempDir;
-
- boolean failureExpected;
-
- @BeforeMethod(alwaysRun=true)
- public void setup() throws Exception {
- app = TestApplication.Factory.newManagedInstanceForTests();
- mgmt = app.getManagementContext();
-
- LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
- host = lhc.obtain();
- app.start(Arrays.asList(host));
- clearExpectedFailure();
- tempDir = Files.createTempDir();
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (mgmt != null) Entities.destroyAll(mgmt);
- mgmt = null;
- FileUtils.deleteDirectory(tempDir);
- checkExpectedFailure();
- }
-
- protected void checkExpectedFailure() {
- if (failureExpected) {
- clearExpectedFailure();
- Assert.fail("Test should have thrown an exception but it did not.");
- }
- }
-
- protected void clearExpectedFailure() {
- failureExpected = false;
- }
-
- protected void setExpectingFailure() {
- failureExpected = true;
- }
-
- public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
- return Entities.submit(app, taskFactory);
- }
-
- // ------------------- basic ssh
-
- @Test(groups="Integration")
- public void testSshEchoHello() {
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
- Assert.assertFalse(t.isDone());
- Assert.assertEquals(t.get(), (Integer)0);
- Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
- Assert.assertEquals(t.getStdout().trim(), "hello world");
- }
-
- @Test(groups="Integration")
- public void testSshPut() throws IOException {
- String fn = Urls.mergePaths(tempDir.getPath(), "f1");
- SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
- t.block();
- Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
- // and make sure this doesn't throw
- Assert.assertTrue(t.isDone());
- Assert.assertTrue(t.isSuccessful());
- Assert.assertEquals(t.get(), null);
- Assert.assertEquals(t.getExitCode(), (Integer)0);
- }
-
- @Test(groups="Integration")
- public void testSshFetch() throws IOException {
- String fn = Urls.mergePaths(tempDir.getPath(), "f2");
- FileUtils.write(new File(fn), "hello fetched world");
-
- SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
- t.block();
-
- Assert.assertTrue(t.isDone());
- Assert.assertEquals(t.get(), "hello fetched world");
- }
-
- // ----------------- pid stuff
-
- @Test(groups="Integration")
- public void testNonRunningPid() {
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
- Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
- Assert.assertNotEquals(t.getExitCode(), (Integer)0);
- ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
- Assert.assertFalse(t2.getTask().getUnchecked());
- }
-
- @Test(groups="Integration")
- public void testNonRunningPidRequired() {
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- }
- checkExpectedFailure();
- }
-
- public static Integer getMyPid() {
- try {
- java.lang.management.RuntimeMXBean runtime =
- java.lang.management.ManagementFactory.getRuntimeMXBean();
- java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
- jvm.setAccessible(true);
-// sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
- Object mgmt = jvm.get(runtime);
- java.lang.reflect.Method pid_method =
- mgmt.getClass().getDeclaredMethod("getProcessId");
- pid_method.setAccessible(true);
-
- return (Integer) pid_method.invoke(mgmt);
- } catch (Exception e) {
- throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
- }
- }
-
- @Test(groups="Integration")
- public void testRunningPid() {
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
- Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
- ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
- Assert.assertTrue(t2.getTask().getUnchecked());
- }
-
- @Test(groups="Integration")
- public void testRunningPidFromFile() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( (""+getMyPid()).getBytes(), f );
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
- Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
- ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
- Assert.assertTrue(t2.getTask().getUnchecked());
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnFailure() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( "99999".getBytes(), f );
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- Assert.assertEquals(t.getExitCode(), (Integer)1);
- }
- checkExpectedFailure();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
-
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- Assert.assertEquals(t.getExitCode(), (Integer)1);
- }
- checkExpectedFailure();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
-
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- Assert.assertEquals(t.getExitCode(), (Integer)2);
- }
- checkExpectedFailure();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnSuccess() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( (""+getMyPid()).getBytes(), f );
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-
- t.getTask().getUnchecked();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( (""+getMyPid()).getBytes(), f );
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
-
- t.getTask().getUnchecked();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
index dec55ec..1aa71f1 100644
--- a/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/ssh/SshMachineLocationTest.java
@@ -43,6 +43,9 @@ import org.apache.brooklyn.api.location.MachineDetails;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.PortRange;
import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorTaskTest;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
@@ -54,9 +57,6 @@ import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorTaskTest;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
index 6b6c0b1..cb0e50c 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
@@ -23,10 +23,10 @@ import java.io.IOException;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasksTest;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasksTest;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index e7e1df9..bc3671f 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -36,6 +36,9 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
@@ -44,9 +47,6 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
index 1c6e75a..bec64cc 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockContainerEntity.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockContainerEntity.java b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockContainerEntity.java
index b11640d..e5b826d 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockContainerEntity.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockContainerEntity.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.group.AbstractGroup;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index 58ec93f..ace9a62 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -33,13 +33,13 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.entity.stock.EffectorStartableImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
index 198d139..5a404a1 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
@@ -20,10 +20,10 @@ package org.apache.brooklyn.entity.salt;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
index c00e48b..d6bacfa 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
@@ -28,14 +28,13 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
-
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.ssh.BashCommands;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
index b25c92f..8dfaaeb 100644
--- a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
+++ b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
@@ -22,6 +22,8 @@ import java.util.Random;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
@@ -38,8 +40,6 @@ import org.testng.annotations.Test;
import org.apache.brooklyn.entity.database.VogellaExampleAccess;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.time.Duration;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
index daf7369..f00b4db 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.entity.brooklynnode.effector.BrooklynNodeUpgradeEffectorBody;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.sensor.core.Sensors;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
index 1ca17fc..0a99d1f 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
@@ -25,13 +25,13 @@ import java.util.concurrent.Callable;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
index bd8cf9b..2dd9067 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
@@ -33,8 +33,8 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.BrooklynVersion;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index f1fd071..c1dd4ed 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -33,6 +33,8 @@ import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
@@ -42,8 +44,6 @@ import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient.ResponseCodePredicates;
import org.apache.brooklyn.entity.brooklynnode.effector.BrooklynNodeUpgradeEffectorBody;
import org.apache.brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
index 6962767..e862df8 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
@@ -29,9 +29,9 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.drivers.downloads.DownloadSubstituters;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
index a031930..cf68641 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/RemoteEffectorBuilder.java
@@ -23,8 +23,8 @@ import java.util.Collection;
import java.util.Map;
import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.Effectors.EffectorBuilder;
import org.apache.brooklyn.entity.brooklynnode.BrooklynEntityMirrorImpl.RemoteEffector;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynClusterUpgradeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynClusterUpgradeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynClusterUpgradeEffectorBody.java
index 3800855..319d5ba 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynClusterUpgradeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynClusterUpgradeEffectorBody.java
@@ -31,12 +31,12 @@ import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.EntityTasks;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster.SelectMasterEffector;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
index b1cb9be..c9f7dd7 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
@@ -29,12 +29,12 @@ import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityTasks;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeDriver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SelectMasterEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SelectMasterEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SelectMasterEffectorBody.java
index 0ce0a91..bd05067 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SelectMasterEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SelectMasterEffectorBody.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.EntityPredicates;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster.SelectMasterEffector;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
index 96d3e49..ca938e9 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.brooklynnode.effector;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.SetHighAvailabilityModeEffector;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
index 4fd1aa4..3560d49 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityPriorityEffectorBody.java
@@ -19,8 +19,8 @@
package org.apache.brooklyn.entity.brooklynnode.effector;
import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.SetHighAvailabilityPriorityEffector;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index 03b7518..869d34d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -23,10 +23,10 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.location.Machines;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
index 327b70b..505f37e 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.chef;
import java.util.Map;
import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.ssh.BashCommands;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
index c8a8b39..c1efa55 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
@@ -23,8 +23,8 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.file.ArchiveTasks;
import org.apache.brooklyn.util.core.file.ArchiveUtils.ArchiveType;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/KnifeConvergeTaskFactory.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
index b66cd4e..c9d99b3 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/KnifeConvergeTaskFactory.java
@@ -29,7 +29,7 @@ import com.google.common.base.Strings;
import com.google.common.net.HostAndPort;
import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.core.effector.EffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
index ce5f82d..c5720ca 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
@@ -28,11 +28,11 @@ import java.util.Map;
import java.util.Set;
import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
index 193f804..2886257 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.AddSensor;
+import org.apache.brooklyn.core.effector.AddSensor;
import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.core.HttpRequestSensor;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntity.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntity.java
index 58c56ea..d3a1254 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntity.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntity.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
index 1bb994d..72d7bef 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.location.Machines;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
index 42a4665..3cf29e7 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
@@ -34,9 +34,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.location.dynamic.LocationOwner;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.machine.MachineEntity;
import org.apache.brooklyn.sensor.core.Sensors;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
index 6089e3f..4307ff6 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
@@ -40,7 +41,6 @@ import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.BasicLocationDefinition;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.dynamic.DynamicLocation;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
index a303f85..a64999c 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
@@ -30,12 +30,12 @@ import java.util.Set;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
import org.apache.brooklyn.core.BrooklynLogging;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.lifecycle.NaiveScriptRunner;
import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
index 0515166..24614af 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
@@ -40,6 +40,9 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.Sanitizer;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
@@ -53,9 +56,6 @@ import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.machine.MachineInitTasks;
import org.apache.brooklyn.entity.machine.ProvidesProvisioningFlags;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/InitdServiceInstaller.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/system_service/InitdServiceInstaller.java b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/InitdServiceInstaller.java
index ce64518..c0de92d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/system_service/InitdServiceInstaller.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/InitdServiceInstaller.java
@@ -29,10 +29,10 @@ import org.apache.brooklyn.api.objs.HasShortName;
import org.apache.brooklyn.api.sensor.Enricher;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.location.cloud.names.AbstractCloudMachineNamer;
-import org.apache.brooklyn.effector.core.EffectorTasks;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
index 35187f8..6470a4b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
@@ -27,11 +27,11 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.sensor.Enricher;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags.WrappedStream;
-import org.apache.brooklyn.effector.core.EffectorTasks;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
[14/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
deleted file mode 100644
index b777352..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeSensorAndConfigKey.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.reflect.TypeToken;
-
-/**
-* A {@link Sensor} describing an attribute that can be configured with inputs that are used to derive the final value.
-* <p>
-* The {@link ConfigKey} will have the same name and description as the sensor but not necessarily the same type.
-* Conversion to set the sensor value from the config key must be supplied in a subclass.
-* <p>
-* {@link ConfigToAttributes#apply(EntityLocal, AttributeSensorAndConfigKey)} is useful to set the attribute from the sensor.
-*/
-public abstract class AttributeSensorAndConfigKey<ConfigType,SensorType> extends BasicAttributeSensor<SensorType>
- implements ConfigKey.HasConfigKey<ConfigType> {
- private static final long serialVersionUID = -3103809215973264600L;
- private static final Logger log = LoggerFactory.getLogger(AttributeSensorAndConfigKey.class);
-
- private ConfigKey<ConfigType> configKey;
-
- public AttributeSensorAndConfigKey(Class<ConfigType> configType, Class<SensorType> sensorType, String name) {
- this(configType, sensorType, name, name, null);
- }
-
- public AttributeSensorAndConfigKey(Class<ConfigType> configType, Class<SensorType> sensorType, String name, String description) {
- this(TypeToken.of(configType), TypeToken.of(sensorType), name, description, null);
- }
-
- public AttributeSensorAndConfigKey(Class<ConfigType> configType, Class<SensorType> sensorType, String name, String description, Object defaultValue) {
- this(TypeToken.of(configType), TypeToken.of(sensorType), name, description, defaultValue);
- }
-
- public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, TypeToken<SensorType> sensorType, String name) {
- this(configType, sensorType, name, null);
- }
-
- public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, TypeToken<SensorType> sensorType, String name, String description) {
- this(configType, sensorType, name, description, null);
- }
-
- public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, TypeToken<SensorType> sensorType, String name, String description, Object defaultValue) {
- super(sensorType, name, description);
- ConfigType defaultValueTyped;
- try {
- defaultValueTyped = TypeCoercions.coerce(defaultValue, configType);
- } catch (Exception e) {
- log.warn("Invalid default value '"+defaultValue+"' for "+name+" (rethrowing: "+e, e);
- throw Exceptions.propagate(e);
- }
- configKey = new BasicConfigKey<ConfigType>(configType, name, description, defaultValueTyped);
- }
-
- public AttributeSensorAndConfigKey(AttributeSensorAndConfigKey<ConfigType,SensorType> orig, ConfigType defaultValue) {
- super(orig.getTypeToken(), orig.getName(), orig.getDescription());
- configKey = ConfigKeys.newConfigKeyWithDefault(orig.configKey,
- TypeCoercions.coerce(defaultValue, orig.configKey.getTypeToken()));
- }
-
- public ConfigKey<ConfigType> getConfigKey() { return configKey; }
-
- /** returns the sensor value for this attribute on the given entity, if present,
- * otherwise works out what the sensor value should be based on the config key's value
- * <p>
- * calls to this may allocate resources (e.g. ports) so should be called only once and
- * then (if non-null) assigned as the sensor's value
- * <p>
- * <b>(for this reason this method should generally not be invoked by callers except in tests and by the framework,
- * and similarly should not be overridden; implement {@link #convertConfigToSensor(Object, Entity)} instead for single-execution calls.
- * the framework calls this from {@link AbstractEntity#setAttribute(AttributeSensorAndConfigKey)}
- * typically via {@link ConfigToAttributes#apply(EntityLocal)} e.g. from SoftwareProcessImpl.preStart().)
- * </b>
- */
- public SensorType getAsSensorValue(Entity e) {
- SensorType sensorValue = e.getAttribute(this);
- if (sensorValue!=null) return sensorValue;
-
- ConfigType v = ((EntityLocal)e).getConfig(this);
- try {
- return convertConfigToSensor(v, e);
- } catch (Throwable t) {
- throw new IllegalArgumentException("Cannot convert config value "+v+" for sensor "+this+": "+t, t);
- }
- }
-
- /**
- * @see {@link #getAsSensorValue(Entity)}
- *
- * Differs in that the config value is converted based on just the management context, rather
- * than for a specific entity. For example, useful if using {@link BrooklynConfigKeys} in BrooklynWebServer.
- * </b>
- */
- public SensorType getAsSensorValue(ManagementContext managementContext) {
- ConfigType v = managementContext.getConfig().getConfig(this);
- try {
- return convertConfigToSensor(v, managementContext);
- } catch (Throwable t) {
- throw new IllegalArgumentException("Cannot convert config value "+v+" for sensor "+this+": "+t, t);
- }
- }
-
- /** converts the given ConfigType value to the corresponding SensorType value,
- * with respect to the given entity
- * <p>
- * this is invoked after checks whether the entity already has a value for the sensor,
- * and the entity-specific config value is passed for convenience if set,
- * otherwise the config key default value is passed for convenience
- * <p>
- * this message should be allowed to return null if the conversion cannot be completed at this time */
- protected abstract SensorType convertConfigToSensor(ConfigType value, Entity entity);
-
- /**
- * @see {@link #convertConfigToSensor(Object, Entity)}
- */
- protected abstract SensorType convertConfigToSensor(ConfigType value, ManagementContext entity);
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java
deleted file mode 100644
index fa50cec..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-
-import com.google.common.reflect.TypeToken;
-
-/**
- * A {@link Sensor} describing an attribute change.
- */
-public class BasicAttributeSensor<T> extends BasicSensor<T> implements AttributeSensor<T> {
- private static final long serialVersionUID = -2493209215974820300L;
-
- private final SensorPersistenceMode persistence;
-
- public BasicAttributeSensor(Class<T> type, String name) {
- this(type, name, name);
- }
-
- public BasicAttributeSensor(Class<T> type, String name, String description) {
- this(TypeToken.of(type), name, description);
- }
-
- public BasicAttributeSensor(TypeToken<T> typeToken, String name) {
- this(typeToken, name, name);
- }
-
- public BasicAttributeSensor(TypeToken<T> typeToken, String name, String description) {
- this(typeToken, name, description, SensorPersistenceMode.REQUIRED);
- }
-
- public BasicAttributeSensor(TypeToken<T> typeToken, String name, String description, SensorPersistenceMode persistence) {
- super(typeToken, name, description);
- this.persistence = checkNotNull(persistence, "persistence");
- }
-
- @Override
- public SensorPersistenceMode getPersistenceMode() {
- // persistence could be null if deserializing state written by an old version; in which case default to 'required'
- return (persistence != null) ? persistence : SensorPersistenceMode.REQUIRED;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
deleted file mode 100644
index 5f473a8..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicAttributeSensorAndConfigKey.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-
-import com.google.common.reflect.TypeToken;
-
-/**
- * A {@link Sensor} describing an attribute that can be configured with a default value.
- *
- * The {@link ConfigKey} has the same type, name and description as the sensor,
- * and is typically used to populate the sensor's value at runtime.
- */
-public class BasicAttributeSensorAndConfigKey<T> extends AttributeSensorAndConfigKey<T,T> {
-
- private static final long serialVersionUID = -2204916730008559688L;
-
- public BasicAttributeSensorAndConfigKey(Class<T> type, String name) {
- this(type, name, name, null);
- }
- public BasicAttributeSensorAndConfigKey(Class<T> type, String name, String description) {
- this(type, name, description, null);
- }
- public BasicAttributeSensorAndConfigKey(Class<T> type, String name, String description, T defaultValue) {
- super(type, type, name, description, defaultValue);
- }
-
- public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name) {
- super(type, type, name);
- }
-
- public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name, String description) {
- super(type, type, name, description);
- }
-
- public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name, String description, Object defaultValue) {
- super(type, type, name, description, defaultValue);
- }
-
- public BasicAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<T,T> orig, T defaultValue) {
- super(orig, defaultValue);
- }
-
- @Override
- protected T convertConfigToSensor(T value, Entity entity) { return value; }
-
- @Override
- protected T convertConfigToSensor(T value, ManagementContext managementContext) { return value; }
-
- public static class StringAttributeSensorAndConfigKey extends BasicAttributeSensorAndConfigKey<String> {
-
- private static final long serialVersionUID = 810512615528081865L;
-
- public StringAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<String,String> orig, String defaultValue) {
- super(orig, defaultValue);
- }
-
- public StringAttributeSensorAndConfigKey(String name, String description, String defaultValue) {
- super(String.class, name, description, defaultValue);
- }
-
- public StringAttributeSensorAndConfigKey(String name, String description) {
- super(String.class, name, description);
- }
-
- public StringAttributeSensorAndConfigKey(String name) {
- super(String.class, name);
- }
-
- }
-
- public static class IntegerAttributeSensorAndConfigKey extends BasicAttributeSensorAndConfigKey<Integer> {
-
- private static final long serialVersionUID = 7159564523829723929L;
-
- public IntegerAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<Integer,Integer> orig, Integer defaultValue) {
- super(orig, defaultValue);
- }
-
- public IntegerAttributeSensorAndConfigKey(String name, String description, Integer defaultValue) {
- super(Integer.class, name, description, defaultValue);
- }
-
- public IntegerAttributeSensorAndConfigKey(String name, String description) {
- super(Integer.class, name, description);
- }
-
- public IntegerAttributeSensorAndConfigKey(String name) {
- super(Integer.class, name);
- }
-
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
deleted file mode 100644
index 627e3c8..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicNotificationSensor.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.sensor.Sensor;
-
-/**
- * A {@link Sensor} used to notify subscribers about events.
- */
-public class BasicNotificationSensor<T> extends BasicSensor<T> {
- private static final long serialVersionUID = -7670909215973264600L;
-
- public BasicNotificationSensor(Class<T> type, String name) {
- this(type, name, name);
- }
-
- public BasicNotificationSensor(Class<T> type, String name, String description) {
- super(type, name, description);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java
deleted file mode 100644
index 439fbb2..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensor.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.util.guava.TypeTokens;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Parent for all {@link Sensor}s.
- */
-public class BasicSensor<T> implements Sensor<T> {
- private static final long serialVersionUID = -3762018534086101323L;
-
- private static final Splitter dots = Splitter.on('.');
-
- private TypeToken<T> typeToken;
- private Class<? super T> type;
- private String name;
- private String description;
- private transient List<String> nameParts;
-
- // FIXME In groovy, fields were `public final` with a default constructor; do we need the gson?
- public BasicSensor() { /* for gson */ }
-
- /** name is typically a dot-separated identifier; description is optional */
- public BasicSensor(Class<T> type, String name) {
- this(type, name, name);
- }
-
- public BasicSensor(Class<T> type, String name, String description) {
- this(TypeToken.of(type), name, description);
- }
-
- public BasicSensor(TypeToken<T> typeToken, String name, String description) {
- this.typeToken = TypeTokens.getTypeTokenIfNotRaw(checkNotNull(typeToken, "typeToken"));
- this.type = TypeTokens.getRawTypeIfRaw(typeToken);
- this.name = checkNotNull(name, "name");
- this.description = description;
- }
-
- /** @see Sensor#getTypeToken() */
- public TypeToken<T> getTypeToken() { return TypeTokens.getTypeToken(typeToken, type); }
-
- /** @see Sensor#getType() */
- public Class<? super T> getType() { return TypeTokens.getRawType(typeToken, type); }
-
- /** @see Sensor#getTypeName() */
- public String getTypeName() {
- return getType().getName();
- }
-
- /** @see Sensor#getName() */
- public String getName() { return name; }
-
- /** @see Sensor#getNameParts() */
- public synchronized List<String> getNameParts() {
- if (nameParts==null) nameParts = ImmutableList.copyOf(dots.split(name));
- return nameParts;
- }
-
- /** @see Sensor#getDescription() */
- public String getDescription() { return description; }
-
- /** @see Sensor#newEvent(Entity, Object) */
- public SensorEvent<T> newEvent(Entity producer, T value) {
- return new BasicSensorEvent<T>(this, producer, value);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(getTypeName(), name, description);
- }
-
- @Override
- public boolean equals(Object other) {
- if (this==other) return true;
- if (!(other instanceof BasicSensor)) return false;
- BasicSensor<?> o = (BasicSensor<?>) other;
-
- return Objects.equal(getTypeName(), o.getTypeName()) && Objects.equal(name, o.name) && Objects.equal(description, o.description);
- }
-
- @Override
- public String toString() {
- return String.format("Sensor: %s (%s)", name, getTypeName());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java b/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java
deleted file mode 100644
index fb0f7a9..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/BasicSensorEvent.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import java.util.ConcurrentModificationException;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-
-/**
- * A {@link SensorEvent} containing data from a {@link Sensor} generated by an {@link Entity}.
- */
-public class BasicSensorEvent<T> implements SensorEvent<T> {
-
- private static final Logger log = LoggerFactory.getLogger(BasicSensorEvent.class);
-
- private final Sensor<T> sensor;
- private final Entity source;
- private final T value;
- private final long timestamp;
-
- public T getValue() { return value; }
-
- public Sensor<T> getSensor() { return sensor; }
-
- public Entity getSource() { return source; }
-
- public long getTimestamp() { return timestamp; }
-
- /** arguments should not be null (except in certain limited testing situations) */
- public BasicSensorEvent(Sensor<T> sensor, Entity source, T value) {
- this(sensor, source, value, System.currentTimeMillis());
- }
-
- public BasicSensorEvent(Sensor<T> sensor, Entity source, T value, long timestamp) {
- this.sensor = sensor;
- this.source = source;
- this.value = value;
- this.timestamp = timestamp;
- }
-
- public static <T> SensorEvent<T> of(Sensor<T> sensor, Entity source, T value, long timestamp) {
- return new BasicSensorEvent<T>(sensor, source, value, timestamp);
- }
-
- @SuppressWarnings("unchecked")
- public static <T> SensorEvent<T> ofUnchecked(Sensor<T> sensor, Entity source, Object value, long timestamp) {
- return new BasicSensorEvent<T>(sensor, source, (T)value, timestamp);
- }
-
- public static <T> SensorEvent<T> of(Sensor<T> sensor, Entity source, T value) {
- return new BasicSensorEvent<T>(sensor, source, value);
- }
-
- @SuppressWarnings("unchecked")
- public static <T> SensorEvent<T> ofUnchecked(Sensor<T> sensor, Entity source, Object value) {
- return new BasicSensorEvent<T>(sensor, source, (T)value);
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(sensor, source, value);
- }
-
- /**
- * Any SensorEvents are equal if their sensor, source and value are equal.
- * Ignore timestamp for ease of use in unit tests.
- */
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof SensorEvent)) return false;
- SensorEvent<?> other = (SensorEvent<?>) o;
- return Objects.equal(sensor, other.getSensor()) && Objects.equal(source, other.getSource()) &&
- Objects.equal(value, other.getValue());
- }
-
- @Override
- public String toString() {
- try {
- return source+"."+sensor+"="+value+" @ "+timestamp;
- } catch (ConcurrentModificationException e) {
- // TODO occasional CME observed on shutdown, wrt map, e.g. in UrlMappingTest
- // transformations should set a copy of the map; see e.g. in ServiceStateLogic.updateMapSensor
- String result = getClass()+":"+source+"."+sensor+"@"+timestamp;
- log.warn("Error creating string for " + result + " (ignoring): " + e);
- if (log.isDebugEnabled())
- log.debug("Trace for error creating string for " + result + " (ignoring): " + e, e);
- return result;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java b/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
deleted file mode 100644
index 9327b19..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/DependentConfiguration.java
+++ /dev/null
@@ -1,823 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import groovy.lang.Closure;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ExecutionContext;
-import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.util.collections.CollectionFunctionals;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.BasicExecutionContext;
-import org.apache.brooklyn.util.core.task.BasicTask;
-import org.apache.brooklyn.util.core.task.DeferredSupplier;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ParallelTask;
-import org.apache.brooklyn.util.core.task.TaskInternal;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.exceptions.NotManagedException;
-import org.apache.brooklyn.util.exceptions.RuntimeTimeoutException;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.CountdownTimer;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-
-/** Conveniences for making tasks which run in entity {@link ExecutionContext}s, subscribing to attributes from other entities, possibly transforming those;
- * these {@link Task} instances are typically passed in {@link EntityLocal#setConfig(ConfigKey, Object)}.
- * <p>
- * If using a lot it may be useful to:
- * <pre>
- * {@code
- * import static brooklyn.event.basic.DependentConfiguration.*;
- * }
- * </pre>
- */
-public class DependentConfiguration {
-
- private static final Logger LOG = LoggerFactory.getLogger(DependentConfiguration.class);
-
- //not instantiable, only a static helper
- private DependentConfiguration() {}
-
- /**
- * Default readiness is Groovy truth.
- *
- * @see #attributeWhenReady(Entity, AttributeSensor, Predicate)
- */
- public static <T> Task<T> attributeWhenReady(Entity source, AttributeSensor<T> sensor) {
- return attributeWhenReady(source, sensor, GroovyJavaMethods.truthPredicate());
- }
-
- public static <T> Task<T> attributeWhenReady(Entity source, AttributeSensor<T> sensor, Closure<Boolean> ready) {
- Predicate<Object> readyPredicate = (ready != null) ? GroovyJavaMethods.<Object>predicateFromClosure(ready) : GroovyJavaMethods.truthPredicate();
- return attributeWhenReady(source, sensor, readyPredicate);
- }
-
- /** returns an unsubmitted {@link Task} which blocks until the given sensor on the given source entity gives a value that satisfies ready, then returns that value;
- * particular useful in Entity configuration where config will block until Tasks have a value
- */
- public static <T> Task<T> attributeWhenReady(final Entity source, final AttributeSensor<T> sensor, final Predicate<? super T> ready) {
- Builder<T, T> builder = builder().attributeWhenReady(source, sensor);
- if (ready != null) builder.readiness(ready);
- return builder.build();
-
- }
-
- public static <T,V> Task<V> attributePostProcessedWhenReady(Entity source, AttributeSensor<T> sensor, Closure<Boolean> ready, Closure<V> postProcess) {
- Predicate<? super T> readyPredicate = (ready != null) ? GroovyJavaMethods.predicateFromClosure(ready) : GroovyJavaMethods.truthPredicate();
- Function<? super T, V> postProcessFunction = GroovyJavaMethods.<T,V>functionFromClosure(postProcess);
- return attributePostProcessedWhenReady(source, sensor, readyPredicate, postProcessFunction);
- }
-
- public static <T,V> Task<V> attributePostProcessedWhenReady(Entity source, AttributeSensor<T> sensor, Closure<V> postProcess) {
- return attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), GroovyJavaMethods.<T,V>functionFromClosure(postProcess));
- }
-
- public static <T> Task<T> valueWhenAttributeReady(Entity source, AttributeSensor<T> sensor, T value) {
- return DependentConfiguration.<T,T>attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), Functions.constant(value));
- }
-
- public static <T,V> Task<V> valueWhenAttributeReady(Entity source, AttributeSensor<T> sensor, Function<? super T,V> valueProvider) {
- return attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), valueProvider);
- }
-
- public static <T,V> Task<V> valueWhenAttributeReady(Entity source, AttributeSensor<T> sensor, Closure<V> valueProvider) {
- return attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), valueProvider);
- }
-
- public static <T,V> Task<V> attributePostProcessedWhenReady(final Entity source, final AttributeSensor<T> sensor, final Predicate<? super T> ready, final Closure<V> postProcess) {
- return attributePostProcessedWhenReady(source, sensor, ready, GroovyJavaMethods.<T,V>functionFromClosure(postProcess));
- }
-
- @SuppressWarnings("unchecked")
- public static <T,V> Task<V> attributePostProcessedWhenReady(final Entity source, final AttributeSensor<T> sensor, final Predicate<? super T> ready, final Function<? super T,V> postProcess) {
- Builder<T,T> builder1 = DependentConfiguration.builder().attributeWhenReady(source, sensor);
- // messy generics here to support null postProcess; would be nice to disallow that here
- Builder<T,V> builder;
- if (postProcess != null) {
- builder = builder1.postProcess(postProcess);
- } else {
- builder = (Builder<T,V>)builder1;
- }
- if (ready != null) builder.readiness(ready);
-
- return builder.build();
- }
-
- public static <T> T waitInTaskForAttributeReady(Entity source, AttributeSensor<T> sensor, Predicate<? super T> ready) {
- return waitInTaskForAttributeReady(source, sensor, ready, ImmutableList.<AttributeAndSensorCondition<?>>of());
- }
-
- public static <T> T waitInTaskForAttributeReady(final Entity source, final AttributeSensor<T> sensor, Predicate<? super T> ready, List<AttributeAndSensorCondition<?>> abortConditions) {
- String blockingDetails = "Waiting for ready from "+source+" "+sensor+" (subscription)";
- return waitInTaskForAttributeReady(source, sensor, ready, abortConditions, blockingDetails);
- }
-
- // TODO would be nice to have an easy semantics for whenServiceUp (cf DynamicWebAppClusterImpl.whenServiceUp)
-
- public static <T> T waitInTaskForAttributeReady(final Entity source, final AttributeSensor<T> sensor, Predicate<? super T> ready, List<AttributeAndSensorCondition<?>> abortConditions, String blockingDetails) {
- return new WaitInTaskForAttributeReady<T,T>(source, sensor, ready, abortConditions, blockingDetails).call();
- }
-
- protected static class WaitInTaskForAttributeReady<T,V> implements Callable<V> {
-
- /* This is a change since before Oct 2014. Previously it would continue to poll,
- * (maybe finding a different error) if the target entity becomes unmanaged.
- * Now it actively checks unmanaged by default, and still throws although it might
- * now find a different problem. */
- private final static boolean DEFAULT_IGNORE_UNMANAGED = false;
-
- protected final Entity source;
- protected final AttributeSensor<T> sensor;
- protected final Predicate<? super T> ready;
- protected final List<AttributeAndSensorCondition<?>> abortSensorConditions;
- protected final String blockingDetails;
- protected final Function<? super T,? extends V> postProcess;
- protected final Duration timeout;
- protected final Maybe<V> onTimeout;
- protected final boolean ignoreUnmanaged;
- protected final Maybe<V> onUnmanaged;
- // TODO onError Continue / Throw / Return(V)
-
- protected WaitInTaskForAttributeReady(Builder<T, V> builder) {
- this.source = builder.source;
- this.sensor = builder.sensor;
- this.ready = builder.readiness;
- this.abortSensorConditions = builder.abortSensorConditions;
- this.blockingDetails = builder.blockingDetails;
- this.postProcess = builder.postProcess;
- this.timeout = builder.timeout;
- this.onTimeout = builder.onTimeout;
- this.ignoreUnmanaged = builder.ignoreUnmanaged;
- this.onUnmanaged = builder.onUnmanaged;
- }
-
- private WaitInTaskForAttributeReady(Entity source, AttributeSensor<T> sensor, Predicate<? super T> ready,
- List<AttributeAndSensorCondition<?>> abortConditions, String blockingDetails) {
- this.source = source;
- this.sensor = sensor;
- this.ready = ready;
- this.abortSensorConditions = abortConditions;
- this.blockingDetails = blockingDetails;
-
- this.timeout = Duration.PRACTICALLY_FOREVER;
- this.onTimeout = Maybe.absent();
- this.ignoreUnmanaged = DEFAULT_IGNORE_UNMANAGED;
- this.onUnmanaged = Maybe.absent();
- this.postProcess = null;
- }
-
- @SuppressWarnings("unchecked")
- protected V postProcess(T value) {
- if (this.postProcess!=null) return postProcess.apply(value);
- // if no post-processing assume the types are correct
- return (V) value;
- }
-
- protected boolean ready(T value) {
- if (ready!=null) return ready.apply(value);
- return GroovyJavaMethods.truth(value);
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- public V call() {
- T value = source.getAttribute(sensor);
-
- // return immediately if either the ready predicate or the abort conditions hold
- if (ready(value)) return postProcess(value);
-
- final List<Exception> abortionExceptions = Lists.newCopyOnWriteArrayList();
- long start = System.currentTimeMillis();
-
- for (AttributeAndSensorCondition abortCondition : abortSensorConditions) {
- Object abortValue = abortCondition.source.getAttribute(abortCondition.sensor);
- if (abortCondition.predicate.apply(abortValue)) {
- abortionExceptions.add(new Exception("Abort due to "+abortCondition.source+" -> "+abortCondition.sensor));
- }
- }
- if (abortionExceptions.size() > 0) {
- throw new CompoundRuntimeException("Aborted waiting for ready from "+source+" "+sensor, abortionExceptions);
- }
-
- TaskInternal<?> current = (TaskInternal<?>) Tasks.current();
- if (current == null) throw new IllegalStateException("Should only be invoked in a running task");
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(current);
- if (entity == null) throw new IllegalStateException("Should only be invoked in a running task with an entity tag; "+
- current+" has no entity tag ("+current.getStatusDetail(false)+")");
-
- final LinkedList<T> publishedValues = new LinkedList<T>();
- final Semaphore semaphore = new Semaphore(0); // could use Exchanger
- SubscriptionHandle subscription = null;
- List<SubscriptionHandle> abortSubscriptions = Lists.newArrayList();
-
- try {
- subscription = ((EntityInternal)entity).getSubscriptionContext().subscribe(source, sensor, new SensorEventListener<T>() {
- @Override public void onEvent(SensorEvent<T> event) {
- synchronized (publishedValues) { publishedValues.add(event.getValue()); }
- semaphore.release();
- }});
- for (final AttributeAndSensorCondition abortCondition : abortSensorConditions) {
- abortSubscriptions.add(((EntityInternal)entity).getSubscriptionContext().subscribe(abortCondition.source, abortCondition.sensor, new SensorEventListener<Object>() {
- @Override public void onEvent(SensorEvent<Object> event) {
- if (abortCondition.predicate.apply(event.getValue())) {
- abortionExceptions.add(new Exception("Abort due to "+abortCondition.source+" -> "+abortCondition.sensor));
- semaphore.release();
- }
- }}));
- Object abortValue = abortCondition.source.getAttribute(abortCondition.sensor);
- if (abortCondition.predicate.apply(abortValue)) {
- abortionExceptions.add(new Exception("Abort due to "+abortCondition.source+" -> "+abortCondition.sensor));
- }
- }
- if (abortionExceptions.size() > 0) {
- throw new CompoundRuntimeException("Aborted waiting for ready from "+source+" "+sensor, abortionExceptions);
- }
-
- CountdownTimer timer = timeout!=null ? timeout.countdownTimer() : null;
- Duration maxPeriod = ValueResolver.PRETTY_QUICK_WAIT;
- Duration nextPeriod = ValueResolver.REAL_QUICK_PERIOD;
- while (true) {
- // check the source on initial run (could be done outside the loop)
- // and also (optionally) on each iteration in case it is more recent
- value = source.getAttribute(sensor);
- if (ready(value)) break;
-
- if (timer!=null) {
- if (timer.getDurationRemaining().isShorterThan(nextPeriod)) {
- nextPeriod = timer.getDurationRemaining();
- }
- if (timer.isExpired()) {
- if (onTimeout.isPresent()) return onTimeout.get();
- throw new RuntimeTimeoutException("Unsatisfied after "+Duration.sinceUtc(start));
- }
- }
-
- String prevBlockingDetails = current.setBlockingDetails(blockingDetails);
- try {
- if (semaphore.tryAcquire(nextPeriod.toMilliseconds(), TimeUnit.MILLISECONDS)) {
- // immediately release so we are available for the next check
- semaphore.release();
- // if other permits have been made available (e.g. multiple notifications) drain them all as no point running multiple times
- semaphore.drainPermits();
- }
- } finally {
- current.setBlockingDetails(prevBlockingDetails);
- }
-
- // check any subscribed values which have come in first
- while (true) {
- synchronized (publishedValues) {
- if (publishedValues.isEmpty()) break;
- value = publishedValues.pop();
- }
- if (ready(value)) break;
- }
-
- // if unmanaged then ignore the other abort conditions
- if (!ignoreUnmanaged && Entities.isNoLongerManaged(entity)) {
- if (onUnmanaged.isPresent()) return onUnmanaged.get();
- throw new NotManagedException(entity);
- }
-
- if (abortionExceptions.size() > 0) {
- throw new CompoundRuntimeException("Aborted waiting for ready from "+source+" "+sensor, abortionExceptions);
- }
-
- nextPeriod = nextPeriod.times(2).upperBound(maxPeriod);
- }
- if (LOG.isDebugEnabled()) LOG.debug("Attribute-ready for {} in entity {}", sensor, source);
- return postProcess(value);
- } catch (InterruptedException e) {
- throw Exceptions.propagate(e);
- } finally {
- if (subscription != null) {
- ((EntityInternal)entity).getSubscriptionContext().unsubscribe(subscription);
- }
- for (SubscriptionHandle handle : abortSubscriptions) {
- ((EntityInternal)entity).getSubscriptionContext().unsubscribe(handle);
- }
- }
- }
- }
-
- /**
- * Returns a {@link Task} which blocks until the given job returns, then returns the value of that job.
- *
- * @deprecated since 0.7; code will be moved into test utilities
- */
- @Deprecated
- public static <T> Task<T> whenDone(Callable<T> job) {
- return new BasicTask<T>(MutableMap.of("tag", "whenDone", "displayName", "waiting for job"), job);
- }
-
- /**
- * Returns a {@link Task} which waits for the result of first parameter, then applies the function in the second
- * parameter to it, returning that result.
- *
- * Particular useful in Entity configuration where config will block until Tasks have completed,
- * allowing for example an {@link #attributeWhenReady(Entity, AttributeSensor, Predicate)} expression to be
- * passed in the first argument then transformed by the function in the second argument to generate
- * the value that is used for the configuration
- */
- public static <U,T> Task<T> transform(final Task<U> task, final Function<U,T> transformer) {
- return transform(MutableMap.of("displayName", "transforming "+task), task, transformer);
- }
-
- /** @see #transform(Task, Function) */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <U,T> Task<T> transform(Task<U> task, Closure transformer) {
- return transform(task, GroovyJavaMethods.functionFromClosure(transformer));
- }
-
- /** @see #transform(Task, Function) */
- @SuppressWarnings({ "rawtypes" })
- public static <U,T> Task<T> transform(final Map flags, final TaskAdaptable<U> task, final Function<U,T> transformer) {
- return new BasicTask<T>(flags, new Callable<T>() {
- public T call() throws Exception {
- if (!task.asTask().isSubmitted()) {
- BasicExecutionContext.getCurrentExecutionContext().submit(task);
- }
- return transformer.apply(task.asTask().get());
- }});
- }
-
- /** Returns a task which waits for multiple other tasks (submitting if necessary)
- * and performs arbitrary computation over the List of results.
- * @see #transform(Task, Function) but note argument order is reversed (counterintuitive) to allow for varargs */
- public static <U,T> Task<T> transformMultiple(Function<List<U>,T> transformer, @SuppressWarnings("unchecked") TaskAdaptable<U> ...tasks) {
- return transformMultiple(MutableMap.of("displayName", "transforming multiple"), transformer, tasks);
- }
-
- /** @see #transformMultiple(Function, TaskAdaptable...) */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <U,T> Task<T> transformMultiple(Closure transformer, TaskAdaptable<U> ...tasks) {
- return transformMultiple(GroovyJavaMethods.functionFromClosure(transformer), tasks);
- }
-
- /** @see #transformMultiple(Function, TaskAdaptable...) */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <U,T> Task<T> transformMultiple(Map flags, Closure transformer, TaskAdaptable<U> ...tasks) {
- return transformMultiple(flags, GroovyJavaMethods.functionFromClosure(transformer), tasks);
- }
-
- /** @see #transformMultiple(Function, TaskAdaptable...) */
- @SuppressWarnings({ "rawtypes" })
- public static <U,T> Task<T> transformMultiple(Map flags, final Function<List<U>,T> transformer, @SuppressWarnings("unchecked") TaskAdaptable<U> ...tasks) {
- return transformMultiple(flags, transformer, Arrays.asList(tasks));
- }
- @SuppressWarnings({ "rawtypes" })
- public static <U,T> Task<T> transformMultiple(Map flags, final Function<List<U>,T> transformer, Collection<? extends TaskAdaptable<U>> tasks) {
- if (tasks.size()==1) {
- return transform(flags, Iterables.getOnlyElement(tasks), new Function<U,T>() {
- @Override
- @Nullable
- public T apply(@Nullable U input) {
- return transformer.apply(ImmutableList.of(input));
- }
- });
- }
- return transform(flags, new ParallelTask<U>(tasks), transformer);
- }
-
-
- /** Method which returns a Future containing a string formatted using String.format,
- * where the arguments can be normal objects or tasks;
- * tasks will be waited on (submitted if necessary) and their results substituted in the call
- * to String.format.
- * <p>
- * Example:
- * <pre>
- * {@code
- * setConfig(URL, DependentConfiguration.formatString("%s:%s",
- * DependentConfiguration.attributeWhenReady(target, Target.HOSTNAME),
- * DependentConfiguration.attributeWhenReady(target, Target.PORT) ) );
- * }
- * </pre>
- */
- @SuppressWarnings("unchecked")
- public static Task<String> formatString(final String spec, final Object ...args) {
- List<TaskAdaptable<Object>> taskArgs = Lists.newArrayList();
- for (Object arg: args) {
- if (arg instanceof TaskAdaptable) taskArgs.add((TaskAdaptable<Object>)arg);
- else if (arg instanceof TaskFactory) taskArgs.add( ((TaskFactory<TaskAdaptable<Object>>)arg).newTask() );
- }
-
- return transformMultiple(
- MutableMap.<String,String>of("displayName", "formatting '"+spec+"' with "+taskArgs.size()+" task"+(taskArgs.size()!=1?"s":"")),
- new Function<List<Object>, String>() {
- @Override public String apply(List<Object> input) {
- Iterator<?> tri = input.iterator();
- Object[] vv = new Object[args.length];
- int i=0;
- for (Object arg : args) {
- if (arg instanceof TaskAdaptable || arg instanceof TaskFactory) vv[i] = tri.next();
- else if (arg instanceof DeferredSupplier) vv[i] = ((DeferredSupplier<?>) arg).get();
- else vv[i] = arg;
- i++;
- }
- return String.format(spec, vv);
- }},
- taskArgs);
- }
-
- /** returns a task for parallel execution returning a list of values for the given sensor for the given entity list,
- * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
- public static <T> Task<List<T>> listAttributesWhenReady(AttributeSensor<T> sensor, Iterable<Entity> entities) {
- return listAttributesWhenReady(sensor, entities, GroovyJavaMethods.truthPredicate());
- }
-
- public static <T> Task<List<T>> listAttributesWhenReady(AttributeSensor<T> sensor, Iterable<Entity> entities, Closure<Boolean> readiness) {
- Predicate<Object> readinessPredicate = (readiness != null) ? GroovyJavaMethods.<Object>predicateFromClosure(readiness) : GroovyJavaMethods.truthPredicate();
- return listAttributesWhenReady(sensor, entities, readinessPredicate);
- }
-
- /** returns a task for parallel execution returning a list of values of the given sensor list on the given entity,
- * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
- public static <T> Task<List<T>> listAttributesWhenReady(final AttributeSensor<T> sensor, Iterable<Entity> entities, Predicate<? super T> readiness) {
- if (readiness == null) readiness = GroovyJavaMethods.truthPredicate();
- return builder().attributeWhenReadyFromMultiple(entities, sensor, readiness).build();
- }
-
- /** @see #waitForTask(Task, Entity, String) */
- public static <T> T waitForTask(Task<T> t, Entity context) throws InterruptedException {
- return waitForTask(t, context, null);
- }
-
- /** blocks until the given task completes, submitting if necessary, returning the result of that task;
- * optional contextMessage is available in status if this is running in a task
- */
- @SuppressWarnings("unchecked")
- public static <T> T waitForTask(Task<T> t, Entity context, String contextMessage) throws InterruptedException {
- try {
- return (T) Tasks.resolveValue(t, Object.class, ((EntityInternal)context).getExecutionContext(), contextMessage);
- } catch (ExecutionException e) {
- throw Throwables.propagate(e);
- }
- }
-
- public static class AttributeAndSensorCondition<T> {
- protected final Entity source;
- protected final AttributeSensor<T> sensor;
- protected final Predicate<? super T> predicate;
-
- public AttributeAndSensorCondition(Entity source, AttributeSensor<T> sensor, Predicate<? super T> predicate) {
- this.source = checkNotNull(source, "source");
- this.sensor = checkNotNull(sensor, "sensor");
- this.predicate = checkNotNull(predicate, "predicate");
- }
- }
-
- public static ProtoBuilder builder() {
- return new ProtoBuilder();
- }
-
- /**
- * Builder for producing variants of attributeWhenReady.
- */
- @Beta
- public static class ProtoBuilder {
- /**
- * Will wait for the attribute on the given entity.
- * If that entity reports {@link Lifecycle#ON_FIRE} for its {@link Attributes#SERVICE_STATE} then it will abort.
- */
- public <T2> Builder<T2,T2> attributeWhenReady(Entity source, AttributeSensor<T2> sensor) {
- return new Builder<T2,T2>(source, sensor).abortIfOnFire();
- }
-
- /**
- * Will wait for the attribute on the given entity, not aborting when it goes {@link Lifecycle#ON_FIRE}.
- */
- public <T2> Builder<T2,T2> attributeWhenReadyAllowingOnFire(Entity source, AttributeSensor<T2> sensor) {
- return new Builder<T2,T2>(source, sensor);
- }
-
- /** Constructs a builder for task for parallel execution returning a list of values of the given sensor list on the given entity,
- * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
- @Beta
- public <T> MultiBuilder<T, T, List<T>> attributeWhenReadyFromMultiple(Iterable<? extends Entity> sources, AttributeSensor<T> sensor) {
- return attributeWhenReadyFromMultiple(sources, sensor, GroovyJavaMethods.truthPredicate());
- }
- /** As {@link #attributeWhenReadyFromMultiple(Iterable, AttributeSensor)} with an explicit readiness test. */
- @Beta
- public <T> MultiBuilder<T, T, List<T>> attributeWhenReadyFromMultiple(Iterable<? extends Entity> sources, AttributeSensor<T> sensor, Predicate<? super T> readiness) {
- return new MultiBuilder<T, T, List<T>>(sources, sensor, readiness);
- }
- }
-
- /**
- * Builder for producing variants of attributeWhenReady.
- */
- public static class Builder<T,V> {
- protected Entity source;
- protected AttributeSensor<T> sensor;
- protected Predicate<? super T> readiness;
- protected Function<? super T, ? extends V> postProcess;
- protected List<AttributeAndSensorCondition<?>> abortSensorConditions = Lists.newArrayList();
- protected String blockingDetails;
- protected Duration timeout;
- protected Maybe<V> onTimeout;
- protected boolean ignoreUnmanaged = WaitInTaskForAttributeReady.DEFAULT_IGNORE_UNMANAGED;
- protected Maybe<V> onUnmanaged;
-
- protected Builder(Entity source, AttributeSensor<T> sensor) {
- this.source = source;
- this.sensor = sensor;
- }
-
- /**
- * Will wait for the attribute on the given entity.
- * If that entity report {@link Lifecycle#ON_FIRE} for its {@link Attributes#SERVICE_STATE_ACTUAL} then it will abort.
- * @deprecated since 0.7.0 use {@link DependentConfiguration#builder()} then {@link ProtoBuilder#attributeWhenReady(Entity, AttributeSensor)} then {@link #abortIfOnFire()}
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <T2> Builder<T2,T2> attributeWhenReady(Entity source, AttributeSensor<T2> sensor) {
- this.source = checkNotNull(source, "source");
- this.sensor = (AttributeSensor) checkNotNull(sensor, "sensor");
- abortIfOnFire();
- return (Builder<T2, T2>) this;
- }
- public Builder<T,V> readiness(Closure<Boolean> val) {
- this.readiness = GroovyJavaMethods.predicateFromClosure(checkNotNull(val, "val"));
- return this;
- }
- public Builder<T,V> readiness(Predicate<? super T> val) {
- this.readiness = checkNotNull(val, "ready");
- return this;
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <V2> Builder<T,V2> postProcess(Closure<V2> val) {
- this.postProcess = (Function) GroovyJavaMethods.<T,V2>functionFromClosure(checkNotNull(val, "postProcess"));
- return (Builder<T,V2>) this;
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <V2> Builder<T,V2> postProcess(final Function<? super T, V2> val) {
- this.postProcess = (Function) checkNotNull(val, "postProcess");
- return (Builder<T,V2>) this;
- }
- public <T2> Builder<T,V> abortIf(Entity source, AttributeSensor<T2> sensor) {
- return abortIf(source, sensor, GroovyJavaMethods.truthPredicate());
- }
- public <T2> Builder<T,V> abortIf(Entity source, AttributeSensor<T2> sensor, Predicate<? super T2> predicate) {
- abortSensorConditions.add(new AttributeAndSensorCondition<T2>(source, sensor, predicate));
- return this;
- }
- public Builder<T,V> abortIfOnFire() {
- abortIf(source, Attributes.SERVICE_STATE_ACTUAL, Predicates.equalTo(Lifecycle.ON_FIRE));
- return this;
- }
- public Builder<T,V> blockingDetails(String val) {
- blockingDetails = val;
- return this;
- }
- /** specifies an optional timeout; by default it waits forever, or until unmanaged or other abort condition */
- public Builder<T,V> timeout(Duration val) {
- timeout = val;
- return this;
- }
- public Builder<T,V> onTimeoutReturn(V val) {
- onTimeout = Maybe.of(val);
- return this;
- }
- public Builder<T,V> onTimeoutThrow() {
- onTimeout = Maybe.<V>absent();
- return this;
- }
- public Builder<T,V> onUnmanagedReturn(V val) {
- onUnmanaged = Maybe.of(val);
- return this;
- }
- public Builder<T,V> onUnmanagedThrow() {
- onUnmanaged = Maybe.<V>absent();
- return this;
- }
- /** @since 0.7.0 included in case old behaviour of not checking whether the entity is managed is required
- * (I can't see why it is; polling will likely give errors, once it is unmanaged this will never completed,
- * and before management the current code will continue, so long as there are no other errors) */ @Deprecated
- public Builder<T,V> onUnmanagedContinue() {
- ignoreUnmanaged = true;
- return this;
- }
- /** take advantage of the fact that this builder can build multiple times, allowing subclasses
- * to change the source along the way */
- protected Builder<T,V> source(Entity source) {
- this.source = source;
- return this;
- }
- /** as {@link #source(Entity)} */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- protected Builder<T,V> sensor(AttributeSensor<? extends T> sensor) {
- this.sensor = (AttributeSensor) sensor;
- return this;
- }
- public Task<V> build() {
- validate();
-
- return Tasks.<V>builder().dynamic(false)
- .name("waiting on "+sensor.getName())
- .description("Waiting on sensor "+sensor.getName()+" from "+source)
- .tag("attributeWhenReady")
- .body(new WaitInTaskForAttributeReady<T,V>(this))
- .build();
- }
-
- public V runNow() {
- validate();
- return new WaitInTaskForAttributeReady<T,V>(this).call();
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private void validate() {
- checkNotNull(source, "Entity source");
- checkNotNull(sensor, "Sensor");
- if (readiness == null) readiness = GroovyJavaMethods.truthPredicate();
- if (postProcess == null) postProcess = (Function) Functions.identity();
- }
- }
-
- /**
- * Builder for producing variants of attributeWhenReady.
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Beta
- public static class MultiBuilder<T, V, V2> {
- protected final String name;
- protected final String descriptionBase;
- protected final Builder<T,V> builder;
- // if desired, the use of this multiSource could allow different conditions;
- // but probably an easier API just for the caller to build the parallel task
- protected final List<AttributeAndSensorCondition<?>> multiSource = Lists.newArrayList();
- protected Function<? super List<V>, V2> postProcessFromMultiple;
-
- /** returns a task for parallel execution returning a list of values of the given sensor list on the given entity,
- * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
- @Beta
- protected MultiBuilder(Iterable<? extends Entity> sources, AttributeSensor<T> sensor) {
- this(sources, sensor, GroovyJavaMethods.truthPredicate());
- }
- @Beta
- protected MultiBuilder(Iterable<? extends Entity> sources, AttributeSensor<T> sensor, Predicate<? super T> readiness) {
- builder = new Builder<T,V>(null, sensor);
- builder.readiness(readiness);
-
- for (Entity s : checkNotNull(sources, "sources")) {
- multiSource.add(new AttributeAndSensorCondition<T>(s, sensor, readiness));
- }
- this.name = "waiting on "+sensor.getName();
- this.descriptionBase = "waiting on "+sensor.getName()+" "+readiness
- +" from "+Iterables.size(sources)+" entit"+Strings.ies(sources);
- }
-
- /** Apply post-processing to the entire list of results */
- public <V2b> MultiBuilder<T, V, V2b> postProcessFromMultiple(final Function<? super List<V>, V2b> val) {
- this.postProcessFromMultiple = (Function) checkNotNull(val, "postProcessFromMulitple");
- return (MultiBuilder<T,V, V2b>) this;
- }
- /** Apply post-processing to the entire list of results
- * See {@link CollectionFunctionals#all(Predicate)} and {@link CollectionFunctionals#quorum(org.apache.brooklyn.util.collections.QuorumCheck, Predicate)
- * which allow useful arguments. */
- public MultiBuilder<T, V, Boolean> postProcessFromMultiple(final Predicate<? super List<V>> val) {
- return postProcessFromMultiple(Functions.forPredicate(val));
- }
-
- public <V1> MultiBuilder<T, V1, V2> postProcess(Closure<V1> val) {
- builder.postProcess(val);
- return (MultiBuilder<T, V1, V2>) this;
- }
- public <V1> MultiBuilder<T, V1, V2> postProcess(final Function<? super T, V1> val) {
- builder.postProcess(val);
- return (MultiBuilder<T, V1, V2>) this;
- }
- public <T2> MultiBuilder<T, V, V2> abortIf(Entity source, AttributeSensor<T2> sensor) {
- builder.abortIf(source, sensor);
- return this;
- }
- public <T2> MultiBuilder<T, V, V2> abortIf(Entity source, AttributeSensor<T2> sensor, Predicate<? super T2> predicate) {
- builder.abortIf(source, sensor, predicate);
- return this;
- }
- public MultiBuilder<T, V, V2> abortIfOnFire() {
- builder.abortIfOnFire();
- return this;
- }
- public MultiBuilder<T, V, V2> blockingDetails(String val) {
- builder.blockingDetails(val);
- return this;
- }
- public MultiBuilder<T, V, V2> timeout(Duration val) {
- builder.timeout(val);
- return this;
- }
- public MultiBuilder<T, V, V2> onTimeoutReturn(V val) {
- builder.onTimeoutReturn(val);
- return this;
- }
- public MultiBuilder<T, V, V2> onTimeoutThrow() {
- builder.onTimeoutThrow();
- return this;
- }
- public MultiBuilder<T, V, V2> onUnmanagedReturn(V val) {
- builder.onUnmanagedReturn(val);
- return this;
- }
- public MultiBuilder<T, V, V2> onUnmanagedThrow() {
- builder.onUnmanagedThrow();
- return this;
- }
-
- public Task<V2> build() {
- List<Task<V>> tasks = MutableList.of();
- for (AttributeAndSensorCondition<?> source: multiSource) {
- builder.source(source.source);
- builder.sensor((AttributeSensor)source.sensor);
- builder.readiness((Predicate)source.predicate);
- tasks.add(builder.build());
- }
- final Task<List<V>> parallelTask = Tasks.<List<V>>builder().parallel(true).addAll(tasks)
- .name(name)
- .description(descriptionBase+
- (builder.timeout!=null ? ", timeout "+builder.timeout : ""))
- .build();
-
- if (postProcessFromMultiple == null) {
- // V2 should be the right type in normal operations
- return (Task<V2>) parallelTask;
- } else {
- return Tasks.<V2>builder().name(name).description(descriptionBase)
- .tag("attributeWhenReady")
- .body(new Callable<V2>() {
- @Override public V2 call() throws Exception {
- List<V> prePostProgress = DynamicTasks.queue(parallelTask).get();
- return DynamicTasks.queue(
- Tasks.<V2>builder().name("post-processing").description("Applying "+postProcessFromMultiple)
- .body(Functionals.callable(postProcessFromMultiple, prePostProgress))
- .build()).get();
- }
- })
- .build();
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
deleted file mode 100644
index 6b9c780..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import java.net.URI;
-
-import net.minidev.json.JSONObject;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.effector.AddSensor;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Functions;
-import com.google.common.base.Supplier;
-
-/**
- * Configurable {@link org.apache.brooklyn.api.entity.EntityInitializer} which adds an HTTP sensor feed to retrieve the
- * {@link JSONObject} from a JSON response in order to populate the sensor with the data at the {@code jsonPath}.
- *
- * @see SshCommandSensor
- * @see JmxAttributeSensor
- */
-@Beta
-public final class HttpRequestSensor<T> extends AddSensor<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(HttpRequestSensor.class);
-
- public static final ConfigKey<String> SENSOR_URI = ConfigKeys.newStringConfigKey("uri", "HTTP URI to poll for JSON");
- public static final ConfigKey<String> JSON_PATH = ConfigKeys.newStringConfigKey("jsonPath", "JSON path to select in HTTP response; default $", "$");
- public static final ConfigKey<String> USERNAME = ConfigKeys.newStringConfigKey("username", "Username for HTTP request, if required");
- public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password", "Password for HTTP request, if required");
-
- protected final Supplier<URI> uri;
- protected final String jsonPath;
- protected final String username;
- protected final String password;
-
- public HttpRequestSensor(final ConfigBag params) {
- super(params);
-
- uri = new Supplier<URI>() {
- @Override
- public URI get() {
- return URI.create(params.get(SENSOR_URI));
- }
- };
- jsonPath = params.get(JSON_PATH);
- username = params.get(USERNAME);
- password = params.get(PASSWORD);
- }
-
- @Override
- public void apply(final EntityLocal entity) {
- super.apply(entity);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Adding HTTP JSON sensor {} to {}", name, entity);
- }
-
- HttpPollConfig<T> pollConfig = new HttpPollConfig<T>(sensor)
- .checkSuccess(HttpValueFunctions.responseCodeEquals(200))
- .onFailureOrException(Functions.constant((T) null))
- .onSuccess(HttpValueFunctions.<T>jsonContentsFromPath(jsonPath))
- .period(period);
-
- HttpFeed.builder().entity(entity)
- .baseUri(uri)
- .credentialsIfNotNull(username, password)
- .poll(pollConfig)
- .build();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
deleted file mode 100644
index e269966..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/PortAttributeSensorAndConfigKey.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineProvisioningLocation;
-import org.apache.brooklyn.api.location.PortRange;
-import org.apache.brooklyn.api.location.PortSupplier;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.core.internal.BrooklynInitialization;
-import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-
-/**
- * A {@link Sensor} describing a port on a system,
- * with a {@link ConfigKey} which can be configured with a port range
- * (either a number e.g. 80, or a string e.g. "80" or "8080-8089" or even "80, 8080-8089, 8800+", or a list of these).
- * <p>
- * To convert at runtime a single port is chosen, respecting the entity.
- */
-public class PortAttributeSensorAndConfigKey extends AttributeSensorAndConfigKey<PortRange,Integer> {
-
- private static final long serialVersionUID = 4680651022807491321L;
-
- public static final Logger LOG = LoggerFactory.getLogger(PortAttributeSensorAndConfigKey.class);
-
- static { BrooklynInitialization.initAll(); }
-
- public PortAttributeSensorAndConfigKey(String name) {
- this(name, name, null);
- }
- public PortAttributeSensorAndConfigKey(String name, String description) {
- this(name, description, null);
- }
- public PortAttributeSensorAndConfigKey(String name, String description, Object defaultValue) {
- super(PortRange.class, Integer.class, name, description, defaultValue);
- }
- public PortAttributeSensorAndConfigKey(PortAttributeSensorAndConfigKey orig, Object defaultValue) {
- super(orig, TypeCoercions.coerce(defaultValue, PortRange.class));
- }
- @Override
- protected Integer convertConfigToSensor(PortRange value, Entity entity) {
- if (value==null) return null;
- Collection<? extends Location> locations = entity.getLocations();
- if (!locations.isEmpty()) {
- Maybe<? extends Location> lo = Locations.findUniqueMachineLocation(locations);
- if (!lo.isPresent()) {
- // Try a unique location which isn't a machine provisioner
- Iterator<? extends Location> li = Iterables.filter(locations,
- Predicates.not(Predicates.instanceOf(MachineProvisioningLocation.class))).iterator();
- if (li.hasNext()) lo = Maybe.of(li.next());
- if (li.hasNext()) lo = Maybe.absent();
- }
- // Fall back to selecting the single location
- if (!lo.isPresent() && locations.size() == 1) {
- lo = Maybe.of(locations.iterator().next());
- }
- if (LOG.isTraceEnabled()) {
- LOG.trace("Convert config to sensor for {} found locations: {}. Selected: {}", new Object[] {entity, locations, lo});
- }
- if (lo.isPresent()) {
- Location l = lo.get();
- Optional<Boolean> locationRunning = Optional.fromNullable(l.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START_IF_RUNNING));
- Optional<Boolean> entityRunning = Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START_IF_RUNNING));
- Optional<Boolean> locationInstalled = Optional.fromNullable(l.getConfig(BrooklynConfigKeys.SKIP_ENTITY_INSTALLATION));
- Optional<Boolean> entityInstalled = Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_INSTALLATION));
- Optional<Boolean> entityStarted = Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START));
- boolean skipCheck = locationRunning.or(entityRunning).or(locationInstalled).or(entityInstalled).or(entityStarted).or(false);
- if (l instanceof PortSupplier) {
- int p = ((PortSupplier) l).obtainPort(value);
- if (p != -1) {
- LOG.debug("{}: choosing port {} for {}", new Object[] { entity, p, getName() });
- return p;
- }
- // If we are not skipping install or already started, fail now
- if (!skipCheck) {
- int rangeSize = Iterables.size(value);
- if (rangeSize == 0) {
- LOG.warn("{}: no port available for {} (empty range {})", new Object[] { entity, getName(), value });
- } else if (rangeSize == 1) {
- Integer pp = value.iterator().next();
- if (pp > 1024) {
- LOG.warn("{}: port {} not available for {}", new Object[] { entity, pp, getName() });
- } else {
- LOG.warn("{}: port {} not available for {} (root may be required?)", new Object[] { entity, pp, getName() });
- }
- } else {
- LOG.warn("{}: no port available for {} (tried range {})", new Object[] { entity, getName(), value });
- }
- return null; // Definitively, no ports available
- }
- }
- // Ports may be available, we just can't tell from the location
- Integer v = (value.isEmpty() ? null : value.iterator().next());
- LOG.debug("{}: choosing port {} (unconfirmed) for {}", new Object[] { entity, v, getName() });
- return v;
- } else {
- LOG.warn("{}: ports not applicable, or not yet applicable, because has multiple locations {}; ignoring ", new Object[] { entity, locations, getName() });
- }
- } else {
- LOG.warn("{}: ports not applicable, or not yet applicable, bacause has no locations; ignoring {}", entity, getName());
- }
- return null;
- }
-
- @Override
- protected Integer convertConfigToSensor(PortRange value, ManagementContext managementContext) {
- LOG.warn("ports not applicable, because given managementContext rather than entity; ignoring {}", getName());
- return null;
- }
-}
[21/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/JsonFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/JsonFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/JsonFunctionsTest.java
deleted file mode 100644
index 41201af..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/JsonFunctionsTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
-import org.apache.brooklyn.util.collections.Jsonya;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.collections.Jsonya.Navigator;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-import com.jayway.jsonpath.PathNotFoundException;
-
-public class JsonFunctionsTest {
-
- public static JsonElement europeMap() {
- Navigator<MutableMap<Object, Object>> europe = Jsonya.newInstance().at("europe", "uk", "edinburgh")
- .put("population", 500*1000)
- .put("weather", "wet", "lighting", "dark")
- .root().at("europe").at("france").put("population", 80*1000*1000)
- .root();
- return new JsonParser().parse( europe.toString() );
- }
-
- @Test
- public void testWalk1() {
- JsonElement pop = JsonFunctions.walk("europe", "france", "population").apply(europeMap());
- Assert.assertEquals( (int)JsonFunctions.cast(Integer.class).apply(pop), 80*1000*1000 );
- }
-
- @Test
- public void testWalk2() {
- String weather = Functionals.chain(
- JsonFunctions.walk("europe.uk.edinburgh.weather"),
- JsonFunctions.cast(String.class) ).apply(europeMap());
- Assert.assertEquals(weather, "wet");
- }
-
- @Test(expectedExceptions=NoSuchElementException.class)
- public void testWalkWrong() {
- Functionals.chain(
- JsonFunctions.walk("europe", "spain", "barcelona"),
- JsonFunctions.cast(String.class) ).apply(europeMap());
- }
-
-
- @Test
- public void testWalkM() {
- Maybe<JsonElement> pop = JsonFunctions.walkM("europe", "france", "population").apply( Maybe.of(europeMap()) );
- Assert.assertEquals( (int)JsonFunctions.castM(Integer.class).apply(pop), 80*1000*1000 );
- }
-
- @Test
- public void testWalkMWrong1() {
- Maybe<JsonElement> m = JsonFunctions.walkM("europe", "spain", "barcelona").apply( Maybe.of( europeMap()) );
- Assert.assertTrue(m.isAbsent());
- }
-
- @Test(expectedExceptions=Exception.class)
- public void testWalkMWrong2() {
- Maybe<JsonElement> m = JsonFunctions.walkM("europe", "spain", "barcelona").apply( Maybe.of( europeMap()) );
- JsonFunctions.castM(String.class).apply(m);
- }
-
-
- @Test
- public void testWalkN() {
- JsonElement pop = JsonFunctions.walkN("europe", "france", "population").apply( europeMap() );
- Assert.assertEquals( (int)JsonFunctions.cast(Integer.class).apply(pop), 80*1000*1000 );
- }
-
- @Test
- public void testWalkNWrong1() {
- JsonElement m = JsonFunctions.walkN("europe", "spain", "barcelona").apply( europeMap() );
- Assert.assertNull(m);
- }
-
- public void testWalkNWrong2() {
- JsonElement m = JsonFunctions.walkN("europe", "spain", "barcelona").apply( europeMap() );
- String n = JsonFunctions.cast(String.class).apply(m);
- Assert.assertNull(n);
- }
-
- @Test
- public void testGetPath1(){
- Integer obj = (Integer) JsonFunctions.getPath("$.europe.uk.edinburgh.population").apply(europeMap());
- Assert.assertEquals((int) obj, 500*1000);
- }
-
- @Test
- public void testGetPath2(){
- String obj = (String) JsonFunctions.getPath("$.europe.uk.edinburgh.lighting").apply(europeMap());
- Assert.assertEquals(obj, "dark");
- }
-
- @Test
- public void testGetMissingPathIsNullOrThrows(){
- try {
- // TODO is there a way to force this to return null if not found?
- // for me (Alex) it throws but for others it seems to return null
- Object obj = JsonFunctions.getPath("$.europe.spain.malaga").apply(europeMap());
- Assert.assertNull(obj);
- } catch (PathNotFoundException e) {
- // not unexpected
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
deleted file mode 100644
index b274cbc..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.shell;
-
-import static org.testng.Assert.assertTrue;
-
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeedTest;
-import org.apache.brooklyn.sensor.feed.shell.ShellFeed;
-import org.apache.brooklyn.sensor.feed.shell.ShellFeedIntegrationTest;
-import org.apache.brooklyn.sensor.feed.shell.ShellPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
-import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.stream.Streams;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class ShellFeedIntegrationTest extends BrooklynAppUnitTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(ShellFeedIntegrationTest.class);
-
- final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
- final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("anInt", "");
- final static AttributeSensor<Long> SENSOR_LONG = Sensors.newLongSensor("aLong", "");
-
- private LocalhostMachineProvisioningLocation loc;
- private EntityLocal entity;
- private ShellFeed feed;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- loc = new LocalhostMachineProvisioningLocation();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (feed != null) feed.stop();
- super.tearDown();
- if (loc != null) Streams.closeQuietly(loc);
- }
-
- @Test(groups="Integration")
- public void testReturnsShellExitStatus() throws Exception {
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<Integer>(SENSOR_INT)
- .command("exit 123")
- .onFailure(SshValueFunctions.exitStatus()))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 123);
- }
-
- @Test(groups="Integration")
- public void testFeedDeDupe() throws Exception {
- testReturnsShellExitStatus();
- entity.addFeed(feed);
- log.info("Feed 0 is: "+feed);
-
- testReturnsShellExitStatus();
- log.info("Feed 1 is: "+feed);
- entity.addFeed(feed);
-
- FeedSupport feeds = ((EntityInternal)entity).feeds();
- Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
- }
-
- // TODO timeout no longer supported; would be nice to have a generic task-timeout feature,
- // now that the underlying impl uses SystemProcessTaskFactory
- @Test(enabled=false, groups={"Integration", "WIP"})
- public void testShellTimesOut() throws Exception {
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<String>(SENSOR_STRING)
- .command("sleep 10")
- .timeout(1, TimeUnit.MILLISECONDS)
- .onException(new FunctionFeedTest.ToStringFunction()))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains("timed out after 1ms"), "val=" + val);
- }});
- }
-
- @Test(groups="Integration")
- public void testShellUsesEnv() throws Exception {
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<String>(SENSOR_STRING)
- .env(ImmutableMap.of("MYENV", "MYVAL"))
- .command("echo hello $MYENV")
- .onSuccess(SshValueFunctions.stdout()))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains("hello MYVAL"), "val="+val);
- }});
- }
-
- @Test(groups="Integration")
- public void testReturnsShellStdout() throws Exception {
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<String>(SENSOR_STRING)
- .command("echo hello")
- .onSuccess(SshValueFunctions.stdout()))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains("hello"), "val="+val);
- }});
- }
-
- @Test(groups="Integration")
- public void testReturnsShellStderr() throws Exception {
- final String cmd = "thiscommanddoesnotexist";
-
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<String>(SENSOR_STRING)
- .command(cmd)
- .onFailure(SshValueFunctions.stderr()))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains(cmd), "val="+val);
- }});
- }
-
- @Test(groups="Integration")
- public void testFailsOnNonZero() throws Exception {
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<String>(SENSOR_STRING)
- .command("exit 123")
- .onSuccess(new Function<SshPollValue, String>() {
- @Override
- public String apply(SshPollValue input) {
- return "Exit status (on success) " + input.getExitStatus();
- }})
- .onFailure(new Function<SshPollValue, String>() {
- @Override
- public String apply(SshPollValue input) {
- return "Exit status (on failure) " + input.getExitStatus();
- }}))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains("Exit status (on failure) 123"), "val="+val);
- }});
- }
-
- // Example in ShellFeed javadoc
- @Test(groups="Integration")
- public void testDiskUsage() throws Exception {
- feed = ShellFeed.builder()
- .entity(entity)
- .poll(new ShellPollConfig<Long>(SENSOR_LONG)
- .command("df -P | tail -1")
- .onSuccess(new Function<SshPollValue, Long>() {
- public Long apply(SshPollValue input) {
- String[] parts = input.getStdout().split("[ \\t]+");
- System.out.println("input="+input+"; parts="+Arrays.toString(parts));
- return Long.parseLong(parts[2]);
- }}))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- Long val = entity.getAttribute(SENSOR_LONG);
- assertTrue(val != null && val >= 0, "val="+val);
- }});
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
deleted file mode 100644
index de9d5f1..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.ssh;
-
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.api.entity.EntityInitializer;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeedIntegrationTest;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
-import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.text.StringFunctions;
-import org.apache.brooklyn.util.text.StringPredicates;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-
-public class SshFeedIntegrationTest extends BrooklynAppUnitTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(SshFeedIntegrationTest.class);
-
- final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
- final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
-
- private LocalhostMachineProvisioningLocation loc;
- private SshMachineLocation machine;
- private EntityLocal entity;
- private SshFeed feed;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- loc = app.newLocalhostProvisioningLocation();
- machine = loc.obtain();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (feed != null) feed.stop();
- super.tearDown();
- if (loc != null) Streams.closeQuietly(loc);
- }
-
- /** this is one of the most common pattern */
- @Test(groups="Integration")
- public void testReturnsSshStdoutAndInfersMachine() throws Exception {
- final TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)
- // inject the machine location, because the app was started with a provisioning location
- // and TestEntity doesn't provision
- .location(machine));
-
- feed = SshFeed.builder()
- .entity(entity2)
- .poll(new SshPollConfig<String>(SENSOR_STRING)
- .command("echo hello")
- .onSuccess(SshValueFunctions.stdout()))
- .build();
-
- EntityTestUtils.assertAttributeEventuallyNonNull(entity2, SENSOR_STRING);
- String val = entity2.getAttribute(SENSOR_STRING);
- Assert.assertTrue(val.contains("hello"), "val="+val);
- Assert.assertEquals(val.trim(), "hello");
- }
-
- @Test(groups="Integration")
- public void testFeedDeDupe() throws Exception {
- testReturnsSshStdoutAndInfersMachine();
- entity.addFeed(feed);
- log.info("Feed 0 is: "+feed);
-
- testReturnsSshStdoutAndInfersMachine();
- log.info("Feed 1 is: "+feed);
- entity.addFeed(feed);
-
- FeedSupport feeds = ((EntityInternal)entity).feeds();
- Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
- }
-
- @Test(groups="Integration")
- public void testReturnsSshExitStatus() throws Exception {
- feed = SshFeed.builder()
- .entity(entity)
- .machine(machine)
- .poll(new SshPollConfig<Integer>(SENSOR_INT)
- .command("exit 123")
- .checkSuccess(Predicates.alwaysTrue())
- .onSuccess(SshValueFunctions.exitStatus()))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 123);
- }
-
- @Test(groups="Integration")
- public void testReturnsSshStdout() throws Exception {
- feed = SshFeed.builder()
- .entity(entity)
- .machine(machine)
- .poll(new SshPollConfig<String>(SENSOR_STRING)
- .command("echo hello")
- .onSuccess(SshValueFunctions.stdout()))
- .build();
-
- EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING,
- Predicates.compose(Predicates.equalTo("hello"), StringFunctions.trim()));
- }
-
- @Test(groups="Integration")
- public void testReturnsSshStderr() throws Exception {
- final String cmd = "thiscommanddoesnotexist";
-
- feed = SshFeed.builder()
- .entity(entity)
- .machine(machine)
- .poll(new SshPollConfig<String>(SENSOR_STRING)
- .command(cmd)
- .onFailure(SshValueFunctions.stderr()))
- .build();
-
- EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, StringPredicates.containsLiteral(cmd));
- }
-
- @Test(groups="Integration")
- public void testFailsOnNonZero() throws Exception {
- feed = SshFeed.builder()
- .entity(entity)
- .machine(machine)
- .poll(new SshPollConfig<String>(SENSOR_STRING)
- .command("exit 123")
- .onFailure(new Function<SshPollValue, String>() {
- @Override
- public String apply(SshPollValue input) {
- return "Exit status " + input.getExitStatus();
- }}))
- .build();
-
- EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, StringPredicates.containsLiteral("Exit status 123"));
- }
-
- @Test(groups="Integration")
- public void testAddedEarly() throws Exception {
- final TestEntity entity2 = app.addChild(EntitySpec.create(TestEntity.class)
- .location(machine)
- .addInitializer(new EntityInitializer() {
- @Override
- public void apply(EntityLocal entity) {
- SshFeed.builder()
- .entity(entity)
- .onlyIfServiceUp()
- .poll(new SshPollConfig<String>(SENSOR_STRING)
- .command("echo hello")
- .onSuccess(SshValueFunctions.stdout()))
- .build();
- }
- }));
- Time.sleep(Duration.seconds(2));
- // would be nice to hook in and assert no errors
- Assert.assertEquals(entity2.getAttribute(SENSOR_STRING), null);
- Entities.manage(entity2);
- Time.sleep(Duration.seconds(2));
- Assert.assertEquals(entity2.getAttribute(SENSOR_STRING), null);
- entity2.setAttribute(Attributes.SERVICE_UP, true);
-
- EntityTestUtils.assertAttributeEventually(entity2, SENSOR_STRING, StringPredicates.containsLiteral("hello"));
- }
-
-
- @Test(groups="Integration")
- public void testDynamicEnvAndCommandSupplier() throws Exception {
- final TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
-
- final AtomicInteger count = new AtomicInteger();
- Supplier<Map<String, String>> envSupplier = new Supplier<Map<String,String>>() {
- @Override
- public Map<String, String> get() {
- return MutableMap.of("COUNT", ""+count.incrementAndGet());
- }
- };
- Supplier<String> cmdSupplier = new Supplier<String>() {
- @Override
- public String get() {
- return "echo count-"+count.incrementAndGet()+"-$COUNT";
- }
- };
-
- feed = SshFeed.builder()
- .entity(entity2)
- .poll(new SshPollConfig<String>(SENSOR_STRING)
- .env(envSupplier)
- .command(cmdSupplier)
- .onSuccess(SshValueFunctions.stdout()))
- .build();
-
- EntityTestUtils.assertAttributeEventuallyNonNull(entity2, SENSOR_STRING);
- final String val1 = assertDifferentOneInOutput(entity2);
-
- EntityTestUtils.assertAttributeEventually(entity2, SENSOR_STRING, Predicates.not(Predicates.equalTo(val1)));
- final String val2 = assertDifferentOneInOutput(entity2);
- log.info("vals from dynamic sensors are: "+val1.trim()+" and "+val2.trim());
- }
-
- private String assertDifferentOneInOutput(final TestEntity entity2) {
- String val = entity2.getAttribute(SENSOR_STRING);
- Assert.assertTrue(val.startsWith("count"), "val="+val);
- try {
- String[] fields = val.trim().split("-");
- int field1 = Integer.parseInt(fields[1]);
- int field2 = Integer.parseInt(fields[2]);
- Assert.assertEquals(Math.abs(field2-field1), 1, "expected difference of 1");
- } catch (Throwable t) {
- Exceptions.propagateIfFatal(t);
- Assert.fail("Wrong output from sensor, got '"+val.trim()+"', giving error: "+t);
- }
- return val;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
deleted file mode 100644
index 42a25c0..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.windows;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.api.location.MachineProvisioningLocation;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * WindowsPerformanceCounterFeed Live Test.
- * <p>
- * This test is currently disabled. To run, you must configure a location named {@code WindowsLiveTest}
- * or adapt the {@link #LOCATION_SPEC} below.
- * <p>
- * The location must provide Windows nodes that are running an SSH server on port 22. The login credentials must
- * be either be auto-detectable or configured in brooklyn.properties in the usual fashion.
- * <p>
- * Here is an example configuration from brooklyn.properties for a pre-configured Windows VM
- * running an SSH server with public key authentication:
- * <pre>
- * {@code brooklyn.location.named.WindowsLiveTest=byon:(hosts="ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com")
- * brooklyn.location.named.WindowsLiveTest.user=Administrator
- * brooklyn.location.named.WindowsLiveTest.privateKeyFile = ~/.ssh/id_rsa
- * brooklyn.location.named.WindowsLiveTest.publicKeyFile = ~/.ssh/id_rsa.pub
- * }</pre>
- * The location must by {@code byon} or another primitive type. Unfortunately, it's not possible to
- * use a jclouds location, as adding a dependency on brooklyn-locations-jclouds would cause a
- * cyclic dependency.
- */
-public class WindowsPerformanceCounterFeedLiveTest extends BrooklynAppLiveTestSupport {
-
- final static AttributeSensor<Double> CPU_IDLE_TIME = Sensors.newDoubleSensor("cpu.idleTime", "");
- final static AttributeSensor<Integer> TELEPHONE_LINES = Sensors.newIntegerSensor("telephone.lines", "");
-
- private static final String LOCATION_SPEC = "named:WindowsLiveTest";
-
- private Location loc;
- private EntityLocal entity;
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- super.setUp();
-
- Map<String,?> allFlags = MutableMap.<String,Object>builder()
- .put("tags", ImmutableList.of(getClass().getName()))
- .build();
- MachineProvisioningLocation<? extends MachineLocation> provisioningLocation =
- (MachineProvisioningLocation<? extends MachineLocation>)
- mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
- loc = provisioningLocation.obtain(ImmutableMap.of());
-
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @Test(groups={"Live","Disabled"}, enabled=false)
- public void testRetrievesPerformanceCounters() throws Exception {
- // We can be pretty sure that a Windows instance in the cloud will have zero telephone lines...
- entity.setAttribute(TELEPHONE_LINES, 42);
- WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
- .entity(entity)
- .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
- .addSensor("\\Telephony\\Lines", TELEPHONE_LINES)
- .build();
- try {
- EntityTestUtils.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
- } finally {
- feed.stop();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
deleted file mode 100644
index 9a27e8e..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.windows;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
-import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterPollConfig;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class WindowsPerformanceCounterFeedTest extends BrooklynAppUnitTestSupport {
-
- private Location loc;
- private EntityLocal entity;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- loc = new LocalhostMachineProvisioningLocation();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeedTest.class);
-
- @Test
- public void testIteratorWithSingleValue() {
- Iterator<?> iterator = new WindowsPerformanceCounterFeed
- .PerfCounterValueIterator("\"10/14/2013 15:28:24.406\",\"0.000000\"");
- assertTrue(iterator.hasNext());
- assertEquals(iterator.next(), "0.000000");
- assertFalse(iterator.hasNext());
- }
-
- @Test
- public void testIteratorWithMultipleValues() {
- Iterator<?> iterator = new WindowsPerformanceCounterFeed
- .PerfCounterValueIterator("\"10/14/2013 15:35:50.582\",\"8803.000000\",\"405622.000000\"");
- assertTrue(iterator.hasNext());
- assertEquals(iterator.next(), "8803.000000");
- assertTrue(iterator.hasNext());
- assertEquals(iterator.next(), "405622.000000");
- assertFalse(iterator.hasNext());
- }
-
- @Test
- public void testSendPerfCountersToSensors() {
- AttributeSensor<String> stringSensor = Sensors.newStringSensor("foo.bar");
- AttributeSensor<Integer> integerSensor = Sensors.newIntegerSensor("bar.baz");
- AttributeSensor<Double> doubleSensor = Sensors.newDoubleSensor("baz.quux");
-
- Collection<WindowsPerformanceCounterPollConfig<?>> polls = ImmutableSet.<WindowsPerformanceCounterPollConfig<?>>of(
- new WindowsPerformanceCounterPollConfig(stringSensor).performanceCounterName("\\processor information(_total)\\% processor time"),
- new WindowsPerformanceCounterPollConfig(integerSensor).performanceCounterName("\\integer.sensor"),
- new WindowsPerformanceCounterPollConfig(doubleSensor).performanceCounterName("\\double\\sensor\\with\\multiple\\sub\\paths")
- );
-
- WindowsPerformanceCounterFeed.SendPerfCountersToSensors sendPerfCountersToSensors = new WindowsPerformanceCounterFeed.SendPerfCountersToSensors(entity, polls);
-
- assertNull(entity.getAttribute(stringSensor));
-
- StringBuilder responseBuilder = new StringBuilder();
- // NOTE: This builds the response in a different order to which they are passed to the SendPerfCountersToSensors constructor
- // this tests that the values are applied correctly even if the (possibly non-deterministic) order in which
- // they are returned by the Get-Counter scriptlet is different
- addMockResponse(responseBuilder, "\\\\machine.name\\double\\sensor\\with\\multiple\\sub\\paths", "3.1415926");
- addMockResponse(responseBuilder, "\\\\win-lge7uj2blau\\processor information(_total)\\% processor time", "99.9");
- addMockResponse(responseBuilder, "\\\\machine.name\\integer.sensor", "15");
-
- sendPerfCountersToSensors.onSuccess(new WinRmToolResponse(responseBuilder.toString(), "", 0));
-
- EntityTestUtils.assertAttributeEquals(entity, stringSensor, "99.9");
- EntityTestUtils.assertAttributeEquals(entity, integerSensor, 15);
- EntityTestUtils.assertAttributeEquals(entity, doubleSensor, 3.1415926);
- }
-
- private void addMockResponse(StringBuilder responseBuilder, String path, String value) {
- responseBuilder.append(path);
- responseBuilder.append(Strings.repeat(" ", 200 - (path.length() + value.length())));
- responseBuilder.append(value);
- responseBuilder.append("\r\n");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
index 8c8f8f7..c5d7415 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
@@ -36,10 +36,10 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.AtomicReferences;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
index ffa8bd6..7cd3bd4 100644
--- a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
@@ -36,10 +36,10 @@ import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.collections.MutableMap;
import com.google.common.base.Objects.ToStringHelper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
index 23cfb2c..07417a5 100644
--- a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
@@ -33,10 +33,10 @@ import org.apache.brooklyn.entity.database.Schema;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index 0070b39..da93a1e 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -39,10 +39,10 @@ import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.stock.EffectorStartableImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
import org.apache.brooklyn.util.ssh.BashCommands;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMasterImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMasterImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMasterImpl.java
index 8c2a3af..40e38c5 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMasterImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMasterImpl.java
@@ -20,9 +20,8 @@ package org.apache.brooklyn.entity.salt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
public class SaltStackMasterImpl extends SoftwareProcessImpl implements SaltStackMaster {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
index 587a152..ef26e8c 100644
--- a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
+++ b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
@@ -37,13 +37,13 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityFunctions;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.PollHandler;
+import org.apache.brooklyn.core.feed.Poller;
import org.apache.brooklyn.core.location.SupportsPortForwarding;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.PollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.core.http.HttpTool;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
import org.apache.brooklyn.util.net.Cidr;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
index 978261c..388994b 100644
--- a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
+++ b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
@@ -21,9 +21,9 @@ package org.apache.brooklyn.entity.monitoring.zabbix;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
+import org.apache.brooklyn.core.feed.PollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
index b4f0f6d..9476673 100644
--- a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
+++ b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
@@ -28,10 +28,10 @@ import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicGroup;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeImpl.java b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeImpl.java
index 6ee1729..d618f0c 100644
--- a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeImpl.java
+++ b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNodeImpl.java
@@ -26,9 +26,9 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.text.Strings;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
index 0d66ba3..bbe5bf2 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
@@ -30,9 +30,9 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceProble
import org.apache.brooklyn.entity.brooklynnode.effector.BrooklynClusterUpgradeEffectorBody;
import org.apache.brooklyn.entity.brooklynnode.effector.SelectMasterEffectorBody;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
index 91622dd..538c170 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
@@ -33,8 +33,8 @@ import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index c1dd4ed..02f5965 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -41,6 +41,7 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
@@ -51,15 +52,14 @@ import org.apache.brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPrior
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwareParameters.StopMode;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
index ca938e9..17baf37 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/SetHighAvailabilityModeEffectorBody.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.SetHighAvailabilityModeEffector;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
import org.apache.brooklyn.util.guava.Functionals;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributeFeed.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributeFeed.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributeFeed.java
index 42dcc1c..1078d90 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributeFeed.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributeFeed.java
@@ -34,10 +34,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.PollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.PollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributePollConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributePollConfig.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributePollConfig.java
index c6e1c6b..badc7e4 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributePollConfig.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefAttributePollConfig.java
@@ -19,7 +19,7 @@
package org.apache.brooklyn.entity.chef;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
+import org.apache.brooklyn.core.feed.PollConfig;
import com.google.common.base.Function;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaAppUtils.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaAppUtils.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaAppUtils.java
index c7a743c..9656878 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaAppUtils.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaAppUtils.java
@@ -32,11 +32,11 @@ import javax.management.openmbean.CompositeData;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher;
import org.apache.brooklyn.policy.enricher.TimeFractionDeltaEnricher;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.apache.brooklyn.util.math.MathFunctions;
import org.apache.brooklyn.util.text.ByteSizeStrings;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
index 64ef6ac..ae80754 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
@@ -30,9 +30,9 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.AddSensor;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.sensor.HttpRequestSensor;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.sensor.ssh.SshCommandSensor;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxSupport.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxSupport.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxSupport.java
index 62fa577..f633f3c 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxSupport.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxSupport.java
@@ -31,10 +31,10 @@ import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.BrooklynMavenArtifacts;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaAppImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaAppImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaAppImpl.java
index a81de86..90da4a9 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaAppImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaAppImpl.java
@@ -25,7 +25,7 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
index 72d7bef..58c64fd 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
@@ -28,10 +28,10 @@ import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
index a64999c..e381c79 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.entity.software.base.lifecycle.NaiveScriptRunner;
import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
@@ -49,7 +50,6 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
index f2dc269..b67780b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
@@ -51,12 +51,12 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle.Transition;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.location.LocationConfigKeys;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
index 24614af..bd6f477 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
@@ -51,6 +51,7 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.entity.trait.StartableMethods;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.Machines;
@@ -76,7 +77,6 @@ import com.google.common.collect.Iterables;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxAttributePollConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxAttributePollConfig.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxAttributePollConfig.java
new file mode 100644
index 0000000..ae19f45
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxAttributePollConfig.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.PollConfig;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+
+public class JmxAttributePollConfig<T> extends PollConfig<Object, T, JmxAttributePollConfig<T>>{
+
+ private ObjectName objectName;
+ private String attributeName;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public JmxAttributePollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ onSuccess((Function)Functions.identity());
+ }
+
+ public JmxAttributePollConfig(JmxAttributePollConfig<T> other) {
+ super(other);
+ this.objectName = other.objectName;
+ this.attributeName = other.attributeName;
+ }
+
+ public ObjectName getObjectName() {
+ return objectName;
+ }
+
+ public String getAttributeName() {
+ return attributeName;
+ }
+
+ public JmxAttributePollConfig<T> objectName(ObjectName val) {
+ this.objectName = val; return this;
+ }
+
+ public JmxAttributePollConfig<T> objectName(String val) {
+ try {
+ return objectName(new ObjectName(val));
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException("Invalid object name ("+val+")", e);
+ }
+ }
+
+ public JmxAttributePollConfig<T> attributeName(String val) {
+ this.attributeName = val; return this;
+ }
+
+ @Override protected String toStringBaseName() { return "jmx"; }
+ @Override protected String toStringPollSource() { return objectName+":"+attributeName; }
+
+}
[30/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java
new file mode 100644
index 0000000..dbc84ed
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherTest.java
@@ -0,0 +1,556 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.entity.group.BasicGroup;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class CustomAggregatingEnricherTest extends BrooklynAppUnitTestSupport {
+
+ public static final Logger log = LoggerFactory.getLogger(CustomAggregatingEnricherTest.class);
+
+ private static final long TIMEOUT_MS = 10*1000;
+ private static final long SHORT_WAIT_MS = 50;
+
+ TestEntity entity;
+ SimulatedLocation loc;
+
+ AttributeSensor<Integer> intSensor;
+ AttributeSensor<Double> doubleSensor;
+ AttributeSensor<Integer> target;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor");
+ doubleSensor = new BasicAttributeSensor<Double>(Double.class, "double sensor");
+ target = new BasicAttributeSensor<Integer>(Integer.class, "target sensor");
+ loc = mgmt.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @Test
+ public void testSummingEnricherWithNoProducersDefaultsToNull() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromChildren()
+ .build());
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
+ }
+
+ @Test
+ public void testSummingEnricherWithNoProducers() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromChildren()
+ .defaultValueForUnreportedSensors(11)
+ .valueToReportIfNoSensors(40)
+ .build());
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 40);
+ }
+
+ @Test
+ public void testSummingEnricherWhenNoSensorValuesYet() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(entity))
+ .defaultValueForUnreportedSensors(11)
+ .valueToReportIfNoSensors(40)
+ .build());
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 11);
+ }
+
+ @Test
+ public void testSummingEnricherWhenNoSensorValuesYetDefaultsToNull() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(entity))
+ .build());
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
+ }
+
+ @Test
+ public void testSummingEnricherWithNoValues() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(entity))
+ .build());
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
+ }
+
+ @Test
+ public void testSummingEnricherWithOneValue() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(entity))
+ .build());
+
+ entity.setAttribute(intSensor, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+ }
+
+ @Test
+ public void testSummingEnricherWhenNullSensorValue() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(entity))
+ .build());
+
+ entity.setAttribute(intSensor, null);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
+ }
+
+ @Test
+ public void testSummingEnricherWhenDefaultValueForUnreportedSensors() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(entity))
+ .defaultValueForUnreportedSensors(3)
+ .valueToReportIfNoSensors(5)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
+
+ entity.setAttribute(intSensor, null);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, 3);
+
+ entity.setAttribute(intSensor, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+
+ entity.setAttribute(intSensor, 7);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 7);
+ }
+
+ @Test
+ public void testMultipleProducersSum() {
+ TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3))
+ .build());
+
+ producer3.setAttribute(intSensor, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+
+ producer1.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
+
+ producer2.setAttribute(intSensor, 4);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 7);
+ }
+
+ @Test
+ public void testAveragingEnricherWhenNoAndNullSensorValues() {
+ TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(doubleSensor)
+ .computingAverage()
+ .fromHardcodedProducers(ImmutableList.of(producer1))
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
+
+ producer1.setAttribute(intSensor, null);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
+ }
+
+ @Test
+ public void testAveragingEnricherWhenDefaultValueForUnreportedSensors() {
+ TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(doubleSensor)
+ .computingAverage()
+ .fromHardcodedProducers(ImmutableList.of(producer1))
+ .defaultValueForUnreportedSensors(3)
+ .valueToReportIfNoSensors(5)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
+
+ producer1.setAttribute(intSensor, null);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, 3d);
+
+ producer1.setAttribute(intSensor, 4);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 4d);
+ }
+
+ @Test
+ public void testAveragingEnricherWhenNoSensors() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(doubleSensor)
+ .computingAverage()
+ .fromChildren()
+ .defaultValueForUnreportedSensors(3)
+ .valueToReportIfNoSensors(5)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 5d);
+ }
+
+ @Test
+ public void testAveragingEnricherWhenNoProducersDefaultsToNull() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(doubleSensor)
+ .computingAverage()
+ .fromChildren()
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
+ }
+
+ @Test
+ public void testMultipleProducersAverage() {
+ TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(doubleSensor)
+ .computingAverage()
+ .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3))
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
+
+ producer1.setAttribute(intSensor, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
+
+ producer2.setAttribute(intSensor, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 2d);
+
+ producer3.setAttribute(intSensor, 5);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
+
+ producer2.setAttribute(intSensor, 4);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 4d);
+ }
+
+ @Test
+ public void testMultipleProducersAverageDefaultingZero() {
+ TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(doubleSensor)
+ .computingAverage()
+ .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3))
+ .defaultValueForUnreportedSensors(0)
+ .valueToReportIfNoSensors(0)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 0d);
+
+ producer1.setAttribute(intSensor, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 1d);
+
+ producer2.setAttribute(intSensor, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 2d);
+
+ producer3.setAttribute(intSensor, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
+ }
+
+ @Test
+ public void testAggregatesNewMembersOfGroup() {
+ BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ log.debug("created {} and the entities it will contain {} {}", new Object[] {group, p1, p2});
+
+ group.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromMembers()
+ .defaultValueForUnreportedSensors(0)
+ .valueToReportIfNoSensors(0)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 0);
+
+ group.addMember(p1);
+ p1.setAttribute(intSensor, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
+
+ group.addMember(p2);
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 3);
+
+ group.removeMember(p2);
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
+ }
+
+ @Test(groups = "Integration", invocationCount=50)
+ public void testAggregatesGroupMembersFiftyTimes() {
+ testAggregatesNewMembersOfGroup();
+ }
+
+ @Test
+ public void testAggregatesExistingMembersOfGroup() {
+ BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
+ TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
+ group.addMember(p1);
+ group.addMember(p2);
+ p1.setAttribute(intSensor, 1);
+ Entities.manage(group);
+
+ group.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromMembers()
+ .build());
+
+
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
+
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 3);
+
+ group.removeMember(p2);
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
+ }
+
+ @Test
+ public void testAggregatesMembersOfProducer() {
+ BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
+ TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
+ group.addMember(p1);
+ group.addMember(p2);
+ p1.setAttribute(intSensor, 1);
+ Entities.manage(group);
+
+ app.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .from(group)
+ .fromMembers()
+ .build());
+
+
+ EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
+
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(app, target, 3);
+
+ group.removeMember(p2);
+ EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
+ }
+
+ @Test
+ public void testAppliesFilterWhenAggregatingMembersOfGroup() {
+ BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ group.addMember(p1);
+ group.addMember(p2);
+ p1.setAttribute(intSensor, 1);
+ p2.setAttribute(intSensor, 2);
+ p3.setAttribute(intSensor, 4);
+
+ group.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromMembers()
+ .entityFilter(Predicates.equalTo((Entity)p1))
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
+
+ group.addMember(p3);
+ EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), group, target, 1);
+ }
+
+ @Test
+ public void testAggregatesNewChidren() {
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromChildren()
+ .defaultValueForUnreportedSensors(0)
+ .valueToReportIfNoSensors(0)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 0);
+
+ TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ p1.setAttribute(intSensor, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+
+ TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
+
+ Entities.unmanage(p2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+ }
+
+ @Test
+ public void testAggregatesExistingChildren() {
+ TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ p1.setAttribute(intSensor, 1);
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromChildren()
+ .build());
+
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
+
+ Entities.unmanage(p2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+ }
+
+ @Test
+ public void testAggregatesChildrenOfProducer() {
+ TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ p1.setAttribute(intSensor, 1);
+
+ app.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .from(entity)
+ .fromChildren()
+ .build());
+
+
+ EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
+
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(app, target, 3);
+
+ Entities.unmanage(p2);
+ EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
+ }
+
+ @Test
+ public void testAppliesFilterWhenAggregatingChildrenOfGroup() {
+ TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ p1.setAttribute(intSensor, 1);
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computingSum()
+ .fromChildren()
+ .entityFilter(Predicates.equalTo((Entity)p1))
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+
+ TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
+ p2.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), entity, target, 1);
+ }
+
+ @Test
+ public void testCustomAggregatingFunction() {
+ TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ Function<Collection<Integer>,Integer> aggregator = new Function<Collection<Integer>, Integer>() {
+ public Integer apply(Collection<Integer> input) {
+ int result = 1;
+ for (Integer in : input) result += in*in;
+ return result;
+ }
+ };
+
+ entity.addEnricher(Enrichers.builder()
+ .aggregating(intSensor)
+ .publishing(target)
+ .computing(aggregator)
+ .fromHardcodedProducers(ImmutableList.of(producer1))
+ .defaultValueForUnreportedSensors(0)
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
+
+ // Event by producer
+ producer1.setAttribute(intSensor, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, target, 5);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java
new file mode 100644
index 0000000..e5c48fa
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/EnrichersTest.java
@@ -0,0 +1,501 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityAdjuncts;
+import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.entity.group.BasicGroup;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.text.StringFunctions;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+@SuppressWarnings("serial")
+public class EnrichersTest extends BrooklynAppUnitTestSupport {
+
+ public static final AttributeSensor<Integer> NUM1 = Sensors.newIntegerSensor("test.num1");
+ public static final AttributeSensor<Integer> NUM2 = Sensors.newIntegerSensor("test.num2");
+ public static final AttributeSensor<Integer> NUM3 = Sensors.newIntegerSensor("test.num3");
+ public static final AttributeSensor<String> STR1 = Sensors.newStringSensor("test.str1");
+ public static final AttributeSensor<String> STR2 = Sensors.newStringSensor("test.str2");
+ public static final AttributeSensor<Set<Object>> SET1 = Sensors.newSensor(new TypeToken<Set<Object>>() {}, "test.set1", "set1 descr");
+ public static final AttributeSensor<Long> LONG1 = Sensors.newLongSensor("test.long1");
+ public static final AttributeSensor<Map<String,String>> MAP1 = Sensors.newSensor(new TypeToken<Map<String,String>>() {}, "test.map1", "map1 descr");
+ @SuppressWarnings("rawtypes")
+ public static final AttributeSensor<Map> MAP2 = Sensors.newSensor(Map.class, "test.map2");
+
+ private TestEntity entity;
+ private TestEntity entity2;
+ private BasicGroup group;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testAdding() {
+ Enricher enr = entity.addEnricher(Enrichers.builder()
+ .combining(NUM1, NUM2)
+ .publishing(NUM3)
+ .computingSum()
+ .build());
+
+ Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(entity), ImmutableList.of(enr));
+
+ entity.setAttribute(NUM1, 2);
+ entity.setAttribute(NUM2, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 5);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testCombiningWithCustomFunction() {
+ entity.addEnricher(Enrichers.builder()
+ .combining(NUM1, NUM2)
+ .publishing(NUM3)
+ .computing(Functions.constant(1))
+ .build());
+
+ entity.setAttribute(NUM1, 2);
+ entity.setAttribute(NUM2, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test(groups="Integration") // because takes a second
+ public void testCombiningRespectsUnchanged() {
+ entity.addEnricher(Enrichers.builder()
+ .combining(NUM1, NUM2)
+ .<Object>publishing(NUM3)
+ .computing(new Function<Iterable<Integer>, Object>() {
+ @Override public Object apply(Iterable<Integer> input) {
+ if (input != null && Iterables.contains(input, 123)) {
+ return Enrichers.sum(input, 0, 0, new TypeToken<Integer>(){});
+ } else {
+ return Entities.UNCHANGED;
+ }
+ }})
+ .build());
+
+ entity.setAttribute(NUM1, 123);
+ entity.setAttribute(NUM2, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 126);
+
+ entity.setAttribute(NUM1, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(entity, NUM3, 126);
+ }
+
+ @Test
+ public void testFromEntity() {
+ entity.addEnricher(Enrichers.builder()
+ .transforming(NUM1)
+ .publishing(NUM1)
+ .computing(Functions.<Integer>identity())
+ .from(entity2)
+ .build());
+
+ entity2.setAttribute(NUM1, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, NUM1, 2);
+ }
+
+ @Test
+ public void testTransforming() {
+ entity.addEnricher(Enrichers.builder()
+ .transforming(STR1)
+ .publishing(STR2)
+ .computing(StringFunctions.append("mysuffix"))
+ .build());
+
+ entity.setAttribute(STR1, "myval");
+ EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myvalmysuffix");
+ }
+
+ @Test
+ public void testTransformingCastsResult() {
+ entity.addEnricher(Enrichers.builder()
+ .transforming(NUM1)
+ .publishing(LONG1)
+ .computing(Functions.constant(Long.valueOf(1)))
+ .build());
+
+ entity.setAttribute(NUM1, 123);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, LONG1, Long.valueOf(1));
+ }
+
+ @Test
+ public void testTransformingFromEvent() {
+ entity.addEnricher(Enrichers.builder()
+ .transforming(STR1)
+ .publishing(STR2)
+ .computingFromEvent(new Function<SensorEvent<String>, String>() {
+ @Override public String apply(SensorEvent<String> input) {
+ return input.getValue() + "mysuffix";
+ }})
+ .build());
+
+ entity.setAttribute(STR1, "myval");
+ EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myvalmysuffix");
+ }
+
+ @Test(groups="Integration") // because takes a second
+ public void testTransformingRespectsUnchangedButWillRepublish() {
+ RecordingSensorEventListener<String> record = new RecordingSensorEventListener<>();
+ app.getManagementContext().getSubscriptionManager().subscribe(entity, STR2, record);
+
+ entity.addEnricher(Enrichers.builder()
+ .transforming(STR1)
+ .<Object>publishing(STR2)
+ .computing(new Function<String, Object>() {
+ @Override public Object apply(String input) {
+ return ("ignoredval".equals(input)) ? Entities.UNCHANGED : input;
+ }})
+ .build());
+ Asserts.assertThat(record.getEvents(), CollectionFunctionals.sizeEquals(0));
+
+ entity.setAttribute(STR1, "myval");
+ Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(1));
+ EntityTestUtils.assertAttributeEquals(entity, STR2, "myval");
+
+ entity.setAttribute(STR1, "ignoredval");
+ EntityTestUtils.assertAttributeEqualsContinually(entity, STR2, "myval");
+
+ entity.setAttribute(STR1, "myval2");
+ Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(2));
+ EntityTestUtils.assertAttributeEquals(entity, STR2, "myval2");
+
+ entity.setAttribute(STR1, "myval2");
+ entity.setAttribute(STR1, "myval2");
+ entity.setAttribute(STR1, "myval3");
+ Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(5));
+ }
+
+ public void testTransformingSuppressDuplicates() {
+ RecordingSensorEventListener<String> record = new RecordingSensorEventListener<>();
+ app.getManagementContext().getSubscriptionManager().subscribe(entity, STR2, record);
+
+ entity.addEnricher(Enrichers.builder()
+ .transforming(STR1)
+ .publishing(STR2)
+ .computing(Functions.<String>identity())
+ .suppressDuplicates(true)
+ .build());
+
+ entity.setAttribute(STR1, "myval");
+ Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(1));
+ EntityTestUtils.assertAttributeEquals(entity, STR2, "myval");
+
+ entity.setAttribute(STR1, "myval2");
+ entity.setAttribute(STR1, "myval2");
+ entity.setAttribute(STR1, "myval3");
+ EntityTestUtils.assertAttributeEqualsContinually(entity, STR2, "myval3");
+ Asserts.assertThat(record.getEvents(), CollectionFunctionals.sizeEquals(3));
+ }
+
+ @Test
+ public void testPropagating() {
+ entity.addEnricher(Enrichers.builder()
+ .propagating(ImmutableList.of(STR1))
+ .from(entity2)
+ .build());
+
+ entity2.setAttribute(STR1, "myval");
+ EntityTestUtils.assertAttributeEqualsEventually(entity, STR1, "myval");
+
+ entity2.setAttribute(STR1, null);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, STR1, null);
+ }
+
+ @Test
+ public void testPropagatingAndRenaming() {
+ entity.addEnricher(Enrichers.builder()
+ .propagating(ImmutableMap.of(STR1, STR2))
+ .from(entity2)
+ .build());
+
+ entity2.setAttribute(STR1, "myval");
+ EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myval");
+ }
+
+ // FIXME What is default? members? children? fail?
+ @Test
+ public void testAggregatingGroupSum() {
+ TestEntity child1 = group.addChild(EntitySpec.create(TestEntity.class));
+ Entities.manage(child1);
+ group.addMember(entity);
+ group.addMember(entity2);
+ group.addEnricher(Enrichers.builder()
+ .aggregating(NUM1)
+ .publishing(NUM2)
+ .fromMembers()
+ .computingSum()
+ .build());
+
+ child1.setAttribute(NUM1, 1);
+ entity.setAttribute(NUM1, 2);
+ entity2.setAttribute(NUM1, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(group, NUM2, 5);
+ }
+
+ @Test
+ public void testAggregatingChildrenSum() {
+ group.addMember(entity);
+ TestEntity child1 = group.addChild(EntitySpec.create(TestEntity.class));
+ Entities.manage(child1);
+ TestEntity child2 = group.addChild(EntitySpec.create(TestEntity.class));
+ Entities.manage(child2);
+ group.addEnricher(Enrichers.builder()
+ .aggregating(NUM1)
+ .publishing(NUM2)
+ .fromChildren()
+ .computingSum()
+ .build());
+
+ entity.setAttribute(NUM1, 1);
+ child1.setAttribute(NUM1, 2);
+ child2.setAttribute(NUM1, 3);
+ EntityTestUtils.assertAttributeEqualsEventually(group, NUM2, 5);
+ }
+
+ @Test
+ public void testAggregatingExcludingBlankString() {
+ group.addMember(entity);
+ group.addMember(entity2);
+ group.addEnricher(Enrichers.builder()
+ .aggregating(STR1)
+ .publishing(SET1)
+ .fromMembers()
+ .excludingBlank()
+ .computing(new Function<Collection<?>, Set<Object>>() {
+ @Override public Set<Object> apply(Collection<?> input) {
+ // accept null values, so don't use ImmutableSet
+ return (input == null) ? ImmutableSet.<Object>of() : MutableSet.<Object>copyOf(input);
+ }})
+ .build());
+
+ entity.setAttribute(STR1, "1");
+ entity2.setAttribute(STR1, "2");
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("1", "2"));
+
+ entity.setAttribute(STR1, "3");
+ entity2.setAttribute(STR1, null);
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("3"));
+
+ entity.setAttribute(STR1, "");
+ entity2.setAttribute(STR1, "4");
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("4"));
+ }
+
+ @Test
+ public void testAggregatingExcludingNull() {
+ group.addMember(entity);
+ group.addEnricher(Enrichers.builder()
+ .aggregating(NUM1)
+ .publishing(SET1)
+ .fromMembers()
+ .excludingBlank()
+ .computing(new Function<Collection<?>, Set<Object>>() {
+ @Override public Set<Object> apply(Collection<?> input) {
+ // accept null values, so don't use ImmutableSet
+ return (input == null) ? ImmutableSet.<Object>of() : MutableSet.<Object>copyOf(input);
+ }})
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of());
+
+ entity.setAttribute(NUM1, 1);
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of(1));
+
+ entity.setAttribute(NUM1, null);
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of());
+
+ entity.setAttribute(NUM1, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of(2));
+ }
+
+ @Test
+ public void testAggregatingCastsResult() {
+ group.addMember(entity);
+ group.addEnricher(Enrichers.builder()
+ .aggregating(NUM1)
+ .publishing(LONG1)
+ .fromMembers()
+ .computing(Functions.constant(Long.valueOf(1)))
+ .build());
+
+ entity.setAttribute(NUM1, 123);
+ EntityTestUtils.assertAttributeEqualsEventually(group, LONG1, Long.valueOf(1));
+ }
+
+ @Test(groups="Integration") // because takes a second
+ public void testAggregatingRespectsUnchanged() {
+ group.addMember(entity);
+ group.addEnricher(Enrichers.builder()
+ .aggregating(NUM1)
+ .<Object>publishing(LONG1)
+ .fromMembers()
+ .computing(new Function<Iterable<Integer>, Object>() {
+ @Override public Object apply(Iterable<Integer> input) {
+ if (input != null && Iterables.contains(input, 123)) {
+ return Enrichers.sum(input, 0, 0, new TypeToken<Integer>(){});
+ } else {
+ return Entities.UNCHANGED;
+ }
+ }})
+ .build());
+
+ entity.setAttribute(NUM1, 123);
+ EntityTestUtils.assertAttributeEqualsEventually(group, LONG1, Long.valueOf(123));
+
+ entity.setAttribute(NUM1, 987654);
+ EntityTestUtils.assertAttributeEqualsContinually(group, LONG1, Long.valueOf(123));
+ }
+ @Test
+ public void testUpdatingMap1() {
+ entity.addEnricher(Enrichers.builder()
+ .updatingMap(MAP1)
+ .from(LONG1)
+ .computing(Functionals.ifEquals(-1L).value("-1 is not allowed"))
+ .build());
+
+ doUpdatingMapChecks(MAP1);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Test
+ public void testUpdatingMap2() {
+ entity.addEnricher(Enrichers.builder()
+ .updatingMap((AttributeSensor)MAP2)
+ .from(LONG1)
+ .computing(Functionals.ifEquals(-1L).value("-1 is not allowed"))
+ .build());
+
+ doUpdatingMapChecks(MAP2);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected void doUpdatingMapChecks(AttributeSensor mapSensor) {
+ EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of());
+
+ entity.setAttribute(LONG1, -1L);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of(
+ LONG1.getName(), "-1 is not allowed"));
+
+ entity.setAttribute(LONG1, 1L);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of());
+ }
+
+ private static AttributeSensor<Object> LIST_SENSOR = Sensors.newSensor(Object.class, "sensor.list");
+
+ @Test
+ public void testJoinerDefault() {
+ entity.addEnricher(Enrichers.builder()
+ .joining(LIST_SENSOR)
+ .publishing(TestEntity.NAME)
+ .build());
+ // null values ignored, and it quotes
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "\"b").append(null));
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "\"a\",\"\\\"b\"");
+
+ // empty list causes ""
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of().append(null));
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "");
+
+ // null causes null
+ entity.setAttribute(LIST_SENSOR, null);
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null);
+ }
+
+ @Test
+ public void testJoinerUnquoted() {
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "\"b", "ccc").append(null));
+ entity.addEnricher(Enrichers.builder()
+ .joining(LIST_SENSOR)
+ .publishing(TestEntity.NAME)
+ .minimum(1)
+ .maximum(2)
+ .separator(":")
+ .quote(false)
+ .build());
+ // in this case, it should be immediately available upon adding the enricher
+ EntityTestUtils.assertAttributeEquals(entity, TestEntity.NAME, "a:\"b");
+
+ // empty list causes null here, because below the minimum
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of().append(null));
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null);
+ }
+
+ @Test
+ public void testJoinerMinMax() {
+ entity.addEnricher(Enrichers.builder()
+ .joining(LIST_SENSOR)
+ .publishing(TestEntity.NAME)
+ .minimum(2)
+ .maximum(4)
+ .quote(false)
+ .build());
+ // null values ignored, and it quotes
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "b"));
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "a,b");
+
+ // empty list causes ""
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of("x"));
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null);
+
+ // null causes null
+ entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "b", "c", "d", "e"));
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "a,b,c,d");
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java
new file mode 100644
index 0000000..a52e2ee
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherDeprecatedTest.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.SensorPropagatingEnricher;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.javalang.AtomicReferences;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+
+public class SensorPropagatingEnricherDeprecatedTest extends BrooklynAppUnitTestSupport {
+
+ private TestEntity entity;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ }
+
+ @Test
+ public void testPropagatesSpecificSensor() {
+ app.addEnricher(SensorPropagatingEnricher.newInstanceListeningTo(entity, TestEntity.NAME));
+
+ // name propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+
+ // sequence not propagated
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
+ }
+
+ @Test
+ public void testPropagatesAllSensors() {
+ app.addEnricher(SensorPropagatingEnricher.newInstanceListeningToAllSensors(entity));
+
+ // all attributes propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2);
+
+ // notification-sensor propagated
+ final AtomicReference<Integer> notif = new AtomicReference<Integer>();
+ app.subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() {
+ @Override public void onEvent(SensorEvent<Integer> event) {
+ notif.set(event.getValue());
+ }});
+ entity.emit(TestEntity.MY_NOTIF, 7);
+ Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7));
+ }
+
+ @Test
+ public void testPropagatesAllBut() {
+ app.addEnricher(SensorPropagatingEnricher.newInstanceListeningToAllSensorsBut(entity, TestEntity.SEQUENCE)) ;
+
+ // name propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+
+ // sequence not propagated
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
+ }
+
+ @Test
+ public void testPropagatingAsDifferentSensor() {
+ final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", "");
+ app.addEnricher(SensorPropagatingEnricher.newInstanceRenaming(entity, ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE)));
+
+ // name propagated as different attribute
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java
new file mode 100644
index 0000000..c660df1
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricherTest.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.enricher.stock.Propagator;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.javalang.AtomicReferences;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class SensorPropagatingEnricherTest extends BrooklynAppUnitTestSupport {
+
+ private TestEntity entity;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ }
+
+ @Test
+ public void testPropagatesSpecificSensor() {
+ app.addEnricher(Enrichers.builder()
+ .propagating(TestEntity.NAME)
+ .from(entity)
+ .build());
+
+ // name propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+
+ // sequence not propagated
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
+ }
+
+ @Test
+ public void testPropagatesCurrentValue() {
+ entity.setAttribute(TestEntity.NAME, "foo");
+
+ app.addEnricher(Enrichers.builder()
+ .propagating(TestEntity.NAME)
+ .from(entity)
+ .build());
+
+ // name propagated
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+ }
+
+ @Test
+ public void testPropagatesAllStaticSensors() {
+ app.addEnricher(Enrichers.builder()
+ .propagatingAll()
+ .from(entity)
+ .build());
+
+ // all attributes propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2);
+
+ // notification-sensor propagated
+ final AtomicReference<Integer> notif = new AtomicReference<Integer>();
+ app.subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() {
+ @Override public void onEvent(SensorEvent<Integer> event) {
+ notif.set(event.getValue());
+ }});
+ entity.emit(TestEntity.MY_NOTIF, 7);
+ Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7));
+ }
+
+ @Test
+ public void testPropagatesAllSensorsIncludesDynamicallyAdded() {
+ AttributeSensor<String> dynamicAttribute = Sensors.newStringSensor("test.dynamicsensor.strattrib");
+ BasicNotificationSensor<String> dynamicNotificationSensor = new BasicNotificationSensor(String.class, "test.dynamicsensor.strnotif");
+
+ app.addEnricher(Enrichers.builder()
+ .propagatingAll()
+ .from(entity)
+ .build());
+
+ entity.setAttribute(dynamicAttribute, "foo");
+
+ EntityTestUtils.assertAttributeEqualsEventually(app, dynamicAttribute, "foo");
+
+ // notification-sensor propagated
+ final AtomicReference<String> notif = new AtomicReference<String>();
+ app.subscribe(app, dynamicNotificationSensor, new SensorEventListener<String>() {
+ @Override public void onEvent(SensorEvent<String> event) {
+ notif.set(event.getValue());
+ }});
+ entity.emit(dynamicNotificationSensor, "mynotifval");
+ Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo("mynotifval"));
+ }
+
+ @Test
+ public void testPropagatesAllBut() {
+ app.addEnricher(Enrichers.builder()
+ .propagatingAllBut(TestEntity.SEQUENCE)
+ .from(entity)
+ .build());
+
+ // name propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+
+ // sequence not propagated
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
+ }
+
+ @Test
+ public void testPropagatingAsDifferentSensor() {
+ final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", "");
+
+ app.addEnricher(Enrichers.builder()
+ .propagating(ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE))
+ .from(entity)
+ .build());
+
+ // name propagated as different attribute
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo");
+ }
+
+ @Test
+ public void testEnricherSpecPropagatesSpecificSensor() throws Exception {
+ app.addEnricher(EnricherSpec.create(Propagator.class)
+ .configure(MutableMap.builder()
+ .putIfNotNull(Propagator.PRODUCER, entity)
+ .putIfNotNull(Propagator.PROPAGATING, ImmutableList.of(TestEntity.NAME))
+ .build()));
+
+ // name propagated
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
+
+ // sequence not propagated
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
+ }
+
+ @Test
+ public void testEnricherSpecPropagatesSpecificSensorAndMapsOthers() throws Exception {
+ final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", "");
+
+ app.addEnricher(EnricherSpec.create(Propagator.class)
+ .configure(MutableMap.builder()
+ .putIfNotNull(Propagator.PRODUCER, entity)
+ .putIfNotNull(Propagator.SENSOR_MAPPING, ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE))
+ .putIfNotNull(Propagator.PROPAGATING, ImmutableList.of(TestEntity.SEQUENCE))
+ .build()));
+
+ // name propagated as alternative sensor
+ entity.setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo");
+
+ // sequence also propagated
+ entity.setAttribute(TestEntity.SEQUENCE, 2);
+ EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2);
+
+ // name not propagated as original sensor
+ EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.NAME, null);
+ }
+
+ @Test
+ public void testEnricherSpecThrowsOnPropagatesAndPropagatesAllSet() throws Exception {
+ try {
+ app.addEnricher(EnricherSpec.create(Propagator.class)
+ .configure(MutableMap.builder()
+ .put(Propagator.PRODUCER, entity)
+ .put(Propagator.PROPAGATING, ImmutableList.of(TestEntity.NAME))
+ .put(Propagator.PROPAGATING_ALL, true)
+ .build()));
+ } catch (Exception e) {
+ IllegalStateException ise = Exceptions.getFirstThrowableOfType(e, IllegalStateException.class);
+ if (ise == null) throw e;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy
new file mode 100644
index 0000000..d1f264d
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherDeprecatedTest.groovy
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock
+
+import java.util.concurrent.Callable
+
+import org.apache.brooklyn.api.entity.EntitySpec
+import org.apache.brooklyn.api.sensor.AttributeSensor
+import org.apache.brooklyn.core.test.entity.TestApplication
+import org.apache.brooklyn.core.test.entity.TestEntity
+import org.apache.brooklyn.enricher.stock.SensorTransformingEnricher;
+import org.apache.brooklyn.core.entity.Entities
+import org.apache.brooklyn.core.location.SimulatedLocation
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
+import org.apache.brooklyn.test.TestUtils
+import org.apache.brooklyn.util.collections.MutableMap
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.Assert
+import org.testng.annotations.AfterMethod
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+public class TransformingEnricherDeprecatedTest {
+
+ public static final Logger log = LoggerFactory.getLogger(TransformingEnricherDeprecatedTest.class);
+
+ private static final long TIMEOUT_MS = 10*1000;
+// private static final long SHORT_WAIT_MS = 250;
+
+ TestApplication app;
+ TestEntity producer;
+ AttributeSensor<Integer> intSensorA;
+ AttributeSensor<Long> target;
+
+ @BeforeMethod()
+ public void before() {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a");
+ target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target");
+
+ app.start(Arrays.asList(new SimulatedLocation()));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void after() {
+ if (app!=null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test
+ public void testTransformingEnricher() throws InterruptedException {
+ final SensorTransformingEnricher e1 = new SensorTransformingEnricher<Integer,Long>(intSensorA, target,
+ { 2*it });
+
+ producer.setAttribute(intSensorA, 3);
+ //ensure previous values get picked up
+ producer.addEnricher(e1);
+
+ TestUtils.assertEventually(MutableMap.of("timeout", TIMEOUT_MS),
+ new Callable<Object>() { public Object call() {
+ Assert.assertEquals(producer.getAttribute(target), (Long)((long)6));
+ return null;
+ }});
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
new file mode 100644
index 0000000..ee8fc9e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/TransformingEnricherTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.math.MathFunctions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+
+public class TransformingEnricherTest extends BrooklynAppUnitTestSupport {
+
+ public static final Logger log = LoggerFactory.getLogger(TransformingEnricherTest.class);
+
+ TestEntity producer;
+ AttributeSensor<Integer> intSensorA;
+ AttributeSensor<Long> target;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a");
+ target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target");
+
+ app.start(ImmutableList.of(new SimulatedLocation()));
+ }
+
+ @Test
+ public void testTransformingEnricher() throws Exception {
+ //ensure previous values get picked up
+ producer.setAttribute(intSensorA, 3);
+
+ producer.addEnricher(Enrichers.builder()
+ .transforming(intSensorA)
+ //.computing(MathFunctions.times(2)) // TODO calling it before "publishing" means it doesn't check return type!
+ .publishing(target)
+ .computing((Function)MathFunctions.times(2)) // TODO doesn't match strongly typed int->long
+ .build());
+
+ EntityTestUtils.assertAttributeEqualsEventually(producer, target, 6L);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java
new file mode 100644
index 0000000..af683ac
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricherTest.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.SubscriptionContext;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.core.entity.AbstractApplication;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher;
+import org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher;
+import org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher.ConfidenceQualifiedNumber;
+import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class YamlRollingTimeWindowMeanEnricherTest {
+
+ AbstractApplication app;
+
+ BasicEntity producer;
+
+ AttributeSensor<Integer> intSensor;
+ AttributeSensor<Double> avgSensor, deltaSensor;
+
+ Duration timePeriod = Duration.ONE_SECOND;
+
+ YamlTimeWeightedDeltaEnricher<Double> delta;
+ YamlRollingTimeWindowMeanEnricher<Double> averager;
+
+ ConfidenceQualifiedNumber average;
+ SubscriptionContext subscription;
+
+ @SuppressWarnings("unchecked")
+ @BeforeMethod
+ public void before() {
+ app = new AbstractApplication() {};
+ Entities.startManagement(app);
+ producer = app.addChild(EntitySpec.create(BasicEntity.class));
+
+ intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor");
+ deltaSensor = new BasicAttributeSensor<Double>(Double.class, "delta sensor");
+ avgSensor = new BasicAttributeSensor<Double>(Double.class, "avg sensor");
+
+ delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class)
+ .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer)
+ .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor)
+ .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor));
+
+ averager = producer.addEnricher(EnricherSpec.create(YamlRollingTimeWindowMeanEnricher.class)
+ .configure(YamlRollingTimeWindowMeanEnricher.PRODUCER, producer)
+ .configure(YamlRollingTimeWindowMeanEnricher.SOURCE_SENSOR, deltaSensor)
+ .configure(YamlRollingTimeWindowMeanEnricher.TARGET_SENSOR, avgSensor)
+ .configure(YamlRollingTimeWindowMeanEnricher.WINDOW_DURATION, timePeriod));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test
+ public void testDefaultAverageWhenEmpty() {
+ ConfidenceQualifiedNumber average = averager.getAverage(0, 0);
+ assertEquals(average.value, 0d);
+ assertEquals(average.confidence, 0.0d);
+ }
+
+ protected BasicSensorEvent<Integer> newIntSensorEvent(int value, long timestamp) {
+ return new BasicSensorEvent<Integer>(intSensor, producer, value, timestamp);
+ }
+ protected BasicSensorEvent<Double> newDeltaSensorEvent(double value, long timestamp) {
+ return new BasicSensorEvent<Double>(deltaSensor, producer, value, timestamp);
+ }
+
+ @Test
+ public void testNoRecentValuesAverage() {
+ averager.onEvent(newDeltaSensorEvent(10, 0));
+ average = averager.getAverage(timePeriod.toMilliseconds()+1000, 0);
+ assertEquals(average.value, 10d);
+ assertEquals(average.confidence, 0d);
+ }
+
+ @Test
+ public void testNoRecentValuesUsesLastForAverage() {
+ averager.onEvent(newDeltaSensorEvent(10, 0));
+ averager.onEvent(newDeltaSensorEvent(20, 10));
+ average = averager.getAverage(timePeriod.toMilliseconds()+1000, 0);
+ assertEquals(average.value, 20d);
+ assertEquals(average.confidence, 0d);
+ }
+
+ @Test
+ public void testSingleValueTimeAverage() {
+ averager.onEvent(newDeltaSensorEvent(10, 1000));
+ average = averager.getAverage(1000, 0);
+ assertEquals(average.confidence, 0d);
+ }
+
+ @Test
+ public void testTwoValueAverageForPeriod() {
+ averager.onEvent(newDeltaSensorEvent(10, 1000));
+ averager.onEvent(newDeltaSensorEvent(10, 2000));
+ average = averager.getAverage(2000, 0);
+ assertEquals(average.value, 10 /1d);
+ assertEquals(average.confidence, 1d);
+ }
+
+ @Test
+ public void testMonospacedAverage() {
+ averager.onEvent(newDeltaSensorEvent(10, 1000));
+ averager.onEvent(newDeltaSensorEvent(20, 1250));
+ averager.onEvent(newDeltaSensorEvent(30, 1500));
+ averager.onEvent(newDeltaSensorEvent(40, 1750));
+ averager.onEvent(newDeltaSensorEvent(50, 2000));
+ average = averager.getAverage(2000, 0);
+ assertEquals(average.value, (20+30+40+50)/4d);
+ assertEquals(average.confidence, 1d);
+ }
+
+ @Test
+ public void testWeightedAverage() {
+ averager.onEvent(newDeltaSensorEvent(10, 1000));
+ averager.onEvent(newDeltaSensorEvent(20, 1100));
+ averager.onEvent(newDeltaSensorEvent(30, 1300));
+ averager.onEvent(newDeltaSensorEvent(40, 1600));
+ averager.onEvent(newDeltaSensorEvent(50, 2000));
+
+ average = averager.getAverage(2000, 0);
+ assertEquals(average.value, (20*0.1d)+(30*0.2d)+(40*0.3d)+(50*0.4d));
+ assertEquals(average.confidence, 1d);
+ }
+
+ @Test
+ public void testConfidenceDecay() {
+ averager.onEvent(newDeltaSensorEvent(10, 1000));
+ averager.onEvent(newDeltaSensorEvent(20, 1250));
+ averager.onEvent(newDeltaSensorEvent(30, 1500));
+ averager.onEvent(newDeltaSensorEvent(40, 1750));
+ averager.onEvent(newDeltaSensorEvent(50, 2000));
+
+ average = averager.getAverage(2250, 0);
+ assertEquals(average.value, (30+40+50)/3d);
+ assertEquals(average.confidence, 0.75d);
+ average = averager.getAverage(2500, 0);
+ assertEquals(average.value, (40+50)/2d);
+ assertEquals(average.confidence, 0.5d);
+ average = averager.getAverage(2750, 0);
+ assertEquals(average.value, 50d);
+ assertEquals(average.confidence, 0.25d);
+ average = averager.getAverage(3000, 0);
+ assertEquals(average.value, 50d);
+ assertEquals(average.confidence, 0d);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java
new file mode 100644
index 0000000..41b75a7
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricherTest.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.SubscriptionContext;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.core.entity.AbstractApplication;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher;
+import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class YamlTimeWeightedDeltaEnricherTest {
+
+ AbstractApplication app;
+
+ BasicEntity producer;
+
+ AttributeSensor<Integer> intSensor;
+ AttributeSensor<Double> avgSensor, deltaSensor;
+ SubscriptionContext subscription;
+
+ @BeforeMethod
+ public void before() {
+ app = new AbstractApplication() {};
+ Entities.startManagement(app);
+ producer = app.addChild(EntitySpec.create(BasicEntity.class));
+
+ intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor");
+ deltaSensor = new BasicAttributeSensor<Double>(Double.class, "delta sensor");
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test
+ public void testMonospaceTimeWeightedDeltaEnricher() {
+ @SuppressWarnings("unchecked")
+ YamlTimeWeightedDeltaEnricher<Integer> delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class)
+ .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer)
+ .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor)
+ .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor));
+
+ delta.onEvent(newIntSensorEvent(0, 0));
+ assertEquals(producer.getAttribute(deltaSensor), null);
+ delta.onEvent(newIntSensorEvent(0, 1000));
+ assertEquals(producer.getAttribute(deltaSensor), 0d);
+ delta.onEvent(newIntSensorEvent(1, 2000));
+ assertEquals(producer.getAttribute(deltaSensor), 1d);
+ delta.onEvent(newIntSensorEvent(3, 3000));
+ assertEquals(producer.getAttribute(deltaSensor), 2d);
+ delta.onEvent(newIntSensorEvent(8, 4000));
+ assertEquals(producer.getAttribute(deltaSensor), 5d);
+ }
+
+ protected BasicSensorEvent<Integer> newIntSensorEvent(int value, long timestamp) {
+ return new BasicSensorEvent<Integer>(intSensor, producer, value, timestamp);
+ }
+
+ @Test
+ public void testVariableTimeWeightedDeltaEnricher() {
+ @SuppressWarnings("unchecked")
+ YamlTimeWeightedDeltaEnricher<Integer> delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class)
+ .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer)
+ .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor)
+ .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor));
+
+ delta.onEvent(newIntSensorEvent(0, 0));
+ delta.onEvent(newIntSensorEvent(0, 2000));
+ assertEquals(producer.getAttribute(deltaSensor), 0d);
+ delta.onEvent(newIntSensorEvent(3, 5000));
+ assertEquals(producer.getAttribute(deltaSensor), 1d);
+ delta.onEvent(newIntSensorEvent(7, 7000));
+ assertEquals(producer.getAttribute(deltaSensor), 2d);
+ delta.onEvent(newIntSensorEvent(12, 7500));
+ assertEquals(producer.getAttribute(deltaSensor), 10d);
+ delta.onEvent(newIntSensorEvent(15, 9500));
+ assertEquals(producer.getAttribute(deltaSensor), 1.5d);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java
deleted file mode 100644
index 04c183f..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/BasicEnricherTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.Enricher;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestApplicationNoEnrichersImpl;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.Iterables;
-
-/**
- * Test that enricher can be created and accessed, by construction and by spec
- */
-public class BasicEnricherTest extends BrooklynAppUnitTestSupport {
-
- // TODO These tests are a copy of BasicPolicyTest, which is a code smell.
- // However, the src/main/java code does not contain as much duplication.
-
- protected void setUpApp() {
- EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class, TestApplicationNoEnrichersImpl.class)
- .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution());
- app = ApplicationBuilder.newManagedApp(appSpec, mgmt);
- }
-
- public static class MyEnricher extends AbstractEnricher {
- @SetFromFlag("intKey")
- public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key");
-
- @SetFromFlag("strKey")
- public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key");
- public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1);
- public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default");
-
- MyEnricher(Map<?,?> flags) {
- super(flags);
- }
-
- public MyEnricher() {
- super();
- }
- }
-
- @Test
- public void testAddInstance() throws Exception {
- MyEnricher enricher = new MyEnricher();
- enricher.setDisplayName("Bob");
- enricher.config().set(MyEnricher.STR_KEY, "aval");
- enricher.config().set(MyEnricher.INT_KEY, 2);
- app.addEnricher(enricher);
-
- assertEquals(enricher.getDisplayName(), "Bob");
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- }
-
- @Test
- public void testAddSpec() throws Exception {
- MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class)
- .displayName("Bob")
- .configure(MyEnricher.STR_KEY, "aval").configure(MyEnricher.INT_KEY, 2));
-
- assertEquals(enricher.getDisplayName(), "Bob");
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- }
-
- @Test
- public void testTagsFromSpec() throws Exception {
- MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x"));
-
- assertEquals(enricher.tags().getTags(), MutableSet.of("x", 99));
- assertEquals(enricher.getUniqueTag(), "x");
- }
-
- @Test
- public void testSameUniqueTagEnricherNotAddedTwice() throws Exception {
- app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x"));
- app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(94).uniqueTag("x"));
-
- assertEquals(app.getEnrichers().size(), 1);
- // the more recent one should dominate
- Enricher enricher = Iterables.getOnlyElement(app.getEnrichers());
- Assert.assertTrue(enricher.tags().containsTag(94));
- Assert.assertFalse(enricher.tags().containsTag(99));
- }
-
-}
[12/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
index 9e322fb..475490b 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
@@ -28,10 +28,10 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.HttpService;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
index 14d9ce1..f04c855 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
@@ -33,9 +33,9 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityFunctions;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.FeedConfig;
import org.apache.brooklyn.sensor.feed.PollConfig;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
index 9406e8a..b274cbc 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/shell/ShellFeedIntegrationTest.java
@@ -28,9 +28,9 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.function.FunctionFeedTest;
import org.apache.brooklyn.sensor.feed.shell.ShellFeed;
import org.apache.brooklyn.sensor.feed.shell.ShellFeedIntegrationTest;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
index d26334f..de9d5f1 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/ssh/SshFeedIntegrationTest.java
@@ -29,9 +29,9 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshFeedIntegrationTest;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
index 0ec3d51..42a25c0 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.MachineProvisioningLocation;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
index f8baf7f..9a27e8e 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -30,9 +30,9 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterPollConfig;
import org.apache.brooklyn.test.EntityTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/util/core/task/TasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/task/TasksTest.java b/core/src/test/java/org/apache/brooklyn/util/core/task/TasksTest.java
index 844fd72..4d1e6e1 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/task/TasksTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/task/TasksTest.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.util.core.task;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/util/core/text/TemplateProcessorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/text/TemplateProcessorTest.java b/core/src/test/java/org/apache/brooklyn/util/core/text/TemplateProcessorTest.java
index 217659b..52535da 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/text/TemplateProcessorTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/text/TemplateProcessorTest.java
@@ -22,10 +22,10 @@ import static org.testng.Assert.assertEquals;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.test.FixedLocaleTest;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
import org.testng.Assert;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
----------------------------------------------------------------------
diff --git a/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
index c83d1d0..99faf04 100644
--- a/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
+++ b/examples/global-web-fabric/src/main/java/org/apache/brooklyn/demo/GlobalWebFabricExample.java
@@ -35,13 +35,13 @@ import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.dns.geoscaling.GeoscalingDnsService;
import org.apache.brooklyn.entity.group.DynamicRegionsFabric;
import org.apache.brooklyn.entity.proxy.AbstractController;
import org.apache.brooklyn.entity.webapp.ElasticJavaWebAppService;
import org.apache.brooklyn.entity.webapp.JavaWebAppService;
import org.apache.brooklyn.launcher.BrooklynLauncher;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.CommandLineUtil;
import org.apache.brooklyn.util.core.BrooklynMavenArtifacts;
import org.apache.brooklyn.util.core.ResourceUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index bc3671f..4c0b87e 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -47,6 +47,7 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
@@ -58,7 +59,6 @@ import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.ha.ServiceFailureDetector;
import org.apache.brooklyn.policy.ha.ServiceReplacer;
import org.apache.brooklyn.policy.ha.ServiceRestarter;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.CommandLineUtil;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
index 5ce062a..086f390 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/NodeJsTodoApplication.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.demo;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.EntitySpec;
@@ -26,10 +26,10 @@ import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.nosql.redis.RedisStore;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.nodejs.NodeJsWebAppService;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
index da1074e..6c56b5f 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
@@ -18,9 +18,9 @@
*/
package org.apache.brooklyn.demo;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.formatString;
import static org.apache.brooklyn.entity.java.JavaEntityMethods.javaSysProp;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.formatString;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -42,7 +43,6 @@ import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
index cff372c..ed8a987 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
@@ -18,8 +18,8 @@
*/
package org.apache.brooklyn.demo;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.formatString;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.formatString;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -36,6 +36,7 @@ import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -47,7 +48,6 @@ import org.apache.brooklyn.entity.java.JavaEntityMethods;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
import org.apache.brooklyn.util.core.BrooklynMavenArtifacts;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
index 8ec01e4..0f852c2 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleGroovy.groovy
@@ -19,8 +19,8 @@
package org.apache.brooklyn.demo;
import static org.apache.brooklyn.entity.java.JavaEntityMethods.javaSysProp
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.formatString
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.formatString
import org.apache.brooklyn.api.entity.EntitySpec
import org.apache.brooklyn.core.entity.AbstractApplication
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/locations/jclouds/src/main/java/org/apache/brooklyn/policy/jclouds/os/CreateUserPolicy.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/policy/jclouds/os/CreateUserPolicy.java b/locations/jclouds/src/main/java/org/apache/brooklyn/policy/jclouds/os/CreateUserPolicy.java
index 4b7e9c5..292a28a 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/policy/jclouds/os/CreateUserPolicy.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/policy/jclouds/os/CreateUserPolicy.java
@@ -31,8 +31,8 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.text.Identifiers;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicy.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicy.java b/policy/src/main/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicy.java
index 0956573..274aa9a 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicy.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicy.java
@@ -47,9 +47,9 @@ import org.apache.brooklyn.core.entity.trait.Resizable;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.policy.autoscaling.SizeHistory.WindowSummary;
import org.apache.brooklyn.policy.loadbalancing.LoadBalancingPolicy;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
index cd23326..8c8f8f7 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
@@ -35,7 +35,7 @@ import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/followthesun/FollowTheSunPool.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/followthesun/FollowTheSunPool.java b/policy/src/main/java/org/apache/brooklyn/policy/followthesun/FollowTheSunPool.java
index 39c1202..a5e6a1e 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/followthesun/FollowTheSunPool.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/followthesun/FollowTheSunPool.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.core.entity.trait.Resizable;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
@ImplementedBy(FollowTheSunPoolImpl.class)
public interface FollowTheSunPool extends Entity, Resizable {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/ha/ConnectionFailureDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/ConnectionFailureDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/ConnectionFailureDetector.java
index 86b2027..a844e00 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/ConnectionFailureDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/ConnectionFailureDetector.java
@@ -23,8 +23,8 @@ import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.policy.ha.HASensors.FailureDescriptor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.net.Networking;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/ha/HASensors.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/HASensors.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/HASensors.java
index 02824fc..6ba1a08 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/HASensors.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/HASensors.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.policy.ha;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import com.google.common.base.Objects;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceFailureDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceFailureDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceFailureDetector.java
index ce6eb86..195886d 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceFailureDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceFailureDetector.java
@@ -32,10 +32,10 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ComputeServiceState;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.policy.ha.HASensors.FailureDescriptor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceReplacer.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceReplacer.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceReplacer.java
index 5e036e1..5d66b85 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceReplacer.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceReplacer.java
@@ -43,9 +43,9 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceProblemsLogic;
import org.apache.brooklyn.core.entity.trait.MemberReplaceable;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.entity.group.StopFailedRuntimeException;
import org.apache.brooklyn.policy.ha.HASensors.FailureDescriptor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceRestarter.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceRestarter.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceRestarter.java
index 37ce701..3d5f84d 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceRestarter.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/ServiceRestarter.java
@@ -36,8 +36,8 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.policy.ha.HASensors.FailureDescriptor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
index 12a1e4c..e5da346 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.policy.ha.HASensors.FailureDescriptor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableContainer.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableContainer.java b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableContainer.java
index 80896de..94887cf 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableContainer.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableContainer.java
@@ -23,8 +23,8 @@ import java.util.Set;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.entity.group.AbstractGroup;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.util.collections.QuorumCheck;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableWorkerPool.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableWorkerPool.java b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableWorkerPool.java
index 62059e5..d34fdc7 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableWorkerPool.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/BalanceableWorkerPool.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.core.entity.trait.Resizable;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
/**
* Represents an elastic group of "container" entities, each of which is capable of hosting "item" entities that perform
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
index bec64cc..44797cf 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/loadbalancing/Movable.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.effector.MethodEffector;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyMetricTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyMetricTest.java b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyMetricTest.java
index 39aeb8e..f9c2961 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyMetricTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyMetricTest.java
@@ -30,11 +30,11 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestCluster;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
index c6ac315..a0b7451 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyRebindTest.java
@@ -29,11 +29,11 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.location.SimulatedLocation;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.time.Duration;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyReconfigurationTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyReconfigurationTest.java b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyReconfigurationTest.java
index aeb09a0..9637235 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyReconfigurationTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyReconfigurationTest.java
@@ -23,9 +23,9 @@ import static org.apache.brooklyn.policy.autoscaling.AutoScalerPolicyTest.curren
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.time.Duration;
import org.testng.annotations.AfterMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyTest.java b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyTest.java
index bb9b247..9cd149a 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/autoscaling/AutoScalerPolicyTest.java
@@ -37,9 +37,9 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Resizable;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestCluster;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/enricher/DeltaEnrichersTests.groovy
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/enricher/DeltaEnrichersTests.groovy b/policy/src/test/java/org/apache/brooklyn/policy/enricher/DeltaEnrichersTests.groovy
index 2e7588c..2004ebd 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/enricher/DeltaEnrichersTests.groovy
+++ b/policy/src/test/java/org/apache/brooklyn/policy/enricher/DeltaEnrichersTests.groovy
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.sensor.Sensor
import org.apache.brooklyn.core.entity.AbstractApplication
import org.apache.brooklyn.core.entity.AbstractEntity
import org.apache.brooklyn.core.entity.Entities
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod
import org.testng.annotations.Test
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetectorTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetectorTest.java b/policy/src/test/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetectorTest.java
index 76cebbf..0aeac73 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetectorTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetectorTest.java
@@ -25,10 +25,10 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.http.BetterMockWebServer;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/enricher/RebindEnricherTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/enricher/RebindEnricherTest.java b/policy/src/test/java/org/apache/brooklyn/policy/enricher/RebindEnricherTest.java
index b12788a..7f3dfb1 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/enricher/RebindEnricherTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/enricher/RebindEnricherTest.java
@@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.policy.enricher.DeltaEnricher;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
@@ -33,7 +34,6 @@ import org.apache.brooklyn.policy.enricher.RollingMeanEnricher;
import org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher;
import org.apache.brooklyn.policy.enricher.TimeFractionDeltaEnricher;
import org.apache.brooklyn.policy.enricher.TimeWeightedDeltaEnricher;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.core.http.BetterMockWebServer;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricherTest.groovy
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricherTest.groovy b/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricherTest.groovy
index 0dc6686..7e5ae62 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricherTest.groovy
+++ b/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricherTest.groovy
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.sensor.Sensor
import org.apache.brooklyn.core.entity.AbstractApplication
import org.apache.brooklyn.core.entity.AbstractEntity
import org.apache.brooklyn.core.entity.Entities
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod
import org.testng.annotations.Test
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricherTest.groovy
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricherTest.groovy b/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricherTest.groovy
index 56d27ee..bd9c13f 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricherTest.groovy
+++ b/policy/src/test/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricherTest.groovy
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.sensor.Sensor
import org.apache.brooklyn.core.entity.AbstractApplication
import org.apache.brooklyn.core.entity.AbstractEntity
import org.apache.brooklyn.core.entity.Entities
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
import org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher.ConfidenceQualifiedNumber
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor
import org.testng.annotations.AfterMethod
import org.testng.annotations.BeforeMethod
import org.testng.annotations.Test
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricherTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricherTest.java b/policy/src/test/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricherTest.java
index 84562b2..bd18631 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricherTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricherTest.java
@@ -29,11 +29,11 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.policy.enricher.TimeFractionDeltaEnricher;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
index fb714ad..eebf16e 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/AbstractLoadBalancingPolicyTest.java
@@ -35,9 +35,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.group.DynamicGroup;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.time.Time;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockItemEntity.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockItemEntity.java b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockItemEntity.java
index 0cf1ca7..c2689a3 100644
--- a/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockItemEntity.java
+++ b/policy/src/test/java/org/apache/brooklyn/policy/loadbalancing/MockItemEntity.java
@@ -23,7 +23,7 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
index e9e3b6a..ffa8bd6 100644
--- a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbyDatabase.java
@@ -32,13 +32,13 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
----------------------------------------------------------------------
diff --git a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
index 5b9c7eb..23cfb2c 100644
--- a/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
+++ b/sandbox/database/src/main/java/org/apache/brooklyn/entity/database/derby/DerbySchema.java
@@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
import javax.management.ObjectName;
import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.entity.database.Schema;
@@ -33,7 +34,6 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index ace9a62..0070b39 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -37,10 +37,10 @@ import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.stock.EffectorStartableImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
import org.apache.brooklyn.util.ssh.BashCommands;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltConfig.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltConfig.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltConfig.java
index cebded8..c67eda0 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltConfig.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltConfig.java
@@ -26,10 +26,10 @@ import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.config.SetConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import com.google.common.annotations.Beta;
import com.google.common.base.Function;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMaster.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMaster.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMaster.java
index a90b836..5b4a085 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMaster.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltStackMaster.java
@@ -29,9 +29,9 @@ import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
index 12d7bac..deb8bf1 100644
--- a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
+++ b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.monitoring.zabbix;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
public interface ZabbixMonitored {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServer.java b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
index 861d103..9ecaada 100644
--- a/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
+++ b/sandbox/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.base.Predicate;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
index d64cd3c..c43e882 100644
--- a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
+++ b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastCluster.java
@@ -29,9 +29,9 @@ import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
/**
* A cluster of {@link HazelcastNode}s based on {@link DynamicCluster}.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNode.java b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
index 54bce7e..e53d0da 100644
--- a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
+++ b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/hazelcast/HazelcastNode.java
@@ -24,12 +24,12 @@ import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.javalang.JavaClassNames;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5Server.java
----------------------------------------------------------------------
diff --git a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5Server.java b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5Server.java
index 7d62229..7ec7bb4 100644
--- a/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5Server.java
+++ b/sandbox/nosql/src/main/java/org/apache/brooklyn/entity/nosql/infinispan/Infinispan5Server.java
@@ -27,11 +27,11 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.java.UsesJmx;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableMap;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
index f00b4db..8052037 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynCluster.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.brooklynnode.effector.BrooklynNodeUpgradeEffectorBody;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
@ImplementedBy(BrooklynClusterImpl.class)
public interface BrooklynCluster extends DynamicCluster {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
index ac884fa..7ccdda9 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.time.Duration;
/** Provides an entity which can sit in one brooklyn domain and reflect the status of an entity
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
index 0a99d1f..91622dd 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
@@ -32,7 +32,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
import org.apache.brooklyn.util.collections.Jsonya;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
index 2dd9067..b668e1b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNode.java
@@ -35,13 +35,13 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.net.Networking;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
index 2886257..64ef6ac 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JmxAttributeSensor.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.AddSensor;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.HttpRequestSensor;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.HttpRequestSensor;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJavaMXBeans.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJavaMXBeans.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJavaMXBeans.java
index 4f2d20b..6922a76 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJavaMXBeans.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJavaMXBeans.java
@@ -23,8 +23,8 @@ import java.util.Map;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
public interface UsesJavaMXBeans {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJmx.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJmx.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJmx.java
index dedbbd9..7d44bd3 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJmx.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/UsesJmx.java
@@ -28,9 +28,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
public interface UsesJmx extends UsesJava {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaApp.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaApp.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaApp.java
index 9319406..fe6f352 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaApp.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/VanillaJavaApp.java
@@ -25,8 +25,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
index a9c2d22..1a7ac9b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineAttributes.java
@@ -24,7 +24,7 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.render.RendererHints;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.guava.Functionals;
import org.apache.brooklyn.util.math.MathFunctions;
import org.apache.brooklyn.util.text.ByteSizeStrings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
index 3cf29e7..668a89e 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPool.java
@@ -37,9 +37,9 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.location.dynamic.LocationOwner;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.machine.MachineEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
/**
* A preallocated server pool is an entity that other applications can deploy to.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
index 4307ff6..c7696e4 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/pool/ServerPoolImpl.java
@@ -41,11 +41,11 @@ import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.BasicLocationDefinition;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.dynamic.DynamicLocation;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
index 339b459..3965f4a 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessWinRmDriver.java
@@ -28,9 +28,9 @@ import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.python.core.PyException;
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.exceptions.ReferenceWithError;
import org.apache.brooklyn.util.repeat.Repeater;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractVanillaProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractVanillaProcess.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractVanillaProcess.java
index ef9c9c4..35bdd94 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractVanillaProcess.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractVanillaProcess.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.entity.software.base;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
public interface AbstractVanillaProcess extends SoftwareProcess {
AttributeSensorAndConfigKey<String, String> DOWNLOAD_URL = SoftwareProcess.DOWNLOAD_URL;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerEntity.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerEntity.java
index 0a0af1d..ea82b3d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerEntity.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SameServerEntity.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.QuorumCheck;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
index 55ff5be..cee2d40 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
@@ -33,8 +33,8 @@ import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle.Transition;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
index 3dabbc9..f2dc269 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
@@ -484,7 +484,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
/** returns the ports that this entity wants to use;
* default implementation returns {@link SoftwareProcess#REQUIRED_OPEN_LOGIN_PORTS} plus first value
- * for each {@link org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey} config key {@link PortRange}
+ * for each {@link org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey} config key {@link PortRange}
* plus any ports defined with a config keys ending in {@code .port}.
*/
protected Collection<Integer> getRequiredOpenPorts() {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/entity/software/base/VanillaWindowsProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/VanillaWindowsProcess.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/VanillaWindowsProcess.java
index 1354b03..6390eba 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/VanillaWindowsProcess.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/VanillaWindowsProcess.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.time.Duration;
import com.google.common.collect.ImmutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
index c3dd177..59dc3c2 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
@@ -25,9 +25,9 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.AddSensor;
+import org.apache.brooklyn.core.sensor.HttpRequestSensor;
import org.apache.brooklyn.entity.java.JmxAttributeSensor;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.HttpRequestSensor;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java b/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
index d4415a9..ad02ce9 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/MockBrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/MockBrooklynNode.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/MockBrooklynNode.java
index 8e5b0bd..c07d899 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/MockBrooklynNode.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/MockBrooklynNode.java
@@ -25,12 +25,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
import org.apache.brooklyn.entity.brooklynnode.CallbackEntityHttpClient.Request;
import org.apache.brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
import org.apache.brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPriorityEffectorBody;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import com.google.common.base.Function;
import com.google.common.reflect.TypeToken;
[33/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorTransformingEnricher.java
new file mode 100644
index 0000000..92319f1
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorTransformingEnricher.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.time.Duration;
+
+import groovy.lang.Closure;
+
+import com.google.common.base.Function;
+
+/**
+ * @deprecated since 0.7.0; use {@link Enrichers.builder()}
+ * @see Transformer if need to sub-class
+ */
+public class SensorTransformingEnricher<T,U> extends AbstractTypeTransformingEnricher {
+
+ private Function<? super T, ? extends U> transformation;
+
+ public SensorTransformingEnricher(Entity producer, Sensor<T> source, Sensor<U> target, Function<? super T, ? extends U> transformation) {
+ super(producer, source, target);
+ this.transformation = transformation;
+ this.uniqueTag = JavaClassNames.simpleClassName(getClass())+":"+source.getName()+"*->"+target.getName();;
+ }
+
+ public SensorTransformingEnricher(Entity producer, Sensor<T> source, Sensor<U> target, Closure transformation) {
+ this(producer, source, target, GroovyJavaMethods.functionFromClosure(transformation));
+ }
+
+ public SensorTransformingEnricher(Sensor<T> source, Sensor<U> target, Function<T,U> transformation) {
+ this(null, source, target, transformation);
+ }
+
+ public SensorTransformingEnricher(Sensor<T> source, Sensor<U> target, Closure transformation) {
+ this(null, source, target, GroovyJavaMethods.functionFromClosure(transformation));
+ }
+
+ @Override
+ public void onEvent(SensorEvent event) {
+ if (accept((T)event.getValue())) {
+ if (target instanceof AttributeSensor)
+ entity.setAttribute((AttributeSensor)target, compute((T)event.getValue()));
+ else
+ entity.emit(target, compute((T)event.getValue()));
+ }
+ }
+
+ protected boolean accept(T value) {
+ return true;
+ }
+
+ protected U compute(T value) {
+ return transformation.apply(value);
+ }
+
+ /**
+ * creates an enricher which listens to a source (from the producer),
+ * transforms it and publishes it under the target
+ *
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * addEnricher(Enrichers.builder()
+ * .transforming(source)
+ * .publishing(target)
+ * .from(producer)
+ * .computing(transformation)
+ * .build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers.builder()}
+ */
+ public static <U,V> SensorTransformingEnricher<U,V> newInstanceTransforming(Entity producer, AttributeSensor<U> source,
+ Function<U,V> transformation, AttributeSensor<V> target) {
+ return new SensorTransformingEnricher<U,V>(producer, source, target, transformation);
+ }
+
+ /** as {@link #newInstanceTransforming(Entity, AttributeSensor, Function, AttributeSensor)}
+ * using the same sensor as the source and the target */
+ public static <T> SensorTransformingEnricher<T,T> newInstanceTransforming(Entity producer, AttributeSensor<T> sensor,
+ Function<T,T> transformation) {
+ return newInstanceTransforming(producer, sensor, transformation, sensor);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/Transformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Transformer.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Transformer.java
new file mode 100644
index 0000000..ef23ab4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Transformer.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ValueResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.reflect.TypeToken;
+
+//@Catalog(name="Transformer", description="Transforms attributes of an entity; see Enrichers.builder().transforming(...)")
+@SuppressWarnings("serial")
+public class Transformer<T,U> extends AbstractTransformer<T,U> {
+
+ @SuppressWarnings("unused")
+ private static final Logger LOG = LoggerFactory.getLogger(Transformer.class);
+
+ // exactly one of these should be supplied to set a value
+ public static ConfigKey<?> TARGET_VALUE = ConfigKeys.newConfigKey(Object.class, "enricher.targetValue");
+ public static ConfigKey<Function<?, ?>> TRANSFORMATION_FROM_VALUE = ConfigKeys.newConfigKey(new TypeToken<Function<?, ?>>() {}, "enricher.transformation");
+ public static ConfigKey<Function<?, ?>> TRANSFORMATION_FROM_EVENT = ConfigKeys.newConfigKey(new TypeToken<Function<?, ?>>() {}, "enricher.transformation.fromevent");
+
+ public Transformer() {
+ }
+
+ /** returns a function for transformation, for immediate use only (not for caching, as it may change) */
+ @Override
+ @SuppressWarnings("unchecked")
+ protected Function<SensorEvent<T>, U> getTransformation() {
+ MutableSet<Object> suppliers = MutableSet.of();
+ suppliers.addIfNotNull(config().getRaw(TARGET_VALUE).orNull());
+ suppliers.addIfNotNull(config().getRaw(TRANSFORMATION_FROM_EVENT).orNull());
+ suppliers.addIfNotNull(config().getRaw(TRANSFORMATION_FROM_VALUE).orNull());
+ checkArgument(suppliers.size()==1,
+ "Must set exactly one of: %s, %s, %s", TARGET_VALUE.getName(), TRANSFORMATION_FROM_VALUE.getName(), TRANSFORMATION_FROM_EVENT.getName());
+
+ Function<?, ?> fromEvent = config().get(TRANSFORMATION_FROM_EVENT);
+ if (fromEvent != null) {
+ return (Function<SensorEvent<T>, U>) fromEvent;
+ }
+
+ final Function<T, U> fromValueFn = (Function<T, U>) config().get(TRANSFORMATION_FROM_VALUE);
+ if (fromValueFn != null) {
+ // named class not necessary as result should not be serialized
+ return new Function<SensorEvent<T>, U>() {
+ @Override public U apply(SensorEvent<T> input) {
+ return fromValueFn.apply(input.getValue());
+ }
+ @Override
+ public String toString() {
+ return ""+fromValueFn;
+ }
+ };
+ }
+
+ // from target value
+ // named class not necessary as result should not be serialized
+ final Object targetValueRaw = config().getRaw(TARGET_VALUE).orNull();
+ return new Function<SensorEvent<T>, U>() {
+ @Override public U apply(SensorEvent<T> input) {
+ // evaluate immediately, or return null
+ // PRETTY_QUICK/200ms seems a reasonable compromise for tasks which require BG evaluation
+ // but which are non-blocking
+ // TODO better would be to have a mode in which tasks are not permitted to block on
+ // external events; they can submit tasks and block on them (or even better, have a callback architecture);
+ // however that is a non-trivial refactoring
+ return (U) Tasks.resolving(targetValueRaw).as(targetSensor.getType())
+ .context(entity)
+ .description("Computing sensor "+targetSensor+" from "+targetValueRaw)
+ .timeout(ValueResolver.PRETTY_QUICK_WAIT)
+ .getMaybe().orNull();
+ }
+ public String toString() {
+ return ""+targetValueRaw;
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
new file mode 100644
index 0000000..b09b6d6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/UpdatingMap.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Enricher which updates an entry in a sensor map ({@link #TARGET_SENSOR})
+ * based on the value of another sensor ({@link #SOURCE_SENSOR}.
+ * <p>
+ * The key used defaults to the name of the source sensor but can be specified with {@link #KEY_IN_TARGET_SENSOR}.
+ * The value placed in the map is the result of applying the function in {@link #COMPUTING} to the sensor value,
+ * with default behaviour being to remove an entry if <code>null</code> is returned
+ * but this can be overriden by setting {@link #REMOVING_IF_RESULT_IS_NULL} false.
+ * {@link Entities#REMOVE} and {@link Entities#UNCHANGED} are also respeced as return values for the computation
+ * (ignoring generics).
+ * Unlike most other enrichers, this defaults to {@link AbstractEnricher#SUPPRESS_DUPLICATES} being true
+ *
+ * @author alex
+ *
+ * @param <S> source sensor type
+ * @param <TKey> key type in target sensor map
+ * @param <TVal> value type in target sensor map
+ */
+@SuppressWarnings("serial")
+public class UpdatingMap<S,TKey,TVal> extends AbstractEnricher implements SensorEventListener<S> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UpdatingMap.class);
+
+ @SetFromFlag("fromSensor")
+ public static final ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
+ @SetFromFlag("targetSensor")
+ public static final ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+ @SetFromFlag("key")
+ public static final ConfigKey<?> KEY_IN_TARGET_SENSOR = ConfigKeys.newConfigKey(Object.class, "enricher.updatingMap.keyInTargetSensor",
+ "Key to update in the target sensor map, defaulting to the name of the source sensor");
+ @SetFromFlag("computing")
+ public static final ConfigKey<Function<?, ?>> COMPUTING = ConfigKeys.newConfigKey(new TypeToken<Function<?,?>>() {}, "enricher.updatingMap.computing");
+ @SetFromFlag("removingIfResultIsNull")
+ public static final ConfigKey<Boolean> REMOVING_IF_RESULT_IS_NULL = ConfigKeys.newBooleanConfigKey("enricher.updatingMap.removingIfResultIsNull",
+ "Whether the key in the target map is removed if the result if the computation is null");
+
+ protected AttributeSensor<S> sourceSensor;
+ protected AttributeSensor<Map<TKey,TVal>> targetSensor;
+ protected TKey key;
+ protected Function<S,? extends TVal> computing;
+ protected Boolean removingIfResultIsNull;
+
+ public UpdatingMap() {
+ this(Maps.newLinkedHashMap());
+ }
+
+ public UpdatingMap(Map<Object, Object> flags) {
+ super(flags);
+ // this always suppresses duplicates, but it updates the same map *in place* so the usual suppress duplicates logic should not be applied
+ // TODO clean up so that we have synchronization guarantees and can inspect the item to see whether it has changed
+ suppressDuplicates = false;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ this.sourceSensor = (AttributeSensor<S>) getRequiredConfig(SOURCE_SENSOR);
+ this.targetSensor = (AttributeSensor<Map<TKey,TVal>>) getRequiredConfig(TARGET_SENSOR);
+ this.key = (TKey) getConfig(KEY_IN_TARGET_SENSOR);
+ this.computing = (Function) getRequiredConfig(COMPUTING);
+ this.removingIfResultIsNull = getConfig(REMOVING_IF_RESULT_IS_NULL);
+
+ subscribe(entity, sourceSensor, this);
+ onUpdated();
+ }
+
+ @Override
+ public void onEvent(SensorEvent<S> event) {
+ onUpdated();
+ }
+
+ /**
+ * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
+ */
+ @SuppressWarnings("unchecked")
+ protected void onUpdated() {
+ try {
+ Object v = computing.apply(entity.getAttribute(sourceSensor));
+ if (v == null && !Boolean.FALSE.equals(removingIfResultIsNull)) {
+ v = Entities.REMOVE;
+ }
+ if (v == Entities.UNCHANGED) {
+ // nothing
+ } else {
+ // TODO check synchronization
+ TKey key = this.key;
+ if (key==null) key = (TKey) sourceSensor.getName();
+
+ Map<TKey, TVal> map = entity.getAttribute(targetSensor);
+
+ boolean created = (map==null);
+ if (created) map = MutableMap.of();
+
+ boolean changed;
+ if (v == Entities.REMOVE) {
+ changed = map.containsKey(key);
+ if (changed)
+ map.remove(key);
+ } else {
+ TVal oldV = map.get(key);
+ if (oldV==null)
+ changed = (v!=null || !map.containsKey(key));
+ else
+ changed = !oldV.equals(v);
+ if (changed)
+ map.put(key, (TVal)v);
+ }
+ if (changed || created)
+ emit(targetSensor, map);
+ }
+ } catch (Throwable t) {
+ LOG.warn("Error calculating map update for enricher "+this, t);
+ throw Exceptions.propagate(t);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricher.java
new file mode 100644
index 0000000..f4e5484
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlRollingTimeWindowMeanEnricher.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.base.Function;
+
+/**
+ * Transforms {@link Sensor} data into a rolling average based on a time window.
+ *
+ * All values within the window are weighted or discarded based on the timestamps associated with
+ * them (discards occur when a new value is added or an average is requested)
+ * <p>
+ * This will not extrapolate figures - it is assumed a value is valid and correct for the entire
+ * time period between it and the previous value. Normally, the average attribute is only updated
+ * when a new value arrives so it can give a fully informed average, but there is a danger of this
+ * going stale.
+ * <p>
+ * When an average is requested, it is likely there will be a segment of the window for which there
+ * isn't a value. Instead of extrapolating a value and providing different extrapolation techniques,
+ * the average is reported with a confidence value which reflects the fraction of the time
+ * window for which the values were valid.
+ * <p>
+ * Consumers of the average may ignore the confidence value and just use the last known average.
+ * They could multiply the returned value by the confidence value to get a decay-type behavior as
+ * the window empties. A third alternative is to, at a certain confidence threshold, report that
+ * the average is no longer meaningful.
+ * <p>
+ * The default average when no data has been received is 0, with a confidence of 0
+ */
+public class YamlRollingTimeWindowMeanEnricher<T extends Number> extends AbstractTransformer<T,Double> {
+
+ public static ConfigKey<Duration> WINDOW_DURATION = ConfigKeys.newConfigKey(Duration.class, "enricher.window.duration",
+ "Duration for which this window should store data, default one minute", Duration.ONE_MINUTE);
+
+ public static ConfigKey<Double> CONFIDENCE_REQUIRED_TO_PUBLISH = ConfigKeys.newDoubleConfigKey("enricher.window.confidenceRequired",
+ "Minimum confidence level (ie period covered) required to publish a rolling average", 0.8d);
+
+ public static class ConfidenceQualifiedNumber {
+ final Double value;
+ final double confidence;
+
+ public ConfidenceQualifiedNumber(Double value, double confidence) {
+ this.value = value;
+ this.confidence = confidence;
+ }
+
+ @Override
+ public String toString() {
+ return ""+value+" ("+(int)(confidence*100)+"%)";
+ }
+
+ }
+
+ private final LinkedList<T> values = new LinkedList<T>();
+ private final LinkedList<Long> timestamps = new LinkedList<Long>();
+ volatile ConfidenceQualifiedNumber lastAverage = new ConfidenceQualifiedNumber(0d,0d);
+
+ @Override
+ protected Function<SensorEvent<T>, Double> getTransformation() {
+ return new Function<SensorEvent<T>, Double>() {
+ @Override
+ public Double apply(SensorEvent<T> event) {
+ long eventTime = event.getTimestamp();
+ if (event.getValue()==null) {
+ return null;
+ }
+ values.addLast(event.getValue());
+ timestamps.addLast(eventTime);
+ if (eventTime>0) {
+ ConfidenceQualifiedNumber average = getAverage(eventTime, 0);
+
+ if (average.confidence > getConfig(CONFIDENCE_REQUIRED_TO_PUBLISH)) {
+ // without confidence, we might publish wildly varying estimates,
+ // causing spurious resizes, so allow it to be configured, and
+ // by default require a high value
+
+ // TODO would be nice to include timestamp, etc
+ return average.value;
+ }
+ }
+ return null;
+ }
+ };
+ }
+
+ public ConfidenceQualifiedNumber getAverage(long fromTime, long graceAllowed) {
+ if (timestamps.isEmpty()) {
+ return lastAverage = new ConfidenceQualifiedNumber(lastAverage.value, 0.0d);
+ }
+
+ long firstTimestamp = -1;
+ Iterator<Long> ti = timestamps.iterator();
+ while (ti.hasNext()) {
+ firstTimestamp = ti.next();
+ if (firstTimestamp>0) break;
+ }
+ if (firstTimestamp<=0) {
+ // no values with reasonable timestamps
+ return lastAverage = new ConfidenceQualifiedNumber(values.get(values.size()-1).doubleValue(), 0.0d);
+ }
+
+ long lastTimestamp = timestamps.get(timestamps.size()-1);
+
+ long now = fromTime;
+ if (lastTimestamp > fromTime - graceAllowed) {
+ // without this, if the computation takes place X seconds after the publish,
+ // we treat X seconds as time for which we have no confidence in the data
+ now = lastTimestamp;
+ }
+ pruneValues(now);
+
+ Duration timePeriod = getConfig(WINDOW_DURATION);
+ long windowStart = Math.max(now-timePeriod.toMilliseconds(), firstTimestamp);
+ long windowEnd = Math.max(now-timePeriod.toMilliseconds(), lastTimestamp);
+ Double confidence = ((double)(windowEnd - windowStart)) / timePeriod.toMilliseconds();
+ if (confidence <= 0.0000001d) {
+ // not enough timestamps in window
+ double lastValue = values.get(values.size()-1).doubleValue();
+ return lastAverage = new ConfidenceQualifiedNumber(lastValue, 0.0d);
+ }
+
+ long start = windowStart;
+ long end;
+ double weightedAverage = 0.0d;
+
+ Iterator<T> valuesIter = values.iterator();
+ Iterator<Long> timestampsIter = timestamps.iterator();
+ while (valuesIter.hasNext()) {
+ // Ignores null and out-of-date values (and also values that are received out-of-order, but that shouldn't happen!)
+ Number val = valuesIter.next();
+ Long timestamp = timestampsIter.next();
+ if (val!=null && timestamp >= start) {
+ end = timestamp;
+ weightedAverage += ((end - start) / (confidence * timePeriod.toMilliseconds())) * val.doubleValue();
+ start = timestamp;
+ }
+ }
+
+ return lastAverage = new ConfidenceQualifiedNumber(weightedAverage, confidence);
+ }
+
+ /**
+ * Discards out-of-date values, but keeps at least one value.
+ */
+ private void pruneValues(long now) {
+ // keep one value from before the period, so that we can tell the window's start time
+ Duration timePeriod = getConfig(WINDOW_DURATION);
+ while(timestamps.size() > 1 && timestamps.get(1) < (now - timePeriod.toMilliseconds())) {
+ timestamps.removeFirst();
+ values.removeFirst();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricher.java
new file mode 100644
index 0000000..e1a661e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/YamlTimeWeightedDeltaEnricher.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.enricher.stock.AbstractTransformer;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+
+/**
+ * Converts an absolute count sensor into a delta sensor (i.e. the diff between the current and previous value),
+ * presented as a units/timeUnit based on the event timing.
+ * <p>
+ * For example, given a requests.count sensor, this can make a requests.per_sec sensor with {@link #DELTA_PERIOD} set to "1s" (the default).
+ * <p>
+ * Suitable for configuration from YAML.
+ */
+public class YamlTimeWeightedDeltaEnricher<T extends Number> extends AbstractTransformer<T,Double> {
+ private static final Logger LOG = LoggerFactory.getLogger(YamlTimeWeightedDeltaEnricher.class);
+
+ transient Object lock = new Object();
+ Number lastValue;
+ long lastTime = -1;
+
+ public static ConfigKey<Duration> DELTA_PERIOD = ConfigKeys.newConfigKey(Duration.class, "enricher.delta.period",
+ "Duration that this delta should compute for, default per second", Duration.ONE_SECOND);
+
+ @Override
+ protected Function<SensorEvent<T>, Double> getTransformation() {
+ return new Function<SensorEvent<T>, Double>() {
+ @Override
+ public Double apply(SensorEvent<T> event) {
+ synchronized (lock) {
+ Double current = TypeCoercions.coerce(event.getValue(), Double.class);
+
+ if (current == null) return null;
+
+ long eventTime = event.getTimestamp();
+ long unitMillis = getConfig(DELTA_PERIOD).toMilliseconds();
+ Double result = null;
+
+ if (eventTime > 0 && eventTime > lastTime) {
+ if (lastValue == null || lastTime < 0) {
+ // cannot calculate time-based delta with a single value
+ if (LOG.isTraceEnabled()) LOG.trace("{} received event but no last value so will not emit, null -> {} at {}", new Object[] {this, current, eventTime});
+ } else {
+ double duration = eventTime - lastTime;
+ result = (current - lastValue.doubleValue()) / (duration / unitMillis);
+ }
+ }
+
+ lastValue = current;
+ lastTime = eventTime;
+
+ return result;
+ }
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
index daedc39..717b0e4 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
@@ -41,7 +41,7 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Changeable;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntityImpl.java b/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntityImpl.java
index a160421..5728635 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntityImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntityImpl.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.entity.stock;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import com.google.common.base.Preconditions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregatingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregatingEnricher.java
deleted file mode 100644
index c140c9f..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregatingEnricher.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.Group;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.entity.trait.Changeable;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-
-
-/**
- * AggregatingEnrichers implicitly subscribes to the same sensor<S> on all entities inside an
- * {@link Group} and should emit an aggregate<T> on the target sensor
- *
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- * @see Aggregator if need to sub-class
- */
-public abstract class AbstractAggregatingEnricher<S,T> extends AbstractEnricher implements SensorEventListener<S> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractAggregatingEnricher.class);
-
- AttributeSensor<? extends S> source;
- protected AttributeSensor<T> target;
- protected S defaultValue;
-
- Set<Entity> producers;
- List<Entity> hardCodedProducers;
- boolean allMembers;
- Predicate<Entity> filter;
-
- /**
- * Users of values should either on it synchronize when iterating over its entries or use
- * copyOfValues to obtain an immutable copy of the map.
- */
- // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
- protected final Map<Entity, S> values = Collections.synchronizedMap(new LinkedHashMap<Entity, S>());
-
- public AbstractAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target) {
- this(flags, source, target, null);
- }
-
- @SuppressWarnings("unchecked")
- public AbstractAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target, S defaultValue) {
- super(flags);
- this.source = source;
- this.target = target;
- this.defaultValue = defaultValue;
- hardCodedProducers = (List<Entity>) (flags.containsKey("producers") ? flags.get("producers") : Collections.emptyList());
- allMembers = (Boolean) (flags.containsKey("allMembers") ? flags.get("allMembers") : false);
- filter = flags.containsKey("filter") ? GroovyJavaMethods.<Entity>castToPredicate(flags.get("filter")) : Predicates.<Entity>alwaysTrue();
- }
-
- public void addProducer(Entity producer) {
- if (LOG.isDebugEnabled()) LOG.debug("{} linked ({}, {}) to {}", new Object[] {this, producer, source, target});
- subscribe(producer, source, this);
- synchronized (values) {
- S vo = values.get(producer);
- if (vo==null) {
- S initialVal = ((EntityLocal)producer).getAttribute(source);
- values.put(producer, initialVal != null ? initialVal : defaultValue);
- //we might skip in onEvent in the short window while !values.containsKey(producer)
- //but that's okay because the put which would have been done there is done here now
- } else {
- //vo will be null unless some weird race with addProducer+removeProducer is occuring
- //(and that's something we can tolerate i think)
- if (LOG.isDebugEnabled()) LOG.debug("{} already had value ({}) for producer ({}); but that producer has just been added", new Object[] {this, vo, producer});
- }
- }
- onUpdated();
- }
-
- // TODO If producer removed but then get (queued) event from it after this method returns,
- public S removeProducer(Entity producer) {
- if (LOG.isDebugEnabled()) LOG.debug("{} unlinked ({}, {}) from {}", new Object[] {this, producer, source, target});
- unsubscribe(producer);
- S removed = values.remove(producer);
- onUpdated();
- return removed;
- }
-
- @Override
- public void onEvent(SensorEvent<S> event) {
- Entity e = event.getSource();
- synchronized (values) {
- if (values.containsKey(e)) {
- values.put(e, event.getValue());
- } else {
- if (LOG.isDebugEnabled()) LOG.debug("{} received event for unknown producer ({}); presumably that producer has recently been removed", this, e);
- }
- }
- onUpdated();
- }
-
- /**
- * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
- * Defaults to no-op
- */
- // TODO should this be abstract?
- protected void onUpdated() {
- // no-op
- }
-
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
-
- for (Entity producer : hardCodedProducers) {
- if (filter.apply(producer)) {
- addProducer(producer);
- }
- }
-
- if (allMembers) {
- subscribe(entity, Changeable.MEMBER_ADDED, new SensorEventListener<Entity>() {
- @Override public void onEvent(SensorEvent<Entity> it) {
- if (filter.apply(it.getValue())) addProducer(it.getValue());
- }
- });
- subscribe(entity, Changeable.MEMBER_REMOVED, new SensorEventListener<Entity>() {
- @Override public void onEvent(SensorEvent<Entity> it) {
- removeProducer(it.getValue());
- }
- });
-
- if (entity instanceof Group) {
- for (Entity member : ((Group)entity).getMembers()) {
- if (filter.apply(member)) {
- addProducer(member);
- }
- }
- }
- }
- }
-
- protected Map<Entity, S> copyOfValues() {
- synchronized (values) {
- return ImmutableMap.copyOf(values);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregator.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregator.java
deleted file mode 100644
index a06e6d6..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractAggregator.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.Group;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.trait.Changeable;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-/** Abstract superclass for enrichers which aggregate from children and/or members */
-@SuppressWarnings("serial")
-public abstract class AbstractAggregator<T,U> extends AbstractEnricher implements SensorEventListener<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractAggregator.class);
-
- public static final ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer", "The entity whose children/members will be aggregated");
-
- public static final ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
-
- // FIXME this is not just for "members" i think -Alex
- public static final ConfigKey<?> DEFAULT_MEMBER_VALUE = ConfigKeys.newConfigKey(Object.class, "enricher.defaultMemberValue");
-
- public static final ConfigKey<Set<? extends Entity>> FROM_HARDCODED_PRODUCERS = ConfigKeys.newConfigKey(new TypeToken<Set<? extends Entity>>() {}, "enricher.aggregating.fromHardcodedProducers");
-
- public static final ConfigKey<Boolean> FROM_MEMBERS = ConfigKeys.newBooleanConfigKey("enricher.aggregating.fromMembers",
- "Whether this enricher looks at members; only supported if a Group producer is supplier; defaults to true for Group entities");
-
- public static final ConfigKey<Boolean> FROM_CHILDREN = ConfigKeys.newBooleanConfigKey("enricher.aggregating.fromChildren",
- "Whether this enricher looks at children; this is the default for non-Group producers");
-
- public static final ConfigKey<Predicate<? super Entity>> ENTITY_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<? super Entity>>() {}, "enricher.aggregating.entityFilter");
-
- public static final ConfigKey<Predicate<?>> VALUE_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<?>>() {}, "enricher.aggregating.valueFilter");
-
- protected Entity producer;
- protected Sensor<U> targetSensor;
- protected T defaultMemberValue;
- protected Set<? extends Entity> fromHardcodedProducers;
- protected Boolean fromMembers;
- protected Boolean fromChildren;
- protected Predicate<? super Entity> entityFilter;
- protected Predicate<? super T> valueFilter;
-
- public AbstractAggregator() {}
-
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- setEntityLoadingConfig();
-
- if (fromHardcodedProducers == null && producer == null) producer = entity;
- checkState(fromHardcodedProducers != null ^ producer != null, "must specify one of %s (%s) or %s (%s)",
- PRODUCER.getName(), producer, FROM_HARDCODED_PRODUCERS.getName(), fromHardcodedProducers);
-
- if (fromHardcodedProducers != null) {
- for (Entity producer : Iterables.filter(fromHardcodedProducers, entityFilter)) {
- addProducerHardcoded(producer);
- }
- }
-
- if (isAggregatingMembers()) {
- setEntityBeforeSubscribingProducerMemberEvents(entity);
- setEntitySubscribeProducerMemberEvents();
- setEntityAfterSubscribingProducerMemberEvents();
- }
-
- if (isAggregatingChildren()) {
- setEntityBeforeSubscribingProducerChildrenEvents();
- setEntitySubscribingProducerChildrenEvents();
- setEntityAfterSubscribingProducerChildrenEvents();
- }
-
- onUpdated();
- }
-
- @SuppressWarnings({ "unchecked" })
- protected void setEntityLoadingConfig() {
- this.producer = getConfig(PRODUCER);
- this.fromHardcodedProducers= getConfig(FROM_HARDCODED_PRODUCERS);
- this.defaultMemberValue = (T) getConfig(DEFAULT_MEMBER_VALUE);
- this.fromMembers = Maybe.fromNullable(getConfig(FROM_MEMBERS)).or(fromMembers);
- this.fromChildren = Maybe.fromNullable(getConfig(FROM_CHILDREN)).or(fromChildren);
- this.entityFilter = (Predicate<? super Entity>) (getConfig(ENTITY_FILTER) == null ? Predicates.alwaysTrue() : getConfig(ENTITY_FILTER));
- this.valueFilter = (Predicate<? super T>) (getConfig(VALUE_FILTER) == null ? getDefaultValueFilter() : getConfig(VALUE_FILTER));
-
- setEntityLoadingTargetConfig();
- }
-
- protected Predicate<?> getDefaultValueFilter() {
- return Predicates.alwaysTrue();
- }
-
- @SuppressWarnings({ "unchecked" })
- protected void setEntityLoadingTargetConfig() {
- this.targetSensor = (Sensor<U>) getRequiredConfig(TARGET_SENSOR);
- }
-
- protected void setEntityBeforeSubscribingProducerMemberEvents(EntityLocal entity) {
- checkState(producer instanceof Group, "Producer must be a group when fromMembers true: producer=%s; entity=%s; "
- + "hardcodedProducers=%s", getConfig(PRODUCER), entity, fromHardcodedProducers);
- }
-
- protected void setEntitySubscribeProducerMemberEvents() {
- subscribe(producer, Changeable.MEMBER_ADDED, new SensorEventListener<Entity>() {
- @Override public void onEvent(SensorEvent<Entity> event) {
- if (entityFilter.apply(event.getValue())) {
- addProducerMember(event.getValue());
- onUpdated();
- }
- }
- });
- subscribe(producer, Changeable.MEMBER_REMOVED, new SensorEventListener<Entity>() {
- @Override public void onEvent(SensorEvent<Entity> event) {
- removeProducer(event.getValue());
- onUpdated();
- }
- });
- }
-
- protected void setEntityAfterSubscribingProducerMemberEvents() {
- if (producer instanceof Group) {
- for (Entity member : Iterables.filter(((Group)producer).getMembers(), entityFilter)) {
- addProducerMember(member);
- }
- }
- }
-
- protected void setEntityBeforeSubscribingProducerChildrenEvents() {
- }
-
- protected void setEntitySubscribingProducerChildrenEvents() {
- subscribe(producer, AbstractEntity.CHILD_REMOVED, new SensorEventListener<Entity>() {
- @Override public void onEvent(SensorEvent<Entity> event) {
- removeProducer(event.getValue());
- onUpdated();
- }
- });
- subscribe(producer, AbstractEntity.CHILD_ADDED, new SensorEventListener<Entity>() {
- @Override public void onEvent(SensorEvent<Entity> event) {
- if (entityFilter.apply(event.getValue())) {
- addProducerChild(event.getValue());
- onUpdated();
- }
- }
- });
- }
-
- protected void setEntityAfterSubscribingProducerChildrenEvents() {
- for (Entity child : Iterables.filter(producer.getChildren(), entityFilter)) {
- addProducerChild(child);
- }
- }
-
- /** true if this should aggregate members */
- protected boolean isAggregatingMembers() {
- if (Boolean.TRUE.equals(fromMembers)) return true;
- if (Boolean.TRUE.equals(fromChildren)) return false;
- if (fromHardcodedProducers!=null) return false;
- if (producer instanceof Group) return true;
- return false;
- }
-
- /** true if this should aggregate members */
- protected boolean isAggregatingChildren() {
- if (Boolean.TRUE.equals(fromChildren)) return true;
- if (Boolean.TRUE.equals(fromMembers)) return false;
- if (fromHardcodedProducers!=null) return false;
- if (producer instanceof Group) return false;
- return true;
- }
-
- protected abstract void addProducerHardcoded(Entity producer);
- protected abstract void addProducerMember(Entity producer);
- protected abstract void addProducerChild(Entity producer);
-
- // TODO If producer removed but then get (queued) event from it after this method returns,
- protected void removeProducer(Entity producer) {
- if (LOG.isDebugEnabled()) LOG.debug("{} stopped listening to {}", new Object[] {this, producer });
- unsubscribe(producer);
- onProducerRemoved(producer);
- }
-
- protected abstract void onProducerAdded(Entity producer);
-
- protected abstract void onProducerRemoved(Entity producer);
-
-
- /**
- * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
- */
- protected void onUpdated() {
- try {
- emit(targetSensor, compute());
- } catch (Throwable t) {
- LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
- throw Exceptions.propagate(t);
- }
- }
-
- protected abstract Object compute();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractEnricher.java
deleted file mode 100644
index edf407d..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractEnricher.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
-import org.apache.brooklyn.api.mgmt.rebind.mementos.EnricherMemento;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Enricher;
-import org.apache.brooklyn.api.sensor.EnricherType;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.mgmt.rebind.BasicEnricherRebindSupport;
-import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.Maps;
-
-/**
-* Base {@link Enricher} implementation; all enrichers should extend this or its children
-*/
-public abstract class AbstractEnricher extends AbstractEntityAdjunct implements Enricher {
-
- public static final ConfigKey<Boolean> SUPPRESS_DUPLICATES = ConfigKeys.newBooleanConfigKey("enricher.suppressDuplicates",
- "Whether duplicate values published by this enricher should be suppressed");
-
- private final EnricherDynamicType enricherType;
- protected Boolean suppressDuplicates;
-
- public AbstractEnricher() {
- this(Maps.newLinkedHashMap());
- }
-
- public AbstractEnricher(Map<?,?> flags) {
- super(flags);
-
- enricherType = new EnricherDynamicType(this);
-
- if (isLegacyConstruction() && !isLegacyNoConstructionInit()) {
- init();
- }
- }
-
- @Override
- public RebindSupport<EnricherMemento> getRebindSupport() {
- return new BasicEnricherRebindSupport(this);
- }
-
- @Override
- public EnricherType getEnricherType() {
- return enricherType.getSnapshot();
- }
-
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- Boolean suppressDuplicates = getConfig(SUPPRESS_DUPLICATES);
- if (suppressDuplicates!=null)
- this.suppressDuplicates = suppressDuplicates;
- }
-
- @Override
- protected void onChanged() {
- requestPersist();
- }
-
- @Override
- protected <T> void emit(Sensor<T> sensor, Object val) {
- checkState(entity != null, "entity must first be set");
- if (val == Entities.UNCHANGED) {
- return;
- }
- if (val == Entities.REMOVE) {
- ((EntityInternal)entity).removeAttribute((AttributeSensor<T>) sensor);
- return;
- }
-
- T newVal = TypeCoercions.coerce(val, sensor.getTypeToken());
- if (sensor instanceof AttributeSensor) {
- if (Boolean.TRUE.equals(suppressDuplicates)) {
- T oldValue = entity.getAttribute((AttributeSensor<T>)sensor);
- if (Objects.equal(oldValue, newVal))
- return;
- }
- entity.setAttribute((AttributeSensor<T>)sensor, newVal);
- } else {
- entity.emit(sensor, newVal);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractMultipleSensorAggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractMultipleSensorAggregator.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractMultipleSensorAggregator.java
deleted file mode 100644
index c625c90..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractMultipleSensorAggregator.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.BrooklynLogging;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-
-/** Building on {@link AbstractAggregator} for a single source sensor (on multiple children and/or members) */
-public abstract class AbstractMultipleSensorAggregator<U> extends AbstractAggregator<Object,U> implements SensorEventListener<Object> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipleSensorAggregator.class);
-
-
- /** access via {@link #getValues(Sensor)} */
- private final Map<String, Map<Entity,Object>> values = Collections.synchronizedMap(new LinkedHashMap<String, Map<Entity,Object>>());
-
- public AbstractMultipleSensorAggregator() {}
-
- protected abstract Collection<Sensor<?>> getSourceSensors();
-
- @Override
- protected void setEntityLoadingConfig() {
- super.setEntityLoadingConfig();
- Preconditions.checkNotNull(getSourceSensors(), "sourceSensors must be set");
- }
-
- @Override
- protected void setEntityBeforeSubscribingProducerChildrenEvents() {
- BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
- "{} subscribing to children of {}", this, producer);
- for (Sensor<?> sourceSensor: getSourceSensors()) {
- subscribeToChildren(producer, sourceSensor, this);
- }
- }
-
- @Override
- protected void addProducerHardcoded(Entity producer) {
- for (Sensor<?> sourceSensor: getSourceSensors()) {
- subscribe(producer, sourceSensor, this);
- }
- onProducerAdded(producer);
- }
-
- @Override
- protected void addProducerChild(Entity producer) {
- // no `subscribe` call needed here, due to previous subscribeToChildren call
- onProducerAdded(producer);
- }
-
- @Override
- protected void addProducerMember(Entity producer) {
- addProducerHardcoded(producer);
- }
-
- @Override
- protected void onProducerAdded(Entity producer) {
- BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
- "{} listening to {}", this, producer);
- synchronized (values) {
- for (Sensor<?> sensor: getSourceSensors()) {
- Map<Entity,Object> vs = values.get(sensor.getName());
- if (vs==null) {
- vs = new LinkedHashMap<Entity,Object>();
- values.put(sensor.getName(), vs);
- }
-
- Object vo = vs.get(producer);
- if (vo==null) {
- Object initialVal;
- if (sensor instanceof AttributeSensor) {
- initialVal = producer.getAttribute((AttributeSensor<?>)sensor);
- } else {
- initialVal = null;
- }
- vs.put(producer, initialVal != null ? initialVal : defaultMemberValue);
- // NB: see notes on possible race, in Aggregator#onProducerAdded
- }
-
- }
- }
- }
-
- @Override
- protected void onProducerRemoved(Entity producer) {
- synchronized (values) {
- for (Sensor<?> sensor: getSourceSensors()) {
- Map<Entity,Object> vs = values.get(sensor.getName());
- if (vs!=null)
- vs.remove(producer);
- }
- }
- onUpdated();
- }
-
- @Override
- public void onEvent(SensorEvent<Object> event) {
- Entity e = event.getSource();
- synchronized (values) {
- Map<Entity,Object> vs = values.get(event.getSensor().getName());
- if (vs==null) {
- LOG.debug(this+" received event when no entry for sensor ("+event+"); likely just added or removed, and will initialize subsequently if needed");
- } else {
- vs.put(e, event.getValue());
- }
- }
- onUpdated();
- }
-
- public <T> Map<Entity,T> getValues(Sensor<T> sensor) {
- Map<Entity, T> valuesCopy = copyValues(sensor);
- return coerceValues(valuesCopy, sensor.getType());
- }
-
- private <T> Map<Entity, T> coerceValues(Map<Entity, T> values, Class<? super T> type) {
- Map<Entity, T> typedValues = MutableMap.of();
- for (Entry<Entity, T> entry : values.entrySet()) {
- @SuppressWarnings("unchecked")
- T typedValue = (T) TypeCoercions.coerce(entry.getValue(), type);
- typedValues.put(entry.getKey(), typedValue);
- }
- return typedValues;
- }
-
- private <T> Map<Entity, T> copyValues(Sensor<T> sensor) {
- synchronized (values) {
- @SuppressWarnings("unchecked")
- Map<Entity, T> sv = (Map<Entity, T>) values.get(sensor.getName());
- //use MutableMap because of potentially null values
- return MutableMap.copyOf(sv).asUnmodifiable();
- }
- }
-
- @Override
- protected abstract Object compute();
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
deleted file mode 100644
index 1ff7938..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.reflect.TypeToken;
-
-@SuppressWarnings("serial")
-public abstract class AbstractTransformer<T,U> extends AbstractEnricher implements SensorEventListener<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(AbstractTransformer.class);
-
- public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
-
- public static ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
-
- public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
-
- protected Entity producer;
- protected Sensor<T> sourceSensor;
- protected Sensor<U> targetSensor;
-
- public AbstractTransformer() {
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
-
- Function<SensorEvent<T>, U> transformation = getTransformation();
- this.producer = getConfig(PRODUCER) == null ? entity: getConfig(PRODUCER);
- this.sourceSensor = (Sensor<T>) getRequiredConfig(SOURCE_SENSOR);
- Sensor<?> targetSensorSpecified = getConfig(TARGET_SENSOR);
- this.targetSensor = targetSensorSpecified!=null ? (Sensor<U>) targetSensorSpecified : (Sensor<U>) this.sourceSensor;
- if (producer.equals(entity) && targetSensorSpecified==null) {
- LOG.error("Refusing to add an enricher which reads and publishes on the same sensor: "+
- producer+"."+sourceSensor+" (computing "+transformation+")");
- // we don't throw because this error may manifest itself after a lengthy deployment,
- // and failing it at that point simply because of an enricher is not very pleasant
- // (at least not until we have good re-run support across the board)
- return;
- }
-
- subscribe(producer, sourceSensor, this);
-
- if (sourceSensor instanceof AttributeSensor) {
- Object value = producer.getAttribute((AttributeSensor<?>)sourceSensor);
- // TODO would be useful to have a convenience to "subscribeAndThenIfItIsAlreadySetRunItOnce"
- if (value!=null) {
- onEvent(new BasicSensorEvent(sourceSensor, producer, value, -1));
- }
- }
- }
-
- /** returns a function for transformation, for immediate use only (not for caching, as it may change) */
- protected abstract Function<SensorEvent<T>, U> getTransformation();
-
- @Override
- public void onEvent(SensorEvent<T> event) {
- emit(targetSensor, compute(event));
- }
-
- protected Object compute(SensorEvent<T> event) {
- // transformation is not going to change, but this design makes it easier to support changing config in future.
- // if it's an efficiency hole we can switch to populate the transformation at start.
- U result = getTransformation().apply(event);
- if (LOG.isTraceEnabled())
- LOG.trace("Enricher "+this+" computed "+result+" from "+event);
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformingEnricher.java
deleted file mode 100644
index 4fea37a..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformingEnricher.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.Sensor;
-
-/**
- * Convenience base for transforming a single sensor into a single new sensor of the same type
- *
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- */
-public abstract class AbstractTransformingEnricher<T> extends AbstractTypeTransformingEnricher<T,T> {
-
- public AbstractTransformingEnricher() { // for rebinding
- }
-
- public AbstractTransformingEnricher(Entity producer, Sensor<T> source, Sensor<T> target) {
- super(producer, source, target);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
deleted file mode 100644
index f66004c..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-
-/**
- * Convenience base for transforming a single sensor into a single new sensor of the same type
- *
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- */
-public abstract class AbstractTypeTransformingEnricher<T,U> extends AbstractEnricher implements SensorEventListener<T> {
-
- @SetFromFlag
- private Entity producer;
-
- @SetFromFlag
- private Sensor<T> source;
-
- @SetFromFlag
- protected Sensor<U> target;
-
- public AbstractTypeTransformingEnricher() { // for rebind
- }
-
- public AbstractTypeTransformingEnricher(Entity producer, Sensor<T> source, Sensor<U> target) {
- this.producer = producer;
- this.source = source;
- this.target = target;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- if (producer==null) producer = entity;
- subscribe(producer, source, this);
-
- if (source instanceof AttributeSensor) {
- Object value = producer.getAttribute((AttributeSensor)source);
- // TODO Aled didn't you write a convenience to "subscribeAndRunIfSet" ? (-Alex)
- if (value!=null)
- onEvent(new BasicSensorEvent(source, producer, value, -1));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
deleted file mode 100644
index 997f974..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-
-/**
- * enricher which adds multiple sensors on an entity to produce a new sensor
- *
- * Instead, consider calling:
- * <pre>
- * {@code
- * addEnricher(Enrichers.builder()
- * .combining(sources)
- * .publishing(target)
- * .computeSum()
- * .build());
- * }
- * </pre>
- * <p>
- *
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- * @see Combiner if need to sub-class
- */
-public class AddingEnricher extends AbstractEnricher implements SensorEventListener {
-
- private Sensor[] sources;
- private Sensor<? extends Number> target;
-
- public AddingEnricher(Sensor sources[], Sensor<? extends Number> target) {
- this.sources = sources;
- this.target = target;
- }
-
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
-
- for (Sensor source: sources) {
- subscribe(entity, source, this);
- if (source instanceof AttributeSensor) {
- Object value = entity.getAttribute((AttributeSensor)source);
- if (value!=null)
- onEvent(new BasicSensorEvent(source, entity, value, -1));
- }
- }
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- public void onEvent(SensorEvent event) {
- Number value = recompute();
- Number typedValue = cast(value, (Class<? extends Number>)target.getType());
- if (target instanceof AttributeSensor) {
- entity.setAttribute((AttributeSensor)target, typedValue);
- } else if (typedValue!=null)
- entity.emit((Sensor)target, typedValue);
- }
-
- @SuppressWarnings("unchecked")
- public static <V> V cast(Number value, Class<V> type) {
- if (value==null) return null;
- if (type.isInstance(value)) return (V)value;
-
- if (type==Integer.class) return (V) (Integer) (int)Math.round(value.doubleValue());
- if (type==Long.class) return (V) (Long) Math.round(value.doubleValue());
- if (type==Double.class) return (V) (Double) value.doubleValue();
- if (type==Float.class) return (V) (Float) value.floatValue();
- if (type==Byte.class) return (V) (Byte) (byte)Math.round(value.doubleValue());
- if (type==Short.class) return (V) (Short) (short)Math.round(value.doubleValue());
-
- throw new UnsupportedOperationException("conversion of mathematical operation to "+type+" not supported");
- }
-
- protected Number recompute() {
- if (sources.length==0) return null;
- Double result = 0d;
- for (Sensor source: sources) {
- Object value = entity.getAttribute((AttributeSensor) source);
- if (value==null) return null;
- result += ((Number)value).doubleValue();
- }
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/Aggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Aggregator.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Aggregator.java
deleted file mode 100644
index af828bc..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Aggregator.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.BrooklynLogging;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.text.StringPredicates;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-/** Building on {@link AbstractAggregator} for a single source sensor (on multiple children and/or members) */
-@SuppressWarnings("serial")
-//@Catalog(name="Aggregator", description="Aggregates attributes from multiple entities into a single attribute value; see Enrichers.builder().aggregating(...)")
-public class Aggregator<T,U> extends AbstractAggregator<T,U> implements SensorEventListener<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(Aggregator.class);
-
- public static final ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
-
- @SetFromFlag("transformation")
- public static final ConfigKey<Object> TRANSFORMATION_UNTYPED = ConfigKeys.newConfigKey(Object.class, "enricher.transformation.untyped",
- "Specifies a transformation, as a function from a collection to the value, or as a string matching a pre-defined named transformation, "
- + "such as 'average' (for numbers), 'sum' (for numbers), or 'list' (the default, putting any collection of items into a list)");
- public static final ConfigKey<Function<? super Collection<?>, ?>> TRANSFORMATION = ConfigKeys.newConfigKey(new TypeToken<Function<? super Collection<?>, ?>>() {}, "enricher.transformation");
-
- public static final ConfigKey<Boolean> EXCLUDE_BLANK = ConfigKeys.newBooleanConfigKey("enricher.aggregator.excludeBlank", "Whether explicit nulls or blank strings should be excluded (default false); this only applies if no value filter set", false);
-
- protected Sensor<T> sourceSensor;
- protected Function<? super Collection<T>, ? extends U> transformation;
-
- /**
- * Users of values should either on it synchronize when iterating over its entries or use
- * copyOfValues to obtain an immutable copy of the map.
- */
- // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
- protected final Map<Entity, T> values = Collections.synchronizedMap(new LinkedHashMap<Entity, T>());
-
- public Aggregator() {}
-
- @SuppressWarnings("unchecked")
- protected void setEntityLoadingConfig() {
- super.setEntityLoadingConfig();
- this.sourceSensor = (Sensor<T>) getRequiredConfig(SOURCE_SENSOR);
-
- this.transformation = (Function<? super Collection<T>, ? extends U>) config().get(TRANSFORMATION);
-
- Object t1 = config().get(TRANSFORMATION_UNTYPED);
- Function<? super Collection<?>, ?> t2 = null;
- if (t1 instanceof String) {
- t2 = lookupTransformation((String)t1);
- if (t2==null) {
- LOG.warn("Unknown transformation '"+t1+"' for "+this+"; will use default transformation");
- }
- }
-
- if (this.transformation==null) {
- this.transformation = (Function<? super Collection<T>, ? extends U>) t2;
- } else if (t1!=null && !Objects.equals(t2, this.transformation)) {
- throw new IllegalStateException("Cannot supply both "+TRANSFORMATION_UNTYPED+" and "+TRANSFORMATION+" unless they are equal.");
- }
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected Function<? super Collection<?>, ?> lookupTransformation(String t1) {
- if ("average".equalsIgnoreCase(t1)) return new Enrichers.ComputingAverage(null, null, targetSensor.getTypeToken());
- if ("sum".equalsIgnoreCase(t1)) return new Enrichers.ComputingAverage(null, null, targetSensor.getTypeToken());
- if ("list".equalsIgnoreCase(t1)) return new ComputingList();
- return null;
- }
-
- private class ComputingList<TT> implements Function<Collection<TT>, List<TT>> {
- @Override
- public List<TT> apply(Collection<TT> input) {
- if (input==null) return null;
- return MutableList.copyOf(input).asUnmodifiable();
- }
-
- }
-
- @Override
- protected void setEntityBeforeSubscribingProducerChildrenEvents() {
- BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
- "{} subscribing to children of {}", this, producer);
- subscribeToChildren(producer, sourceSensor, this);
- }
-
- @Override
- protected void addProducerHardcoded(Entity producer) {
- subscribe(producer, sourceSensor, this);
- onProducerAdded(producer);
- }
-
- @Override
- protected void addProducerChild(Entity producer) {
- // no subscription needed here, due to the subscribeToChildren call
- onProducerAdded(producer);
- }
-
- @Override
- protected void addProducerMember(Entity producer) {
- subscribe(producer, sourceSensor, this);
- onProducerAdded(producer);
- }
-
- @Override
- protected void onProducerAdded(Entity producer) {
- BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
- "{} listening to {}", this, producer);
- synchronized (values) {
- T vo = values.get(producer);
- if (vo==null) {
- T initialVal;
- if (sourceSensor instanceof AttributeSensor) {
- initialVal = producer.getAttribute((AttributeSensor<T>)sourceSensor);
- } else {
- initialVal = null;
- }
- values.put(producer, initialVal != null ? initialVal : defaultMemberValue);
- //we might skip in onEvent in the short window while !values.containsKey(producer)
- //but that's okay because the put which would have been done there is done here now
- } else {
- //vo will be null unless some weird race with addProducer+removeProducer is occuring
- //(and that's something we can tolerate i think)
- if (LOG.isDebugEnabled()) LOG.debug("{} already had value ({}) for producer ({}); but that producer has just been added", new Object[] {this, vo, producer});
- }
- }
- }
-
- @Override
- protected Predicate<?> getDefaultValueFilter() {
- if (getConfig(EXCLUDE_BLANK))
- return StringPredicates.isNonBlank();
- else
- return Predicates.alwaysTrue();
- }
-
- @Override
- protected void onProducerRemoved(Entity producer) {
- values.remove(producer);
- onUpdated();
- }
-
- @Override
- public void onEvent(SensorEvent<T> event) {
- Entity e = event.getSource();
- synchronized (values) {
- if (values.containsKey(e)) {
- values.put(e, event.getValue());
- } else {
- if (LOG.isDebugEnabled()) LOG.debug("{} received event for unknown producer ({}); presumably that producer has recently been removed", this, e);
- }
- }
- onUpdated();
- }
-
- protected void onUpdated() {
- try {
- emit(targetSensor, compute());
- } catch (Throwable t) {
- LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
- throw Exceptions.propagate(t);
- }
- }
-
- @Override
- protected Object compute() {
- synchronized (values) {
- // TODO Could avoid copying when filter not needed
- List<T> vs = MutableList.copyOf(Iterables.filter(values.values(), valueFilter));
- if (transformation==null) return vs;
- return transformation.apply(vs);
- }
- }
-
- protected Map<Entity, T> copyOfValues() {
- // Don't use ImmutableMap, as can contain null values
- synchronized (values) {
- return Collections.unmodifiableMap(MutableMap.copyOf(values));
- }
- }
-
-}
[08/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to
o.a.b.core.effector
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
new file mode 100644
index 0000000..37e582d
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasks.java
@@ -0,0 +1,335 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector.ssh;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.StringConfigMap;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigUtils;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshTasks;
+import org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.ssh.BashCommands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+/**
+ * Conveniences for generating {@link Task} instances to perform SSH activities.
+ * <p>
+ * If the {@link SshMachineLocation machine} is not specified directly it
+ * will be inferred from the {@link Entity} context of either the {@link Effector}
+ * or the current {@link Task}.
+ *
+ * @see SshTasks
+ * @since 0.6.0
+ */
+@Beta
+public class SshEffectorTasks {
+
+ private static final Logger log = LoggerFactory.getLogger(SshEffectorTasks.class);
+
+ public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
+ "Whether to ignore any ssh flags (behaviour constraints) set on the entity or location " +
+ "where this is running, using only flags explicitly specified", false);
+
+ /**
+ * Like {@link EffectorBody} but providing conveniences when in an entity with a single machine location.
+ */
+ public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
+
+ /** convenience for accessing the machine */
+ public SshMachineLocation machine() {
+ return EffectorTasks.getSshMachine(entity());
+ }
+
+ /** convenience for generating an {@link PlainSshExecTaskFactory} which can be further customised if desired, and then (it must be explicitly) queued */
+ public ProcessTaskFactory<Integer> ssh(String ...commands) {
+ return new SshEffectorTaskFactory<Integer>(commands).machine(machine());
+ }
+ }
+
+ /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link EffectorTaskFactory} signature so can be used directly as an impl for an effector,
+ * also injects the machine automatically; can also be used outwith effector contexts, and machine is still injected if it is
+ * run from inside a task at an entity with a single SshMachineLocation */
+ public static class SshEffectorTaskFactory<RET> extends AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements EffectorTaskFactory<RET> {
+
+ public SshEffectorTaskFactory(String ...commands) {
+ super(commands);
+ }
+ public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
+ super(machine, commands);
+ }
+ @Override
+ public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> effector, ConfigBag parameters) {
+ markDirty();
+ if (summary==null) summary(effector.getName()+" (ssh)");
+ machine(EffectorTasks.getSshMachine(entity));
+ return newTask();
+ }
+ @Override
+ public synchronized ProcessTaskWrapper<RET> newTask() {
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ if (machine==null) {
+ if (log.isDebugEnabled())
+ log.debug("Using an ssh task not in an effector without any machine; will attempt to infer the machine: "+this);
+ if (entity!=null)
+ machine(EffectorTasks.getSshMachine(entity));
+ }
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+
+ @Override
+ public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType type) {
+ return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
+ }
+
+ @Override
+ public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
+ return (SshEffectorTaskFactory<Boolean>) super.returningIsExitCodeZero();
+ }
+
+ public SshEffectorTaskFactory<String> requiringZeroAndReturningStdout() {
+ return (SshEffectorTaskFactory<String>) super.requiringZeroAndReturningStdout();
+ }
+
+ public <RET2> SshEffectorTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
+ return (SshEffectorTaskFactory<RET2>) super.returning(resultTransformation);
+ }
+ }
+
+ public static class SshPutEffectorTaskFactory extends SshPutTaskFactory implements EffectorTaskFactory<Void> {
+ public SshPutEffectorTaskFactory(String remoteFile) {
+ super(remoteFile);
+ }
+ public SshPutEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
+ super(machine, remoteFile);
+ }
+ @Override
+ public SshPutTaskWrapper newTask(Entity entity, Effector<Void> effector, ConfigBag parameters) {
+ machine(EffectorTasks.getSshMachine(entity));
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ @Override
+ public SshPutTaskWrapper newTask() {
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ if (machine==null) {
+ if (log.isDebugEnabled())
+ log.debug("Using an ssh put task not in an effector without any machine; will attempt to infer the machine: "+this);
+ if (entity!=null) {
+ machine(EffectorTasks.getSshMachine(entity));
+ }
+
+ }
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ }
+
+ public static class SshFetchEffectorTaskFactory extends SshFetchTaskFactory implements EffectorTaskFactory<String> {
+ public SshFetchEffectorTaskFactory(String remoteFile) {
+ super(remoteFile);
+ }
+ public SshFetchEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
+ super(machine, remoteFile);
+ }
+ @Override
+ public SshFetchTaskWrapper newTask(Entity entity, Effector<String> effector, ConfigBag parameters) {
+ machine(EffectorTasks.getSshMachine(entity));
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ @Override
+ public SshFetchTaskWrapper newTask() {
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ if (machine==null) {
+ if (log.isDebugEnabled())
+ log.debug("Using an ssh fetch task not in an effector without any machine; will attempt to infer the machine: "+this);
+ if (entity!=null)
+ machine(EffectorTasks.getSshMachine(entity));
+ }
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ }
+
+ public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
+ return new SshEffectorTaskFactory<Integer>(commands);
+ }
+
+ public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
+ return ssh(commands.toArray(new String[commands.size()]));
+ }
+
+ public static SshPutTaskFactory put(String remoteFile) {
+ return new SshPutEffectorTaskFactory(remoteFile);
+ }
+
+ public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
+ return new SshFetchEffectorTaskFactory(remoteFile);
+ }
+
+ /** task which returns 0 if pid is running */
+ public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
+ return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit code)").allowingNonZeroExitCode();
+ }
+
+ /** task which fails if the given PID is not running */
+ public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
+ return codePidRunning(pid).summary("PID "+pid+" is-running check (required)").requiringExitCodeZero("Process with PID "+pid+" is required to be running");
+ }
+
+ /** as {@link #codePidRunning(Integer)} but returning boolean */
+ public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
+ return codePidRunning(pid).summary("PID "+pid+" is-running check (boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+ public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return Integer.valueOf(0).equals(input.getExitCode()); }
+ });
+ }
+
+
+ /** task which returns 0 if pid in the given file is running;
+ * method accepts wildcards so long as they match a single file on the remote end
+ * <p>
+ * returns 1 if no matching file,
+ * 1 if matching file but no matching process,
+ * and 2 if 2+ matching files */
+ public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final String pidFile) {
+ return ssh(BashCommands.chain(
+ // this fails, but isn't an error
+ BashCommands.requireTest("-f "+pidFile, "The PID file "+pidFile+" does not exist."),
+ // this fails and logs an error picked up later
+ BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", "ERROR: there are multiple matching PID files"),
+ // this fails and logs an error picked up later
+ BashCommands.require("cat "+pidFile, "ERROR: the PID file "+pidFile+" cannot be read (permissions?)."),
+ // finally check the process
+ "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" is-running check (exit code)")
+ .allowingNonZeroExitCode()
+ .addCompletionListener(new Function<ProcessTaskWrapper<?>,Void>() {
+ public Void apply(ProcessTaskWrapper<?> input) {
+ if (input.getStderr().contains("ERROR:"))
+ throw new IllegalStateException("Invalid or inaccessible PID filespec: "+pidFile);
+ return null;
+ }
+ });
+ }
+
+ /** task which fails if the pid in the given file is not running (or if there is no such PID file);
+ * method accepts wildcards so long as they match a single file on the remote end (fails if 0 or 2+ matching files) */
+ public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String pidFile) {
+ return codePidFromFileRunning(pidFile)
+ .summary("PID file "+pidFile+" is-running check (required)")
+ .requiringExitCodeZero("Process with PID from file "+pidFile+" is required to be running");
+ }
+
+ /** as {@link #codePidFromFileRunning(String)} but returning boolean */
+ public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String pidFile) {
+ return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" is-running check (boolean)").
+ returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+ public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return ((Integer)0).equals(input.getExitCode()); }
+ });
+ }
+
+ /** extracts the values for the main brooklyn.ssh.config.* config keys (i.e. those declared in ConfigKeys)
+ * as declared on the entity, and inserts them in a map using the unprefixed state, for ssh.
+ * <p>
+ * currently this is computed for each call, which may be wasteful, but it is reliable in the face of config changes.
+ * we could cache the Map. note that we do _not_ cache (or even own) the SshTool;
+ * the SshTool is created or re-used by the SshMachineLocation making use of these properties */
+ @Beta
+ public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
+ ConfigBag allConfig = ConfigBag.newInstance();
+
+ StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
+ allConfig.putAll(globalConfig.getAllConfig());
+
+ if (optionalLocation!=null)
+ allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
+
+ allConfig.putAll(((EntityInternal)entity).getAllConfig());
+
+ Map<String, Object> result = Maps.newLinkedHashMap();
+ for (String keyS : allConfig.getAllConfig().keySet()) {
+ if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
+ ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
+
+ Object val = allConfig.getStringKey(keyS);
+
+ /*
+ * NOV 2013 changing this to rely on config above being inserted in the right order,
+ * so entity config will be preferred over location, and location over global.
+ * If that is consistent then remove the lines below.
+ * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
+ */
+
+// // have to use raw config to test whether the config is set
+// Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
+// if (val!=null) {
+// val = entity.getConfig(key);
+// } else {
+// val = globalConfig.getRawConfig(key);
+// if (val!=null) val = globalConfig.getConfig(key);
+// }
+// if (val!=null) {
+ result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
+// }
+ }
+ }
+ return result;
+ }
+
+ private static void applySshFlags(ConfigBag config, Entity entity, Location machine) {
+ if (entity!=null) {
+ if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
+ config.putIfAbsent(getSshFlags(entity, machine));
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
index e35205a..ca561e1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
@@ -62,6 +62,7 @@ import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.config.Sanitizer;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.entity.trait.StartableMethods;
import org.apache.brooklyn.core.internal.BrooklynProperties;
@@ -76,7 +77,6 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.mgmt.internal.NonDeploymentManagementContext;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.objs.proxy.EntityProxyImpl;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
index 0db0d46..6d65f41 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityDynamicType.java
@@ -31,14 +31,14 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityType;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
+import org.apache.brooklyn.core.effector.EffectorAndBody;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorWithBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
import org.apache.brooklyn.core.objs.BrooklynDynamicType;
-import org.apache.brooklyn.effector.core.EffectorAndBody;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorWithBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.MethodEffector;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorBodyTaskFactory;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
import org.apache.brooklyn.util.javalang.Reflections;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/entity/trait/MemberReplaceable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/trait/MemberReplaceable.java b/core/src/main/java/org/apache/brooklyn/core/entity/trait/MemberReplaceable.java
index a67b1af..238e261 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/trait/MemberReplaceable.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/trait/MemberReplaceable.java
@@ -22,7 +22,7 @@ import java.util.NoSuchElementException;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.group.StopFailedRuntimeException;
public interface MemberReplaceable {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Resizable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Resizable.java b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Resizable.java
index ebf37d0..68c9398 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Resizable.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Resizable.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.core.entity.trait;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
/**
* Defines an entity group that can be re-sized dynamically.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
index 304dba2..96812ce 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Startable.java
@@ -26,10 +26,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.Tasks;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/entity/trait/StartableMethods.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/trait/StartableMethods.java b/core/src/main/java/org/apache/brooklyn/core/entity/trait/StartableMethods.java
index 47d1623..b49d259 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/trait/StartableMethods.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/trait/StartableMethods.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
index 4a018e3..49e1c1c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/EntityManagementUtils.java
@@ -36,13 +36,13 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityFunctions;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.plan.PlanNotRecognizedException;
import org.apache.brooklyn.core.plan.PlanToSpecFactory;
import org.apache.brooklyn.core.plan.PlanToSpecTransformer;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.TaskBuilder;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/EffectorUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/EffectorUtils.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/EffectorUtils.java
index 9429836..fa7eaaa 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/EffectorUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/EffectorUtils.java
@@ -33,9 +33,9 @@ import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.effector.ParameterType;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.BasicParameterType;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.BasicParameterType;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java
index 24392e6..f464d3b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/internal/LocalManagementContext.java
@@ -43,6 +43,7 @@ import org.apache.brooklyn.api.mgmt.SubscriptionManager;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.core.BrooklynFeatureEnablement;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.drivers.downloads.BasicDownloadsManager;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.internal.BrooklynProperties.Factory.Builder;
@@ -52,7 +53,6 @@ import org.apache.brooklyn.core.mgmt.ha.OsgiManager;
import org.apache.brooklyn.core.objs.proxy.InternalEntityFactory;
import org.apache.brooklyn.core.objs.proxy.InternalLocationFactory;
import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.util.core.task.BasicExecutionContext;
import org.apache.brooklyn.util.core.task.BasicExecutionManager;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
index eb07bc1..e1d704b 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
@@ -44,6 +44,10 @@ import org.apache.brooklyn.api.sensor.Feed;
import org.apache.brooklyn.core.catalog.internal.CatalogBundleDto;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.effector.BasicParameterType;
+import org.apache.brooklyn.core.effector.EffectorAndBody;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContextSequential;
import org.apache.brooklyn.core.mgmt.classloading.ClassLoaderFromBrooklynClassLoadingContext;
@@ -55,10 +59,6 @@ import org.apache.brooklyn.core.mgmt.rebind.dto.BasicFeedMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicLocationMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicPolicyMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.MutableBrooklynMemento;
-import org.apache.brooklyn.effector.core.BasicParameterType;
-import org.apache.brooklyn.effector.core.EffectorAndBody;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorBodyTaskFactory;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.xstream.XmlSerializer;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/EntityProxyImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/EntityProxyImpl.java b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/EntityProxyImpl.java
index 3b6e52a..97b8f39 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/EntityProxyImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/EntityProxyImpl.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.core.effector.EffectorWithBody;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.internal.EntityTransientCopyInternal;
@@ -41,7 +42,6 @@ import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
import org.apache.brooklyn.core.mgmt.internal.EntityManagerInternal;
import org.apache.brooklyn.core.mgmt.internal.ManagementTransitionMode;
import org.apache.brooklyn.core.mgmt.rebind.RebindManagerImpl.RebindTracker;
-import org.apache.brooklyn.effector.core.EffectorWithBody;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskTags;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/AbstractEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/AbstractEffector.java b/core/src/main/java/org/apache/brooklyn/effector/core/AbstractEffector.java
deleted file mode 100644
index 74863c8..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/AbstractEffector.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableMap;
-
-/**
- * The abstract {@link Effector} implementation.
- *
- * The concrete subclass (often anonymous) will supply the {@link #call(Entity, Map)} implementation,
- * and the fields in the constructor.
- */
-public abstract class AbstractEffector<T> extends EffectorBase<T> implements EffectorWithBody<T> {
-
- private static final long serialVersionUID = 1832435915652457843L;
-
- @SuppressWarnings("unused")
- private static final Logger LOG = LoggerFactory.getLogger(AbstractEffector.class);
-
- public AbstractEffector(String name, Class<T> returnType, List<ParameterType<?>> parameters, String description) {
- super(name, returnType, parameters, description);
- }
-
- public abstract T call(Entity entity, @SuppressWarnings("rawtypes") Map parameters);
-
- /** Convenience for named-parameter syntax (needs map in first argument) */
- public T call(Entity entity) { return call(ImmutableMap.of(), entity); }
-
- /** Convenience for named-parameter syntax (needs map in first argument) */
- public T call(@SuppressWarnings("rawtypes") Map parameters, Entity entity) { return call(entity, parameters); }
-
- /** @deprecated since 0.7.0 use {@link #getFlagsForTaskInvocationAt(Entity, Effector, ConfigBag)} */ @Deprecated
- protected final Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity) {
- return getFlagsForTaskInvocationAt(entity, this, null);
- }
- /** subclasses may override to add additional flags, but they should include the flags returned here
- * unless there is very good reason not to */
- protected Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity, Effector<T> effector, ConfigBag parameters) {
- return EffectorUtils.getTaskFlagsForEffectorInvocation(entity, effector, parameters);
- }
-
- /** not meant for overriding; subclasses should override the abstract {@link #call(Entity, Map)} method in this class */
- @Override
- public final EffectorTaskFactory<T> getBody() {
- return new EffectorTaskFactory<T>() {
- @Override
- public Task<T> newTask(final Entity entity, final Effector<T> effector, final ConfigBag parameters) {
- return new DynamicSequentialTask<T>(
- getFlagsForTaskInvocationAt(entity, AbstractEffector.this, parameters),
- new Callable<T>() {
- @Override public T call() {
- return AbstractEffector.this.call(parameters.getAllConfig(), entity);
- }
- });
- }
- };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/AddChildrenEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/AddChildrenEffector.java b/core/src/main/java/org/apache/brooklyn/effector/core/AddChildrenEffector.java
deleted file mode 100644
index 8a96e37..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/AddChildrenEffector.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
-import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult;
-import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.gson.Gson;
-
-/** Entity initializer which defines an effector which adds a child blueprint to an entity.
- * <p>
- * One of the config keys {@link #BLUEPRINT_YAML} (containing a YAML blueprint (map or string))
- * or {@link #BLUEPRINT_TYPE} (containing a string referring to a catalog type) should be supplied, but not both.
- * Parameters defined here are supplied as config during the entity creation.
- *
- * @since 0.7.0 */
-@Beta
-public class AddChildrenEffector extends AddEffector {
-
- private static final Logger log = LoggerFactory.getLogger(AddChildrenEffector.class);
-
- public static final ConfigKey<Object> BLUEPRINT_YAML = ConfigKeys.newConfigKey(Object.class, "blueprint_yaml");
- public static final ConfigKey<String> BLUEPRINT_TYPE = ConfigKeys.newStringConfigKey("blueprint_type");
- public static final ConfigKey<Boolean> AUTO_START = ConfigKeys.newBooleanConfigKey("auto_start");
-
- public AddChildrenEffector(ConfigBag params) {
- super(newEffectorBuilder(params).build());
- }
-
- public AddChildrenEffector(Map<String,String> params) {
- this(ConfigBag.newInstance(params));
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static EffectorBuilder<List<String>> newEffectorBuilder(ConfigBag params) {
- EffectorBuilder<List<String>> eff = (EffectorBuilder) AddEffector.newEffectorBuilder(List.class, params);
- eff.impl(new Body(eff.buildAbstract(), params));
- return eff;
- }
-
- protected static class Body extends EffectorBody<List<String>> {
-
- private final Effector<?> effector;
- private final String blueprintBase;
- private final Boolean autostart;
-
- public Body(Effector<?> eff, ConfigBag params) {
- this.effector = eff;
- String newBlueprint = null;
- Object yaml = params.get(BLUEPRINT_YAML);
- if (yaml instanceof Map) {
- newBlueprint = new Gson().toJson(yaml);
- } else if (yaml instanceof String) {
- newBlueprint = (String) yaml;
- } else if (yaml!=null) {
- throw new IllegalArgumentException(this+" requires map or string in "+BLUEPRINT_YAML+"; not "+yaml.getClass()+" ("+yaml+")");
- }
- String blueprintType = params.get(BLUEPRINT_TYPE);
- if (blueprintType!=null) {
- if (newBlueprint!=null) {
- throw new IllegalArgumentException(this+" cannot take both "+BLUEPRINT_TYPE+" and "+BLUEPRINT_YAML);
- }
- newBlueprint = "services: [ { type: "+blueprintType+" } ]";
- }
- if (newBlueprint==null) {
- throw new IllegalArgumentException(this+" requires either "+BLUEPRINT_TYPE+" or "+BLUEPRINT_YAML);
- }
- blueprintBase = newBlueprint;
- autostart = params.get(AUTO_START);
- }
-
- @Override
- public List<String> call(ConfigBag params) {
- params = getMergedParams(effector, params);
-
- String blueprint = blueprintBase;
- if (!params.isEmpty()) {
- blueprint = blueprint+"\n"+"brooklyn.config: "+
- new Gson().toJson(params.getAllConfig());
- }
-
- log.debug(this+" adding children to "+entity()+":\n"+blueprint);
- CreationResult<List<Entity>, List<String>> result = EntityManagementUtils.addChildren(entity(), blueprint, autostart);
- log.debug(this+" added children to "+entity()+": "+result.get());
- return result.task().getUnchecked();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/AddEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/AddEffector.java b/core/src/main/java/org/apache/brooklyn/effector/core/AddEffector.java
deleted file mode 100644
index 44f1d04..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/AddEffector.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.EntityInitializer;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.config.MapConfigKey;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-/**
- * Entity initializer which adds an effector to an entity.
- * <p>
- * This instance provides a {@link #newEffectorBuilder(Class, ConfigBag)}
- * which returns an abstract (body-less) effector defining:
- * <li> the name from {@link #EFFECTOR_NAME};
- * <li> the description from {@link #EFFECTOR_DESCRIPTION}
- * <li> the parameters from {@link #EFFECTOR_PARAMETER_DEFS}
- * <p>
- * Callers should pass the effector to instantiate into the constructor.
- * Often subclasses will supply a constructor which takes a ConfigBag of parameters,
- * and a custom {@link #newEffectorBuilder(Class, ConfigBag)} which adds the body
- * before passing to this class.
- * <p>
- * Note that the parameters passed to the call method in the body of the effector implementation
- * are only those supplied by a user at runtime; in order to merge with default
- * values, use {@link #getMergedParams(Effector, ConfigBag)}.
- *
- * @since 0.7.0 */
-@Beta
-public class AddEffector implements EntityInitializer {
-
- public static final ConfigKey<String> EFFECTOR_NAME = ConfigKeys.newStringConfigKey("name");
- public static final ConfigKey<String> EFFECTOR_DESCRIPTION = ConfigKeys.newStringConfigKey("description");
-
- public static final ConfigKey<Map<String,Object>> EFFECTOR_PARAMETER_DEFS = new MapConfigKey<Object>(Object.class, "parameters");
-
- final Effector<?> effector;
-
- public AddEffector(Effector<?> effector) {
- this.effector = Preconditions.checkNotNull(effector, "effector");
- }
-
- @Override
- public void apply(EntityLocal entity) {
- ((EntityInternal)entity).getMutableEntityType().addEffector(effector);
- }
-
- public static <T> EffectorBuilder<T> newEffectorBuilder(Class<T> type, ConfigBag params) {
- String name = Preconditions.checkNotNull(params.get(EFFECTOR_NAME), "name must be supplied when defining an effector: %s", params);
- EffectorBuilder<T> eff = Effectors.effector(type, name);
- eff.description(params.get(EFFECTOR_DESCRIPTION));
-
- Map<String, Object> paramDefs = params.get(EFFECTOR_PARAMETER_DEFS);
- if (paramDefs!=null) {
- for (Map.Entry<String, Object> paramDef: paramDefs.entrySet()){
- if (paramDef!=null) {
- String paramName = paramDef.getKey();
- Object value = paramDef.getValue();
- if (value==null) value = Collections.emptyMap();
- if (!(value instanceof Map)) {
- if (value instanceof CharSequence && Strings.isBlank((CharSequence) value))
- value = Collections.emptyMap();
- }
- if (!(value instanceof Map))
- throw new IllegalArgumentException("Illegal argument of type "+value.getClass()+" value '"+value+"' supplied as parameter definition "
- + "'"+paramName);
- eff.parameter(ConfigKeys.DynamicKeys.newNamedInstance(paramName, (Map<?, ?>) value));
- }
- }
- }
-
- return eff;
- }
-
- /** returns a ConfigBag containing the merger of the supplied parameters with default values on the effector-defined parameters */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public static ConfigBag getMergedParams(Effector<?> eff, ConfigBag params) {
- ConfigBag result = ConfigBag.newInstanceCopying(params);
- for (ParameterType<?> param: eff.getParameters()) {
- ConfigKey key = Effectors.asConfigKey(param);
- if (!result.containsKey(key))
- result.configure(key, params.get(key));
- }
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/AddSensor.java b/core/src/main/java/org/apache/brooklyn/effector/core/AddSensor.java
deleted file mode 100644
index 84c2239..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/AddSensor.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntityInitializer;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.javalang.Boxing;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-/**
- * Creates a new {@link AttributeSensor} on an entity.
- * <p>
- * The configuration can include the sensor {@code name}, {@code period} and {@code targetType}.
- * For the targetType, currently this only supports classes on the initial classpath, not those in
- * OSGi bundles added at runtime.
- *
- * @since 0.7.0
- */
-@Beta
-public class AddSensor<T> implements EntityInitializer {
-
- public static final ConfigKey<String> SENSOR_NAME = ConfigKeys.newStringConfigKey("name", "The name of the sensor to create");
- public static final ConfigKey<Duration> SENSOR_PERIOD = ConfigKeys.newConfigKey(Duration.class, "period", "Period, including units e.g. 1m or 5s or 200ms; default 5 minutes", Duration.FIVE_MINUTES);
- public static final ConfigKey<String> SENSOR_TYPE = ConfigKeys.newStringConfigKey("targetType", "Target type for the value; default String", "java.lang.String");
-
- protected final String name;
- protected final Duration period;
- protected final String type;
- protected final AttributeSensor<T> sensor;
-
- public AddSensor(Map<String, String> params) {
- this(ConfigBag.newInstance(params));
- }
-
- public AddSensor(final ConfigBag params) {
- this.name = Preconditions.checkNotNull(params.get(SENSOR_NAME), "Name must be supplied when defining a sensor");
- this.period = params.get(SENSOR_PERIOD);
- this.type = params.get(SENSOR_TYPE);
- this.sensor = newSensor();
- }
-
- @Override
- public void apply(EntityLocal entity) {
- ((EntityInternal) entity).getMutableEntityType().addSensor(sensor);
- }
-
- private AttributeSensor<T> newSensor() {
- String className = getFullClassName(type);
- Class<T> clazz = getType(className);
- return Sensors.newSensor(clazz, name);
- }
-
- @SuppressWarnings("unchecked")
- protected Class<T> getType(String className) {
- try {
- // TODO use OSGi loader (low priority however); also ensure that allows primitives
- Maybe<Class<?>> primitive = Boxing.getPrimitiveType(className);
- if (primitive.isPresent()) return (Class<T>) primitive.get();
- return (Class<T>) Class.forName(className);
- } catch (ClassNotFoundException e) {
- if (!className.contains(".")) {
- // could be assuming "java.lang" package; try again with that
- try {
- return (Class<T>) Class.forName("java.lang."+className);
- } catch (ClassNotFoundException e2) {
- throw new IllegalArgumentException("Invalid target type for sensor "+name+": " + className+" (also tried java.lang."+className+")");
- }
- } else {
- throw new IllegalArgumentException("Invalid target type for sensor "+name+": " + className);
- }
- }
- }
-
- protected String getFullClassName(String className) {
- if (className.equalsIgnoreCase("string")) {
- return "java.lang.String";
- } else if (className.equalsIgnoreCase("int") || className.equalsIgnoreCase("integer")) {
- return "java.lang.Integer";
- } else if (className.equalsIgnoreCase("long")) {
- return "java.lang.Long";
- } else if (className.equalsIgnoreCase("float")) {
- return "java.lang.Float";
- } else if (className.equalsIgnoreCase("double")) {
- return "java.lang.Double";
- } else if (className.equalsIgnoreCase("bool") || className.equalsIgnoreCase("boolean")) {
- return "java.lang.Boolean";
- } else if (className.equalsIgnoreCase("byte")) {
- return "java.lang.Byte";
- } else if (className.equalsIgnoreCase("char") || className.equalsIgnoreCase("character")) {
- return "java.lang.Character";
- } else if (className.equalsIgnoreCase("object")) {
- return "java.lang.Object";
- } else {
- return className;
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/BasicParameterType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/BasicParameterType.java b/core/src/main/java/org/apache/brooklyn/effector/core/BasicParameterType.java
deleted file mode 100644
index 2367cd0..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/BasicParameterType.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.effector.ParameterType;
-
-import com.google.common.base.Objects;
-
-public class BasicParameterType<T> implements ParameterType<T> {
- private static final long serialVersionUID = -5521879180483663919L;
-
- private String name;
- private Class<T> type;
- private String description;
- private Boolean hasDefaultValue = null;
- private T defaultValue = null;
-
- public BasicParameterType() {
- this(Collections.emptyMap());
- }
-
- @SuppressWarnings("unchecked")
- public BasicParameterType(Map<?, ?> arguments) {
- if (arguments.containsKey("name")) name = (String) arguments.get("name");
- if (arguments.containsKey("type")) type = (Class<T>) arguments.get("type");
- if (arguments.containsKey("description")) description = (String) arguments.get("description");
- if (arguments.containsKey("defaultValue")) defaultValue = (T) arguments.get("defaultValue");
- }
-
- public BasicParameterType(String name, Class<T> type) {
- this(name, type, null, null, false);
- }
-
- public BasicParameterType(String name, Class<T> type, String description) {
- this(name, type, description, null, false);
- }
-
- public BasicParameterType(String name, Class<T> type, String description, T defaultValue) {
- this(name, type, description, defaultValue, true);
- }
-
- public BasicParameterType(String name, Class<T> type, String description, T defaultValue, boolean hasDefaultValue) {
- this.name = name;
- this.type = type;
- this.description = description;
- this.defaultValue = defaultValue;
- if (defaultValue!=null && !defaultValue.getClass().equals(Object.class)) {
- // if default value is null (or is an Object, which is ambiguous on resolution to to rebind),
- // don't bother to set this as it creates noise in the persistence files
- this.hasDefaultValue = hasDefaultValue;
- }
- }
-
- @Override
- public String getName() { return name; }
-
- @Override
- public Class<T> getParameterClass() { return type; }
-
- @Override
- public String getParameterClassName() { return type.getCanonicalName(); }
-
- @Override
- public String getDescription() { return description; }
-
- @Override
- public T getDefaultValue() {
- return hasDefaultValue() ? defaultValue : null;
- }
-
- public boolean hasDefaultValue() {
- // a new Object() was previously used to indicate no default value, but that doesn't work well across serialization boundaries!
- return hasDefaultValue!=null ? hasDefaultValue : defaultValue!=null && !defaultValue.getClass().equals(Object.class);
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this).omitNullValues()
- .add("name", name).add("description", description).add("type", getParameterClassName())
- .add("defaultValue", defaultValue)
- .toString();
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(name, description, type, defaultValue);
- }
-
- @Override
- public boolean equals(Object obj) {
- return (obj instanceof ParameterType) &&
- Objects.equal(name, ((ParameterType<?>)obj).getName()) &&
- Objects.equal(description, ((ParameterType<?>)obj).getDescription()) &&
- Objects.equal(type, ((ParameterType<?>)obj).getParameterClass()) &&
- Objects.equal(defaultValue, ((ParameterType<?>)obj).getDefaultValue());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorAndBody.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorAndBody.java b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorAndBody.java
deleted file mode 100644
index 71fbadb..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorAndBody.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.List;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Objects;
-
-@Beta // added in 0.6.0
-public class EffectorAndBody<T> extends EffectorBase<T> implements EffectorWithBody<T> {
-
- private static final long serialVersionUID = -6023389678748222968L;
- private final EffectorTaskFactory<T> body;
-
- public EffectorAndBody(Effector<T> original, EffectorTaskFactory<T> body) {
- this(original.getName(), original.getReturnType(), original.getParameters(), original.getDescription(), body);
- }
-
- public EffectorAndBody(String name, Class<T> returnType, List<ParameterType<?>> parameters, String description, EffectorTaskFactory<T> body) {
- super(name, returnType, parameters, description);
- this.body = body;
- }
-
- @Override
- public EffectorTaskFactory<T> getBody() {
- return body;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(super.hashCode(), getBody());
- }
-
- @Override
- public boolean equals(Object other) {
- return super.equals(other) && Objects.equal(getBody(), ((EffectorAndBody<?>)other).getBody());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBase.java b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBase.java
deleted file mode 100644
index 511b50b..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBase.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-
-/** concrete implementation of Effector interface,
- * but not (at this level of the hirarchy) defining an implementation
- * (see {@link EffectorTaskFactory} and {@link EffectorWithBody}) */
-public class EffectorBase<T> implements Effector<T> {
-
- @SuppressWarnings("unused")
- private static final Logger log = LoggerFactory.getLogger(EffectorBase.class);
-
- private static final long serialVersionUID = -4153962199078384835L;
-
- private final String name;
- private final Class<T> returnType;
- private final List<ParameterType<?>> parameters;
- private final String description;
-
- public EffectorBase(String name, Class<T> returnType, List<ParameterType<?>> parameters, String description) {
- this.name = name;
- this.returnType = returnType;
- this.parameters = new ArrayList<ParameterType<?>>(parameters);
- this.description = description;
- }
-
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public Class<T> getReturnType() {
- return returnType;
- }
-
- @Override
- public String getReturnTypeName() {
- return returnType.getCanonicalName();
- }
-
- @Override
- public List<ParameterType<?>> getParameters() {
- return parameters;
- }
-
- @Override
- public String getDescription() {
- return description;
- }
-
- @Override
- public String toString() {
- List<String> parameterNames = new ArrayList<String>(parameters.size());
- for (ParameterType<?> parameter: parameters) {
- String parameterName = (parameter.getName() != null) ? parameter.getName() : "<unknown>";
- parameterNames.add(parameterName);
- }
- return name+"["+Joiner.on(",").join(parameterNames)+"]";
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(name, returnType, parameters, description);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof EffectorBase)) return false;
- if (!(other.getClass().equals(getClass()))) return false;
- if (!Objects.equal(hashCode(), other.hashCode())) return false;
- return Objects.equal(getName(), ((EffectorBase<?>)other).getName()) &&
- Objects.equal(getReturnType(), ((EffectorBase<?>)other).getReturnType()) &&
- Objects.equal(getParameters(), ((EffectorBase<?>)other).getParameters()) &&
- Objects.equal(getDescription(), ((EffectorBase<?>)other).getDescription());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBody.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBody.java b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBody.java
deleted file mode 100644
index 099bc71..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorBody.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.Tasks;
-
-import com.google.common.annotations.Beta;
-
-/** Typical implementations override {@link #main(ConfigBag)} to do the work of the effector
- * <p>
- * See also {@link EffectorTasks}: possibly this will be deleted in preference for an approach based on {@link EffectorTasks}.
- *
- * @since 0.6.0
- **/
-@Beta
-public abstract class EffectorBody<T> {
- /** Does the work of the effector, either in place, or (better) by building up
- * subtasks, which can by added using {@link DynamicTasks} methods
- * (and various convenience methods which do that automatically; see subclasses of EffectorBody
- * for more info on usage; or see {@link DynamicSequentialTask} for details of the threading model
- * by which added tasks are placed in a secondary thread)
- * <p>
- * The associated entity can be accessed through the {@link #entity()} method.
- */
- public abstract T call(ConfigBag parameters);
-
- // NB: we could also support an 'init' method which is done at creation,
- // as a place where implementers can describe the structure of the task before it executes
- // (and init gets invoked in EffectorBodyTaskFactory.newTask _before_ the task is submitted and main is called)
-
-
- // ---- convenience method(s) for implementers of main -- see subclasses and *Tasks statics for more
-
- protected EntityInternal entity() {
- return (EntityInternal) BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- }
-
- protected <V extends TaskAdaptable<?>> V queue(V task) {
- return DynamicTasks.queue(task);
- }
-
- protected <V extends TaskAdaptable<?>> void queue(V task1, V task2, V ...tasks) {
- DynamicTasks.queue(task1);
- DynamicTasks.queue(task2);
- for (V task: tasks)
- DynamicTasks.queue(task);
- }
-
- protected <V extends TaskFactory<?>> void queue(V task1, V task2, V ...tasks) {
- DynamicTasks.queue(task1.newTask());
- DynamicTasks.queue(task2.newTask());
- for (V task: tasks)
- DynamicTasks.queue(task.newTask());
- }
-
- protected <U extends TaskAdaptable<?>> U queue(TaskFactory<U> task) {
- return DynamicTasks.queue(task.newTask());
- }
-
- /** see {@link DynamicTasks#waitForLast()} */
- protected Task<?> waitForLast() {
- return DynamicTasks.waitForLast();
- }
-
- /** Returns the result of the last task queued in this context, coerced to the given type */
- protected <V> V last(Class<V> type) {
- Task<?> last = waitForLast();
- if (last==null)
- throw new IllegalStateException("No last task available (in "+DynamicTasks.getTaskQueuingContext()+")");
- if (!Tasks.isQueuedOrSubmitted(last))
- throw new IllegalStateException("Last task "+last+" has not been queued or submitted; will not block on its result");
-
- return TypeCoercions.coerce(last.getUnchecked(), type);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java
deleted file mode 100644
index 249da53..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorTasks.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.location.Machines;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.TaskBuilder;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.javalang.Reflections;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-
-/**
- * Miscellaneous tasks which are useful in effectors.
- * @since 0.6.0
- */
-@Beta
-public class EffectorTasks {
-
- @SuppressWarnings("unused")
- private static final Logger log = LoggerFactory.getLogger(EffectorTasks.class);
-
- public interface EffectorTaskFactory<T> {
- public abstract TaskAdaptable<T> newTask(Entity entity, Effector<T> effector, ConfigBag parameters);
- }
-
- /** wrapper for {@link EffectorBody} which simply runs that body on each invocation;
- * the body must be thread safe and ideally stateless */
- public static class EffectorBodyTaskFactory<T> implements EffectorTaskFactory<T> {
- private final EffectorBody<T> effectorBody;
- public EffectorBodyTaskFactory(EffectorBody<T> effectorBody) {
- this.effectorBody = effectorBody;
- }
-
- @Override
- public Task<T> newTask(final Entity entity, final org.apache.brooklyn.api.effector.Effector<T> effector, final ConfigBag parameters) {
- final AtomicReference<DynamicSequentialTask<T>> dst = new AtomicReference<DynamicSequentialTask<T>>();
-
- dst.set(new DynamicSequentialTask<T>(
- getFlagsForTaskInvocationAt(entity, effector, parameters),
- new Callable<T>() {
- @Override
- public T call() throws Exception {
- try {
- DynamicTasks.setTaskQueueingContext(dst.get());
- return effectorBody.call(parameters);
- } finally {
- DynamicTasks.removeTaskQueueingContext();
- }
- }
- }) {
- @Override
- public void handleException(Throwable throwable) throws Exception {
- EffectorUtils.handleEffectorException(entity, effector, throwable);
- }
- });
- return dst.get();
- };
-
- /** @deprecated since 0.7.0 use {@link #getFlagsForTaskInvocationAt(Entity, Effector, ConfigBag)} */ @Deprecated
- protected final Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity, Effector<?> effector) {
- return getFlagsForTaskInvocationAt(entity, effector, null);
- }
- /** subclasses may override to add additional flags, but they should include the flags returned here
- * unless there is very good reason not to; default impl returns a MutableMap */
- protected Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity, Effector<?> effector, ConfigBag parameters) {
- return EffectorUtils.getTaskFlagsForEffectorInvocation(entity, effector, parameters);
- }
- }
-
- /** wrapper for {@link EffectorTaskFactory} which ensures effector task tags are applied to it if needed
- * (wrapping in a task if needed); without this, {@link EffectorBody}-based effectors get it by
- * virtue of the call to {@link #getFlagsForTaskInvocationAt(Entity,Effector,ConfigBag)} therein
- * but {@link EffectorTaskFactory}-based effectors generate a task without the right tags
- * to be able to tell using {@link BrooklynTaskTags} the effector-context of the task
- * <p>
- * this gets applied automatically so marked as package-private */
- static class EffectorMarkingTaskFactory<T> implements EffectorTaskFactory<T> {
- private final EffectorTaskFactory<T> effectorTaskFactory;
- public EffectorMarkingTaskFactory(EffectorTaskFactory<T> effectorTaskFactory) {
- this.effectorTaskFactory = effectorTaskFactory;
- }
-
- @Override
- public Task<T> newTask(final Entity entity, final org.apache.brooklyn.api.effector.Effector<T> effector, final ConfigBag parameters) {
- if (effectorTaskFactory instanceof EffectorBodyTaskFactory)
- return effectorTaskFactory.newTask(entity, effector, parameters).asTask();
- // if we're in an effector context for this effector already, then also pass through
- if (BrooklynTaskTags.isInEffectorTask(Tasks.current(), entity, effector, false))
- return effectorTaskFactory.newTask(entity, effector, parameters).asTask();
- // otherwise, create the task inside an appropriate effector body so tags, name, etc are set correctly
- return new EffectorBodyTaskFactory<T>(new EffectorBody<T>() {
- @Override
- public T call(ConfigBag parameters) {
- TaskAdaptable<T> t = DynamicTasks.queue(effectorTaskFactory.newTask(entity, effector, parameters));
- return t.asTask().getUnchecked();
- }
- }).newTask(entity, effector, parameters);
- }
- }
-
- public static <T> ConfigKey<T> asConfigKey(ParameterType<T> t) {
- return ConfigKeys.newConfigKey(t.getParameterClass(), t.getName());
- }
-
- public static <T> ParameterTask<T> parameter(ParameterType<T> t) {
- return new ParameterTask<T>(asConfigKey(t)).
- name("parameter "+t);
- }
- public static <T> ParameterTask<T> parameter(Class<T> type, String name) {
- return new ParameterTask<T>(ConfigKeys.newConfigKey(type, name)).
- name("parameter "+name+" ("+type+")");
- }
- public static <T> ParameterTask<T> parameter(final ConfigKey<T> p) {
- return new ParameterTask<T>(p);
- }
- public static class ParameterTask<T> implements EffectorTaskFactory<T> {
- final ConfigKey<T> p;
- private TaskBuilder<T> builder;
- public ParameterTask(ConfigKey<T> p) {
- this.p = p;
- this.builder = Tasks.<T>builder().name("parameter "+p);
- }
- public ParameterTask<T> name(String taskName) {
- builder.name(taskName);
- return this;
- }
- @Override
- public Task<T> newTask(Entity entity, Effector<T> effector, final ConfigBag parameters) {
- return builder.body(new Callable<T>() {
- @Override
- public T call() throws Exception {
- return parameters.get(p);
- }
-
- }).build();
- }
-
- }
-
- public static <T> EffectorTaskFactory<T> of(final Task<T> task) {
- return new EffectorTaskFactory<T>() {
- @Override
- public Task<T> newTask(Entity entity, Effector<T> effector, ConfigBag parameters) {
- return task;
- }
- };
- }
-
- /** Finds the entity where this task is running
- * @throws NullPointerException if there is none (no task, or no context entity for that task) */
- public static Entity findEntity() {
- return Preconditions.checkNotNull(BrooklynTaskTags.getTargetOrContextEntity(Tasks.current()),
- "This must be executed in a task whose execution context has a target or context entity " +
- "(i.e. it must be run from within an effector)");
- }
-
- /** Finds the entity where this task is running, casted to the given Entity subtype
- * @throws NullPointerException if there is none
- * @throws IllegalArgumentException if it is not of the indicated type */
- public static <T extends Entity> T findEntity(Class<T> type) {
- Entity t = findEntity();
- return Reflections.cast(t, type);
- }
-
- /** Finds a unique {@link SshMachineLocation} attached to the entity
- * where this task is running
- * @throws NullPointerException if {@link #findEntity()} fails
- * @throws IllegalStateException if call to {@link #getSshMachine(Entity)} fails */
- public static SshMachineLocation findSshMachine() {
- return getSshMachine(findEntity());
- }
-
- /** Finds a unique {@link SshMachineLocation} attached to the supplied entity
- * @throws IllegalStateException if there is not a unique such {@link SshMachineLocation} */
- public static SshMachineLocation getSshMachine(Entity entity) {
- try {
- return Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
- } catch (Exception e) {
- throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single SshMachineLocation, but has "+entity.getLocations(), e);
- }
- }
-
- /** Finds a unique {@link WinRmMachineLocation} attached to the supplied entity
- * @throws IllegalStateException if there is not a unique such {@link WinRmMachineLocation} */
- public static WinRmMachineLocation getWinRmMachine(Entity entity) {
- try {
- return Machines.findUniqueWinRmMachineLocation(entity.getLocations()).get();
- } catch (Exception e) {
- throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single WinRmMachineLocation, but has "+entity.getLocations(), e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorWithBody.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorWithBody.java b/core/src/main/java/org/apache/brooklyn/effector/core/EffectorWithBody.java
deleted file mode 100644
index 6ba2d30..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/EffectorWithBody.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-
-import com.google.common.annotations.Beta;
-
-@Beta // added in 0.6.0
-public interface EffectorWithBody<T> extends Effector<T> {
-
- /** returns the body of the effector, i.e. a factory which can generate tasks which can run */
- public EffectorTaskFactory<T> getBody();
-
-}
[29/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
deleted file mode 100644
index b35c329..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher
-
-import static org.testng.Assert.assertEquals
-
-import org.apache.brooklyn.api.entity.EntitySpec
-import org.apache.brooklyn.api.sensor.AttributeSensor
-import org.apache.brooklyn.core.test.entity.TestApplication
-import org.apache.brooklyn.core.test.entity.TestEntity
-import org.apache.brooklyn.core.entity.Entities
-import org.apache.brooklyn.entity.group.BasicGroup
-import org.apache.brooklyn.core.location.SimulatedLocation
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor
-import org.apache.brooklyn.test.TestUtils
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-import com.google.common.base.Function
-
-class CustomAggregatingEnricherDeprecatedTest {
-
- public static final Logger log = LoggerFactory.getLogger(CustomAggregatingEnricherDeprecatedTest.class);
-
- private static final long TIMEOUT_MS = 10*1000
- private static final long SHORT_WAIT_MS = 250
-
- TestApplication app
- TestEntity producer
-
- AttributeSensor<Integer> intSensor
- AttributeSensor<Integer> target
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() {
- app = TestApplication.Factory.newManagedInstanceForTests();
- producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor")
- target = new BasicAttributeSensor<Integer>(Long.class, "target sensor")
-
- app.start([new SimulatedLocation()])
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() {
- if (app!=null) Entities.destroyAll(app.getManagementContext());
- }
-
- @Test
- public void testEnrichersWithNoProducers() {
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher([:], intSensor, target, 11, 40)
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), 40
- }
-
- @Test
- public void testSummingEnricherWhenNoSensorValuesYet() {
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
- intSensor, target, producers:[producer], 11, 40)
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), 11
- }
-
- @Test
- public void testSingleProducerSum() {
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
- intSensor, target, null, null, producers:[producer])
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), null
- cae.onEvent(intSensor.newEvent(producer, 1))
- assertEquals cae.getAggregate(), 1
- }
-
- @Test
- public void testSummingEnricherWhenNoAndNullSensorValue() {
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
- intSensor, target, null, null, producers:[producer])
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), null
- cae.onEvent(intSensor.newEvent(producer, null))
- assertEquals cae.getAggregate(), null
- }
-
- @Test
- public void testSummingEnricherWhenNoAndNullSensorValueExplicitValue() {
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
- intSensor, target, 3 /** if null */, 5 /** if none */, producers:[producer])
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), 3
- cae.onEvent(intSensor.newEvent(producer, null))
- assertEquals cae.getAggregate(), 3
- cae.onEvent(intSensor.newEvent(producer, 1))
- assertEquals cae.getAggregate(), 1
- cae.onEvent(intSensor.newEvent(producer, 7))
- assertEquals cae.getAggregate(), 7
- }
-
- @Test
- public void testMultipleProducersSum() {
- List<TestEntity> producers = [
- app.createAndManageChild(EntitySpec.create(TestEntity.class)),
- app.createAndManageChild(EntitySpec.create(TestEntity.class)),
- app.createAndManageChild(EntitySpec.create(TestEntity.class))
- ]
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
- intSensor, target, null, null, producers:producers)
-
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), null
- cae.onEvent(intSensor.newEvent(producers[2], 1))
- assertEquals cae.getAggregate(), 1
- cae.onEvent(intSensor.newEvent(producers[0], 3))
- assertEquals cae.getAggregate(), 4
- cae.onEvent(intSensor.newEvent(producers[1], 3))
- assertEquals cae.getAggregate(), 7
-
- }
-
- @Test
- public void testAveragingEnricherWhenNoAndNullSensorValues() {
- List<TestEntity> producers = [
- app.createAndManageChild(EntitySpec.create(TestEntity.class))
- ]
- CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
- intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), null, null, producers:producers)
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), null
- cae.onEvent(intSensor.newEvent(producers[0], null))
- assertEquals cae.getAggregate(), null
- }
-
- @Test
- public void testAveragingEnricherWhenNoAndNullSensorValuesExplicit() {
- List<TestEntity> producers = [
- app.createAndManageChild(EntitySpec.create(TestEntity.class))
- ]
- CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
- intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 3 /** if null */, 5 /** if none */,
- producers:producers)
- producer.addEnricher(cae)
-
- assertEquals cae.getAggregate(), 3d
- cae.onEvent(intSensor.newEvent(producers[0], null))
- assertEquals cae.getAggregate(), 3d
- cae.onEvent(intSensor.newEvent(producers[0], 4))
- assertEquals cae.getAggregate(), 4d
- }
-
- @Test
- public void testAveragingEnricherWhenNoSensors() {
- List<TestEntity> producers = [
- ]
- CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
- intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 3 /** if null */, 5 /** if none */,
- producers:producers)
- producer.addEnricher(cae)
-
- assertEquals cae.getAggregate(), 5d
- }
-
- @Test
- public void testMultipleProducersAverage() {
- List<TestEntity> producers = [
- app.createAndManageChild(EntitySpec.create(TestEntity.class)),
- app.createAndManageChild(EntitySpec.create(TestEntity.class)),
- app.createAndManageChild(EntitySpec.create(TestEntity.class))
- ]
- CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
- intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), null, null, producers:producers)
-
- producer.addEnricher(cae)
-
- assertEquals cae.getAggregate(), null
- cae.onEvent(intSensor.newEvent(producers[0], 3))
- assertEquals cae.getAggregate(), 3d
-
- cae.onEvent(intSensor.newEvent(producers[1], 3))
- assertEquals cae.getAggregate(), 3d
-
- cae.onEvent(intSensor.newEvent(producers[2], 6))
- assertEquals cae.getAggregate(), 4d
-
- // change p2's value to 7.5, average increase of 0.5.
- cae.onEvent(intSensor.newEvent(producers[2], 7.5))
- assertEquals cae.getAggregate(), 4.5d
- }
-
- @Test
- public void testMultipleProducersAverageDefaultingZero() {
- List<TestEntity> producers = [
- app.createAndManageChild(EntitySpec.create(TestEntity.class)),
- app.createAndManageChild(EntitySpec.create(TestEntity.class)),
- app.createAndManageChild(EntitySpec.create(TestEntity.class))
- ]
- CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
- intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 0, 0, producers:producers)
-
- producer.addEnricher(cae)
-
- assertEquals cae.getAggregate(), 0d
- cae.onEvent(intSensor.newEvent(producers[0], 3))
- assertEquals cae.getAggregate(), 1d
-
- cae.onEvent(intSensor.newEvent(producers[1], 3))
- assertEquals cae.getAggregate(), 2d
-
- cae.onEvent(intSensor.newEvent(producers[2], 6))
- assertEquals cae.getAggregate(), 4d
-
- // change p2's value to 7.5, average increase of 0.5.
- cae.onEvent(intSensor.newEvent(producers[2], 7.5))
- assertEquals cae.getAggregate(), 4.5d
- }
-
- @Test
- public void testAddingAndRemovingProducers() {
- TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
- intSensor, target, null, null, producers:[p1])
-
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), null
-
- // Event by initial producer
- cae.onEvent(intSensor.newEvent(p1, 1))
- assertEquals cae.getAggregate(), 1
-
- // Add producer and fire event
- cae.addProducer(p2)
- cae.onEvent(intSensor.newEvent(p2, 4))
- assertEquals cae.getAggregate(), 5
-
- cae.removeProducer(p2)
- assertEquals cae.getAggregate(), 1
- }
-
- @Test
- public void testAggregatesNewMembersOfGroup() {
- try {
- BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class))
- TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class))
- log.debug("created $group and the entities it will contain $p1 $p2")
-
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(intSensor, target, 0, 0, allMembers:true)
- group.addEnricher(cae)
-
- assertEquals cae.getAggregate(), 0
-
- group.addMember(p1)
- p1.setAttribute(intSensor, 1)
- TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
- assertEquals cae.getAggregate(), 1
- }
-
- group.addMember(p2)
- p2.setAttribute(intSensor, 2)
- TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
- assertEquals cae.getAggregate(), 3
- }
-
- group.removeMember(p2)
- TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
- assertEquals cae.getAggregate(), 1
- }
- } catch (Exception e) {
- log.error("testAggregatesNewMembersOfGroup failed (now cleaning up): "+e)
- throw e;
- }
- }
-
- @Test(groups = "Integration")
- public void testAggregatesGroupMembersFiftyTimes() {
- for (int i=0; i<50; i++) {
- log.debug "testAggregatesNewMembersOfGroup $i"
- testAggregatesNewMembersOfGroup();
- }
- }
-
- @Test
- public void testAggregatesExistingMembersOfGroup() {
- BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
- TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
- group.addMember(p1)
- group.addMember(p2)
- p1.setAttribute(intSensor, 1)
- Entities.manage(group);
-
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(intSensor, target, null, null, allMembers:true)
- group.addEnricher(cae)
-
- assertEquals cae.getAggregate(), 1
-
- p2.setAttribute(intSensor, 2)
- TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
- assertEquals cae.getAggregate(), 3
- }
-
- group.removeMember(p2)
- TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
- assertEquals cae.getAggregate(), 1
- }
- }
-
- @Test
- public void testAppliesFilterWhenAggregatingMembersOfGroup() {
- BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- group.addMember(p1)
- group.addMember(p2)
- p1.setAttribute(intSensor, 1)
- p2.setAttribute(intSensor, 2)
- p3.setAttribute(intSensor, 4)
-
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(intSensor, target, null, null, allMembers:true, filter:{it == p1})
- group.addEnricher(cae)
-
- assertEquals cae.getAggregate(), 1
-
- group.addMember(p3)
- TestUtils.assertSucceedsContinually(timeout:SHORT_WAIT_MS) {
- assertEquals cae.getAggregate(), 1
- }
- }
-
- @Test
- public void testCustomAggregatingFunction() {
- TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- Function<Collection<Integer>,Integer> aggregator = { Collection c ->
- int result = 0; c.each { result += it*it }; return result;
- } as Function
-
- CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newEnricher(
- intSensor, target, aggregator, 0, producers:[p1])
-
- producer.addEnricher(cae)
- assertEquals cae.getAggregate(), 0
-
- // Event by producer
- cae.onEvent(intSensor.newEvent(p1, 2))
- assertEquals cae.getAggregate(), 4
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
deleted file mode 100644
index 30737b7..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.location.SimulatedLocation;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class CustomAggregatingEnricherTest extends BrooklynAppUnitTestSupport {
-
- public static final Logger log = LoggerFactory.getLogger(CustomAggregatingEnricherTest.class);
-
- private static final long TIMEOUT_MS = 10*1000;
- private static final long SHORT_WAIT_MS = 50;
-
- TestEntity entity;
- SimulatedLocation loc;
-
- AttributeSensor<Integer> intSensor;
- AttributeSensor<Double> doubleSensor;
- AttributeSensor<Integer> target;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor");
- doubleSensor = new BasicAttributeSensor<Double>(Double.class, "double sensor");
- target = new BasicAttributeSensor<Integer>(Integer.class, "target sensor");
- loc = mgmt.getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
- app.start(ImmutableList.of(loc));
- }
-
- @Test
- public void testSummingEnricherWithNoProducersDefaultsToNull() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromChildren()
- .build());
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
- }
-
- @Test
- public void testSummingEnricherWithNoProducers() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromChildren()
- .defaultValueForUnreportedSensors(11)
- .valueToReportIfNoSensors(40)
- .build());
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 40);
- }
-
- @Test
- public void testSummingEnricherWhenNoSensorValuesYet() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(entity))
- .defaultValueForUnreportedSensors(11)
- .valueToReportIfNoSensors(40)
- .build());
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 11);
- }
-
- @Test
- public void testSummingEnricherWhenNoSensorValuesYetDefaultsToNull() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(entity))
- .build());
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
- }
-
- @Test
- public void testSummingEnricherWithNoValues() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(entity))
- .build());
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
- }
-
- @Test
- public void testSummingEnricherWithOneValue() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(entity))
- .build());
-
- entity.setAttribute(intSensor, 1);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
- }
-
- @Test
- public void testSummingEnricherWhenNullSensorValue() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(entity))
- .build());
-
- entity.setAttribute(intSensor, null);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, null);
- }
-
- @Test
- public void testSummingEnricherWhenDefaultValueForUnreportedSensors() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(entity))
- .defaultValueForUnreportedSensors(3)
- .valueToReportIfNoSensors(5)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
-
- entity.setAttribute(intSensor, null);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, target, 3);
-
- entity.setAttribute(intSensor, 1);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
-
- entity.setAttribute(intSensor, 7);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 7);
- }
-
- @Test
- public void testMultipleProducersSum() {
- TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3))
- .build());
-
- producer3.setAttribute(intSensor, 1);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
-
- producer1.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
-
- producer2.setAttribute(intSensor, 4);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 7);
- }
-
- @Test
- public void testAveragingEnricherWhenNoAndNullSensorValues() {
- TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(doubleSensor)
- .computingAverage()
- .fromHardcodedProducers(ImmutableList.of(producer1))
- .build());
-
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
-
- producer1.setAttribute(intSensor, null);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
- }
-
- @Test
- public void testAveragingEnricherWhenDefaultValueForUnreportedSensors() {
- TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(doubleSensor)
- .computingAverage()
- .fromHardcodedProducers(ImmutableList.of(producer1))
- .defaultValueForUnreportedSensors(3)
- .valueToReportIfNoSensors(5)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
-
- producer1.setAttribute(intSensor, null);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, 3d);
-
- producer1.setAttribute(intSensor, 4);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 4d);
- }
-
- @Test
- public void testAveragingEnricherWhenNoSensors() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(doubleSensor)
- .computingAverage()
- .fromChildren()
- .defaultValueForUnreportedSensors(3)
- .valueToReportIfNoSensors(5)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 5d);
- }
-
- @Test
- public void testAveragingEnricherWhenNoProducersDefaultsToNull() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(doubleSensor)
- .computingAverage()
- .fromChildren()
- .build());
-
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
- }
-
- @Test
- public void testMultipleProducersAverage() {
- TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(doubleSensor)
- .computingAverage()
- .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3))
- .build());
-
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 50), entity, doubleSensor, null);
-
- producer1.setAttribute(intSensor, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
-
- producer2.setAttribute(intSensor, 1);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 2d);
-
- producer3.setAttribute(intSensor, 5);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
-
- producer2.setAttribute(intSensor, 4);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 4d);
- }
-
- @Test
- public void testMultipleProducersAverageDefaultingZero() {
- TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity producer2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity producer3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(doubleSensor)
- .computingAverage()
- .fromHardcodedProducers(ImmutableList.of(producer1, producer2, producer3))
- .defaultValueForUnreportedSensors(0)
- .valueToReportIfNoSensors(0)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 0d);
-
- producer1.setAttribute(intSensor, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 1d);
-
- producer2.setAttribute(intSensor, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 2d);
-
- producer3.setAttribute(intSensor, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, doubleSensor, 3d);
- }
-
- @Test
- public void testAggregatesNewMembersOfGroup() {
- BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- log.debug("created {} and the entities it will contain {} {}", new Object[] {group, p1, p2});
-
- group.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromMembers()
- .defaultValueForUnreportedSensors(0)
- .valueToReportIfNoSensors(0)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 0);
-
- group.addMember(p1);
- p1.setAttribute(intSensor, 1);
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
-
- group.addMember(p2);
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 3);
-
- group.removeMember(p2);
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
- }
-
- @Test(groups = "Integration", invocationCount=50)
- public void testAggregatesGroupMembersFiftyTimes() {
- testAggregatesNewMembersOfGroup();
- }
-
- @Test
- public void testAggregatesExistingMembersOfGroup() {
- BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
- TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
- group.addMember(p1);
- group.addMember(p2);
- p1.setAttribute(intSensor, 1);
- Entities.manage(group);
-
- group.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromMembers()
- .build());
-
-
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
-
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 3);
-
- group.removeMember(p2);
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
- }
-
- @Test
- public void testAggregatesMembersOfProducer() {
- BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
- TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
- group.addMember(p1);
- group.addMember(p2);
- p1.setAttribute(intSensor, 1);
- Entities.manage(group);
-
- app.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .from(group)
- .fromMembers()
- .build());
-
-
- EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
-
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(app, target, 3);
-
- group.removeMember(p2);
- EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
- }
-
- @Test
- public void testAppliesFilterWhenAggregatingMembersOfGroup() {
- BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
- TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- group.addMember(p1);
- group.addMember(p2);
- p1.setAttribute(intSensor, 1);
- p2.setAttribute(intSensor, 2);
- p3.setAttribute(intSensor, 4);
-
- group.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromMembers()
- .entityFilter(Predicates.equalTo((Entity)p1))
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(group, target, 1);
-
- group.addMember(p3);
- EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), group, target, 1);
- }
-
- @Test
- public void testAggregatesNewChidren() {
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromChildren()
- .defaultValueForUnreportedSensors(0)
- .valueToReportIfNoSensors(0)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 0);
-
- TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- p1.setAttribute(intSensor, 1);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
-
- TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
-
- Entities.unmanage(p2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
- }
-
- @Test
- public void testAggregatesExistingChildren() {
- TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- p1.setAttribute(intSensor, 1);
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromChildren()
- .build());
-
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
-
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 3);
-
- Entities.unmanage(p2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
- }
-
- @Test
- public void testAggregatesChildrenOfProducer() {
- TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- p1.setAttribute(intSensor, 1);
-
- app.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .from(entity)
- .fromChildren()
- .build());
-
-
- EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
-
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(app, target, 3);
-
- Entities.unmanage(p2);
- EntityTestUtils.assertAttributeEqualsEventually(app, target, 1);
- }
-
- @Test
- public void testAppliesFilterWhenAggregatingChildrenOfGroup() {
- TestEntity p1 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- p1.setAttribute(intSensor, 1);
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computingSum()
- .fromChildren()
- .entityFilter(Predicates.equalTo((Entity)p1))
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
-
- TestEntity p2 = entity.createAndManageChild(EntitySpec.create(TestEntity.class));
- p2.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsContinually(ImmutableMap.of("timeout", SHORT_WAIT_MS), entity, target, 1);
- }
-
- @Test
- public void testCustomAggregatingFunction() {
- TestEntity producer1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- Function<Collection<Integer>,Integer> aggregator = new Function<Collection<Integer>, Integer>() {
- public Integer apply(Collection<Integer> input) {
- int result = 1;
- for (Integer in : input) result += in*in;
- return result;
- }
- };
-
- entity.addEnricher(Enrichers.builder()
- .aggregating(intSensor)
- .publishing(target)
- .computing(aggregator)
- .fromHardcodedProducers(ImmutableList.of(producer1))
- .defaultValueForUnreportedSensors(0)
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 1);
-
- // Event by producer
- producer1.setAttribute(intSensor, 2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, target, 5);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnricherConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnricherConfigTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnricherConfigTest.java
deleted file mode 100644
index 9015d19..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnricherConfigTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.sensor.enricher.BasicEnricherTest.MyEnricher;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.testng.annotations.Test;
-
-/**
- * Test that configuration properties are usable and inherited correctly.
- */
-public class EnricherConfigTest extends BrooklynAppUnitTestSupport {
-
- // TODO These tests are a copy of PolicyConfigTest, which is a code smell.
- // However, the src/main/java code does not contain as much duplication.
-
- private BasicConfigKey<String> differentKey = new BasicConfigKey<String>(String.class, "differentkey", "diffval");
-
- @Test
- public void testConfigFlagsPassedInAtConstructionIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put("strKey", "aval")
- .put("intKey", 2)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- // this is set, because key name matches annotation on STR_KEY
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "aval");
- }
-
- @Test
- public void testUnknownConfigPassedInAtConstructionIsWarnedAndIgnored() throws Exception {
- // TODO Also assert it's warned
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(differentKey, "aval")
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(differentKey), null);
- assertEquals(enricher.getEnricherType().getConfigKey(differentKey.getName()), null);
- }
-
- @Test
- public void testConfigPassedInAtConstructionIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY, "aval")
- .put(MyEnricher.INT_KEY, 2)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- // this is not set (contrast with above)
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), MyEnricher.STR_KEY_WITH_DEFAULT.getDefaultValue());
- }
-
- @Test
- public void testConfigSetToGroovyTruthFalseIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.INT_KEY_WITH_DEFAULT, 0)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY_WITH_DEFAULT), (Integer)0);
- }
-
- @Test
- public void testConfigSetToNullIsAvailable() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY_WITH_DEFAULT, null)
- .build());
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), null);
- }
-
- @Test
- public void testConfigCanBeSetOnEnricher() throws Exception {
- MyEnricher enricher = new MyEnricher();
- enricher.config().set(MyEnricher.STR_KEY, "aval");
- enricher.config().set(MyEnricher.INT_KEY, 2);
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
- assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
- }
-
- @Test
- public void testConfigSetterOverridesConstructorValue() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY, "aval")
- .build());
- enricher.config().set(MyEnricher.STR_KEY, "diffval");
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "diffval");
- }
-
- @Test
- public void testConfigCannotBeSetAfterApplicationIsStarted() throws Exception {
- MyEnricher enricher = new MyEnricher(MutableMap.builder()
- .put(MyEnricher.STR_KEY, "origval")
- .build());
- app.addEnricher(enricher);
-
- try {
- enricher.config().set(MyEnricher.STR_KEY,"newval");
- fail();
- } catch (UnsupportedOperationException e) {
- // success
- }
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "origval");
- }
-
- @Test
- public void testConfigReturnsDefaultValueIfNotSet() throws Exception {
- MyEnricher enricher = new MyEnricher();
- app.addEnricher(enricher);
-
- assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "str key default");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
deleted file mode 100644
index ff76342..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Enricher;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityAdjuncts;
-import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.CollectionFunctionals;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.text.StringFunctions;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-@SuppressWarnings("serial")
-public class EnrichersTest extends BrooklynAppUnitTestSupport {
-
- public static final AttributeSensor<Integer> NUM1 = Sensors.newIntegerSensor("test.num1");
- public static final AttributeSensor<Integer> NUM2 = Sensors.newIntegerSensor("test.num2");
- public static final AttributeSensor<Integer> NUM3 = Sensors.newIntegerSensor("test.num3");
- public static final AttributeSensor<String> STR1 = Sensors.newStringSensor("test.str1");
- public static final AttributeSensor<String> STR2 = Sensors.newStringSensor("test.str2");
- public static final AttributeSensor<Set<Object>> SET1 = Sensors.newSensor(new TypeToken<Set<Object>>() {}, "test.set1", "set1 descr");
- public static final AttributeSensor<Long> LONG1 = Sensors.newLongSensor("test.long1");
- public static final AttributeSensor<Map<String,String>> MAP1 = Sensors.newSensor(new TypeToken<Map<String,String>>() {}, "test.map1", "map1 descr");
- @SuppressWarnings("rawtypes")
- public static final AttributeSensor<Map> MAP2 = Sensors.newSensor(Map.class, "test.map2");
-
- private TestEntity entity;
- private TestEntity entity2;
- private BasicGroup group;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testAdding() {
- Enricher enr = entity.addEnricher(Enrichers.builder()
- .combining(NUM1, NUM2)
- .publishing(NUM3)
- .computingSum()
- .build());
-
- Assert.assertEquals(EntityAdjuncts.getNonSystemEnrichers(entity), ImmutableList.of(enr));
-
- entity.setAttribute(NUM1, 2);
- entity.setAttribute(NUM2, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 5);
- }
-
- @SuppressWarnings("unchecked")
- @Test
- public void testCombiningWithCustomFunction() {
- entity.addEnricher(Enrichers.builder()
- .combining(NUM1, NUM2)
- .publishing(NUM3)
- .computing(Functions.constant(1))
- .build());
-
- entity.setAttribute(NUM1, 2);
- entity.setAttribute(NUM2, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 1);
- }
-
- @SuppressWarnings("unchecked")
- @Test(groups="Integration") // because takes a second
- public void testCombiningRespectsUnchanged() {
- entity.addEnricher(Enrichers.builder()
- .combining(NUM1, NUM2)
- .<Object>publishing(NUM3)
- .computing(new Function<Iterable<Integer>, Object>() {
- @Override public Object apply(Iterable<Integer> input) {
- if (input != null && Iterables.contains(input, 123)) {
- return Enrichers.sum(input, 0, 0, new TypeToken<Integer>(){});
- } else {
- return Entities.UNCHANGED;
- }
- }})
- .build());
-
- entity.setAttribute(NUM1, 123);
- entity.setAttribute(NUM2, 3);
- EntityTestUtils.assertAttributeEqualsEventually(entity, NUM3, 126);
-
- entity.setAttribute(NUM1, 2);
- EntityTestUtils.assertAttributeEqualsContinually(entity, NUM3, 126);
- }
-
- @Test
- public void testFromEntity() {
- entity.addEnricher(Enrichers.builder()
- .transforming(NUM1)
- .publishing(NUM1)
- .computing(Functions.<Integer>identity())
- .from(entity2)
- .build());
-
- entity2.setAttribute(NUM1, 2);
- EntityTestUtils.assertAttributeEqualsEventually(entity, NUM1, 2);
- }
-
- @Test
- public void testTransforming() {
- entity.addEnricher(Enrichers.builder()
- .transforming(STR1)
- .publishing(STR2)
- .computing(StringFunctions.append("mysuffix"))
- .build());
-
- entity.setAttribute(STR1, "myval");
- EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myvalmysuffix");
- }
-
- @Test
- public void testTransformingCastsResult() {
- entity.addEnricher(Enrichers.builder()
- .transforming(NUM1)
- .publishing(LONG1)
- .computing(Functions.constant(Long.valueOf(1)))
- .build());
-
- entity.setAttribute(NUM1, 123);
- EntityTestUtils.assertAttributeEqualsEventually(entity, LONG1, Long.valueOf(1));
- }
-
- @Test
- public void testTransformingFromEvent() {
- entity.addEnricher(Enrichers.builder()
- .transforming(STR1)
- .publishing(STR2)
- .computingFromEvent(new Function<SensorEvent<String>, String>() {
- @Override public String apply(SensorEvent<String> input) {
- return input.getValue() + "mysuffix";
- }})
- .build());
-
- entity.setAttribute(STR1, "myval");
- EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myvalmysuffix");
- }
-
- @Test(groups="Integration") // because takes a second
- public void testTransformingRespectsUnchangedButWillRepublish() {
- RecordingSensorEventListener<String> record = new RecordingSensorEventListener<>();
- app.getManagementContext().getSubscriptionManager().subscribe(entity, STR2, record);
-
- entity.addEnricher(Enrichers.builder()
- .transforming(STR1)
- .<Object>publishing(STR2)
- .computing(new Function<String, Object>() {
- @Override public Object apply(String input) {
- return ("ignoredval".equals(input)) ? Entities.UNCHANGED : input;
- }})
- .build());
- Asserts.assertThat(record.getEvents(), CollectionFunctionals.sizeEquals(0));
-
- entity.setAttribute(STR1, "myval");
- Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(1));
- EntityTestUtils.assertAttributeEquals(entity, STR2, "myval");
-
- entity.setAttribute(STR1, "ignoredval");
- EntityTestUtils.assertAttributeEqualsContinually(entity, STR2, "myval");
-
- entity.setAttribute(STR1, "myval2");
- Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(2));
- EntityTestUtils.assertAttributeEquals(entity, STR2, "myval2");
-
- entity.setAttribute(STR1, "myval2");
- entity.setAttribute(STR1, "myval2");
- entity.setAttribute(STR1, "myval3");
- Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(5));
- }
-
- public void testTransformingSuppressDuplicates() {
- RecordingSensorEventListener<String> record = new RecordingSensorEventListener<>();
- app.getManagementContext().getSubscriptionManager().subscribe(entity, STR2, record);
-
- entity.addEnricher(Enrichers.builder()
- .transforming(STR1)
- .publishing(STR2)
- .computing(Functions.<String>identity())
- .suppressDuplicates(true)
- .build());
-
- entity.setAttribute(STR1, "myval");
- Asserts.eventually(Suppliers.ofInstance(record), CollectionFunctionals.sizeEquals(1));
- EntityTestUtils.assertAttributeEquals(entity, STR2, "myval");
-
- entity.setAttribute(STR1, "myval2");
- entity.setAttribute(STR1, "myval2");
- entity.setAttribute(STR1, "myval3");
- EntityTestUtils.assertAttributeEqualsContinually(entity, STR2, "myval3");
- Asserts.assertThat(record.getEvents(), CollectionFunctionals.sizeEquals(3));
- }
-
- @Test
- public void testPropagating() {
- entity.addEnricher(Enrichers.builder()
- .propagating(ImmutableList.of(STR1))
- .from(entity2)
- .build());
-
- entity2.setAttribute(STR1, "myval");
- EntityTestUtils.assertAttributeEqualsEventually(entity, STR1, "myval");
-
- entity2.setAttribute(STR1, null);
- EntityTestUtils.assertAttributeEqualsEventually(entity, STR1, null);
- }
-
- @Test
- public void testPropagatingAndRenaming() {
- entity.addEnricher(Enrichers.builder()
- .propagating(ImmutableMap.of(STR1, STR2))
- .from(entity2)
- .build());
-
- entity2.setAttribute(STR1, "myval");
- EntityTestUtils.assertAttributeEqualsEventually(entity, STR2, "myval");
- }
-
- // FIXME What is default? members? children? fail?
- @Test
- public void testAggregatingGroupSum() {
- TestEntity child1 = group.addChild(EntitySpec.create(TestEntity.class));
- Entities.manage(child1);
- group.addMember(entity);
- group.addMember(entity2);
- group.addEnricher(Enrichers.builder()
- .aggregating(NUM1)
- .publishing(NUM2)
- .fromMembers()
- .computingSum()
- .build());
-
- child1.setAttribute(NUM1, 1);
- entity.setAttribute(NUM1, 2);
- entity2.setAttribute(NUM1, 3);
- EntityTestUtils.assertAttributeEqualsEventually(group, NUM2, 5);
- }
-
- @Test
- public void testAggregatingChildrenSum() {
- group.addMember(entity);
- TestEntity child1 = group.addChild(EntitySpec.create(TestEntity.class));
- Entities.manage(child1);
- TestEntity child2 = group.addChild(EntitySpec.create(TestEntity.class));
- Entities.manage(child2);
- group.addEnricher(Enrichers.builder()
- .aggregating(NUM1)
- .publishing(NUM2)
- .fromChildren()
- .computingSum()
- .build());
-
- entity.setAttribute(NUM1, 1);
- child1.setAttribute(NUM1, 2);
- child2.setAttribute(NUM1, 3);
- EntityTestUtils.assertAttributeEqualsEventually(group, NUM2, 5);
- }
-
- @Test
- public void testAggregatingExcludingBlankString() {
- group.addMember(entity);
- group.addMember(entity2);
- group.addEnricher(Enrichers.builder()
- .aggregating(STR1)
- .publishing(SET1)
- .fromMembers()
- .excludingBlank()
- .computing(new Function<Collection<?>, Set<Object>>() {
- @Override public Set<Object> apply(Collection<?> input) {
- // accept null values, so don't use ImmutableSet
- return (input == null) ? ImmutableSet.<Object>of() : MutableSet.<Object>copyOf(input);
- }})
- .build());
-
- entity.setAttribute(STR1, "1");
- entity2.setAttribute(STR1, "2");
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("1", "2"));
-
- entity.setAttribute(STR1, "3");
- entity2.setAttribute(STR1, null);
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("3"));
-
- entity.setAttribute(STR1, "");
- entity2.setAttribute(STR1, "4");
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of("4"));
- }
-
- @Test
- public void testAggregatingExcludingNull() {
- group.addMember(entity);
- group.addEnricher(Enrichers.builder()
- .aggregating(NUM1)
- .publishing(SET1)
- .fromMembers()
- .excludingBlank()
- .computing(new Function<Collection<?>, Set<Object>>() {
- @Override public Set<Object> apply(Collection<?> input) {
- // accept null values, so don't use ImmutableSet
- return (input == null) ? ImmutableSet.<Object>of() : MutableSet.<Object>copyOf(input);
- }})
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of());
-
- entity.setAttribute(NUM1, 1);
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of(1));
-
- entity.setAttribute(NUM1, null);
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of());
-
- entity.setAttribute(NUM1, 2);
- EntityTestUtils.assertAttributeEqualsEventually(group, SET1, ImmutableSet.<Object>of(2));
- }
-
- @Test
- public void testAggregatingCastsResult() {
- group.addMember(entity);
- group.addEnricher(Enrichers.builder()
- .aggregating(NUM1)
- .publishing(LONG1)
- .fromMembers()
- .computing(Functions.constant(Long.valueOf(1)))
- .build());
-
- entity.setAttribute(NUM1, 123);
- EntityTestUtils.assertAttributeEqualsEventually(group, LONG1, Long.valueOf(1));
- }
-
- @Test(groups="Integration") // because takes a second
- public void testAggregatingRespectsUnchanged() {
- group.addMember(entity);
- group.addEnricher(Enrichers.builder()
- .aggregating(NUM1)
- .<Object>publishing(LONG1)
- .fromMembers()
- .computing(new Function<Iterable<Integer>, Object>() {
- @Override public Object apply(Iterable<Integer> input) {
- if (input != null && Iterables.contains(input, 123)) {
- return Enrichers.sum(input, 0, 0, new TypeToken<Integer>(){});
- } else {
- return Entities.UNCHANGED;
- }
- }})
- .build());
-
- entity.setAttribute(NUM1, 123);
- EntityTestUtils.assertAttributeEqualsEventually(group, LONG1, Long.valueOf(123));
-
- entity.setAttribute(NUM1, 987654);
- EntityTestUtils.assertAttributeEqualsContinually(group, LONG1, Long.valueOf(123));
- }
- @Test
- public void testUpdatingMap1() {
- entity.addEnricher(Enrichers.builder()
- .updatingMap(MAP1)
- .from(LONG1)
- .computing(Functionals.ifEquals(-1L).value("-1 is not allowed"))
- .build());
-
- doUpdatingMapChecks(MAP1);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Test
- public void testUpdatingMap2() {
- entity.addEnricher(Enrichers.builder()
- .updatingMap((AttributeSensor)MAP2)
- .from(LONG1)
- .computing(Functionals.ifEquals(-1L).value("-1 is not allowed"))
- .build());
-
- doUpdatingMapChecks(MAP2);
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected void doUpdatingMapChecks(AttributeSensor mapSensor) {
- EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of());
-
- entity.setAttribute(LONG1, -1L);
- EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of(
- LONG1.getName(), "-1 is not allowed"));
-
- entity.setAttribute(LONG1, 1L);
- EntityTestUtils.assertAttributeEqualsEventually(entity, mapSensor, MutableMap.<String,String>of());
- }
-
- private static AttributeSensor<Object> LIST_SENSOR = Sensors.newSensor(Object.class, "sensor.list");
-
- @Test
- public void testJoinerDefault() {
- entity.addEnricher(Enrichers.builder()
- .joining(LIST_SENSOR)
- .publishing(TestEntity.NAME)
- .build());
- // null values ignored, and it quotes
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "\"b").append(null));
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "\"a\",\"\\\"b\"");
-
- // empty list causes ""
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of().append(null));
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "");
-
- // null causes null
- entity.setAttribute(LIST_SENSOR, null);
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null);
- }
-
- @Test
- public void testJoinerUnquoted() {
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "\"b", "ccc").append(null));
- entity.addEnricher(Enrichers.builder()
- .joining(LIST_SENSOR)
- .publishing(TestEntity.NAME)
- .minimum(1)
- .maximum(2)
- .separator(":")
- .quote(false)
- .build());
- // in this case, it should be immediately available upon adding the enricher
- EntityTestUtils.assertAttributeEquals(entity, TestEntity.NAME, "a:\"b");
-
- // empty list causes null here, because below the minimum
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of().append(null));
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null);
- }
-
- @Test
- public void testJoinerMinMax() {
- entity.addEnricher(Enrichers.builder()
- .joining(LIST_SENSOR)
- .publishing(TestEntity.NAME)
- .minimum(2)
- .maximum(4)
- .quote(false)
- .build());
- // null values ignored, and it quotes
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "b"));
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "a,b");
-
- // empty list causes ""
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of("x"));
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, null);
-
- // null causes null
- entity.setAttribute(LIST_SENSOR, MutableList.<String>of("a", "b", "c", "d", "e"));
- EntityTestUtils.assertAttributeEqualsEventually(entity, TestEntity.NAME, "a,b,c,d");
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
deleted file mode 100644
index 9b55006..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.enricher.SensorPropagatingEnricher;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.javalang.AtomicReferences;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-
-public class SensorPropagatingEnricherDeprecatedTest extends BrooklynAppUnitTestSupport {
-
- private TestEntity entity;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- }
-
- @Test
- public void testPropagatesSpecificSensor() {
- app.addEnricher(SensorPropagatingEnricher.newInstanceListeningTo(entity, TestEntity.NAME));
-
- // name propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
-
- // sequence not propagated
- entity.setAttribute(TestEntity.SEQUENCE, 2);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
- }
-
- @Test
- public void testPropagatesAllSensors() {
- app.addEnricher(SensorPropagatingEnricher.newInstanceListeningToAllSensors(entity));
-
- // all attributes propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- entity.setAttribute(TestEntity.SEQUENCE, 2);
-
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2);
-
- // notification-sensor propagated
- final AtomicReference<Integer> notif = new AtomicReference<Integer>();
- app.subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() {
- @Override public void onEvent(SensorEvent<Integer> event) {
- notif.set(event.getValue());
- }});
- entity.emit(TestEntity.MY_NOTIF, 7);
- Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7));
- }
-
- @Test
- public void testPropagatesAllBut() {
- app.addEnricher(SensorPropagatingEnricher.newInstanceListeningToAllSensorsBut(entity, TestEntity.SEQUENCE)) ;
-
- // name propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
-
- // sequence not propagated
- entity.setAttribute(TestEntity.SEQUENCE, 2);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
- }
-
- @Test
- public void testPropagatingAsDifferentSensor() {
- final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", "");
- app.addEnricher(SensorPropagatingEnricher.newInstanceRenaming(entity, ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE)));
-
- // name propagated as different attribute
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
deleted file mode 100644
index 82067c4..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.enricher.Propagator;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.javalang.AtomicReferences;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class SensorPropagatingEnricherTest extends BrooklynAppUnitTestSupport {
-
- private TestEntity entity;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- }
-
- @Test
- public void testPropagatesSpecificSensor() {
- app.addEnricher(Enrichers.builder()
- .propagating(TestEntity.NAME)
- .from(entity)
- .build());
-
- // name propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
-
- // sequence not propagated
- entity.setAttribute(TestEntity.SEQUENCE, 2);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
- }
-
- @Test
- public void testPropagatesCurrentValue() {
- entity.setAttribute(TestEntity.NAME, "foo");
-
- app.addEnricher(Enrichers.builder()
- .propagating(TestEntity.NAME)
- .from(entity)
- .build());
-
- // name propagated
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
- }
-
- @Test
- public void testPropagatesAllStaticSensors() {
- app.addEnricher(Enrichers.builder()
- .propagatingAll()
- .from(entity)
- .build());
-
- // all attributes propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- entity.setAttribute(TestEntity.SEQUENCE, 2);
-
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2);
-
- // notification-sensor propagated
- final AtomicReference<Integer> notif = new AtomicReference<Integer>();
- app.subscribe(app, TestEntity.MY_NOTIF, new SensorEventListener<Integer>() {
- @Override public void onEvent(SensorEvent<Integer> event) {
- notif.set(event.getValue());
- }});
- entity.emit(TestEntity.MY_NOTIF, 7);
- Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo(7));
- }
-
- @Test
- public void testPropagatesAllSensorsIncludesDynamicallyAdded() {
- AttributeSensor<String> dynamicAttribute = Sensors.newStringSensor("test.dynamicsensor.strattrib");
- BasicNotificationSensor<String> dynamicNotificationSensor = new BasicNotificationSensor(String.class, "test.dynamicsensor.strnotif");
-
- app.addEnricher(Enrichers.builder()
- .propagatingAll()
- .from(entity)
- .build());
-
- entity.setAttribute(dynamicAttribute, "foo");
-
- EntityTestUtils.assertAttributeEqualsEventually(app, dynamicAttribute, "foo");
-
- // notification-sensor propagated
- final AtomicReference<String> notif = new AtomicReference<String>();
- app.subscribe(app, dynamicNotificationSensor, new SensorEventListener<String>() {
- @Override public void onEvent(SensorEvent<String> event) {
- notif.set(event.getValue());
- }});
- entity.emit(dynamicNotificationSensor, "mynotifval");
- Asserts.eventually(AtomicReferences.supplier(notif), Predicates.equalTo("mynotifval"));
- }
-
- @Test
- public void testPropagatesAllBut() {
- app.addEnricher(Enrichers.builder()
- .propagatingAllBut(TestEntity.SEQUENCE)
- .from(entity)
- .build());
-
- // name propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
-
- // sequence not propagated
- entity.setAttribute(TestEntity.SEQUENCE, 2);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
- }
-
- @Test
- public void testPropagatingAsDifferentSensor() {
- final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", "");
-
- app.addEnricher(Enrichers.builder()
- .propagating(ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE))
- .from(entity)
- .build());
-
- // name propagated as different attribute
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo");
- }
-
- @Test
- public void testEnricherSpecPropagatesSpecificSensor() throws Exception {
- app.addEnricher(EnricherSpec.create(Propagator.class)
- .configure(MutableMap.builder()
- .putIfNotNull(Propagator.PRODUCER, entity)
- .putIfNotNull(Propagator.PROPAGATING, ImmutableList.of(TestEntity.NAME))
- .build()));
-
- // name propagated
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.NAME, "foo");
-
- // sequence not propagated
- entity.setAttribute(TestEntity.SEQUENCE, 2);
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.SEQUENCE, null);
- }
-
- @Test
- public void testEnricherSpecPropagatesSpecificSensorAndMapsOthers() throws Exception {
- final AttributeSensor<String> ANOTHER_ATTRIBUTE = Sensors.newStringSensor("another.attribute", "");
-
- app.addEnricher(EnricherSpec.create(Propagator.class)
- .configure(MutableMap.builder()
- .putIfNotNull(Propagator.PRODUCER, entity)
- .putIfNotNull(Propagator.SENSOR_MAPPING, ImmutableMap.of(TestEntity.NAME, ANOTHER_ATTRIBUTE))
- .putIfNotNull(Propagator.PROPAGATING, ImmutableList.of(TestEntity.SEQUENCE))
- .build()));
-
- // name propagated as alternative sensor
- entity.setAttribute(TestEntity.NAME, "foo");
- EntityTestUtils.assertAttributeEqualsEventually(app, ANOTHER_ATTRIBUTE, "foo");
-
- // sequence also propagated
- entity.setAttribute(TestEntity.SEQUENCE, 2);
- EntityTestUtils.assertAttributeEqualsEventually(app, TestEntity.SEQUENCE, 2);
-
- // name not propagated as original sensor
- EntityTestUtils.assertAttributeEqualsContinually(MutableMap.of("timeout", 100), app, TestEntity.NAME, null);
- }
-
- @Test
- public void testEnricherSpecThrowsOnPropagatesAndPropagatesAllSet() throws Exception {
- try {
- app.addEnricher(EnricherSpec.create(Propagator.class)
- .configure(MutableMap.builder()
- .put(Propagator.PRODUCER, entity)
- .put(Propagator.PROPAGATING, ImmutableList.of(TestEntity.NAME))
- .put(Propagator.PROPAGATING_ALL, true)
- .build()));
- } catch (Exception e) {
- IllegalStateException ise = Exceptions.getFirstThrowableOfType(e, IllegalStateException.class);
- if (ise == null) throw e;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
deleted file mode 100644
index 9db0d37..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher
-
-import java.util.concurrent.Callable
-
-import org.apache.brooklyn.api.entity.EntitySpec
-import org.apache.brooklyn.api.sensor.AttributeSensor
-import org.apache.brooklyn.core.test.entity.TestApplication
-import org.apache.brooklyn.core.test.entity.TestEntity
-import org.apache.brooklyn.core.entity.Entities
-import org.apache.brooklyn.core.location.SimulatedLocation
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor
-import org.apache.brooklyn.test.TestUtils
-import org.apache.brooklyn.util.collections.MutableMap
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.Assert
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-public class TransformingEnricherDeprecatedTest {
-
- public static final Logger log = LoggerFactory.getLogger(TransformingEnricherDeprecatedTest.class);
-
- private static final long TIMEOUT_MS = 10*1000;
-// private static final long SHORT_WAIT_MS = 250;
-
- TestApplication app;
- TestEntity producer;
- AttributeSensor<Integer> intSensorA;
- AttributeSensor<Long> target;
-
- @BeforeMethod()
- public void before() {
- app = TestApplication.Factory.newManagedInstanceForTests();
- producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a");
- target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target");
-
- app.start(Arrays.asList(new SimulatedLocation()));
- }
-
- @AfterMethod(alwaysRun=true)
- public void after() {
- if (app!=null) Entities.destroyAll(app.getManagementContext());
- }
-
- @Test
- public void testTransformingEnricher() throws InterruptedException {
- final SensorTransformingEnricher e1 = new SensorTransformingEnricher<Integer,Long>(intSensorA, target,
- { 2*it });
-
- producer.setAttribute(intSensorA, 3);
- //ensure previous values get picked up
- producer.addEnricher(e1);
-
- TestUtils.assertEventually(MutableMap.of("timeout", TIMEOUT_MS),
- new Callable<Object>() { public Object call() {
- Assert.assertEquals(producer.getAttribute(target), (Long)((long)6));
- return null;
- }});
-
- }
-}
[27/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
Rename o.a.b.sensor.feed to o.a.b.feed and o.a.b.core.feed
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/daf40919
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/daf40919
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/daf40919
Branch: refs/heads/master
Commit: daf40919b6fa20f16b6cd7d9eb1ad9f79baaa8f4
Parents: 2a78e27
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 22:56:13 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 19 22:56:13 2015 +0100
----------------------------------------------------------------------
.../brooklyn/core/entity/AbstractEntity.java | 4 +-
.../apache/brooklyn/core/feed/AbstractFeed.java | 240 ++++++
.../core/feed/AttributePollHandler.java | 248 +++++++
.../brooklyn/core/feed/ConfigToAttributes.java | 59 ++
.../core/feed/DelegatingPollHandler.java | 96 +++
.../apache/brooklyn/core/feed/FeedConfig.java | 297 ++++++++
.../apache/brooklyn/core/feed/PollConfig.java | 85 +++
.../apache/brooklyn/core/feed/PollHandler.java | 38 +
.../org/apache/brooklyn/core/feed/Poller.java | 205 ++++++
.../mgmt/rebind/BasicEntityRebindSupport.java | 2 +-
.../mgmt/rebind/BasicFeedRebindSupport.java | 2 +-
.../core/mgmt/rebind/RebindIteration.java | 2 +-
.../mgmt/rebind/dto/MementosGenerators.java | 2 +-
.../sensor/AttributeSensorAndConfigKey.java | 2 +-
.../brooklyn/core/sensor/HttpRequestSensor.java | 6 +-
.../entity/group/DynamicMultiGroupImpl.java | 4 +-
.../brooklyn/entity/stock/DataEntityImpl.java | 4 +-
.../brooklyn/feed/function/FunctionFeed.java | 208 ++++++
.../feed/function/FunctionPollConfig.java | 111 +++
.../org/apache/brooklyn/feed/http/HttpFeed.java | 382 ++++++++++
.../brooklyn/feed/http/HttpPollConfig.java | 160 ++++
.../brooklyn/feed/http/HttpPollValue.java | 40 +
.../apache/brooklyn/feed/http/HttpPolls.java | 39 +
.../brooklyn/feed/http/HttpValueFunctions.java | 154 ++++
.../brooklyn/feed/http/JsonFunctions.java | 235 ++++++
.../apache/brooklyn/feed/shell/ShellFeed.java | 273 +++++++
.../brooklyn/feed/shell/ShellPollConfig.java | 125 ++++
.../org/apache/brooklyn/feed/ssh/SshFeed.java | 290 ++++++++
.../apache/brooklyn/feed/ssh/SshPollConfig.java | 142 ++++
.../apache/brooklyn/feed/ssh/SshPollValue.java | 60 ++
.../brooklyn/feed/ssh/SshValueFunctions.java | 73 ++
.../windows/WindowsPerformanceCounterFeed.java | 412 +++++++++++
.../WindowsPerformanceCounterPollConfig.java | 53 ++
.../brooklyn/sensor/feed/AbstractFeed.java | 240 ------
.../sensor/feed/AttributePollHandler.java | 248 -------
.../sensor/feed/ConfigToAttributes.java | 59 --
.../sensor/feed/DelegatingPollHandler.java | 96 ---
.../apache/brooklyn/sensor/feed/FeedConfig.java | 297 --------
.../apache/brooklyn/sensor/feed/PollConfig.java | 85 ---
.../brooklyn/sensor/feed/PollHandler.java | 38 -
.../org/apache/brooklyn/sensor/feed/Poller.java | 205 ------
.../sensor/feed/function/FunctionFeed.java | 208 ------
.../feed/function/FunctionPollConfig.java | 111 ---
.../brooklyn/sensor/feed/http/HttpFeed.java | 382 ----------
.../sensor/feed/http/HttpPollConfig.java | 160 ----
.../sensor/feed/http/HttpPollValue.java | 40 -
.../brooklyn/sensor/feed/http/HttpPolls.java | 39 -
.../sensor/feed/http/HttpValueFunctions.java | 154 ----
.../sensor/feed/http/JsonFunctions.java | 235 ------
.../brooklyn/sensor/feed/shell/ShellFeed.java | 273 -------
.../sensor/feed/shell/ShellPollConfig.java | 125 ----
.../brooklyn/sensor/feed/ssh/SshFeed.java | 290 --------
.../brooklyn/sensor/feed/ssh/SshPollConfig.java | 142 ----
.../brooklyn/sensor/feed/ssh/SshPollValue.java | 60 --
.../sensor/feed/ssh/SshValueFunctions.java | 73 --
.../windows/WindowsPerformanceCounterFeed.java | 412 -----------
.../WindowsPerformanceCounterPollConfig.java | 53 --
.../util/core/http/HttpToolResponse.java | 2 +-
.../core/feed/ConfigToAttributesTest.java | 70 ++
.../apache/brooklyn/core/feed/PollerTest.java | 108 +++
.../core/location/TestPortSupplierLocation.java | 2 +-
.../core/mgmt/rebind/RebindFeedTest.java | 16 +-
.../feed/function/FunctionFeedTest.java | 315 ++++++++
.../feed/http/HttpFeedIntegrationTest.java | 160 ++++
.../apache/brooklyn/feed/http/HttpFeedTest.java | 392 ++++++++++
.../feed/http/HttpValueFunctionsTest.java | 94 +++
.../brooklyn/feed/http/JsonFunctionsTest.java | 130 ++++
.../feed/shell/ShellFeedIntegrationTest.java | 226 ++++++
.../feed/ssh/SshFeedIntegrationTest.java | 264 +++++++
.../WindowsPerformanceCounterFeedLiveTest.java | 104 +++
.../WindowsPerformanceCounterFeedTest.java | 132 ++++
.../sensor/feed/ConfigToAttributesTest.java | 70 --
.../apache/brooklyn/sensor/feed/PollerTest.java | 108 ---
.../sensor/feed/function/FunctionFeedTest.java | 315 --------
.../feed/http/HttpFeedIntegrationTest.java | 160 ----
.../brooklyn/sensor/feed/http/HttpFeedTest.java | 392 ----------
.../feed/http/HttpValueFunctionsTest.java | 94 ---
.../sensor/feed/http/JsonFunctionsTest.java | 130 ----
.../feed/shell/ShellFeedIntegrationTest.java | 226 ------
.../sensor/feed/ssh/SshFeedIntegrationTest.java | 264 -------
.../WindowsPerformanceCounterFeedLiveTest.java | 104 ---
.../WindowsPerformanceCounterFeedTest.java | 132 ----
.../policy/enricher/HttpLatencyDetector.java | 6 +-
.../entity/database/derby/DerbyDatabase.java | 2 +-
.../entity/database/derby/DerbySchema.java | 6 +-
.../postgresql/PostgreSqlNodeSaltImpl.java | 4 +-
.../entity/salt/SaltStackMasterImpl.java | 3 +-
.../entity/monitoring/zabbix/ZabbixFeed.java | 10 +-
.../monitoring/zabbix/ZabbixPollConfig.java | 6 +-
.../monitoring/zabbix/ZabbixServerImpl.java | 6 +-
.../nosql/hazelcast/HazelcastNodeImpl.java | 6 +-
.../brooklynnode/BrooklynClusterImpl.java | 4 +-
.../brooklynnode/BrooklynEntityMirrorImpl.java | 4 +-
.../entity/brooklynnode/BrooklynNodeImpl.java | 10 +-
.../SetHighAvailabilityModeEffectorBody.java | 4 +-
.../brooklyn/entity/chef/ChefAttributeFeed.java | 8 +-
.../entity/chef/ChefAttributePollConfig.java | 2 +-
.../brooklyn/entity/java/JavaAppUtils.java | 6 +-
.../entity/java/JmxAttributeSensor.java | 6 +-
.../apache/brooklyn/entity/java/JmxSupport.java | 2 +-
.../entity/java/VanillaJavaAppImpl.java | 2 +-
.../entity/machine/MachineEntityImpl.java | 6 +-
.../base/AbstractSoftwareProcessSshDriver.java | 2 +-
.../software/base/SoftwareProcessImpl.java | 4 +-
.../MachineLifecycleEffectorTasks.java | 2 +-
.../feed/jmx/JmxAttributePollConfig.java | 74 ++
.../org/apache/brooklyn/feed/jmx/JmxFeed.java | 423 +++++++++++
.../org/apache/brooklyn/feed/jmx/JmxHelper.java | 724 +++++++++++++++++++
.../feed/jmx/JmxNotificationFilters.java | 64 ++
.../jmx/JmxNotificationSubscriptionConfig.java | 95 +++
.../feed/jmx/JmxOperationPollConfig.java | 121 ++++
.../brooklyn/feed/jmx/JmxValueFunctions.java | 95 +++
.../sensor/feed/jmx/JmxAttributePollConfig.java | 74 --
.../brooklyn/sensor/feed/jmx/JmxFeed.java | 423 -----------
.../brooklyn/sensor/feed/jmx/JmxHelper.java | 724 -------------------
.../sensor/feed/jmx/JmxNotificationFilters.java | 64 --
.../jmx/JmxNotificationSubscriptionConfig.java | 95 ---
.../sensor/feed/jmx/JmxOperationPollConfig.java | 121 ----
.../sensor/feed/jmx/JmxValueFunctions.java | 95 ---
.../brooklyn/sensor/ssh/SshCommandSensor.java | 6 +-
.../winrm/WindowsPerformanceCounterSensors.java | 2 +-
.../BrooklynNodeIntegrationTest.java | 2 +-
.../entity/brooklynnode/BrooklynNodeTest.java | 2 +-
.../brooklynnode/SameBrooklynNodeImpl.java | 6 +-
.../brooklynnode/SelectMasterEffectorTest.java | 6 +-
.../mysql/ChefSoloDriverToyMySqlEntity.java | 4 +-
.../brooklyn/entity/java/EntityPollingTest.java | 4 +-
.../entity/java/VanillaJavaAppTest.java | 2 +-
.../base/lifecycle/ScriptHelperTest.java | 4 +-
.../software/base/test/jmx/JmxService.java | 2 +-
.../apache/brooklyn/feed/jmx/JmxFeedTest.java | 422 +++++++++++
.../apache/brooklyn/feed/jmx/JmxHelperTest.java | 311 ++++++++
.../brooklyn/feed/jmx/RebindJmxFeedTest.java | 148 ++++
.../brooklyn/sensor/feed/jmx/JmxFeedTest.java | 422 -----------
.../brooklyn/sensor/feed/jmx/JmxHelperTest.java | 311 --------
.../sensor/feed/jmx/RebindJmxFeedTest.java | 148 ----
.../entity/database/crate/CrateNodeImpl.java | 8 +-
.../database/mariadb/MariaDbNodeImpl.java | 6 +-
.../entity/database/mysql/MySqlClusterImpl.java | 4 +-
.../entity/database/mysql/MySqlNodeImpl.java | 6 +-
.../PostgreSqlNodeChefImplFromScratch.java | 4 +-
.../messaging/activemq/ActiveMQBrokerImpl.java | 4 +-
.../activemq/ActiveMQDestinationImpl.java | 4 +-
.../messaging/activemq/ActiveMQQueueImpl.java | 4 +-
.../entity/messaging/kafka/KafkaBrokerImpl.java | 6 +-
.../messaging/kafka/KafkaClusterImpl.java | 2 +-
.../entity/messaging/qpid/QpidBrokerImpl.java | 6 +-
.../messaging/qpid/QpidDestinationImpl.java | 4 +-
.../entity/messaging/qpid/QpidQueueImpl.java | 4 +-
.../entity/messaging/rabbit/RabbitQueue.java | 6 +-
.../entity/messaging/storm/StormImpl.java | 4 +-
.../entity/zookeeper/AbstractZooKeeperImpl.java | 6 +-
.../entity/monitoring/monit/MonitNodeImpl.java | 6 +-
.../nosql/cassandra/CassandraNodeImpl.java | 12 +-
.../nosql/couchbase/CouchbaseClusterImpl.java | 8 +-
.../nosql/couchbase/CouchbaseNodeImpl.java | 8 +-
.../nosql/couchbase/CouchbaseNodeSshDriver.java | 2 +-
.../couchbase/CouchbaseSyncGatewayImpl.java | 6 +-
.../entity/nosql/couchdb/CouchDBNodeImpl.java | 6 +-
.../elasticsearch/ElasticSearchNodeImpl.java | 8 +-
.../entity/nosql/mongodb/MongoDBServerImpl.java | 4 +-
.../mongodb/sharding/MongoDBRouterImpl.java | 4 +-
.../entity/nosql/redis/RedisStoreImpl.java | 8 +-
.../entity/nosql/riak/RiakNodeImpl.java | 6 +-
.../entity/nosql/solr/SolrServerImpl.java | 6 +-
.../ElasticSearchClusterIntegrationTest.java | 2 +-
.../ElasticSearchNodeIntegrationTest.java | 2 +-
.../entity/osgi/karaf/KarafContainerImpl.java | 10 +-
.../entity/proxy/AbstractControllerImpl.java | 2 +-
.../AbstractNonProvisionedControllerImpl.java | 2 +-
.../entity/proxy/nginx/NginxControllerImpl.java | 8 +-
.../ControlledDynamicWebAppClusterImpl.java | 2 +-
.../entity/webapp/jboss/JBoss6ServerImpl.java | 4 +-
.../entity/webapp/jboss/JBoss7ServerImpl.java | 6 +-
.../entity/webapp/jetty/Jetty6ServerImpl.java | 4 +-
.../webapp/nodejs/NodeJsWebAppServiceImpl.java | 8 +-
.../entity/webapp/tomcat/TomcatServerImpl.java | 4 +-
.../qa/load/SimulatedJBoss7ServerImpl.java | 10 +-
.../qa/load/SimulatedMySqlNodeImpl.java | 4 +-
.../qa/load/SimulatedNginxControllerImpl.java | 10 +-
.../brooklynnode/DeployBlueprintTest.java | 2 +-
181 files changed, 8717 insertions(+), 8718 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index 994961c..0ec5903 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -63,6 +63,8 @@ import org.apache.brooklyn.core.entity.internal.EntityConfigMap;
import org.apache.brooklyn.core.entity.lifecycle.PolicyDescriptor;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.internal.BrooklynInitialization;
import org.apache.brooklyn.core.internal.storage.BrooklynStorage;
import org.apache.brooklyn.core.internal.storage.Reference;
@@ -82,8 +84,6 @@ import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/AbstractFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/AbstractFeed.java b/core/src/main/java/org/apache/brooklyn/core/feed/AbstractFeed.java
new file mode 100644
index 0000000..a31b73e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/AbstractFeed.java
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.FeedMemento;
+import org.apache.brooklyn.api.sensor.Feed;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.BrooklynFeatureEnablement;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.rebind.BasicFeedRebindSupport;
+import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Captures common fields and processes for sensor feeds.
+ * These generally poll or subscribe to get sensor values for an entity.
+ * They make it easy to poll over http, jmx, etc.
+ */
+public abstract class AbstractFeed extends AbstractEntityAdjunct implements Feed {
+
+ private static final Logger log = LoggerFactory.getLogger(AbstractFeed.class);
+
+ public static final ConfigKey<Boolean> ONLY_IF_SERVICE_UP = ConfigKeys.newBooleanConfigKey("feed.onlyIfServiceUp", "", false);
+
+ private final Object pollerStateMutex = new Object();
+ private transient volatile Poller<?> poller;
+ private transient volatile boolean activated;
+ private transient volatile boolean suspended;
+
+ public AbstractFeed() {
+ }
+
+ /**
+ * @deprecated since 0.7.0; use no-arg constructor; call {@link #setEntity(EntityLocal)}
+ */
+ @Deprecated
+ public AbstractFeed(EntityLocal entity) {
+ this(entity, false);
+ }
+
+ /**
+ * @deprecated since 0.7.0; use no-arg constructor; call {@link #setEntity(EntityLocal)} and {@code setConfig(ONLY_IF_SERVICE_UP, onlyIfServiceUp)}
+ */
+ @Deprecated
+ public AbstractFeed(EntityLocal entity, boolean onlyIfServiceUp) {
+ this.entity = checkNotNull(entity, "entity");
+ setConfig(ONLY_IF_SERVICE_UP, onlyIfServiceUp);
+ }
+
+ // Ensure idempotent, as called in builders (in case not registered with entity), and also called
+ // when registering with entity
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_FEED_REGISTRATION_PROPERTY)) {
+ ((EntityInternal)entity).feeds().addFeed(this);
+ }
+ }
+
+ protected void initUniqueTag(String uniqueTag, Object ...valsForDefault) {
+ if (Strings.isNonBlank(uniqueTag)) this.uniqueTag = uniqueTag;
+ else this.uniqueTag = getDefaultUniqueTag(valsForDefault);
+ }
+
+ protected String getDefaultUniqueTag(Object ...valsForDefault) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(JavaClassNames.simpleClassName(this));
+ if (valsForDefault.length==0) {
+ sb.append("@");
+ sb.append(hashCode());
+ } else if (valsForDefault.length==1 && valsForDefault[0] instanceof Collection){
+ sb.append(Strings.toUniqueString(valsForDefault[0], 80));
+ } else {
+ sb.append("[");
+ boolean first = true;
+ for (Object x: valsForDefault) {
+ if (!first) sb.append(";");
+ else first = false;
+ sb.append(Strings.toUniqueString(x, 80));
+ }
+ sb.append("]");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public void start() {
+ if (log.isDebugEnabled()) log.debug("Starting feed {} for {}", this, entity);
+ if (activated) {
+ throw new IllegalStateException(String.format("Attempt to start feed %s of entity %s when already running",
+ this, entity));
+ }
+ if (poller != null) {
+ throw new IllegalStateException(String.format("Attempt to re-start feed %s of entity %s", this, entity));
+ }
+
+ poller = new Poller<Object>(entity, getConfig(ONLY_IF_SERVICE_UP));
+ activated = true;
+ preStart();
+ synchronized (pollerStateMutex) {
+ // don't start poller if we are suspended
+ if (!suspended) {
+ poller.start();
+ }
+ }
+ }
+
+ @Override
+ public void suspend() {
+ synchronized (pollerStateMutex) {
+ if (activated && !suspended) {
+ poller.stop();
+ }
+ suspended = true;
+ }
+ }
+
+ @Override
+ public void resume() {
+ synchronized (pollerStateMutex) {
+ if (activated && suspended) {
+ poller.start();
+ }
+ suspended = false;
+ }
+ }
+
+ @Override
+ public void destroy() {
+ stop();
+ }
+
+ @Override
+ public void stop() {
+ if (!activated) {
+ log.debug("Ignoring attempt to stop feed {} of entity {} when not running", this, entity);
+ return;
+ }
+ if (log.isDebugEnabled()) log.debug("stopping feed {} for {}", this, entity);
+
+ activated = false;
+ preStop();
+ synchronized (pollerStateMutex) {
+ if (!suspended) {
+ poller.stop();
+ }
+ }
+ postStop();
+ super.destroy();
+ }
+
+ @Override
+ public boolean isActivated() {
+ return activated;
+ }
+
+ public EntityLocal getEntity() {
+ return entity;
+ }
+
+ protected boolean isConnected() {
+ // TODO Default impl will result in multiple logs for same error if becomes unreachable
+ // (e.g. if ssh gets NoRouteToHostException, then every AttributePollHandler for that
+ // feed will log.warn - so if polling for 10 sensors/attributes will get 10 log messages).
+ // Would be nice if reduced this logging duplication.
+ // (You can reduce it by providing a better 'isConnected' implementation of course.)
+ return isRunning() && entity!=null && !((EntityInternal)entity).getManagementSupport().isNoLongerManaged();
+ }
+
+ @Override
+ public boolean isSuspended() {
+ return suspended;
+ }
+
+ @Override
+ public boolean isRunning() {
+ return isActivated() && !isSuspended() && !isDestroyed() && getPoller()!=null && getPoller().isRunning();
+ }
+
+ @Override
+ public RebindSupport<FeedMemento> getRebindSupport() {
+ return new BasicFeedRebindSupport(this);
+ }
+
+ @Override
+ protected void onChanged() {
+ // TODO Auto-generated method stub
+ }
+
+ /**
+ * For overriding.
+ */
+ protected void preStart() {
+ }
+
+ /**
+ * For overriding.
+ */
+ protected void preStop() {
+ }
+
+ /**
+ * For overriding.
+ */
+ protected void postStop() {
+ }
+
+ /**
+ * For overriding, where sub-class can change return-type generics!
+ */
+ protected Poller<?> getPoller() {
+ return poller;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/AttributePollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/AttributePollHandler.java b/core/src/main/java/org/apache/brooklyn/core/feed/AttributePollHandler.java
new file mode 100644
index 0000000..c266836
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/AttributePollHandler.java
@@ -0,0 +1,248 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle.Transition;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+
+/**
+ * Handler for when polling an entity's attribute. On each poll result the entity's attribute is set.
+ *
+ * Calls to onSuccess and onError will happen sequentially, but may be called from different threads
+ * each time. Note that no guarantees of a synchronized block exist, so additional synchronization
+ * would be required for the Java memory model's "happens before" relationship.
+ *
+ * @author aled
+ */
+public class AttributePollHandler<V> implements PollHandler<V> {
+
+ public static final Logger log = LoggerFactory.getLogger(AttributePollHandler.class);
+
+ private final FeedConfig<V,?,?> config;
+ private final EntityLocal entity;
+ @SuppressWarnings("rawtypes")
+ private final AttributeSensor sensor;
+ private final AbstractFeed feed;
+ private final boolean suppressDuplicates;
+
+ // allow 30 seconds before logging at WARN, if there has been no success yet;
+ // after success WARN immediately
+ // TODO these should both be configurable
+ private Duration logWarningGraceTimeOnStartup = Duration.THIRTY_SECONDS;
+ private Duration logWarningGraceTime = Duration.millis(0);
+
+ // internal state to look after whether to log warnings
+ private volatile Long lastSuccessTime = null;
+ private volatile Long currentProblemStartTime = null;
+ private volatile boolean currentProblemLoggedAsWarning = false;
+ private volatile boolean lastWasProblem = false;
+
+
+ public AttributePollHandler(FeedConfig<V,?,?> config, EntityLocal entity, AbstractFeed feed) {
+ this.config = checkNotNull(config, "config");
+ this.entity = checkNotNull(entity, "entity");
+ this.sensor = checkNotNull(config.getSensor(), "sensor");
+ this.feed = checkNotNull(feed, "feed");
+ this.suppressDuplicates = config.getSupressDuplicates();
+ }
+
+ @Override
+ public boolean checkSuccess(V val) {
+ // Always true if no checkSuccess predicate was configured.
+ return !config.hasCheckSuccessHandler() || config.getCheckSuccess().apply(val);
+ }
+
+ @Override
+ public void onSuccess(V val) {
+ if (lastWasProblem) {
+ if (currentProblemLoggedAsWarning) {
+ log.info("Success (following previous problem) reading "+getBriefDescription());
+ } else {
+ log.debug("Success (following previous problem) reading "+getBriefDescription());
+ }
+ lastWasProblem = false;
+ currentProblemStartTime = null;
+ currentProblemLoggedAsWarning = false;
+ }
+ lastSuccessTime = System.currentTimeMillis();
+ if (log.isTraceEnabled()) log.trace("poll for {} got: {}", new Object[] {getBriefDescription(), val});
+
+ try {
+ setSensor(transformValueOnSuccess(val));
+ } catch (Exception e) {
+ if (feed.isConnected()) {
+ log.warn("unable to compute "+getBriefDescription()+"; on val="+val, e);
+ } else {
+ if (log.isDebugEnabled()) log.debug("unable to compute "+getBriefDescription()+"; val="+val+" (when inactive)", e);
+ }
+ }
+ }
+
+ /** allows post-processing, such as applying a success handler;
+ * default applies the onSuccess handler (which is recommended) */
+ protected Object transformValueOnSuccess(V val) {
+ return config.hasSuccessHandler() ? config.getOnSuccess().apply(val) : val;
+ }
+
+ @Override
+ public void onFailure(V val) {
+ if (!config.hasFailureHandler()) {
+ onException(new Exception("checkSuccess of "+this+" for "+getBriefDescription()+" was false but poller has no failure handler"));
+ } else {
+ logProblem("failure", val);
+
+ try {
+ setSensor(config.hasFailureHandler() ? config.getOnFailure().apply((V)val) : val);
+ } catch (Exception e) {
+ if (feed.isConnected()) {
+ log.warn("Error computing " + getBriefDescription() + "; val=" + val+": "+ e, e);
+ } else {
+ if (log.isDebugEnabled())
+ log.debug("Error computing " + getBriefDescription() + "; val=" + val + " (when inactive)", e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onException(Exception exception) {
+ if (!feed.isConnected()) {
+ if (log.isTraceEnabled()) log.trace("Read of {} in {} gave exception (while not connected or not yet connected): {}", new Object[] {this, getBriefDescription(), exception});
+ } else {
+ logProblem("exception", exception);
+ }
+
+ if (config.hasExceptionHandler()) {
+ try {
+ setSensor( config.getOnException().apply(exception) );
+ } catch (Exception e) {
+ if (feed.isConnected()) {
+ log.warn("unable to compute "+getBriefDescription()+"; on exception="+exception, e);
+ } else {
+ if (log.isDebugEnabled()) log.debug("unable to compute "+getBriefDescription()+"; exception="+exception+" (when inactive)", e);
+ }
+ }
+ }
+ }
+
+ protected void logProblem(String type, Object val) {
+ if (lastWasProblem && currentProblemLoggedAsWarning) {
+ if (log.isTraceEnabled())
+ log.trace("Recurring {} reading {} in {}: {}", new Object[] {type, this, getBriefDescription(), val});
+ } else {
+ long nowTime = System.currentTimeMillis();
+ // get a non-volatile value
+ Long currentProblemStartTimeCache = currentProblemStartTime;
+ long expiryTime =
+ (lastSuccessTime!=null && !isTransitioningOrStopped()) ? lastSuccessTime+logWarningGraceTime.toMilliseconds() :
+ currentProblemStartTimeCache!=null ? currentProblemStartTimeCache+logWarningGraceTimeOnStartup.toMilliseconds() :
+ nowTime+logWarningGraceTimeOnStartup.toMilliseconds();
+ if (!lastWasProblem) {
+ if (expiryTime <= nowTime) {
+ currentProblemLoggedAsWarning = true;
+ if (entity==null || !Entities.isNoLongerManaged(entity)) {
+ log.warn("Read of " + getBriefDescription() + " gave " + type + ": " + val);
+ } else {
+ log.debug("Read of " + getBriefDescription() + " gave " + type + ": " + val);
+ }
+ if (log.isDebugEnabled() && val instanceof Throwable)
+ log.debug("Trace for "+type+" reading "+getBriefDescription()+": "+val, (Throwable)val);
+ } else {
+ if (log.isDebugEnabled())
+ log.debug("Read of " + getBriefDescription() + " gave " + type + " (in grace period): " + val);
+ }
+ lastWasProblem = true;
+ currentProblemStartTime = nowTime;
+ } else {
+ if (expiryTime <= nowTime) {
+ currentProblemLoggedAsWarning = true;
+ log.warn("Read of " + getBriefDescription() + " gave " + type +
+ " (grace period expired, occurring for "+Duration.millis(nowTime - currentProblemStartTimeCache)+
+ (config.hasExceptionHandler() ? "" : ", no exception handler set for sensor")+
+ ")"+
+ ": " + val);
+ if (log.isDebugEnabled() && val instanceof Throwable)
+ log.debug("Trace for "+type+" reading "+getBriefDescription()+": "+val, (Throwable)val);
+ } else {
+ if (log.isDebugEnabled())
+ log.debug("Recurring {} reading {} in {} (still in grace period): {}", new Object[] {type, this, getBriefDescription(), val});
+ }
+ }
+ }
+ }
+
+ protected boolean isTransitioningOrStopped() {
+ if (entity==null) return false;
+ Transition expected = entity.getAttribute(Attributes.SERVICE_STATE_EXPECTED);
+ if (expected==null) return false;
+ return (expected.getState()==Lifecycle.STARTING || expected.getState()==Lifecycle.STOPPING || expected.getState()==Lifecycle.STOPPED);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected void setSensor(Object v) {
+ if (Entities.isNoLongerManaged(entity)) {
+ if (Tasks.isInterrupted()) return;
+ log.warn(""+entity+" is not managed; feed "+this+" setting "+sensor+" to "+v+" at this time is not supported ("+Tasks.current()+")");
+ }
+
+ if (v == FeedConfig.UNCHANGED) {
+ // nothing
+ } else if (v == FeedConfig.REMOVE) {
+ ((EntityInternal)entity).removeAttribute(sensor);
+ } else if (sensor == FeedConfig.NO_SENSOR) {
+ // nothing
+ } else {
+ Object coercedV = TypeCoercions.coerce(v, sensor.getType());
+ if (suppressDuplicates && Objects.equal(coercedV, entity.getAttribute(sensor))) {
+ // no change; nothing
+ } else {
+ entity.setAttribute(sensor, coercedV);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString()+"["+getDescription()+"]";
+ }
+
+ @Override
+ public String getDescription() {
+ return sensor.getName()+" @ "+entity.getId()+" <- "+config;
+ }
+
+ protected String getBriefDescription() {
+ return ""+entity+"->"+(sensor==FeedConfig.NO_SENSOR ? "(dynamic sensors)" : ""+sensor);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/ConfigToAttributes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/ConfigToAttributes.java b/core/src/main/java/org/apache/brooklyn/core/feed/ConfigToAttributes.java
new file mode 100644
index 0000000..d455e80
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/ConfigToAttributes.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
+
+
+/** Simple config adapter for setting {@link AttributeSensorAndConfigKey} sensor values from the config value or config default */
+public class ConfigToAttributes {
+
+ //normally just applied once, statically, not registered...
+ public static void apply(EntityLocal entity) {
+ for (Sensor<?> it : entity.getEntityType().getSensors()) {
+ if (it instanceof AttributeSensorAndConfigKey) {
+ apply(entity, (AttributeSensorAndConfigKey<?,?>)it);
+ }
+ }
+ }
+
+ /**
+ * Convenience for ensuring an individual sensor is set from its config key
+ * (e.g. sub-classes of DynamicWebAppCluster that don't want to set HTTP_PORT etc!)
+ */
+ public static <T> T apply(EntityLocal entity, AttributeSensorAndConfigKey<?,T> key) {
+ T v = entity.getAttribute(key);
+ if (v!=null) return v;
+ v = key.getAsSensorValue(entity);
+ if (v!=null) entity.setAttribute(key, v);
+ return v;
+ }
+
+ /**
+ * Convenience for transforming a config value (e.g. processing a {@link TemplatedStringAttributeSensorAndConfigKey}),
+ * outside of the context of an entity.
+ */
+ public static <T> T transform(ManagementContext managementContext, AttributeSensorAndConfigKey<?,T> key) {
+ return key.getAsSensorValue(managementContext);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/DelegatingPollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/DelegatingPollHandler.java b/core/src/main/java/org/apache/brooklyn/core/feed/DelegatingPollHandler.java
new file mode 100644
index 0000000..fae7dd6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/DelegatingPollHandler.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import java.util.List;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * A poll handler that delegates each call to a set of poll handlers.
+ *
+ * @author aled
+ */
+public class DelegatingPollHandler<V> implements PollHandler<V> {
+
+ private final List<AttributePollHandler<? super V>> delegates;
+
+ public DelegatingPollHandler(Iterable<AttributePollHandler<? super V>> delegates) {
+ super();
+ this.delegates = ImmutableList.copyOf(delegates);
+ }
+
+ @Override
+ public boolean checkSuccess(V val) {
+ for (AttributePollHandler<? super V> delegate : delegates) {
+ if (!delegate.checkSuccess(val))
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void onSuccess(V val) {
+ for (AttributePollHandler<? super V> delegate : delegates) {
+ delegate.onSuccess(val);
+ }
+ }
+
+ @Override
+ public void onFailure(V val) {
+ for (AttributePollHandler<? super V> delegate : delegates) {
+ delegate.onFailure(val);
+ }
+ }
+
+ @Override
+ public void onException(Exception exception) {
+ for (AttributePollHandler<? super V> delegate : delegates) {
+ delegate.onException(exception);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString()+"["+getDescription()+"]";
+ }
+
+ @Override
+ public String getDescription() {
+ if (delegates.isEmpty())
+ return "(empty delegate list)";
+ if (delegates.size()==1)
+ return delegates.get(0).getDescription();
+ StringBuilder sb = new StringBuilder();
+ sb.append("[");
+ int count = 0;
+ for (AttributePollHandler<? super V> delegate : delegates) {
+ if (count>0) sb.append("; ");
+ sb.append(delegate.getDescription());
+ if (count>2) {
+ sb.append("; ...");
+ break;
+ }
+ count++;
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java b/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java
new file mode 100644
index 0000000..4d06680
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/FeedConfig.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+
+/**
+ * Configuration for a poll, or a subscription etc, that is being added to a feed.
+ *
+ * @author aled
+ */
+public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
+
+ /** The onSuccess or onError functions can return this value to indicate that the sensor should not change.
+ * @deprecated since 0.7.0 use UNCHANGED */
+ public static final Object UNSET = Entities.UNCHANGED;
+ /** The onSuccess or onError functions can return this value to indicate that the sensor should not change. */
+ public static final Object UNCHANGED = Entities.UNCHANGED;
+ /** The onSuccess or onError functions can return this value to indicate that the sensor value should be removed
+ * (cf 'null', but useful in dynamic situations) */
+ public static final Object REMOVE = Entities.REMOVE;
+
+ /** Indicates that no sensor is being used here. This sensor is suppressed,
+ * but is useful where you want to use the feeds with custom success/exception/failure functions
+ * which directly set multiple sensors, e.g. dynamically based on the poll response.
+ * <p>
+ * See {@link HttpPollConfig#forMultiple()} and its usages.
+ * (It can work for any poll config, but conveniences have not been supplied for others.) */
+ public static final AttributeSensor<Void> NO_SENSOR = Sensors.newSensor(Void.class, "brooklyn.no.sensor");
+
+ private final AttributeSensor<T> sensor;
+ private Function<? super V, T> onsuccess;
+ private Function<? super V, T> onfailure;
+ private Function<? super Exception, T> onexception;
+ private Predicate<? super V> checkSuccess;
+ private boolean suppressDuplicates;
+ private boolean enabled = true;
+
+ public FeedConfig(AttributeSensor<T> sensor) {
+ this.sensor = checkNotNull(sensor, "sensor");
+ }
+
+ public FeedConfig(FeedConfig<V, T, F> other) {
+ this.sensor = other.sensor;
+ this.onsuccess = other.onsuccess;
+ this.onfailure = other.onfailure;
+ this.onexception = other.onexception;
+ this.checkSuccess = other.checkSuccess;
+ this.suppressDuplicates = other.suppressDuplicates;
+ this.enabled = other.enabled;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected F self() {
+ return (F) this;
+ }
+
+ public AttributeSensor<T> getSensor() {
+ return sensor;
+ }
+
+ public Predicate<? super V> getCheckSuccess() {
+ return checkSuccess;
+ }
+
+ public Function<? super V, T> getOnSuccess() {
+ return onsuccess;
+ }
+
+ public Function<? super V, T> getOnFailure() {
+ return onfailure;
+ }
+
+ public Function<? super Exception, T> getOnException() {
+ return onexception;
+ }
+
+ public boolean getSupressDuplicates() {
+ return suppressDuplicates;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ /** sets the predicate used to check whether a feed run is successful */
+ public F checkSuccess(Predicate<? super V> val) {
+ this.checkSuccess = checkNotNull(val, "checkSuccess");
+ return self();
+ }
+ /** as {@link #checkSuccess(Predicate)} */
+ public F checkSuccess(final Function<? super V,Boolean> val) {
+ return checkSuccess(Functionals.predicate(val));
+ }
+ @SuppressWarnings("unused")
+ /** @deprecated since 0.7.0, kept for rebind */ @Deprecated
+ private F checkSuccessLegacy(final Function<? super V,Boolean> val) {
+ return checkSuccess(new Predicate<V>() {
+ @Override
+ public boolean apply(V input) {
+ return val.apply(input);
+ }
+ });
+ }
+
+ public F onSuccess(Function<? super V,T> val) {
+ this.onsuccess = checkNotNull(val, "onSuccess");
+ return self();
+ }
+
+ public F setOnSuccess(T val) {
+ return onSuccess(Functions.constant(val));
+ }
+
+ /** a failure is when the connection is fine (no exception) but the other end returns a result object V
+ * which the feed can tell indicates a failure (e.g. HTTP code 404) */
+ public F onFailure(Function<? super V,T> val) {
+ this.onfailure = checkNotNull(val, "onFailure");
+ return self();
+ }
+
+ public F setOnFailure(T val) {
+ return onFailure(Functions.constant(val));
+ }
+
+ /** registers a callback to be used {@link #onSuccess(Function)} and {@link #onFailure(Function)},
+ * i.e. whenever a result comes back, but not in case of exceptions being thrown (ie problems communicating) */
+ public F onResult(Function<? super V, T> val) {
+ onSuccess(val);
+ return onFailure(val);
+ }
+
+ public F setOnResult(T val) {
+ return onResult(Functions.constant(val));
+ }
+
+ /** an exception is when there is an error in the communication */
+ public F onException(Function<? super Exception,T> val) {
+ this.onexception = checkNotNull(val, "onException");
+ return self();
+ }
+
+ public F setOnException(T val) {
+ return onException(Functions.constant(val));
+ }
+
+ /** convenience for indicating a behaviour to occur for both
+ * {@link #onException(Function)}
+ * (error connecting) and
+ * {@link #onFailure(Function)}
+ * (successful communication but failure report from remote end) */
+ public F onFailureOrException(Function<Object,T> val) {
+ onFailure(val);
+ return onException(val);
+ }
+
+ public F setOnFailureOrException(T val) {
+ return onFailureOrException(Functions.constant(val));
+ }
+
+ public F suppressDuplicates(boolean val) {
+ suppressDuplicates = val;
+ return self();
+ }
+
+ /**
+ * Whether this feed is enabled (defaulting to true).
+ */
+ public F enabled(boolean val) {
+ enabled = val;
+ return self();
+ }
+
+ public boolean hasSuccessHandler() {
+ return this.onsuccess != null;
+ }
+
+ public boolean hasFailureHandler() {
+ return this.onfailure != null;
+ }
+
+ public boolean hasExceptionHandler() {
+ return this.onexception != null;
+ }
+
+ public boolean hasCheckSuccessHandler() {
+ return this.checkSuccess != null;
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append(toStringBaseName());
+ result.append("[");
+ boolean contents = false;
+ Object source = toStringPollSource();
+ AttributeSensor<T> s = getSensor();
+ if (Strings.isNonBlank(Strings.toString(source))) {
+ result.append(Strings.toUniqueString(source, 40));
+ if (s!=null) {
+ result.append("->");
+ result.append(s.getName());
+ }
+ contents = true;
+ } else if (s!=null) {
+ result.append(s.getName());
+ contents = true;
+ }
+ MutableList<Object> fields = toStringOtherFields();
+ if (fields!=null) {
+ for (Object field: fields) {
+ if (Strings.isNonBlank(Strings.toString(field))) {
+ if (contents) result.append(";");
+ contents = true;
+ result.append(field);
+ }
+ }
+ }
+ result.append("]");
+ return result.toString();
+ }
+
+ /** can be overridden to supply a simpler base name than the class name */
+ protected String toStringBaseName() {
+ return JavaClassNames.simpleClassName(this);
+ }
+ /** can be overridden to supply add'l info for the {@link #toString()}; subclasses can add to the returned value */
+ protected MutableList<Object> toStringOtherFields() {
+ return MutableList.<Object>of();
+ }
+ /** can be overridden to supply add'l info for the {@link #toString()}, placed before the sensor with -> */
+ protected Object toStringPollSource() {
+ return null;
+ }
+ /** all configs should supply a unique tag element, inserted into the feed */
+ protected String getUniqueTag() {
+ return toString();
+ }
+
+ /** returns fields which should be used for equality, including by default {@link #toStringOtherFields()} and {@link #toStringPollSource()};
+ * subclasses can add to the returned value */
+ protected MutableList<Object> equalsFields() {
+ MutableList<Object> result = MutableList.of().appendIfNotNull(getSensor()).appendIfNotNull(toStringPollSource());
+ for (Object field: toStringOtherFields()) result.appendIfNotNull(field);
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ int hc = super.hashCode();
+ for (Object f: equalsFields())
+ hc = Objects.hashCode(hc, f);
+ return hc;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!super.equals(obj)) return false;
+ PollConfig<?,?,?> other = (PollConfig<?,?,?>) obj;
+ if (!Objects.equal(getUniqueTag(), other.getUniqueTag())) return false;
+ if (!Objects.equal(equalsFields(), other.equalsFields())) return false;
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java b/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java
new file mode 100644
index 0000000..133431b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/PollConfig.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.time.Duration;
+
+/**
+ * Configuration for polling, which is being added to a feed (e.g. to poll a given URL over http).
+ *
+ * @author aled
+ */
+public class PollConfig<V, T, F extends PollConfig<V, T, F>> extends FeedConfig<V, T, F> {
+
+ private long period = -1;
+ private String description;
+
+ public PollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ }
+
+ public PollConfig(PollConfig<V,T,F> other) {
+ super(other);
+ this.period = other.period;
+ }
+
+ public long getPeriod() {
+ return period;
+ }
+
+ public F period(Duration val) {
+ checkArgument(val.toMilliseconds() >= 0, "period must be greater than or equal to zero");
+ this.period = val.toMilliseconds();
+ return self();
+ }
+
+ public F period(long val) {
+ checkArgument(val >= 0, "period must be greater than or equal to zero");
+ this.period = val; return self();
+ }
+
+ public F period(long val, TimeUnit units) {
+ checkArgument(val >= 0, "period must be greater than or equal to zero");
+ return period(units.toMillis(val));
+ }
+
+ public F description(String description) {
+ this.description = description;
+ return self();
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ @Override protected MutableList<Object> toStringOtherFields() {
+ return super.toStringOtherFields().appendIfNotNull(description);
+ }
+
+ @Override
+ protected MutableList<Object> equalsFields() {
+ return super.equalsFields().appendIfNotNull(period);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java b/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java
new file mode 100644
index 0000000..a63ebde
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/PollHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+/**
+ * Notified by the Poller of the result for each job, on each poll.
+ *
+ * @author aled
+ */
+public interface PollHandler<V> {
+
+ public boolean checkSuccess(V val);
+
+ public void onSuccess(V val);
+
+ public void onFailure(V val);
+
+ public void onException(Exception exception);
+
+ public String getDescription();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java b/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java
new file mode 100644
index 0000000..fd50ebd
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/feed/Poller.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
+import org.apache.brooklyn.util.core.task.ScheduledTask;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+
+
+/**
+ * For executing periodic polls.
+ * Jobs are added to the schedule, and then the poller is started.
+ * The jobs will then be executed periodically, and the handler called for the result/failure.
+ *
+ * Assumes the schedule+start will be done single threaded, and that stop will not be done concurrently.
+ */
+public class Poller<V> {
+ public static final Logger log = LoggerFactory.getLogger(Poller.class);
+
+ private final EntityLocal entity;
+ private final boolean onlyIfServiceUp;
+ private final Set<Callable<?>> oneOffJobs = new LinkedHashSet<Callable<?>>();
+ private final Set<PollJob<V>> pollJobs = new LinkedHashSet<PollJob<V>>();
+ private final Set<Task<?>> oneOffTasks = new LinkedHashSet<Task<?>>();
+ private final Set<ScheduledTask> tasks = new LinkedHashSet<ScheduledTask>();
+ private volatile boolean started = false;
+
+ private static class PollJob<V> {
+ final PollHandler<? super V> handler;
+ final Duration pollPeriod;
+ final Runnable wrappedJob;
+ private boolean loggedPreviousException = false;
+
+ PollJob(final Callable<V> job, final PollHandler<? super V> handler, Duration period) {
+ this.handler = handler;
+ this.pollPeriod = period;
+
+ wrappedJob = new Runnable() {
+ public void run() {
+ try {
+ V val = job.call();
+ loggedPreviousException = false;
+ if (handler.checkSuccess(val)) {
+ handler.onSuccess(val);
+ } else {
+ handler.onFailure(val);
+ }
+ } catch (Exception e) {
+ if (loggedPreviousException) {
+ if (log.isTraceEnabled()) log.trace("PollJob for {}, repeated consecutive failures, handling {} using {}", new Object[] {job, e, handler});
+ } else {
+ if (log.isDebugEnabled()) log.debug("PollJob for {} handling {} using {}", new Object[] {job, e, handler});
+ loggedPreviousException = true;
+ }
+ handler.onException(e);
+ }
+ }
+ };
+ }
+ }
+
+ /** @deprecated since 0.7.0, pass in whether should run onlyIfServiceUp */
+ @Deprecated
+ public Poller(EntityLocal entity) {
+ this(entity, false);
+ }
+ public Poller(EntityLocal entity, boolean onlyIfServiceUp) {
+ this.entity = entity;
+ this.onlyIfServiceUp = onlyIfServiceUp;
+ }
+
+ /** Submits a one-off poll job; recommended that callers supply to-String so that task has a decent description */
+ public void submit(Callable<?> job) {
+ if (started) {
+ throw new IllegalStateException("Cannot submit additional tasks after poller has started");
+ }
+ oneOffJobs.add(job);
+ }
+
+ public void scheduleAtFixedRate(Callable<V> job, PollHandler<? super V> handler, long period) {
+ scheduleAtFixedRate(job, handler, Duration.millis(period));
+ }
+ public void scheduleAtFixedRate(Callable<V> job, PollHandler<? super V> handler, Duration period) {
+ if (started) {
+ throw new IllegalStateException("Cannot schedule additional tasks after poller has started");
+ }
+ PollJob<V> foo = new PollJob<V>(job, handler, period);
+ pollJobs.add(foo);
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ public void start() {
+ // TODO Previous incarnation of this logged this logged polledSensors.keySet(), but we don't know that anymore
+ // Is that ok, are can we do better?
+
+ if (log.isDebugEnabled()) log.debug("Starting poll for {} (using {})", new Object[] {entity, this});
+ if (started) {
+ throw new IllegalStateException(String.format("Attempt to start poller %s of entity %s when already running",
+ this, entity));
+ }
+
+ started = true;
+
+ for (final Callable<?> oneOffJob : oneOffJobs) {
+ Task<?> task = Tasks.builder().dynamic(false).body((Callable<Object>) oneOffJob).name("Poll").description("One-time poll job "+oneOffJob).build();
+ oneOffTasks.add(((EntityInternal)entity).getExecutionContext().submit(task));
+ }
+
+ for (final PollJob<V> pollJob : pollJobs) {
+ final String scheduleName = pollJob.handler.getDescription();
+ if (pollJob.pollPeriod.compareTo(Duration.ZERO) > 0) {
+ Callable<Task<?>> pollingTaskFactory = new Callable<Task<?>>() {
+ public Task<?> call() {
+ DynamicSequentialTask<Void> task = new DynamicSequentialTask<Void>(MutableMap.of("displayName", scheduleName, "entity", entity),
+ new Callable<Void>() { public Void call() {
+ if (onlyIfServiceUp && !Boolean.TRUE.equals(entity.getAttribute(Attributes.SERVICE_UP))) {
+ return null;
+ }
+ pollJob.wrappedJob.run();
+ return null;
+ } } );
+ BrooklynTaskTags.setTransient(task);
+ return task;
+ }
+ };
+ ScheduledTask task = new ScheduledTask(MutableMap.of("period", pollJob.pollPeriod, "displayName", "scheduled:"+scheduleName), pollingTaskFactory);
+ tasks.add((ScheduledTask)Entities.submit(entity, task));
+ } else {
+ if (log.isDebugEnabled()) log.debug("Activating poll (but leaving off, as period {}) for {} (using {})", new Object[] {pollJob.pollPeriod, entity, this});
+ }
+ }
+ }
+
+ public void stop() {
+ if (log.isDebugEnabled()) log.debug("Stopping poll for {} (using {})", new Object[] {entity, this});
+ if (!started) {
+ throw new IllegalStateException(String.format("Attempt to stop poller %s of entity %s when not running",
+ this, entity));
+ }
+
+ started = false;
+ for (Task<?> task : oneOffTasks) {
+ if (task != null) task.cancel(true);
+ }
+ for (ScheduledTask task : tasks) {
+ if (task != null) task.cancel();
+ }
+ oneOffTasks.clear();
+ tasks.clear();
+ }
+
+ public boolean isRunning() {
+ boolean hasActiveTasks = false;
+ for (Task<?> task: tasks) {
+ if (task.isBegun() && !task.isDone()) {
+ hasActiveTasks = true;
+ break;
+ }
+ }
+ if (!started && hasActiveTasks) {
+ log.warn("Poller should not be running, but has active tasks, tasks: "+tasks);
+ }
+ return started && hasActiveTasks;
+ }
+
+ protected boolean isEmpty() {
+ return pollJobs.isEmpty();
+ }
+
+ public String toString() {
+ return Objects.toStringHelper(this).add("entity", entity).toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
index 2e4a971..2a5e92e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
@@ -34,11 +34,11 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.AbstractFeed;
import org.apache.brooklyn.core.mgmt.rebind.dto.MementosGenerators;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.entity.group.AbstractGroupImpl;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicFeedRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicFeedRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicFeedRebindSupport.java
index 479fbbf..4630be1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicFeedRebindSupport.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicFeedRebindSupport.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.core.mgmt.rebind;
import org.apache.brooklyn.api.mgmt.rebind.RebindContext;
import org.apache.brooklyn.api.mgmt.rebind.mementos.FeedMemento;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AbstractFeed;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
index c3e8030..e9478ef 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
@@ -67,6 +67,7 @@ import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.AbstractFeed;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
@@ -86,7 +87,6 @@ import org.apache.brooklyn.core.objs.proxy.InternalLocationFactory;
import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
index 761341b..929b63c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
@@ -51,6 +51,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.catalog.internal.CatalogItemDo;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.AbstractFeed;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.persist.BrooklynPersistenceUtils;
import org.apache.brooklyn.core.mgmt.rebind.AbstractBrooklynObjectRebindSupport;
@@ -58,7 +59,6 @@ import org.apache.brooklyn.core.mgmt.rebind.TreeUtils;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
index 940d949..f76baaa 100644
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
index 79660ce..542fc01 100644
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.AddSensor;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroupImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroupImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroupImpl.java
index a6880b7..e914bd2 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroupImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroupImpl.java
@@ -30,8 +30,8 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
import com.google.common.base.Function;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/entity/stock/DataEntityImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/stock/DataEntityImpl.java b/core/src/main/java/org/apache/brooklyn/entity/stock/DataEntityImpl.java
index af34e0d..7f10d5b 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/stock/DataEntityImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/stock/DataEntityImpl.java
@@ -24,8 +24,8 @@ import java.util.Map;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import com.google.common.base.Functions;
import com.google.common.base.Supplier;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/function/FunctionFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/function/FunctionFeed.java b/core/src/main/java/org/apache/brooklyn/feed/function/FunctionFeed.java
new file mode 100644
index 0000000..55db890
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/function/FunctionFeed.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.function;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.DelegatingPollHandler;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Provides a feed of attribute values, by periodically invoking functions.
+ *
+ * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
+ * <pre>
+ * {@code
+ * private FunctionFeed feed;
+ *
+ * //@Override
+ * protected void connectSensors() {
+ * super.connectSensors();
+ *
+ * feed = FunctionFeed.builder()
+ * .entity(this)
+ * .poll(new FunctionPollConfig<Object, Boolean>(SERVICE_UP)
+ * .period(500, TimeUnit.MILLISECONDS)
+ * .callable(new Callable<Boolean>() {
+ * public Boolean call() throws Exception {
+ * return getDriver().isRunning();
+ * }
+ * })
+ * .onExceptionOrFailure(Functions.constant(Boolan.FALSE))
+ * .build();
+ * }
+ *
+ * {@literal @}Override
+ * protected void disconnectSensors() {
+ * super.disconnectSensors();
+ * if (feed != null) feed.stop();
+ * }
+ * }
+ * </pre>
+ *
+ * @author aled
+ */
+public class FunctionFeed extends AbstractFeed {
+
+ private static final Logger log = LoggerFactory.getLogger(FunctionFeed.class);
+
+ // Treat as immutable once built
+ @SuppressWarnings("serial")
+ public static final ConfigKey<SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>>>() {},
+ "polls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static Builder builder(String uniqueTag) {
+ return new Builder().uniqueTag(uniqueTag);
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private boolean onlyIfServiceUp = false;
+ private long period = 500;
+ private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
+ private List<FunctionPollConfig<?,?>> polls = Lists.newArrayList();
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = val;
+ return this;
+ }
+ public Builder onlyIfServiceUp() { return onlyIfServiceUp(true); }
+ public Builder onlyIfServiceUp(boolean onlyIfServiceUp) {
+ this.onlyIfServiceUp = onlyIfServiceUp;
+ return this;
+ }
+ public Builder period(Duration d) {
+ return period(d.toMilliseconds(), TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long millis) {
+ return period(millis, TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long val, TimeUnit units) {
+ this.period = val;
+ this.periodUnits = units;
+ return this;
+ }
+ public Builder poll(FunctionPollConfig<?,?> config) {
+ polls.add(config);
+ return this;
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public FunctionFeed build() {
+ built = true;
+ FunctionFeed result = new FunctionFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("FunctionFeed.Builder created, but build() never called");
+ }
+ }
+
+ private static class FunctionPollIdentifier {
+ final Callable<?> job;
+
+ private FunctionPollIdentifier(Callable<?> job) {
+ this.job = checkNotNull(job, "job");
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(job);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof FunctionPollIdentifier) && Objects.equal(job, ((FunctionPollIdentifier)other).job);
+ }
+ }
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public FunctionFeed() {
+ }
+
+ protected FunctionFeed(Builder builder) {
+ setConfig(ONLY_IF_SERVICE_UP, builder.onlyIfServiceUp);
+
+ SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>> polls = HashMultimap.<FunctionPollIdentifier,FunctionPollConfig<?,?>>create();
+ for (FunctionPollConfig<?,?> config : builder.polls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ FunctionPollConfig<?,?> configCopy = new FunctionPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
+ Callable<?> job = config.getCallable();
+ polls.put(new FunctionPollIdentifier(job), configCopy);
+ }
+ setConfig(POLLS, polls);
+ initUniqueTag(builder.uniqueTag, polls.values());
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ protected void preStart() {
+ SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?, ?>> polls = getConfig(POLLS);
+ for (final FunctionPollIdentifier pollInfo : polls.keySet()) {
+ Set<FunctionPollConfig<?,?>> configs = polls.get(pollInfo);
+ long minPeriod = Integer.MAX_VALUE;
+ Set<AttributePollHandler<?>> handlers = Sets.newLinkedHashSet();
+
+ for (FunctionPollConfig<?,?> config : configs) {
+ handlers.add(new AttributePollHandler(config, entity, this));
+ if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
+ }
+
+ getPoller().scheduleAtFixedRate(
+ (Callable)pollInfo.job,
+ new DelegatingPollHandler(handlers),
+ minPeriod);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/function/FunctionPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/function/FunctionPollConfig.java b/core/src/main/java/org/apache/brooklyn/feed/function/FunctionPollConfig.java
new file mode 100644
index 0000000..4951868
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/function/FunctionPollConfig.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.function;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import groovy.lang.Closure;
+
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.FeedConfig;
+import org.apache.brooklyn.core.feed.PollConfig;
+import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.javalang.JavaClassNames;
+
+import com.google.common.base.Supplier;
+
+public class FunctionPollConfig<S, T> extends PollConfig<S, T, FunctionPollConfig<S, T>> {
+
+ private Callable<?> callable;
+
+ public static <T> FunctionPollConfig<?, T> forSensor(AttributeSensor<T> sensor) {
+ return new FunctionPollConfig<Object, T>(sensor);
+ }
+
+ public FunctionPollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ }
+
+ public FunctionPollConfig(FunctionPollConfig<S, T> other) {
+ super(other);
+ callable = other.callable;
+ }
+
+ public Callable<? extends Object> getCallable() {
+ return callable;
+ }
+
+ /**
+ * The {@link Callable} to be invoked on each poll.
+ * <p>
+ * Note this <em>must</em> use generics, otherwise the return type of subsequent chained
+ * calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
+ * return the wrong type.
+ */
+ @SuppressWarnings("unchecked")
+ public <newS> FunctionPollConfig<newS, T> callable(Callable<? extends newS> val) {
+ this.callable = checkNotNull(val, "callable");
+ return (FunctionPollConfig<newS, T>) this;
+ }
+
+ /**
+ * Supplies the value to be returned by each poll.
+ * <p>
+ * Note this <em>must</em> use generics, otherwise the return type of subsequent chained
+ * calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
+ * return the wrong type.
+ */
+ @SuppressWarnings("unchecked")
+ public <newS> FunctionPollConfig<newS, T> supplier(final Supplier<? extends newS> val) {
+ this.callable = Functionals.callable( checkNotNull(val, "supplier") );
+ return (FunctionPollConfig<newS, T>) this;
+ }
+
+ /** @deprecated since 0.7.0, kept for legacy compatibility when deserializing */
+ @SuppressWarnings({ "unchecked", "unused" })
+ private <newS> FunctionPollConfig<newS, T> supplierLegacy(final Supplier<? extends newS> val) {
+ checkNotNull(val, "supplier");
+ this.callable = new Callable<newS>() {
+ @Override
+ public newS call() throws Exception {
+ return val.get();
+ }
+ };
+ return (FunctionPollConfig<newS, T>) this;
+ }
+
+ public FunctionPollConfig<S, T> closure(Closure<?> val) {
+ this.callable = GroovyJavaMethods.callableFromClosure(checkNotNull(val, "closure"));
+ return this;
+ }
+
+ @Override protected String toStringBaseName() { return "fn"; }
+ @Override protected String toStringPollSource() {
+ if (callable==null) return null;
+ String cs = callable.toString();
+ if (!cs.contains( ""+Integer.toHexString(callable.hashCode()) )) {
+ return cs;
+ }
+ // if hashcode is in callable it's probably a custom internal; return class name
+ return JavaClassNames.simpleClassName(callable);
+ }
+
+}
[24/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpFeed.java
deleted file mode 100644
index 9ae5431..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpFeed.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.net.URI;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.core.http.HttpTool.HttpClientBuilder;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.http.auth.Credentials;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.HttpClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Provides a feed of attribute values, by polling over http.
- *
- * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
- * <pre>
- * {@code
- * private HttpFeed feed;
- *
- * //@Override
- * protected void connectSensors() {
- * super.connectSensors();
- *
- * feed = HttpFeed.builder()
- * .entity(this)
- * .period(200)
- * .baseUri(String.format("http://%s:%s/management/subsystem/web/connector/http/read-resource", host, port))
- * .baseUriVars(ImmutableMap.of("include-runtime","true"))
- * .poll(new HttpPollConfig<Boolean>(SERVICE_UP)
- * .onSuccess(HttpValueFunctions.responseCodeEquals(200))
- * .onError(Functions.constant(false)))
- * .poll(new HttpPollConfig<Integer>(REQUEST_COUNT)
- * .onSuccess(HttpValueFunctions.jsonContents("requestCount", Integer.class)))
- * .build();
- * }
- *
- * {@literal @}Override
- * protected void disconnectSensors() {
- * super.disconnectSensors();
- * if (feed != null) feed.stop();
- * }
- * }
- * </pre>
- * <p>
- *
- * This also supports giving a Supplier for the URL
- * (e.g. {@link Entities#attributeSupplier(org.apache.brooklyn.api.entity.Entity, org.apache.brooklyn.api.event.AttributeSensor)})
- * from a sensor. Note however that if a Supplier-based sensor is *https*,
- * https-specific initialization may not occur if the URL is not available at start time,
- * and it may report errors if that sensor is not available.
- * Some guidance for controlling enablement of a feed based on availability of a sensor
- * can be seen in HttpLatencyDetector (in brooklyn-policy).
- *
- * @author aled
- */
-public class HttpFeed extends AbstractFeed {
-
- public static final Logger log = LoggerFactory.getLogger(HttpFeed.class);
-
- @SuppressWarnings("serial")
- public static final ConfigKey<SetMultimap<HttpPollIdentifier, HttpPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<HttpPollIdentifier, HttpPollConfig<?>>>() {},
- "polls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EntityLocal entity;
- private boolean onlyIfServiceUp = false;
- private Supplier<URI> baseUriProvider;
- private Duration period = Duration.millis(500);
- private List<HttpPollConfig<?>> polls = Lists.newArrayList();
- private URI baseUri;
- private Map<String, String> baseUriVars = Maps.newLinkedHashMap();
- private Map<String, String> headers = Maps.newLinkedHashMap();
- private boolean suspended = false;
- private Credentials credentials;
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = val;
- return this;
- }
- public Builder onlyIfServiceUp() { return onlyIfServiceUp(true); }
- public Builder onlyIfServiceUp(boolean onlyIfServiceUp) {
- this.onlyIfServiceUp = onlyIfServiceUp;
- return this;
- }
- public Builder baseUri(Supplier<URI> val) {
- if (baseUri!=null && val!=null)
- throw new IllegalStateException("Builder cannot take both a URI and a URI Provider");
- this.baseUriProvider = val;
- return this;
- }
- public Builder baseUri(URI val) {
- if (baseUriProvider!=null && val!=null)
- throw new IllegalStateException("Builder cannot take both a URI and a URI Provider");
- this.baseUri = val;
- return this;
- }
- public Builder baseUrl(URL val) {
- return baseUri(URI.create(val.toString()));
- }
- public Builder baseUri(String val) {
- return baseUri(URI.create(val));
- }
- public Builder baseUriVars(Map<String,String> vals) {
- baseUriVars.putAll(vals);
- return this;
- }
- public Builder baseUriVar(String key, String val) {
- baseUriVars.put(key, val);
- return this;
- }
- public Builder headers(Map<String,String> vals) {
- headers.putAll(vals);
- return this;
- }
- public Builder header(String key, String val) {
- headers.put(key, val);
- return this;
- }
- public Builder period(Duration duration) {
- this.period = duration;
- return this;
- }
- public Builder period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public Builder period(long val, TimeUnit units) {
- return period(Duration.of(val, units));
- }
- public Builder poll(HttpPollConfig<?> config) {
- polls.add(config);
- return this;
- }
- public Builder suspended() {
- return suspended(true);
- }
- public Builder suspended(boolean startsSuspended) {
- this.suspended = startsSuspended;
- return this;
- }
- public Builder credentials(String username, String password) {
- this.credentials = new UsernamePasswordCredentials(username, password);
- return this;
- }
- public Builder credentialsIfNotNull(String username, String password) {
- if (username != null && password != null) {
- this.credentials = new UsernamePasswordCredentials(username, password);
- }
- return this;
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public HttpFeed build() {
- built = true;
- HttpFeed result = new HttpFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- if (suspended) result.suspend();
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("HttpFeed.Builder created, but build() never called");
- }
- }
-
- private static class HttpPollIdentifier {
- final String method;
- final Supplier<URI> uriProvider;
- final Map<String,String> headers;
- final byte[] body;
- final Optional<Credentials> credentials;
- final Duration connectionTimeout;
- final Duration socketTimeout;
- private HttpPollIdentifier(String method, Supplier<URI> uriProvider, Map<String, String> headers, byte[] body,
- Optional<Credentials> credentials, Duration connectionTimeout, Duration socketTimeout) {
- this.method = checkNotNull(method, "method").toLowerCase();
- this.uriProvider = checkNotNull(uriProvider, "uriProvider");
- this.headers = checkNotNull(headers, "headers");
- this.body = body;
- this.credentials = checkNotNull(credentials, "credentials");
- this.connectionTimeout = connectionTimeout;
- this.socketTimeout = socketTimeout;
-
- if (!(this.method.equals("get") || this.method.equals("post"))) {
- throw new IllegalArgumentException("Unsupported HTTP method (only supports GET and POST): "+method);
- }
- if (body != null && method.equalsIgnoreCase("get")) {
- throw new IllegalArgumentException("Must not set body for http GET method");
- }
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(method, uriProvider, headers, body, credentials);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof HttpPollIdentifier)) {
- return false;
- }
- HttpPollIdentifier o = (HttpPollIdentifier) other;
- return Objects.equal(method, o.method) &&
- Objects.equal(uriProvider, o.uriProvider) &&
- Objects.equal(headers, o.headers) &&
- Objects.equal(body, o.body) &&
- Objects.equal(credentials, o.credentials);
- }
- }
-
- /**
- * For rebind; do not call directly; use builder
- */
- public HttpFeed() {
- }
-
- protected HttpFeed(Builder builder) {
- setConfig(ONLY_IF_SERVICE_UP, builder.onlyIfServiceUp);
- Map<String,String> baseHeaders = ImmutableMap.copyOf(checkNotNull(builder.headers, "headers"));
-
- SetMultimap<HttpPollIdentifier, HttpPollConfig<?>> polls = HashMultimap.<HttpPollIdentifier,HttpPollConfig<?>>create();
- for (HttpPollConfig<?> config : builder.polls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "unchecked", "rawtypes" })
- HttpPollConfig<?> configCopy = new HttpPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
- String method = config.getMethod();
- Map<String,String> headers = config.buildHeaders(baseHeaders);
- byte[] body = config.getBody();
- Duration connectionTimeout = config.getConnectionTimeout();
- Duration socketTimeout = config.getSocketTimeout();
-
- Optional<Credentials> credentials = Optional.fromNullable(builder.credentials);
-
- Supplier<URI> baseUriProvider = builder.baseUriProvider;
- if (builder.baseUri!=null) {
- if (baseUriProvider!=null)
- throw new IllegalStateException("Not permitted to supply baseUri and baseUriProvider");
- Map<String,String> baseUriVars = ImmutableMap.copyOf(checkNotNull(builder.baseUriVars, "baseUriVars"));
- URI uri = config.buildUri(builder.baseUri, baseUriVars);
- baseUriProvider = Suppliers.ofInstance(uri);
- } else if (!builder.baseUriVars.isEmpty()) {
- throw new IllegalStateException("Not permitted to supply URI vars when using a URI provider; pass the vars to the provider instead");
- }
- checkNotNull(baseUriProvider);
-
- polls.put(new HttpPollIdentifier(method, baseUriProvider, headers, body, credentials, connectionTimeout, socketTimeout), configCopy);
- }
- setConfig(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls.values());
- }
-
- @Override
- protected void preStart() {
- SetMultimap<HttpPollIdentifier, HttpPollConfig<?>> polls = getConfig(POLLS);
-
- for (final HttpPollIdentifier pollInfo : polls.keySet()) {
- // Though HttpClients are thread safe and can take advantage of connection pooling
- // and authentication caching, the httpcomponents documentation says:
- // "While HttpClient instances are thread safe and can be shared between multiple
- // threads of execution, it is highly recommended that each thread maintains its
- // own dedicated instance of HttpContext.
- // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
- final HttpClient httpClient = createHttpClient(pollInfo);
-
- Set<HttpPollConfig<?>> configs = polls.get(pollInfo);
- long minPeriod = Integer.MAX_VALUE;
- Set<AttributePollHandler<? super HttpToolResponse>> handlers = Sets.newLinkedHashSet();
-
- for (HttpPollConfig<?> config : configs) {
- handlers.add(new AttributePollHandler<HttpToolResponse>(config, entity, this));
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- }
-
- Callable<HttpToolResponse> pollJob;
-
- if (pollInfo.method.equals("get")) {
- pollJob = new Callable<HttpToolResponse>() {
- public HttpToolResponse call() throws Exception {
- if (log.isTraceEnabled()) log.trace("http polling for {} sensors at {}", entity, pollInfo);
- return HttpTool.httpGet(httpClient, pollInfo.uriProvider.get(), pollInfo.headers);
- }};
- } else if (pollInfo.method.equals("post")) {
- pollJob = new Callable<HttpToolResponse>() {
- public HttpToolResponse call() throws Exception {
- if (log.isTraceEnabled()) log.trace("http polling for {} sensors at {}", entity, pollInfo);
- return HttpTool.httpPost(httpClient, pollInfo.uriProvider.get(), pollInfo.headers, pollInfo.body);
- }};
- } else if (pollInfo.method.equals("head")) {
- pollJob = new Callable<HttpToolResponse>() {
- public HttpToolResponse call() throws Exception {
- if (log.isTraceEnabled()) log.trace("http polling for {} sensors at {}", entity, pollInfo);
- return HttpTool.httpHead(httpClient, pollInfo.uriProvider.get(), pollInfo.headers);
- }};
- } else {
- throw new IllegalStateException("Unexpected http method: "+pollInfo.method);
- }
-
- getPoller().scheduleAtFixedRate(pollJob, new DelegatingPollHandler<HttpToolResponse>(handlers), minPeriod);
- }
- }
-
- // TODO Should we really trustAll for https? Make configurable?
- private HttpClient createHttpClient(HttpPollIdentifier pollIdentifier) {
- URI uri = pollIdentifier.uriProvider.get();
- HttpClientBuilder builder = HttpTool.httpClientBuilder()
- .trustAll()
- .laxRedirect(true);
- if (uri != null) builder.uri(uri);
- if (uri != null) builder.credential(pollIdentifier.credentials);
- if (pollIdentifier.connectionTimeout != null) {
- builder.connectionTimeout(pollIdentifier.connectionTimeout);
- }
- if (pollIdentifier.socketTimeout != null) {
- builder.socketTimeout(pollIdentifier.socketTimeout);
- }
- return builder.build();
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<HttpToolResponse> getPoller() {
- return (Poller<HttpToolResponse>) super.getPoller();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollConfig.java
deleted file mode 100644
index eead23f..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollConfig.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import java.net.URI;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-
-public class HttpPollConfig<T> extends PollConfig<HttpToolResponse, T, HttpPollConfig<T>> {
-
- private String method = "GET";
- private String suburl = "";
- private Map<String, String> vars = ImmutableMap.<String,String>of();
- private Map<String, String> headers = ImmutableMap.<String,String>of();
- private byte[] body;
- private Duration connectionTimeout;
- private Duration socketTimeout;
-
- public static final Predicate<HttpToolResponse> DEFAULT_SUCCESS = new Predicate<HttpToolResponse>() {
- @Override
- public boolean apply(@Nullable HttpToolResponse input) {
- return input != null && input.getResponseCode() >= 200 && input.getResponseCode() <= 399;
- }};
-
- public static <T> HttpPollConfig<T> forSensor(AttributeSensor<T> sensor) {
- return new HttpPollConfig<T>(sensor);
- }
-
- public static HttpPollConfig<Void> forMultiple() {
- return new HttpPollConfig<Void>(PollConfig.NO_SENSOR);
- }
-
- public HttpPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- super.checkSuccess(DEFAULT_SUCCESS);
- }
-
- public HttpPollConfig(HttpPollConfig<T> other) {
- super(other);
- suburl = other.suburl;
- vars = other.vars;
- method = other.method;
- headers = other.headers;
- }
-
- public String getSuburl() {
- return suburl;
- }
-
- public Map<String, String> getVars() {
- return vars;
- }
-
- public Duration getConnectionTimeout() {
- return connectionTimeout;
- }
-
- public Duration getSocketTimeout() {
- return socketTimeout;
- }
-
- public String getMethod() {
- return method;
- }
-
- public byte[] getBody() {
- return body;
- }
-
- public HttpPollConfig<T> method(String val) {
- this.method = val; return this;
- }
-
- public HttpPollConfig<T> suburl(String val) {
- this.suburl = val; return this;
- }
-
- public HttpPollConfig<T> vars(Map<String,String> val) {
- this.vars = val; return this;
- }
-
- public HttpPollConfig<T> headers(Map<String,String> val) {
- this.headers = val; return this;
- }
-
- public HttpPollConfig<T> body(byte[] val) {
- this.body = val; return this;
- }
- public HttpPollConfig<T> connectionTimeout(Duration val) {
- this.connectionTimeout = val;
- return this;
- }
- public HttpPollConfig<T> socketTimeout(Duration val) {
- this.socketTimeout = val;
- return this;
- }
- public URI buildUri(URI baseUri, Map<String,String> baseUriVars) {
- String uri = (baseUri != null ? baseUri.toString() : "") + (suburl != null ? suburl : "");
- Map<String,String> allvars = concat(baseUriVars, vars);
-
- if (allvars != null && allvars.size() > 0) {
- uri += "?" + HttpTool.encodeUrlParams(allvars);
- }
-
- return URI.create(uri);
- }
-
- public Map<String, String> buildHeaders(Map<String, String> baseHeaders) {
- return MutableMap.<String,String>builder()
- .putAll(baseHeaders)
- .putAll(headers)
- .build();
- }
-
- @SuppressWarnings("unchecked")
- private <K,V> Map<K,V> concat(Map<? extends K,? extends V> map1, Map<? extends K,? extends V> map2) {
- if (map1 == null || map1.isEmpty()) return (Map<K,V>) map2;
- if (map2 == null || map2.isEmpty()) return (Map<K,V>) map1;
-
- // TODO Not using Immutable builder, because that fails if duplicates in map1 and map2
- return MutableMap.<K,V>builder().putAll(map1).putAll(map2).build();
- }
-
- @Override protected String toStringBaseName() { return "http"; }
- @Override protected String toStringPollSource() { return suburl; }
- @Override
- protected MutableList<Object> equalsFields() {
- return super.equalsFields().appendIfNotNull(method).appendIfNotNull(vars).appendIfNotNull(headers)
- .appendIfNotNull(body).appendIfNotNull(connectionTimeout).appendIfNotNull(socketTimeout);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollValue.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollValue.java
deleted file mode 100644
index 04432bd..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPollValue.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-
-/** @deprecated since 0.7.0, use {@link HttpToolResponse}.
- * the old {@link HttpPollValue} concrete class has been renamed {@link HttpToolResponse}
- * because it has nothing specific to polls. this is now just a transitional interface. */
-@Deprecated
-public interface HttpPollValue {
-
- public int getResponseCode();
- public String getReasonPhrase();
- public long getStartTime();
- public long getLatencyFullContent();
- public long getLatencyFirstResponse();
- public Map<String, List<String>> getHeaderLists();
- public byte[] getContent();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPolls.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPolls.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPolls.java
deleted file mode 100644
index aacd186..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpPolls.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import java.net.URI;
-
-import org.apache.brooklyn.util.core.http.HttpTool;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.http.impl.client.DefaultHttpClient;
-
-import com.google.common.collect.ImmutableMap;
-
-/**
- * @deprecated since 0.7; use {@link HttpTool}
- */
-@Deprecated
-public class HttpPolls {
-
- public static HttpToolResponse executeSimpleGet(URI uri) {
- return HttpTool.httpGet(new DefaultHttpClient(), uri, ImmutableMap.<String,String>of());
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctions.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctions.java
deleted file mode 100644
index 3fcbe07..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctions.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import java.util.List;
-
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.guava.Functionals;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Lists;
-import com.google.gson.JsonElement;
-
-public class HttpValueFunctions {
-
- private HttpValueFunctions() {} // instead use static utility methods
-
- public static Function<HttpToolResponse, Integer> responseCode() {
- return new ResponseCode();
- }
-
- /** @deprecated since 0.7.0; only here for deserialization of persisted state */
- private static Function<HttpToolResponse, Integer> responseCodeLegacy() {
- return new Function<HttpToolResponse, Integer>() {
- @Override public Integer apply(HttpToolResponse input) {
- return input.getResponseCode();
- }
- };
- }
-
- private static class ResponseCode implements Function<HttpToolResponse, Integer> {
- @Override public Integer apply(HttpToolResponse input) {
- return input.getResponseCode();
- }
- }
-
- public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int expected) {
- return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.equalTo(expected)));
- }
-
- public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int... expected) {
- List<Integer> expectedList = Lists.newArrayList();
- for (int e : expected) {
- expectedList.add((Integer)e);
- }
- return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.in(expectedList)));
- }
-
- public static Function<HttpToolResponse, String> stringContentsFunction() {
- return new StringContents();
- }
-
- /** @deprecated since 0.7.0; only here for deserialization of persisted state */
- private static Function<HttpToolResponse, String> stringContentsFunctionLegacy() {
- return new Function<HttpToolResponse, String>() {
- @Override public String apply(HttpToolResponse input) {
- return input.getContentAsString();
- }
- };
- }
-
- private static class StringContents implements Function<HttpToolResponse, String> {
- @Override public String apply(HttpToolResponse input) {
- return input.getContentAsString();
- }
- }
-
- public static Function<HttpToolResponse, JsonElement> jsonContents() {
- return Functionals.chain(stringContentsFunction(), JsonFunctions.asJson());
- }
-
- public static <T> Function<HttpToolResponse, T> jsonContents(String element, Class<T> expected) {
- return jsonContents(new String[] {element}, expected);
- }
-
- public static <T> Function<HttpToolResponse, T> jsonContents(String[] elements, Class<T> expected) {
- return Functionals.chain(jsonContents(), JsonFunctions.walk(elements), JsonFunctions.cast(expected));
- }
-
- public static <T> Function<HttpToolResponse, T> jsonContentsFromPath(String path){
- return Functionals.chain(jsonContents(), JsonFunctions.<T>getPath(path));
- }
-
- public static Function<HttpToolResponse, Long> latency() {
- return new Latency();
- }
-
- /** @deprecated since 0.7.0; only here for deserialization of persisted state */
- private static Function<HttpToolResponse, Long> latencyLegacy() {
- return new Function<HttpToolResponse, Long>() {
- public Long apply(HttpToolResponse input) {
- return input.getLatencyFullContent();
- }
- };
- }
-
- private static class Latency implements Function<HttpToolResponse, Long> {
- public Long apply(HttpToolResponse input) {
- return input.getLatencyFullContent();
- }
- };
-
- public static Function<HttpToolResponse, Boolean> containsHeader(String header) {
- return new ContainsHeader(header);
- }
-
- private static class ContainsHeader implements Function<HttpToolResponse, Boolean> {
- private final String header;
-
- public ContainsHeader(String header) {
- this.header = header;
- }
- @Override
- public Boolean apply(HttpToolResponse input) {
- List<String> actual = input.getHeaderLists().get(header);
- return actual != null && actual.size() > 0;
- }
- }
-
-
- /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function)} */ @Deprecated
- public static <A,B,C> Function<A,C> chain(final Function<A,? extends B> f1, final Function<B,C> f2) {
- return Functionals.chain(f1, f2);
- }
-
- /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function, Function)} */ @Deprecated
- public static <A,B,C,D> Function<A,D> chain(final Function<A,? extends B> f1, final Function<B,? extends C> f2, final Function<C,D> f3) {
- return Functionals.chain(f1, f2, f3);
- }
-
- /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function, Function, Function)} */ @Deprecated
- public static <A,B,C,D,E> Function<A,E> chain(final Function<A,? extends B> f1, final Function<B,? extends C> f2, final Function<C,? extends D> f3, final Function<D,E> f4) {
- return Functionals.chain(f1, f2, f3, f4);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/http/JsonFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/JsonFunctions.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/http/JsonFunctions.java
deleted file mode 100644
index f84109f..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/http/JsonFunctions.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import java.lang.reflect.Array;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.guava.MaybeFunctions;
-
-import com.google.common.base.Function;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
-import com.google.gson.*;
-import com.jayway.jsonpath.JsonPath;
-
-public class JsonFunctions {
-
- private JsonFunctions() {} // instead use static utility methods
-
- public static Function<String, JsonElement> asJson() {
- return new Function<String, JsonElement>() {
- @Override public JsonElement apply(String input) {
- return new JsonParser().parse(input);
- }
- };
- }
-
- public static <T> Function<JsonElement, List<T>> forEach(final Function<JsonElement, T> func) {
- return new Function<JsonElement, List<T>>() {
- @Override public List<T> apply(JsonElement input) {
- JsonArray array = (JsonArray) input;
- List<T> result = Lists.newArrayList();
- for (int i = 0; i < array.size(); i++) {
- result.add(func.apply(array.get(i)));
- }
- return result;
- }
- };
- }
-
-
- /** as {@link #walkM(Iterable)} taking a single string consisting of a dot separated path */
- public static Function<JsonElement, JsonElement> walk(String elementOrDotSeparatedElements) {
- return walk( Splitter.on('.').split(elementOrDotSeparatedElements) );
- }
-
- /** as {@link #walkM(Iterable)} taking a series of strings (dot separators not respected here) */
- public static Function<JsonElement, JsonElement> walk(final String... elements) {
- return walk(Arrays.asList(elements));
- }
-
- /** returns a function which traverses the supplied path of entries in a json object (maps of maps of maps...),
- * @throws NoSuchElementException if any path is not present as a key in that map */
- public static Function<JsonElement, JsonElement> walk(final Iterable<String> elements) {
- // could do this instead, pointing at Maybe for this, and for walkN, but it's slightly less efficient
-// return Functionals.chain(MaybeFunctions.<JsonElement>wrap(), walkM(elements), MaybeFunctions.<JsonElement>get());
-
- return new Function<JsonElement, JsonElement>() {
- @Override public JsonElement apply(JsonElement input) {
- JsonElement curr = input;
- for (String element : elements) {
- JsonObject jo = curr.getAsJsonObject();
- curr = jo.get(element);
- if (curr==null)
- throw new NoSuchElementException("No element '"+element+" in JSON, when walking "+elements);
- }
- return curr;
- }
- };
- }
-
-
- /** as {@link #walk(String)} but if any element is not found it simply returns null */
- public static Function<JsonElement, JsonElement> walkN(@Nullable String elements) {
- return walkN( Splitter.on('.').split(elements) );
- }
-
- /** as {@link #walk(String...))} but if any element is not found it simply returns null */
- public static Function<JsonElement, JsonElement> walkN(final String... elements) {
- return walkN(Arrays.asList(elements));
- }
-
- /** as {@link #walk(Iterable))} but if any element is not found it simply returns null */
- public static Function<JsonElement, JsonElement> walkN(final Iterable<String> elements) {
- return new Function<JsonElement, JsonElement>() {
- @Override public JsonElement apply(JsonElement input) {
- JsonElement curr = input;
- for (String element : elements) {
- if (curr==null) return null;
- JsonObject jo = curr.getAsJsonObject();
- curr = jo.get(element);
- }
- return curr;
- }
- };
- }
-
- /** as {@link #walk(String))} and {@link #walk(Iterable)} */
- public static Function<Maybe<JsonElement>, Maybe<JsonElement>> walkM(@Nullable String elements) {
- return walkM( Splitter.on('.').split(elements) );
- }
-
- /** as {@link #walk(String...))} and {@link #walk(Iterable)} */
- public static Function<Maybe<JsonElement>, Maybe<JsonElement>> walkM(final String... elements) {
- return walkM(Arrays.asList(elements));
- }
-
- /** as {@link #walk(Iterable))} but working with objects which {@link Maybe} contain {@link JsonElement},
- * simply preserving a {@link Maybe#absent()} object if additional walks are requested upon it
- * (cf jquery) */
- public static Function<Maybe<JsonElement>, Maybe<JsonElement>> walkM(final Iterable<String> elements) {
- return new Function<Maybe<JsonElement>, Maybe<JsonElement>>() {
- @Override public Maybe<JsonElement> apply(Maybe<JsonElement> input) {
- Maybe<JsonElement> curr = input;
- for (String element : elements) {
- if (curr.isAbsent()) return curr;
- JsonObject jo = curr.get().getAsJsonObject();
- JsonElement currO = jo.get(element);
- if (currO==null) return Maybe.absent("No element '"+element+" in JSON, when walking "+elements);
- curr = Maybe.of(currO);
- }
- return curr;
- }
- };
- }
-
- /**
- * returns an element from a single json primitive value given a full path {@link com.jayway.jsonpath.JsonPath}
- */
- public static <T> Function<JsonElement,T> getPath(final String path) {
- return new Function<JsonElement, T>() {
- @SuppressWarnings("unchecked")
- @Override public T apply(JsonElement input) {
- String jsonString = input.toString();
- Object rawElement = JsonPath.read(jsonString, path);
- return (T) rawElement;
- }
- };
- }
-
- @SuppressWarnings("unchecked")
- public static <T> Function<JsonElement, T> cast(final Class<T> expected) {
- return new Function<JsonElement, T>() {
- @Override public T apply(JsonElement input) {
- if (input == null) {
- return (T) null;
- } else if (input.isJsonNull()) {
- return (T) null;
- } else if (expected == boolean.class || expected == Boolean.class) {
- return (T) (Boolean) input.getAsBoolean();
- } else if (expected == char.class || expected == Character.class) {
- return (T) (Character) input.getAsCharacter();
- } else if (expected == byte.class || expected == Byte.class) {
- return (T) (Byte) input.getAsByte();
- } else if (expected == short.class || expected == Short.class) {
- return (T) (Short) input.getAsShort();
- } else if (expected == int.class || expected == Integer.class) {
- return (T) (Integer) input.getAsInt();
- } else if (expected == long.class || expected == Long.class) {
- return (T) (Long) input.getAsLong();
- } else if (expected == float.class || expected == Float.class) {
- return (T) (Float) input.getAsFloat();
- } else if (expected == double.class || expected == Double.class) {
- return (T) (Double) input.getAsDouble();
- } else if (expected == BigDecimal.class) {
- return (T) input.getAsBigDecimal();
- } else if (expected == BigInteger.class) {
- return (T) input.getAsBigInteger();
- } else if (Number.class.isAssignableFrom(expected)) {
- // TODO Will result in a class-cast if it's an unexpected sub-type of Number not handled above
- return (T) input.getAsNumber();
- } else if (expected == String.class) {
- return (T) input.getAsString();
- } else if (expected.isArray()) {
- JsonArray array = input.getAsJsonArray();
- Class<?> componentType = expected.getComponentType();
- if (JsonElement.class.isAssignableFrom(componentType)) {
- JsonElement[] result = new JsonElement[array.size()];
- for (int i = 0; i < array.size(); i++) {
- result[i] = array.get(i);
- }
- return (T) result;
- } else {
- Object[] result = (Object[]) Array.newInstance(componentType, array.size());
- for (int i = 0; i < array.size(); i++) {
- result[i] = cast(componentType).apply(array.get(i));
- }
- return (T) result;
- }
- } else {
- throw new IllegalArgumentException("Cannot cast json element to type "+expected);
- }
- }
- };
- }
-
- public static <T> Function<Maybe<JsonElement>, T> castM(final Class<T> expected) {
- return Functionals.chain(MaybeFunctions.<JsonElement>get(), cast(expected));
- }
-
- public static <T> Function<Maybe<JsonElement>, T> castM(final Class<T> expected, final T defaultValue) {
- return new Function<Maybe<JsonElement>, T>() {
- @Override
- public T apply(Maybe<JsonElement> input) {
- if (input.isAbsent()) return defaultValue;
- return cast(expected).apply(input.get());
- }
- };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellFeed.java
deleted file mode 100644
index 19e5bf5..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellFeed.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.shell;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.File;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ExecutionContext;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.core.task.system.internal.SystemProcessTaskFactory.ConcreteSystemProcessTaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Provides a feed of attribute values, by executing shell commands (on the local machine where
- * this instance of brooklyn is running). Useful e.g. for paas tools such as Cloud Foundry vmc
- * which operate against a remote target.
- *
- * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
- * <pre>
- * {@code
- * private ShellFeed feed;
- *
- * //@Override
- * protected void connectSensors() {
- * super.connectSensors();
- *
- * feed = ShellFeed.builder()
- * .entity(this)
- * .machine(mySshMachineLachine)
- * .poll(new ShellPollConfig<Long>(DISK_USAGE)
- * .command("df -P | grep /dev")
- * .failOnNonZeroResultCode(true)
- * .onSuccess(new Function<SshPollValue, Long>() {
- * public Long apply(SshPollValue input) {
- * String[] parts = input.getStdout().split("[ \\t]+");
- * return Long.parseLong(parts[2]);
- * }}))
- * .build();
- * }
- *
- * {@literal @}Override
- * protected void disconnectSensors() {
- * super.disconnectSensors();
- * if (feed != null) feed.stop();
- * }
- * }
- * </pre>
- *
- * @see SshFeed (to run on remote machines)
- * @see FunctionFeed (for arbitrary functions)
- *
- * @author aled
- */
-public class ShellFeed extends AbstractFeed {
-
- public static final Logger log = LoggerFactory.getLogger(ShellFeed.class);
-
- @SuppressWarnings("serial")
- private static final ConfigKey<SetMultimap<ShellPollIdentifier, ShellPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<ShellPollIdentifier, ShellPollConfig<?>>>() {},
- "polls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EntityLocal entity;
- private long period = 500;
- private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
- private List<ShellPollConfig<?>> polls = Lists.newArrayList();
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = val;
- return this;
- }
- public Builder period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public Builder period(long val, TimeUnit units) {
- this.period = val;
- this.periodUnits = units;
- return this;
- }
- public Builder poll(ShellPollConfig<?> config) {
- polls.add(config);
- return this;
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public ShellFeed build() {
- built = true;
- ShellFeed result = new ShellFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("ShellFeed.Builder created, but build() never called");
- }
- }
-
- private static class ShellPollIdentifier {
- final String command;
- final Map<String, String> env;
- final File dir;
- final String input;
- final String context;
- final long timeout;
-
- private ShellPollIdentifier(String command, Map<String, String> env, File dir, String input, String context, long timeout) {
- this.command = checkNotNull(command, "command");
- this.env = checkNotNull(env, "env");
- this.dir = dir;
- this.input = input;
- this.context = checkNotNull(context, "context");
- this.timeout = timeout;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(command, env, dir, input, timeout);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof ShellPollIdentifier)) {
- return false;
- }
- ShellPollIdentifier o = (ShellPollIdentifier) other;
- return Objects.equal(command, o.command) &&
- Objects.equal(env, o.env) &&
- Objects.equal(dir, o.dir) &&
- Objects.equal(input, o.input) &&
- Objects.equal(timeout, o.timeout);
- }
- }
-
- /**
- * For rebind; do not call directly; use builder
- */
- public ShellFeed() {
- }
-
- protected ShellFeed(Builder builder) {
- super();
-
- SetMultimap<ShellPollIdentifier, ShellPollConfig<?>> polls = HashMultimap.<ShellPollIdentifier,ShellPollConfig<?>>create();
- for (ShellPollConfig<?> config : builder.polls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "unchecked", "rawtypes" })
- ShellPollConfig<?> configCopy = new ShellPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
- String command = config.getCommand();
- Map<String, String> env = config.getEnv();
- File dir = config.getDir();
- String input = config.getInput();
- String context = config.getSensor().getName();
- long timeout = config.getTimeout();
-
- polls.put(new ShellPollIdentifier(command, env, dir, input, context, timeout), configCopy);
- }
- setConfig(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls.values());
- }
-
- @Override
- protected void preStart() {
- SetMultimap<ShellPollIdentifier, ShellPollConfig<?>> polls = getConfig(POLLS);
-
- for (final ShellPollIdentifier pollInfo : polls.keySet()) {
- Set<ShellPollConfig<?>> configs = polls.get(pollInfo);
- long minPeriod = Integer.MAX_VALUE;
- Set<AttributePollHandler<? super SshPollValue>> handlers = Sets.newLinkedHashSet();
-
- for (ShellPollConfig<?> config : configs) {
- handlers.add(new AttributePollHandler<SshPollValue>(config, entity, this));
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- }
-
- final ProcessTaskFactory<?> taskFactory = newTaskFactory(pollInfo.command, pollInfo.env, pollInfo.dir,
- pollInfo.input, pollInfo.context, pollInfo.timeout);
- final ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext();
-
- getPoller().scheduleAtFixedRate(
- new Callable<SshPollValue>() {
- @Override public SshPollValue call() throws Exception {
- ProcessTaskWrapper<?> taskWrapper = taskFactory.newTask();
- executionContext.submit(taskWrapper);
- taskWrapper.block();
- Optional<Integer> exitCode = Optional.fromNullable(taskWrapper.getExitCode());
- return new SshPollValue(null, exitCode.or(-1), taskWrapper.getStdout(), taskWrapper.getStderr());
- }},
- new DelegatingPollHandler<SshPollValue>(handlers),
- minPeriod);
- }
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<SshPollValue> getPoller() {
- return (Poller<SshPollValue>) super.getPoller();
- }
-
- /**
- * Executes the given command (using `bash -l -c $command`, so as to have a good path set).
- *
- * @param command The command to execute
- * @param env Environment variable settings, in format name=value
- * @param dir Working directory, or null to inherit from current process
- * @param input Input to send to the command (if not null)
- */
- protected ProcessTaskFactory<?> newTaskFactory(final String command, Map<String,String> env, File dir, String input, final String summary, final long timeout) {
- // FIXME Add generic timeout() support to task ExecutionManager
- if (timeout > 0) {
- log.warn("Timeout ({}ms) not currently supported for ShellFeed {}", timeout, this);
- }
-
- return new ConcreteSystemProcessTaskFactory<Object>(command)
- .environmentVariables(env)
- .loginShell(true)
- .directory(dir)
- .runAsCommand()
- .summary(summary);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellPollConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellPollConfig.java
deleted file mode 100644
index 782b094..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/shell/ShellPollConfig.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.shell;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.File;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
-import org.apache.brooklyn.util.collections.MutableList;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.Maps;
-
-public class ShellPollConfig<T> extends PollConfig<SshPollValue, T, ShellPollConfig<T>> {
-
- private String command;
- private Map<String,String> env = Maps.newLinkedHashMap();
- private long timeout = -1;
- private File dir;
- private String input;
-
- public static final Predicate<SshPollValue> DEFAULT_SUCCESS = new Predicate<SshPollValue>() {
- @Override
- public boolean apply(@Nullable SshPollValue input) {
- return input != null && input.getExitStatus() == 0;
- }};
-
- public ShellPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- super.checkSuccess(DEFAULT_SUCCESS);
- }
-
- public ShellPollConfig(ShellPollConfig<T> other) {
- super(other);
- command = other.command;
- env = other.env;
- timeout = other.timeout;
- dir = other.dir;
- input = other.input;
- }
-
- public String getCommand() {
- return command;
- }
-
- public Map<String, String> getEnv() {
- return env;
- }
-
- public File getDir() {
- return dir;
- }
-
- public String getInput() {
- return input;
- }
-
- public long getTimeout() {
- return timeout;
- }
-
- public ShellPollConfig<T> command(String val) {
- this.command = val;
- return this;
- }
-
- public ShellPollConfig<T> env(String key, String val) {
- env.put(checkNotNull(key, "key"), checkNotNull(val, "val"));
- return this;
- }
-
- public ShellPollConfig<T> env(Map<String,String> val) {
- for (Map.Entry<String, String> entry : checkNotNull(val, "map").entrySet()) {
- env(entry.getKey(), entry.getValue());
- }
- return this;
- }
-
- public ShellPollConfig<T> dir(File val) {
- this.dir = val;
- return this;
- }
-
- public ShellPollConfig<T> input(String val) {
- this.input = val;
- return this;
- }
-
- public ShellPollConfig<T> timeout(long timeout) {
- return timeout(timeout, TimeUnit.MILLISECONDS);
- }
-
- public ShellPollConfig<T> timeout(long timeout, TimeUnit units) {
- this.timeout = units.toMillis(timeout);
- return this;
- }
-
- @Override protected String toStringBaseName() { return "shell"; }
- @Override protected String toStringPollSource() { return command; }
- @Override protected MutableList<Object> equalsFields() { return super.equalsFields().appendIfNotNull(command); }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
deleted file mode 100644
index 6e5a485..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshFeed.java
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.ssh;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.core.location.Machines;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Provides a feed of attribute values, by polling over ssh.
- *
- * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
- * <pre>
- * {@code
- * private SshFeed feed;
- *
- * //@Override
- * protected void connectSensors() {
- * super.connectSensors();
- *
- * feed = SshFeed.builder()
- * .entity(this)
- * .machine(mySshMachineLachine)
- * .poll(new SshPollConfig<Boolean>(SERVICE_UP)
- * .command("rabbitmqctl -q status")
- * .onSuccess(new Function<SshPollValue, Boolean>() {
- * public Boolean apply(SshPollValue input) {
- * return (input.getExitStatus() == 0);
- * }}))
- * .build();
- * }
- *
- * {@literal @}Override
- * protected void disconnectSensors() {
- * super.disconnectSensors();
- * if (feed != null) feed.stop();
- * }
- * }
- * </pre>
- *
- * @author aled
- */
-public class SshFeed extends AbstractFeed {
-
- public static final Logger log = LoggerFactory.getLogger(SshFeed.class);
-
- @SuppressWarnings("serial")
- public static final ConfigKey<Supplier<SshMachineLocation>> MACHINE = ConfigKeys.newConfigKey(
- new TypeToken<Supplier<SshMachineLocation>>() {},
- "machine");
-
- public static final ConfigKey<Boolean> EXEC_AS_COMMAND = ConfigKeys.newBooleanConfigKey("execAsCommand");
-
- @SuppressWarnings("serial")
- public static final ConfigKey<SetMultimap<SshPollIdentifier, SshPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<SshPollIdentifier, SshPollConfig<?>>>() {},
- "polls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EntityLocal entity;
- private boolean onlyIfServiceUp = false;
- private Supplier<SshMachineLocation> machine;
- private Duration period = Duration.of(500, TimeUnit.MILLISECONDS);
- private List<SshPollConfig<?>> polls = Lists.newArrayList();
- private boolean execAsCommand = false;
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = val;
- return this;
- }
- public Builder onlyIfServiceUp() { return onlyIfServiceUp(true); }
- public Builder onlyIfServiceUp(boolean onlyIfServiceUp) {
- this.onlyIfServiceUp = onlyIfServiceUp;
- return this;
- }
- /** optional, to force a machine; otherwise it is inferred from the entity */
- public Builder machine(SshMachineLocation val) { return machine(Suppliers.ofInstance(val)); }
- /** optional, to force a machine; otherwise it is inferred from the entity */
- public Builder machine(Supplier<SshMachineLocation> val) {
- this.machine = val;
- return this;
- }
- public Builder period(Duration period) {
- this.period = period;
- return this;
- }
- public Builder period(long millis) {
- return period(Duration.of(millis, TimeUnit.MILLISECONDS));
- }
- public Builder period(long val, TimeUnit units) {
- return period(Duration.of(val, units));
- }
- public Builder poll(SshPollConfig<?> config) {
- polls.add(config);
- return this;
- }
- public Builder execAsCommand() {
- execAsCommand = true;
- return this;
- }
- public Builder execAsScript() {
- execAsCommand = false;
- return this;
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public SshFeed build() {
- built = true;
- SshFeed result = new SshFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("SshFeed.Builder created, but build() never called");
- }
- }
-
- private static class SshPollIdentifier {
- final Supplier<String> command;
- final Supplier<Map<String, String>> env;
-
- private SshPollIdentifier(Supplier<String> command, Supplier<Map<String, String>> env) {
- this.command = checkNotNull(command, "command");
- this.env = checkNotNull(env, "env");
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(command, env);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof SshPollIdentifier)) {
- return false;
- }
- SshPollIdentifier o = (SshPollIdentifier) other;
- return Objects.equal(command, o.command) &&
- Objects.equal(env, o.env);
- }
- }
-
- /** @deprecated since 0.7.0, use static convenience on {@link Locations} */
- @Deprecated
- public static SshMachineLocation getMachineOfEntity(Entity entity) {
- return Machines.findUniqueSshMachineLocation(entity.getLocations()).orNull();
- }
-
- /**
- * For rebind; do not call directly; use builder
- */
- public SshFeed() {
- }
-
- protected SshFeed(final Builder builder) {
- setConfig(ONLY_IF_SERVICE_UP, builder.onlyIfServiceUp);
- setConfig(MACHINE, builder.machine != null ? builder.machine : null);
- setConfig(EXEC_AS_COMMAND, builder.execAsCommand);
-
- SetMultimap<SshPollIdentifier, SshPollConfig<?>> polls = HashMultimap.<SshPollIdentifier,SshPollConfig<?>>create();
- for (SshPollConfig<?> config : builder.polls) {
- @SuppressWarnings({ "unchecked", "rawtypes" })
- SshPollConfig<?> configCopy = new SshPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
- polls.put(new SshPollIdentifier(config.getCommandSupplier(), config.getEnvSupplier()), configCopy);
- }
- setConfig(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls.values());
- }
-
- protected SshMachineLocation getMachine() {
- Supplier<SshMachineLocation> supplier = getConfig(MACHINE);
- if (supplier != null) {
- return supplier.get();
- } else {
- return Locations.findUniqueSshMachineLocation(entity.getLocations()).get();
- }
- }
-
- @Override
- protected void preStart() {
- SetMultimap<SshPollIdentifier, SshPollConfig<?>> polls = getConfig(POLLS);
-
- for (final SshPollIdentifier pollInfo : polls.keySet()) {
- Set<SshPollConfig<?>> configs = polls.get(pollInfo);
- long minPeriod = Integer.MAX_VALUE;
- Set<AttributePollHandler<? super SshPollValue>> handlers = Sets.newLinkedHashSet();
-
- for (SshPollConfig<?> config : configs) {
- handlers.add(new AttributePollHandler<SshPollValue>(config, entity, this));
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- }
-
- getPoller().scheduleAtFixedRate(
- new Callable<SshPollValue>() {
- public SshPollValue call() throws Exception {
- return exec(pollInfo.command.get(), pollInfo.env.get());
- }},
- new DelegatingPollHandler<SshPollValue>(handlers),
- minPeriod);
- }
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<SshPollValue> getPoller() {
- return (Poller<SshPollValue>) super.getPoller();
- }
-
- private SshPollValue exec(String command, Map<String,String> env) throws IOException {
- SshMachineLocation machine = getMachine();
- Boolean execAsCommand = getConfig(EXEC_AS_COMMAND);
- if (log.isTraceEnabled()) log.trace("Ssh polling for {}, executing {} with env {}", new Object[] {machine, command, env});
- ByteArrayOutputStream stdout = new ByteArrayOutputStream();
- ByteArrayOutputStream stderr = new ByteArrayOutputStream();
-
- int exitStatus;
- ConfigBag flags = ConfigBag.newInstance()
- .configure(SshTool.PROP_NO_EXTRA_OUTPUT, true)
- .configure(SshTool.PROP_OUT_STREAM, stdout)
- .configure(SshTool.PROP_ERR_STREAM, stderr);
- if (Boolean.TRUE.equals(execAsCommand)) {
- exitStatus = machine.execCommands(flags.getAllConfig(),
- "ssh-feed", ImmutableList.of(command), env);
- } else {
- exitStatus = machine.execScript(flags.getAllConfig(),
- "ssh-feed", ImmutableList.of(command), env);
- }
-
- return new SshPollValue(machine, exitStatus, new String(stdout.toByteArray()), new String(stderr.toByteArray()));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollConfig.java
deleted file mode 100644
index b666d42..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollConfig.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.ssh;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-
-public class SshPollConfig<T> extends PollConfig<SshPollValue, T, SshPollConfig<T>> {
-
- private Supplier<String> commandSupplier;
- private List<Supplier<Map<String,String>>> dynamicEnvironmentSupplier = MutableList.of();
-
- public static final Predicate<SshPollValue> DEFAULT_SUCCESS = new Predicate<SshPollValue>() {
- @Override
- public boolean apply(@Nullable SshPollValue input) {
- return input != null && input.getExitStatus() == 0;
- }};
-
- public SshPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- super.checkSuccess(DEFAULT_SUCCESS);
- }
-
- public SshPollConfig(SshPollConfig<T> other) {
- super(other);
- commandSupplier = other.commandSupplier;
- }
-
- /** @deprecated since 0.7.0; use {@link #getCommandSupplier()} and resolve just-in-time */
- public String getCommand() {
- return getCommandSupplier().get();
- }
- public Supplier<String> getCommandSupplier() {
- return commandSupplier;
- }
-
- /** @deprecated since 0.7.0; use {@link #getEnvSupplier()} and resolve just-in-time */
- public Map<String, String> getEnv() {
- return getEnvSupplier().get();
- }
- public Supplier<Map<String,String>> getEnvSupplier() {
- return new Supplier<Map<String,String>>() {
- @Override
- public Map<String, String> get() {
- Map<String,String> result = MutableMap.of();
- for (Supplier<Map<String, String>> envS: dynamicEnvironmentSupplier) {
- if (envS!=null) {
- Map<String, String> envM = envS.get();
- if (envM!=null) {
- mergeEnvMaps(envM, result);
- }
- }
- }
- return result;
- }
- };
- }
-
- protected void mergeEnvMaps(Map<String,String> supplied, Map<String,String> target) {
- if (supplied==null) return;
- // as the value is a string there is no need to look at deep merge behaviour
- target.putAll(supplied);
- }
-
- public SshPollConfig<T> command(String val) { return command(Suppliers.ofInstance(val)); }
- public SshPollConfig<T> command(Supplier<String> val) {
- this.commandSupplier = val;
- return this;
- }
-
- /** add the given env param; sequence is as per {@link #env(Supplier)} */
- public SshPollConfig<T> env(String key, String val) {
- return env(Collections.singletonMap(key, val));
- }
-
- /** add the given env params; sequence is as per {@link #env(Supplier)}.
- * behaviour is undefined if the map supplied here is subsequently changed.
- * <p>
- * if a map's contents might change, use {@link #env(Supplier)} */
- public SshPollConfig<T> env(Map<String,String> val) {
- if (val==null) return this;
- return env(Suppliers.ofInstance(val));
- }
-
- /**
- * adds the given dynamic supplier of environment variables.
- * <p>
- * use of a supplier allows env vars to be computed on each execution,
- * for example to take the most recent sensor values.
- * <p>
- * in the case of multiple map suppliers, static maps, or static {@link #env(String, String)}
- * key value pairs, the order in which they are specified here is the order
- * in which they are computed and applied.
- **/
- public SshPollConfig<T> env(Supplier<Map<String,String>> val) {
- Preconditions.checkNotNull(val);
- dynamicEnvironmentSupplier.add(val);
- return this;
- }
-
- @Override protected String toStringBaseName() { return "ssh"; }
- @Override protected Object toStringPollSource() {
- if (getCommandSupplier()==null) return null;
- String command = getCommandSupplier().get();
- return command;
- }
- @Override protected MutableList<Object> equalsFields() {
- return super.equalsFields()
- .appendIfNotNull(getCommandSupplier()!=null ? getCommandSupplier().get() : null)
- .appendIfNotNull(getEnvSupplier()!=null ? getEnvSupplier().get() : null);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
deleted file mode 100644
index 8f1885d..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshPollValue.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.ssh;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-public class SshPollValue {
-
- private final SshMachineLocation machine;
- private final int exitStatus;
- private final String stdout;
- private final String stderr;
-
- public SshPollValue(SshMachineLocation machine, int exitStatus, String stdout, String stderr) {
- this.machine = machine;
- this.exitStatus = exitStatus;
- this.stdout = stdout;
- this.stderr = stderr;
- }
-
- /** The machine the command will run on. */
- public SshMachineLocation getMachine() {
- return machine;
- }
-
- /** Command exit status, or -1 if error is set. */
- public int getExitStatus() {
- return exitStatus;
- }
-
- /** Command standard output; may be null if no content available. */
- @Nullable
- public String getStdout() {
- return stdout;
- }
-
- /** Command standard error; may be null if no content available. */
- @Nullable
- public String getStderr() {
- return stderr;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshValueFunctions.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshValueFunctions.java
deleted file mode 100644
index 9ef3048..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ssh/SshValueFunctions.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.ssh;
-
-import javax.annotation.Nullable;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicates;
-
-public class SshValueFunctions {
-
- public static Function<SshPollValue, Integer> exitStatus() {
- return new Function<SshPollValue, Integer>() {
- @Override public Integer apply(SshPollValue input) {
- return input.getExitStatus();
- }
- };
- }
-
- public static Function<SshPollValue, String> stdout() {
- return new Function<SshPollValue, String>() {
- @Override public String apply(SshPollValue input) {
- return input.getStdout();
- }
- };
- }
-
- public static Function<SshPollValue, String> stderr() {
- return new Function<SshPollValue, String>() {
- @Override public String apply(SshPollValue input) {
- return input.getStderr();
- }
- };
- }
-
- public static Function<SshPollValue, Boolean> exitStatusEquals(final int expected) {
- return chain(SshValueFunctions.exitStatus(), Functions.forPredicate(Predicates.equalTo(expected)));
- }
-
- // TODO Do we want these chain methods? Does guava have them already? Duplicated in HttpValueFunctions.
- public static <A,B,C> Function<A,C> chain(final Function<A,? extends B> f1, final Function<B,C> f2) {
- return new Function<A,C>() {
- @Override public C apply(@Nullable A input) {
- return f2.apply(f1.apply(input));
- }
- };
- }
-
- public static <A,B,C,D> Function<A,D> chain(final Function<A,? extends B> f1, final Function<B,? extends C> f2, final Function<C,D> f3) {
- return new Function<A,D>() {
- @Override public D apply(@Nullable A input) {
- return f3.apply(f2.apply(f1.apply(input)));
- }
- };
- }
-}
[17/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
index 01fde1f..5f55ae8 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
@@ -30,11 +30,11 @@ import org.apache.brooklyn.entity.chef.ChefConfig;
import org.apache.brooklyn.entity.chef.ChefLifecycleEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefServerTasks;
import org.apache.brooklyn.entity.stock.EffectorStartableImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
index a22e9e0..3e9dd2b 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBrokerImpl.java
@@ -27,8 +27,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.messaging.jms.JMSBrokerImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import com.google.common.base.Functions;
import com.google.common.base.Objects.ToStringHelper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQDestinationImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQDestinationImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQDestinationImpl.java
index 28375a0..6a27030 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQDestinationImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQDestinationImpl.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import com.google.common.base.Preconditions;
import org.apache.brooklyn.entity.messaging.jms.JMSDestinationImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.exceptions.Exceptions;
public abstract class ActiveMQDestinationImpl extends JMSDestinationImpl implements ActiveMQDestination {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQQueueImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQQueueImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQQueueImpl.java
index dddb6c9..daa121e 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQQueueImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQQueueImpl.java
@@ -18,8 +18,8 @@
*/
package org.apache.brooklyn.entity.messaging.activemq;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
index a0563b7..56db260 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBrokerImpl.java
@@ -30,9 +30,9 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.messaging.MessageBroker;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import com.google.common.base.Functions;
import com.google.common.base.Objects.ToStringHelper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
index dff0728..ceb4422 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
@@ -27,12 +27,12 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperNode;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
index 19335d9..72e6280 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBrokerImpl.java
@@ -33,9 +33,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.java.JmxSupport;
import org.apache.brooklyn.entity.messaging.jms.JMSBrokerImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import com.google.common.base.Function;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidDestinationImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidDestinationImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidDestinationImpl.java
index 61553bf..155e43a 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidDestinationImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidDestinationImpl.java
@@ -29,8 +29,8 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.messaging.amqp.AmqpServer;
import org.apache.brooklyn.entity.messaging.jms.JMSDestinationImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidQueueImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidQueueImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidQueueImpl.java
index d1b81af..e9d6b95 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidQueueImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidQueueImpl.java
@@ -24,8 +24,8 @@ import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.apache.brooklyn.entity.messaging.amqp.AmqpExchange;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.util.exceptions.Exceptions;
public class QpidQueueImpl extends QpidDestinationImpl implements QpidQueue {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitQueue.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitQueue.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitQueue.java
index ae84f60..037085b 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitQueue.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitQueue.java
@@ -19,9 +19,9 @@
package org.apache.brooklyn.entity.messaging.rabbit;
import org.apache.brooklyn.entity.messaging.Queue;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
import com.google.common.base.Function;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormImpl.java
index 38b8ac0..a1fc3d8 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormImpl.java
@@ -24,8 +24,8 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessDriver;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/AbstractZooKeeperImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/AbstractZooKeeperImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/AbstractZooKeeperImpl.java
index f0d4872..60175c9 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/AbstractZooKeeperImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/AbstractZooKeeperImpl.java
@@ -24,9 +24,9 @@ import javax.management.ObjectName;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessDriver;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
index 8b5914c..5af6dff 100644
--- a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
+++ b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNodeImpl.java
@@ -23,10 +23,10 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index d549776..b753df6 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -45,16 +45,16 @@ import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxOperationPollConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher;
import org.apache.brooklyn.policy.enricher.TimeWeightedDeltaEnricher;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
-import org.apache.brooklyn.sensor.feed.jmx.JmxOperationPollConfig;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
index c065897..4bff736 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
@@ -45,13 +45,13 @@ import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.collections.QuorumCheck;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
index bed5a3d..74deb3e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
@@ -35,13 +35,13 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index 5da3c47..cc21867 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -42,9 +42,9 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.http.HttpTool;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
index 724f246..c2e0395 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewayImpl.java
@@ -21,9 +21,9 @@ package org.apache.brooklyn.entity.nosql.couchbase;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import com.google.common.base.Functions;
import com.google.common.net.HostAndPort;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
index 163e126..06078f8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNodeImpl.java
@@ -25,9 +25,9 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
import org.apache.brooklyn.entity.webapp.WebAppServiceMethods;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.guava.Functionals;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
index b2cb577..413b82c 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeImpl.java
@@ -23,10 +23,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
import org.apache.brooklyn.util.guava.Functionals;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
index de56c8a..ea9c406 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServerImpl.java
@@ -27,11 +27,11 @@ import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.bson.BasicBSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import com.google.common.base.Functions;
import com.google.common.base.Objects;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterImpl.java
index 5698ee6..149457d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterImpl.java
@@ -23,8 +23,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.entity.nosql.mongodb.MongoDBClientSupport;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
index 857c048..5b35c63 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStoreImpl.java
@@ -27,11 +27,11 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
-import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
import com.google.common.base.Function;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
index 090f36d..85ac3e8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
@@ -35,10 +35,10 @@ import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.webapp.WebAppServiceMethods;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.guava.Functionals;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
index 903fc58..3ee54fe 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServerImpl.java
@@ -21,9 +21,9 @@ package org.apache.brooklyn.entity.nosql.solr;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import com.google.common.base.Functions;
import com.google.common.net.HostAndPort;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
index e25aef6..211c754 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchClusterIntegrationTest.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.core.http.HttpTool;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
index 7437d7a..a908886 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNodeIntegrationTest.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.core.http.HttpTool;
import org.apache.brooklyn.util.core.http.HttpToolResponse;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerImpl.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerImpl.java b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerImpl.java
index a864f6c..7051b86 100644
--- a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerImpl.java
+++ b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerImpl.java
@@ -37,13 +37,13 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.entity.java.JmxSupport;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
-import org.apache.brooklyn.sensor.feed.jmx.JmxValueFunctions;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxValueFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
index b98779e..ec3e714 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractControllerImpl.java
@@ -38,6 +38,7 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
@@ -45,7 +46,6 @@ import org.apache.brooklyn.entity.group.Cluster;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
index cbbd115..7996444 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractNonProvisionedControllerImpl.java
@@ -32,9 +32,9 @@ import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.Cluster;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.guava.Maybe;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
index e1f67c3..7952c91 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
@@ -35,15 +35,15 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.proxy.AbstractControllerImpl;
import org.apache.brooklyn.entity.proxy.ProxySslConfig;
import org.apache.brooklyn.entity.proxy.nginx.NginxController.NginxControllerInternal;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.file.ArchiveUtils;
import org.apache.brooklyn.util.core.http.HttpTool;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
index 74cb01c..7ff08a5 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
@@ -37,12 +37,12 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.entity.trait.StartableMethods;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.entity.group.DynamicGroupImpl;
import org.apache.brooklyn.entity.proxy.LoadBalancer;
import org.apache.brooklyn.entity.proxy.nginx.NginxController;
import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
index e5e7696..7c7173b 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
@@ -25,9 +25,9 @@ import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index f58c40a..f32d6a0 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -25,12 +25,12 @@ import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.guava.Functionals;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
index a6862fa..d264c66 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
@@ -24,9 +24,9 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
index bd5b873..d72b6db 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/nodejs/NodeJsWebAppServiceImpl.java
@@ -19,15 +19,15 @@
package org.apache.brooklyn.entity.webapp.nodejs;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.webapp.WebAppServiceMethods;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import com.google.common.base.Predicates;
import com.google.common.net.HostAndPort;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
index a55fa44..22cab1f 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServerImpl.java
@@ -24,8 +24,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
index 856306e..05f40ed 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
@@ -27,13 +27,13 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7ServerImpl;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7SshDriver;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.guava.Functionals;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
index 34c8ba4..30da612 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
@@ -28,9 +28,9 @@ import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.database.mysql.MySqlNodeImpl;
import org.apache.brooklyn.entity.database.mysql.MySqlSshDriver;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
index 258da82..d57bf63 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedNginxControllerImpl.java
@@ -29,15 +29,15 @@ import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.entity.proxy.nginx.NginxControllerImpl;
import org.apache.brooklyn.entity.proxy.nginx.NginxSshDriver;
import org.apache.brooklyn.entity.proxy.nginx.UrlMapping;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Networking;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/usage/rest-server/src/test/java/org/apache/brooklyn/rest/test/entity/brooklynnode/DeployBlueprintTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/test/entity/brooklynnode/DeployBlueprintTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/test/entity/brooklynnode/DeployBlueprintTest.java
index 6750add..2a464f2 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/test/entity/brooklynnode/DeployBlueprintTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/test/entity/brooklynnode/DeployBlueprintTest.java
@@ -30,8 +30,8 @@ import org.apache.brooklyn.api.mgmt.EntityManager;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.DeployBlueprintEffector;
import org.apache.brooklyn.entity.stock.BasicApplication;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.brooklyn.rest.BrooklynRestApiLauncherTestFixture;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
import org.apache.brooklyn.test.HttpTestUtils;
import org.apache.brooklyn.util.guava.Functionals;
import org.eclipse.jetty.server.Server;
[34/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/Combiner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Combiner.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Combiner.java
new file mode 100644
index 0000000..6819a33
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Combiner.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+@SuppressWarnings("serial")
+//@Catalog(name="Combiner", description="Combines attributes; see Enrichers.builder().combining(...)")
+public class Combiner<T,U> extends AbstractEnricher implements SensorEventListener<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Combiner.class);
+
+ public static ConfigKey<Function<?, ?>> TRANSFORMATION = ConfigKeys.newConfigKey(new TypeToken<Function<?, ?>>() {}, "enricher.transformation");
+
+ public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
+
+ public static ConfigKey<Set<Sensor<?>>> SOURCE_SENSORS = ConfigKeys.newConfigKey(new TypeToken<Set<Sensor<?>>>() {}, "enricher.sourceSensors");
+
+ public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+
+ public static final ConfigKey<Predicate<?>> VALUE_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<?>>() {}, "enricher.aggregating.valueFilter");
+
+ protected Function<? super Collection<T>, ? extends U> transformation;
+ protected Entity producer;
+ protected Set<Sensor<T>> sourceSensors;
+ protected Sensor<U> targetSensor;
+ protected Predicate<? super T> valueFilter;
+
+ /**
+ * Users of values should either on it synchronize when iterating over its entries or use
+ * copyOfValues to obtain an immutable copy of the map.
+ */
+ // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
+ protected final Map<Sensor<T>, T> values = Collections.synchronizedMap(new LinkedHashMap<Sensor<T>, T>());
+
+ public Combiner() {
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ this.transformation = (Function<? super Collection<T>, ? extends U>) getRequiredConfig(TRANSFORMATION);
+ this.producer = getConfig(PRODUCER) == null ? entity: getConfig(PRODUCER);
+ this.sourceSensors = (Set) getRequiredConfig(SOURCE_SENSORS);
+ this.targetSensor = (Sensor<U>) getRequiredConfig(TARGET_SENSOR);
+ this.valueFilter = (Predicate<? super T>) (getConfig(VALUE_FILTER) == null ? Predicates.alwaysTrue() : getConfig(VALUE_FILTER));
+
+ checkState(sourceSensors.size() > 0, "must specify at least one sourceSensor");
+
+ for (Sensor<T> sourceSensor : sourceSensors) {
+ subscribe(producer, sourceSensor, this);
+ }
+
+ for (Sensor<T> sourceSensor : sourceSensors) {
+ if (sourceSensor instanceof AttributeSensor) {
+ Object value = producer.getAttribute((AttributeSensor<?>)sourceSensor);
+ // TODO Aled didn't you write a convenience to "subscribeAndRunIfSet" ? (-Alex)
+ // Unfortunately not yet!
+ if (value != null) {
+ onEvent(new BasicSensorEvent(sourceSensor, producer, value, -1));
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onEvent(SensorEvent<T> event) {
+ synchronized (values) {
+ values.put(event.getSensor(), event.getValue());
+ }
+ onUpdated();
+ }
+
+ /**
+ * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
+ */
+ protected void onUpdated() {
+ try {
+ emit(targetSensor, compute());
+ } catch (Throwable t) {
+ LOG.warn("Error calculating and setting combination for enricher "+this, t);
+ throw Exceptions.propagate(t);
+ }
+ }
+
+ protected Object compute() {
+ synchronized (values) {
+ // TODO Could avoid copying when filter not needed
+ List<T> vs = MutableList.copyOf(Iterables.filter(values.values(), valueFilter));
+ return transformation.apply(vs);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java
new file mode 100644
index 0000000..0a03dca
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricher.java
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import groovy.lang.Closure;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Throwables;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Subscribes to events from producers with a sensor of type T, aggregates them with the
+ * provided closure and emits the result on the target sensor V.
+ * @param <T>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+public class CustomAggregatingEnricher<S,T> extends AbstractAggregatingEnricher<S,T> implements SensorEventListener<S> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CustomAggregatingEnricher.class);
+
+ protected final Function<Collection<S>, T> aggregator;
+
+ /**
+ * The valid keys for the flags are:
+ * - producers: a collection of entities to be aggregated
+ * - allMembers: indicates that should track members of the entity that the aggregator is associated with,
+ * to aggregate across all those members.
+ * - filter: a Predicate or Closure, indicating which entities to include
+ *
+ * @param flags
+ * @param source
+ * @param target
+ * @param aggregator Aggregates a collection of values, to return a single value for the target sensor
+ * @param defaultIniitalValueForUnreportedSensors Default value to populate the collection given to aggregator,
+ * where sensors are null or not present initially, defaults to null (note however that subsequent null reports will put an explicit null)
+ */
+ public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
+ Function<Collection<S>, T> aggregator, S defaultIniitalValueForUnreportedSensors) {
+ super(flags, source, target, defaultIniitalValueForUnreportedSensors);
+ this.aggregator = aggregator;
+ }
+
+ public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
+ Function<Collection<S>, T> aggregator) {
+ this(flags, source, target, aggregator, null);
+ }
+
+ public CustomAggregatingEnricher(AttributeSensor<? extends S> source, AttributeSensor<T> target,
+ Function<Collection<S>, T> aggregator, S defaultValue) {
+ this(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultValue);
+ }
+
+ public CustomAggregatingEnricher(AttributeSensor<? extends S> source, AttributeSensor<T> target,
+ Function<Collection<S>, T> aggregator) {
+ this(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
+ }
+
+ /**
+ * @param flags
+ * @param source
+ * @param target
+ * @param aggregator Should take a collection of values and return a single, aggregate value
+ * @param defaultValueForUnreportedSensors
+ *
+ * @see #CustomAggregatingEnricher(Map, AttributeSensor, AttributeSensor, Function, Object)
+ */
+ @SuppressWarnings("unchecked")
+ public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
+ Closure<?> aggregator, S defaultValueForUnreportedSensors) {
+ this(flags, source, target, GroovyJavaMethods.<Collection<S>, T>functionFromClosure((Closure<T>)aggregator), defaultValueForUnreportedSensors);
+ }
+
+ public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target, Closure<?> aggregator) {
+ this(flags, source, target, aggregator, null);
+ }
+
+ public CustomAggregatingEnricher(AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultValueForUnreportedSensors) {
+ this(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultValueForUnreportedSensors);
+ }
+
+ public CustomAggregatingEnricher(AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
+ this(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
+ }
+
+ @Override
+ public void onUpdated() {
+ try {
+ entity.setAttribute(target, getAggregate());
+ } catch (Throwable t) {
+ LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
+ throw Throwables.propagate(t);
+ }
+ }
+
+ public T getAggregate() {
+ synchronized (values) {
+ return (T) aggregator.apply(values.values());
+ }
+ }
+
+ /**
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * Enrichers.Builder builder = Enrichers.builder()
+ * .aggregating(source)
+ * .publishing(target)
+ * .computing(GroovyJavaMethods.<Collection<S>, T>functionFromClosure((Closure<T>)aggregator))
+ * .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors);
+ *
+ * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
+ * if (filter != null) builder.entityFilter(filter);
+ * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
+ *
+ * addEnricher(builder.build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultVal) {
+ return new CustomAggregatingEnricher<S,T>(flags, source, target, aggregator, defaultVal);
+ }
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
+ return newEnricher(flags, source, target, aggregator, null);
+ }
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultVal) {
+ return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultVal);
+ }
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
+ return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
+ }
+
+ /**
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * Enrichers.Builder builder = Enrichers.builder()
+ * .aggregating(source)
+ * .publishing(target)
+ * .computing(aggregator)
+ * .defaultValueForUnreportedSensors(defaultVal);
+ *
+ * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
+ * if (filter != null) builder.entityFilter(filter);
+ * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
+ *
+ * addEnricher(builder.build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator, S defaultVal) {
+ return new CustomAggregatingEnricher<S,T>(flags, source, target, aggregator, defaultVal);
+ }
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator) {
+ return newEnricher(flags, source, target, aggregator, null);
+ }
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator, S defaultVal) {
+ return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultVal);
+ }
+ public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
+ AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator) {
+ return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
+ }
+
+ /**
+ * creates an enricher which sums over all children/members,
+ * defaulting to excluding sensors which have not published anything (or published null), and null if there are no sensors;
+ * this behaviour can be customised, both default value for sensors, and what to report if no sensors
+ *
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * Enrichers.Builder builder = Enrichers.builder()
+ * .aggregating(source)
+ * .publishing(target)
+ * .computingSum()
+ * .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors)
+ * .valueToReportIfNoSensors(valueToReportIfNoSensors);
+ *
+ * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
+ * if (filter != null) builder.entityFilter(filter);
+ * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
+ *
+ * addEnricher(builder.build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public static <N extends Number, T extends Number> CustomAggregatingEnricher<N,T> newSummingEnricher(
+ Map<String,?> flags, AttributeSensor<N> source, final AttributeSensor<T> target,
+ final N defaultValueForUnreportedSensors, final T valueToReportIfNoSensors) {
+
+ Function<Collection<N>, T> aggregator = new Function<Collection<N>, T>() {
+ @Override public T apply(Collection<N> vals) {
+ return sum(vals, defaultValueForUnreportedSensors, valueToReportIfNoSensors, target.getTypeToken());
+ }
+ };
+ return new CustomAggregatingEnricher<N,T>(flags, source, target, aggregator, defaultValueForUnreportedSensors);
+ }
+
+ /** @see {@link #newSummingEnricher(Map, AttributeSensor, AttributeSensor, Number, Number)} */
+ public static <N extends Number> CustomAggregatingEnricher<N,N> newSummingEnricher(
+ AttributeSensor<N> source, AttributeSensor<N> target) {
+ return newSummingEnricher(Collections.<String,Object>emptyMap(), source, target, null, null);
+ }
+
+ /** creates an enricher which averages over all children/members,
+ * defaulting to excluding sensors which have not published anything (or published null), and null if there are no sensors;
+ * this behaviour can be customised, both default value for sensors, and what to report if no sensors
+ *
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * Enrichers.Builder builder = Enrichers.builder()
+ * .aggregating(source)
+ * .publishing(target)
+ * .computingAverage()
+ * .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors)
+ * .valueToReportIfNoSensors(valueToReportIfNoSensors);
+ *
+ * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
+ * if (filter != null) builder.entityFilter(filter);
+ * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
+ *
+ * addEnricher(builder.build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public static <N extends Number> CustomAggregatingEnricher<N,Double> newAveragingEnricher(
+ Map<String,?> flags, AttributeSensor<? extends N> source, final AttributeSensor<Double> target,
+ final N defaultValueForUnreportedSensors, final Double valueToReportIfNoSensors) {
+ Function<Collection<N>, Double> aggregator = new Function<Collection<N>, Double>() {
+ @Override public Double apply(Collection<N> vals) {
+ int count = count(vals, defaultValueForUnreportedSensors!=null);
+ return (count==0) ? valueToReportIfNoSensors :
+ (Double) ((sum(vals, defaultValueForUnreportedSensors, 0, TypeToken.of(Double.class)) / count));
+ }
+ };
+ return new CustomAggregatingEnricher<N,Double>(flags, source, target, aggregator, defaultValueForUnreportedSensors);
+ }
+
+ /** @see #newAveragingEnricher(Map, AttributeSensor, AttributeSensor, Number, Double) */
+ public static <N extends Number> CustomAggregatingEnricher<N,Double> newAveragingEnricher(
+ AttributeSensor<N> source, AttributeSensor<Double> target) {
+ return newAveragingEnricher(Collections.<String,Object>emptyMap(), source, target, null, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <N extends Number> N cast(Number n, TypeToken<? extends N> numberType) {
+ return (N) TypeCoercions.castPrimitive(n, numberType.getRawType());
+ }
+
+ private static <N extends Number> N sum(Iterable<? extends Number> vals, Number valueIfNull, Number valueIfNone, TypeToken<N> type) {
+ double result = 0d;
+ int count = 0;
+ if (vals!=null) {
+ for (Number val : vals) {
+ if (val!=null) {
+ result += val.doubleValue();
+ count++;
+ } else if (valueIfNull!=null) {
+ result += valueIfNull.doubleValue();
+ count++;
+ }
+ }
+ }
+ if (count==0) return cast(valueIfNone, type);
+ return cast(result, type);
+ }
+
+ private static int count(Iterable<? extends Object> vals, boolean includeNullValues) {
+ int result = 0;
+ if (vals!=null)
+ for (Object val : vals)
+ if (val!=null || includeNullValues) result++;
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
new file mode 100644
index 0000000..baed4f1
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Enrichers.java
@@ -0,0 +1,825 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import com.google.common.reflect.TypeToken;
+
+public class Enrichers {
+
+ private Enrichers() {}
+
+ public static InitialBuilder builder() {
+ return new InitialBuilder();
+ }
+
+ public abstract static class Builder<B extends Builder<B>> {
+ @SuppressWarnings("unchecked")
+ protected B self() {
+ return (B) this;
+ }
+ }
+
+ public abstract static class AbstractEnricherBuilder<B extends AbstractEnricherBuilder<B>> extends Builder<B> {
+ final Class<? extends Enricher> enricherType;
+ Boolean suppressDuplicates;
+ String uniqueTag;
+ Set<Object> tags = MutableSet.of();
+
+ public AbstractEnricherBuilder(Class<? extends Enricher> enricherType) {
+ this.enricherType = enricherType;
+ }
+
+ public B uniqueTag(String tag) {
+ uniqueTag = Preconditions.checkNotNull(tag);
+ return self();
+ }
+ public B addTag(Object tag) {
+ tags.add(Preconditions.checkNotNull(tag));
+ return self();
+ }
+ public B suppressDuplicates(Boolean suppressDuplicates) {
+ this.suppressDuplicates = suppressDuplicates;
+ return self();
+ }
+
+ protected abstract String getDefaultUniqueTag();
+
+ protected EnricherSpec<? extends Enricher> build() {
+ EnricherSpec<? extends Enricher> spec = EnricherSpec.create(enricherType);
+
+ String uniqueTag2 = uniqueTag;
+ if (uniqueTag2==null)
+ uniqueTag2 = getDefaultUniqueTag();
+ if (uniqueTag2!=null)
+ spec.uniqueTag(uniqueTag2);
+
+ if (!tags.isEmpty()) spec.tags(tags);
+ if (suppressDuplicates!=null)
+ spec.configure(AbstractEnricher.SUPPRESS_DUPLICATES, suppressDuplicates);
+
+ return spec;
+ }
+ }
+
+ protected abstract static class AbstractInitialBuilder<B extends AbstractInitialBuilder<B>> extends Builder<B> {
+ public PropagatorBuilder propagating(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) {
+ return new PropagatorBuilder(vals);
+ }
+ public PropagatorBuilder propagating(Iterable<? extends Sensor<?>> vals) {
+ return new PropagatorBuilder(vals);
+ }
+ public PropagatorBuilder propagating(Sensor<?>... vals) {
+ return new PropagatorBuilder(vals);
+ }
+ public PropagatorBuilder propagatingAll() {
+ return new PropagatorBuilder(true, null);
+ }
+ public PropagatorBuilder propagatingAllButUsualAnd(Sensor<?>... vals) {
+ return new PropagatorBuilder(true, ImmutableSet.<Sensor<?>>builder().addAll(Propagator.SENSORS_NOT_USUALLY_PROPAGATED).add(vals).build());
+ }
+ public PropagatorBuilder propagatingAllBut(Sensor<?>... vals) {
+ return new PropagatorBuilder(true, ImmutableSet.copyOf(vals));
+ }
+ public PropagatorBuilder propagatingAllBut(Iterable<? extends Sensor<?>> vals) {
+ return new PropagatorBuilder(true, vals);
+ }
+
+ /**
+ * Builds an enricher which transforms a given sensor:
+ * <li> applying a (required) function ({@link TransformerBuilder#computing(Function)}, or
+ * {@link AbstractAggregatorBuilder#computingAverage()}/
+ * {@link AbstractAggregatorBuilder#computingSum()}, mandatory);
+ * <li> and publishing it on the entity where the enricher is attached;
+ * <li> optionally taking the sensor from a different source entity ({@link TransformerBuilder#from(Entity)});
+ * <li> and optionally publishing it as a different sensor ({@link TransformerBuilder#publishing(AttributeSensor)});
+ * <p> You must supply at least one of the optional values, of course, otherwise the enricher may loop endlessly!
+ */
+ public <S> TransformerBuilder<S, Object> transforming(AttributeSensor<S> val) {
+ return new TransformerBuilder<S, Object>(val);
+ }
+ /** as {@link #transforming(AttributeSensor)} but accepting multiple sensors, with the function acting on the set of values */
+ public <S> CombinerBuilder<S, Object> combining(Collection<AttributeSensor<? extends S>> vals) {
+ return new CombinerBuilder<S, Object>(vals);
+ }
+ /** as {@link #combining(Collection)} */
+ @SafeVarargs
+ public final <S> CombinerBuilder<S, Object> combining(AttributeSensor<? extends S>... vals) {
+ return new CombinerBuilder<S, Object>(vals);
+ }
+ /** as {@link #combining(Collection)} but the collection of values comes from the given sensor on multiple entities */
+ public <S> AggregatorBuilder<S, Object> aggregating(AttributeSensor<S> val) {
+ return new AggregatorBuilder<S,Object>(val);
+ }
+ /** creates an {@link UpdatingMap} enricher:
+ * {@link UpdatingMapBuilder#from(AttributeSensor)} and {@link UpdatingMapBuilder#computing(Function)} are required
+ **/
+ public <S,TKey,TVal> UpdatingMapBuilder<S, TKey, TVal> updatingMap(AttributeSensor<Map<TKey,TVal>> target) {
+ return new UpdatingMapBuilder<S, TKey, TVal>(target);
+ }
+ /** creates a {@link org.apache.brooklyn.enricher.stock.Joiner} enricher builder
+ * which joins entries in a list to produce a String
+ **/
+ public JoinerBuilder joining(AttributeSensor<?> source) {
+ return new JoinerBuilder(source);
+ }
+ }
+
+
+ protected abstract static class AbstractAggregatorBuilder<S, T, B extends AbstractAggregatorBuilder<S, T, B>> extends AbstractEnricherBuilder<B> {
+ protected final AttributeSensor<S> aggregating;
+ protected AttributeSensor<T> publishing;
+ protected Entity fromEntity;
+ /** @deprecated since 0.7.0, kept for backwards compatibility for rebind, but not used otherwise */
+ @Deprecated protected Function<? super Collection<S>, ? extends T> computing;
+ // use supplier so latest values of other fields can be used
+ protected Supplier<Function<? super Collection<S>, ? extends T>> computingSupplier;
+ protected Boolean fromMembers;
+ protected Boolean fromChildren;
+ protected Boolean excludingBlank;
+ protected ImmutableSet<Entity> fromHardcodedProducers;
+ protected Predicate<? super Entity> entityFilter;
+ protected Predicate<Object> valueFilter;
+ protected Object defaultValueForUnreportedSensors;
+ protected Object valueToReportIfNoSensors;
+
+ public AbstractAggregatorBuilder(AttributeSensor<S> aggregating) {
+ super(Aggregator.class);
+ this.aggregating = aggregating;
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <T2 extends T> AggregatorBuilder<S,T2> publishing(AttributeSensor<? extends T2> val) {
+ this.publishing = (AttributeSensor) checkNotNull(val);
+ return (AggregatorBuilder) self();
+ }
+ public B from(Entity val) {
+ this.fromEntity = checkNotNull(val);
+ return self();
+ }
+ public B fromMembers() {
+ this.fromMembers = true;
+ return self();
+ }
+ public B fromChildren() {
+ this.fromChildren = true;
+ return self();
+ }
+ public B fromHardcodedProducers(Iterable<? extends Entity> val) {
+ this.fromHardcodedProducers = ImmutableSet.copyOf(val);
+ return self();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public B computing(Function<? super Collection<S>, ? extends T> val) {
+ this.computingSupplier = (Supplier)Suppliers.ofInstance(checkNotNull(val));
+ return self();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes", "unused" })
+ private B computingSumLegacy() {
+ // since 0.7.0, kept in case we need to rebind to this
+ Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
+ @Override public Number apply(Collection<S> input) {
+ return sum((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
+ }};
+ this.computing((Function)function);
+ return self();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes", "unused" })
+ private B computingAverageLegacy() {
+ // since 0.7.0, kept in case we need to rebind to this
+ Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
+ @Override public Number apply(Collection<S> input) {
+ return average((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
+ }};
+ this.computing((Function)function);
+ return self();
+ }
+ public B computingSum() {
+ this.computingSupplier = new Supplier<Function<? super Collection<S>, ? extends T>>() {
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Function<? super Collection<S>, ? extends T> get() {
+ // relies on TypeCoercion of result from Number to T, and type erasure for us to get away with it!
+ return (Function)new ComputingSum((Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, publishing.getTypeToken());
+ }
+ };
+ return self();
+ }
+
+ public B computingAverage() {
+ this.computingSupplier = new Supplier<Function<? super Collection<S>, ? extends T>>() {
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public Function<? super Collection<S>, ? extends T> get() {
+ // relies on TypeCoercion of result from Number to T, and type erasure for us to get away with it!
+ return (Function)new ComputingAverage((Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, publishing.getTypeToken());
+ }
+ };
+ return self();
+ }
+ public B defaultValueForUnreportedSensors(S val) {
+ this.defaultValueForUnreportedSensors = val;
+ return self();
+ }
+ public B valueToReportIfNoSensors(Object val) {
+ this.valueToReportIfNoSensors = val;
+ return self();
+ }
+ public B entityFilter(Predicate<? super Entity> val) {
+ this.entityFilter = val;
+ return self();
+ }
+ public B excludingBlank() {
+ this.excludingBlank = true;
+ return self();
+ }
+ @Override
+ protected String getDefaultUniqueTag() {
+ if (publishing==null) return null;
+ return "aggregator:"+publishing.getName();
+ }
+ public EnricherSpec<?> build() {
+ Predicate<Object> valueFilter;
+ if (Boolean.TRUE.equals(excludingBlank)) {
+ valueFilter = new Predicate<Object>() {
+ @Override public boolean apply(Object input) {
+ return (input != null) &&
+ ((input instanceof CharSequence) ? Strings.isNonBlank((CharSequence)input) : true);
+ }
+ };
+ // above kept for deserialization; not sure necessary
+ valueFilter = StringPredicates.isNonBlank();
+ } else {
+ valueFilter = null;
+ }
+ // FIXME excludingBlank; use valueFilter? exclude means ignored entirely or substituted for defaultMemberValue?
+ return super.build().configure(MutableMap.builder()
+ .putIfNotNull(Aggregator.PRODUCER, fromEntity)
+ .put(Aggregator.TARGET_SENSOR, publishing)
+ .put(Aggregator.SOURCE_SENSOR, aggregating)
+ .putIfNotNull(Aggregator.FROM_CHILDREN, fromChildren)
+ .putIfNotNull(Aggregator.FROM_MEMBERS, fromMembers)
+ .putIfNotNull(Aggregator.TRANSFORMATION, computingSupplier.get())
+ .putIfNotNull(Aggregator.FROM_HARDCODED_PRODUCERS, fromHardcodedProducers)
+ .putIfNotNull(Aggregator.ENTITY_FILTER, entityFilter)
+ .putIfNotNull(Aggregator.VALUE_FILTER, valueFilter)
+ .putIfNotNull(Aggregator.DEFAULT_MEMBER_VALUE, defaultValueForUnreportedSensors)
+ .build());
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .omitNullValues()
+ .add("aggregating", aggregating)
+ .add("publishing", publishing)
+ .add("fromEntity", fromEntity)
+ .add("computing", computingSupplier)
+ .add("fromMembers", fromMembers)
+ .add("fromChildren", fromChildren)
+ .add("excludingBlank", excludingBlank)
+ .add("fromHardcodedProducers", fromHardcodedProducers)
+ .add("entityFilter", entityFilter)
+ .add("valueFilter", valueFilter)
+ .add("defaultValueForUnreportedSensors", defaultValueForUnreportedSensors)
+ .add("valueToReportIfNoSensors", valueToReportIfNoSensors)
+ .toString();
+ }
+ }
+
+ protected abstract static class AbstractCombinerBuilder<S, T, B extends AbstractCombinerBuilder<S, T, B>> extends AbstractEnricherBuilder<B> {
+ protected final List<AttributeSensor<? extends S>> combining;
+ protected AttributeSensor<T> publishing;
+ protected Entity fromEntity;
+ protected Function<? super Collection<S>, ? extends T> computing;
+ protected Boolean excludingBlank;
+ protected Object valueToReportIfNoSensors;
+ protected Predicate<Object> valueFilter;
+
+ // For summing/averaging
+ protected Object defaultValueForUnreportedSensors;
+
+ @SafeVarargs
+ public AbstractCombinerBuilder(AttributeSensor<? extends S>... vals) {
+ this(ImmutableList.copyOf(vals));
+ }
+ public AbstractCombinerBuilder(Collection<AttributeSensor<? extends S>> vals) {
+ super(Combiner.class);
+ checkArgument(checkNotNull(vals).size() > 0, "combining-sensors must be non-empty");
+ this.combining = ImmutableList.<AttributeSensor<? extends S>>copyOf(vals);
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <T2 extends T> CombinerBuilder<S,T2> publishing(AttributeSensor<? extends T2> val) {
+ this.publishing = (AttributeSensor) checkNotNull(val);
+ return (CombinerBuilder) this;
+ }
+ public B from(Entity val) {
+ this.fromEntity = checkNotNull(val);
+ return self();
+ }
+ public B computing(Function<? super Collection<S>, ? extends T> val) {
+ this.computing = checkNotNull(val);
+ return self();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public B computingSum() {
+ Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
+ @Override public Number apply(Collection<S> input) {
+ return sum((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
+ }};
+ this.computing((Function)function);
+ return self();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public B computingAverage() {
+ Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
+ @Override public Number apply(Collection<S> input) {
+ return average((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
+ }};
+ this.computing((Function)function);
+ return self();
+ }
+ public B defaultValueForUnreportedSensors(Object val) {
+ this.defaultValueForUnreportedSensors = val;
+ return self();
+ }
+ public B valueToReportIfNoSensors(Object val) {
+ this.valueToReportIfNoSensors = val;
+ return self();
+ }
+ public B excludingBlank() {
+ this.excludingBlank = true;
+ return self();
+ }
+ @Override
+ protected String getDefaultUniqueTag() {
+ if (publishing==null) return null;
+ return "combiner:"+publishing.getName();
+ }
+ public EnricherSpec<?> build() {
+ return super.build().configure(MutableMap.builder()
+ .putIfNotNull(Combiner.PRODUCER, fromEntity)
+ .put(Combiner.TARGET_SENSOR, publishing)
+ .put(Combiner.SOURCE_SENSORS, combining)
+ .putIfNotNull(Combiner.TRANSFORMATION, computing)
+ .putIfNotNull(Combiner.VALUE_FILTER, valueFilter)
+ .build());
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .omitNullValues()
+ .add("combining", combining)
+ .add("publishing", publishing)
+ .add("fromEntity", fromEntity)
+ .add("computing", computing)
+ .add("excludingBlank", excludingBlank)
+ .add("valueToReportIfNoSensors", valueToReportIfNoSensors)
+ .add("valueFilter", valueFilter)
+ .toString();
+ }
+ }
+
+ protected abstract static class AbstractTransformerBuilder<S, T, B extends AbstractTransformerBuilder<S, T, B>> extends AbstractEnricherBuilder<B> {
+ protected final AttributeSensor<S> transforming;
+ protected AttributeSensor<T> publishing;
+ protected Entity fromEntity;
+ protected Function<? super S, ?> computing;
+ protected Function<? super SensorEvent<S>, ?> computingFromEvent;
+
+ public AbstractTransformerBuilder(AttributeSensor<S> val) {
+ super(Transformer.class);
+ this.transforming = checkNotNull(val);
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <T2 extends T> TransformerBuilder<S,T2> publishing(AttributeSensor<? extends T2> val) {
+ this.publishing = (AttributeSensor) checkNotNull(val);
+ return (TransformerBuilder) this;
+ }
+ public B from(Entity val) {
+ this.fromEntity = checkNotNull(val);
+ return self();
+ }
+ public B computing(Function<? super S, ? extends T> val) {
+ this.computing = checkNotNull(val);
+ return self();
+ }
+ public B computingFromEvent(Function<? super SensorEvent<S>, ? extends T> val) {
+ this.computingFromEvent = checkNotNull(val);
+ return self();
+ }
+ @Override
+ protected String getDefaultUniqueTag() {
+ if (publishing==null) return null;
+ return "transformer:"+publishing.getName();
+ }
+ public EnricherSpec<?> build() {
+ return super.build().configure(MutableMap.builder()
+ .putIfNotNull(Transformer.PRODUCER, fromEntity)
+ .put(Transformer.TARGET_SENSOR, publishing)
+ .put(Transformer.SOURCE_SENSOR, transforming)
+ .putIfNotNull(Transformer.TRANSFORMATION_FROM_VALUE, computing)
+ .putIfNotNull(Transformer.TRANSFORMATION_FROM_EVENT, computingFromEvent)
+ .build());
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .omitNullValues()
+ .add("publishing", publishing)
+ .add("transforming", transforming)
+ .add("fromEntity", fromEntity)
+ .add("computing", computing)
+ .toString();
+ }
+ }
+
+ protected abstract static class AbstractPropagatorBuilder<B extends AbstractPropagatorBuilder<B>> extends AbstractEnricherBuilder<B> {
+ protected final Map<? extends Sensor<?>, ? extends Sensor<?>> propagating;
+ protected final Boolean propagatingAll;
+ protected final Iterable<? extends Sensor<?>> propagatingAllBut;
+ protected Entity fromEntity;
+
+ public AbstractPropagatorBuilder(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) {
+ super(Propagator.class);
+ checkArgument(checkNotNull(vals).size() > 0, "propagating-sensors must be non-empty");
+ this.propagating = vals;
+ this.propagatingAll = null;
+ this.propagatingAllBut = null;
+ }
+ public AbstractPropagatorBuilder(Iterable<? extends Sensor<?>> vals) {
+ this(newIdentityMap(ImmutableSet.copyOf(vals)));
+ }
+ public AbstractPropagatorBuilder(Sensor<?>... vals) {
+ this(newIdentityMap(ImmutableSet.copyOf(vals)));
+ }
+ AbstractPropagatorBuilder(boolean propagatingAll, Iterable<? extends Sensor<?>> butVals) {
+ super(Propagator.class);
+ // Ugly constructor! Taking boolean to differentiate it from others; could use a static builder
+ // but feels like overkill having a builder for a builder, being called by a builder!
+ checkArgument(propagatingAll, "Not propagating all; use PropagatingAll(vals)");
+ this.propagating = null;
+ this.propagatingAll = true;
+ this.propagatingAllBut = (butVals == null || Iterables.isEmpty(butVals)) ? null: butVals;
+ }
+ public B from(Entity val) {
+ this.fromEntity = checkNotNull(val);
+ return self();
+ }
+ @Override
+ protected String getDefaultUniqueTag() {
+ List<String> summary = MutableList.of();
+ if (propagating!=null) {
+ for (Map.Entry<? extends Sensor<?>, ? extends Sensor<?>> entry: propagating.entrySet()) {
+ if (entry.getKey().getName().equals(entry.getValue().getName()))
+ summary.add(entry.getKey().getName());
+ else
+ summary.add(entry.getKey().getName()+"->"+entry.getValue().getName());
+ }
+ }
+ if (Boolean.TRUE.equals(propagatingAll))
+ summary.add("ALL");
+ if (propagatingAllBut!=null && !Iterables.isEmpty(propagatingAllBut)) {
+ List<String> allBut = MutableList.of();
+ for (Sensor<?> s: propagatingAllBut) allBut.add(s.getName());
+ summary.add("ALL_BUT:"+com.google.common.base.Joiner.on(",").join(allBut));
+ }
+
+ return "propagating["+fromEntity.getId()+":"+com.google.common.base.Joiner.on(",").join(summary)+"]";
+ }
+ public EnricherSpec<? extends Enricher> build() {
+ return super.build().configure(MutableMap.builder()
+ .putIfNotNull(Propagator.PRODUCER, fromEntity)
+ .putIfNotNull(Propagator.SENSOR_MAPPING, propagating)
+ .putIfNotNull(Propagator.PROPAGATING_ALL, propagatingAll)
+ .putIfNotNull(Propagator.PROPAGATING_ALL_BUT, propagatingAllBut)
+ .build());
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .omitNullValues()
+ .add("fromEntity", fromEntity)
+ .add("propagating", propagating)
+ .add("propagatingAll", propagatingAll)
+ .add("propagatingAllBut", propagatingAllBut)
+ .toString();
+ }
+ }
+
+ public abstract static class AbstractUpdatingMapBuilder<S, TKey, TVal, B extends AbstractUpdatingMapBuilder<S, TKey, TVal, B>> extends AbstractEnricherBuilder<B> {
+ protected AttributeSensor<Map<TKey,TVal>> targetSensor;
+ protected AttributeSensor<? extends S> fromSensor;
+ protected TKey key;
+ protected Function<S, ? extends TVal> computing;
+ protected Boolean removingIfResultIsNull;
+
+ public AbstractUpdatingMapBuilder(AttributeSensor<Map<TKey,TVal>> target) {
+ super(UpdatingMap.class);
+ this.targetSensor = target;
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <S2 extends S> UpdatingMapBuilder<S2,TKey,TVal> from(AttributeSensor<S2> fromSensor) {
+ this.fromSensor = checkNotNull(fromSensor);
+ return (UpdatingMapBuilder) this;
+ }
+ public B computing(Function<S,? extends TVal> val) {
+ this.computing = checkNotNull(val);
+ return self();
+ }
+ /** sets an explicit key to use; defaults to using the name of the source sensor specified in {@link #from(AttributeSensor)} */
+ public B key(TKey key) {
+ this.key = key;
+ return self();
+ }
+ /** sets explicit behaviour for treating <code>null</code> return values;
+ * default is to remove */
+ public B removingIfResultIsNull(boolean val) {
+ this.removingIfResultIsNull = val;
+ return self();
+ }
+ @Override
+ protected String getDefaultUniqueTag() {
+ if (targetSensor==null || fromSensor==null) return null;
+ return "updating:"+targetSensor.getName()+"<-"+fromSensor.getName();
+ }
+ public EnricherSpec<?> build() {
+ return super.build().configure(MutableMap.builder()
+ .put(UpdatingMap.TARGET_SENSOR, targetSensor)
+ .put(UpdatingMap.SOURCE_SENSOR, fromSensor)
+ .putIfNotNull(UpdatingMap.KEY_IN_TARGET_SENSOR, key)
+ .put(UpdatingMap.COMPUTING, computing)
+ .putIfNotNull(UpdatingMap.REMOVING_IF_RESULT_IS_NULL, removingIfResultIsNull)
+ .build());
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .omitNullValues()
+ .add("publishing", targetSensor)
+ .add("fromSensor", fromSensor)
+ .add("key", key)
+ .add("computing", computing)
+ .add("removingIfResultIsNull", removingIfResultIsNull)
+ .toString();
+ }
+ }
+
+ protected abstract static class AbstractJoinerBuilder<B extends AbstractJoinerBuilder<B>> extends AbstractEnricherBuilder<B> {
+ protected final AttributeSensor<?> transforming;
+ protected AttributeSensor<String> publishing;
+ protected Entity fromEntity;
+ protected String separator;
+ protected Boolean quote;
+ protected Integer minimum;
+ protected Integer maximum;
+
+ public AbstractJoinerBuilder(AttributeSensor<?> source) {
+ super(Joiner.class);
+ this.transforming = checkNotNull(source);
+ }
+ public B publishing(AttributeSensor<String> target) {
+ this.publishing = checkNotNull(target);
+ return self();
+ }
+ public B separator(String separator) {
+ this.separator = separator;
+ return self();
+ }
+ public B quote(Boolean quote) {
+ this.quote = quote;
+ return self();
+ }
+ public B minimum(Integer minimum) {
+ this.minimum = minimum;
+ return self();
+ }
+ public B maximum(Integer maximum) {
+ this.maximum = maximum;
+ return self();
+ }
+ @Override
+ protected String getDefaultUniqueTag() {
+ if (transforming==null || publishing==null) return null;
+ return "joiner:"+transforming.getName()+"->"+publishing.getName();
+ }
+ public EnricherSpec<?> build() {
+ return super.build().configure(MutableMap.builder()
+ .putIfNotNull(Joiner.PRODUCER, fromEntity)
+ .put(Joiner.TARGET_SENSOR, publishing)
+ .put(Joiner.SOURCE_SENSOR, transforming)
+ .putIfNotNull(Joiner.SEPARATOR, separator)
+ .putIfNotNull(Joiner.QUOTE, quote)
+ .putIfNotNull(Joiner.MINIMUM, minimum)
+ .putIfNotNull(Joiner.MAXIMUM, maximum)
+ .build());
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .omitNullValues()
+ .add("publishing", publishing)
+ .add("transforming", transforming)
+ .add("separator", separator)
+ .toString();
+ }
+ }
+
+ public static class InitialBuilder extends AbstractInitialBuilder<InitialBuilder> {
+ }
+
+ public static class AggregatorBuilder<S, T> extends AbstractAggregatorBuilder<S, T, AggregatorBuilder<S, T>> {
+ public AggregatorBuilder(AttributeSensor<S> aggregating) {
+ super(aggregating);
+ }
+ }
+
+ public static class PropagatorBuilder extends AbstractPropagatorBuilder<PropagatorBuilder> {
+ public PropagatorBuilder(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) {
+ super(vals);
+ }
+ public PropagatorBuilder(Iterable<? extends Sensor<?>> vals) {
+ super(vals);
+ }
+ public PropagatorBuilder(Sensor<?>... vals) {
+ super(vals);
+ }
+ PropagatorBuilder(boolean propagatingAll, Iterable<? extends Sensor<?>> butVals) {
+ super(propagatingAll, butVals);
+ }
+ }
+
+ public static class CombinerBuilder<S, T> extends AbstractCombinerBuilder<S, T, CombinerBuilder<S, T>> {
+ @SafeVarargs
+ public CombinerBuilder(AttributeSensor<? extends S>... vals) {
+ super(vals);
+ }
+ public CombinerBuilder(Collection<AttributeSensor<? extends S>> vals) {
+ super(vals);
+ }
+ }
+
+ public static class TransformerBuilder<S, T> extends AbstractTransformerBuilder<S, T, TransformerBuilder<S, T>> {
+ public TransformerBuilder(AttributeSensor<S> val) {
+ super(val);
+ }
+ }
+
+ public static class UpdatingMapBuilder<S, TKey, TVal> extends AbstractUpdatingMapBuilder<S, TKey, TVal, UpdatingMapBuilder<S, TKey, TVal>> {
+ public UpdatingMapBuilder(AttributeSensor<Map<TKey,TVal>> val) {
+ super(val);
+ }
+ }
+
+ public static class JoinerBuilder extends AbstractJoinerBuilder<JoinerBuilder> {
+ public JoinerBuilder(AttributeSensor<?> source) {
+ super(source);
+ }
+ }
+
+ @Beta
+ private abstract static class ComputingNumber<T extends Number> implements Function<Collection<T>, T> {
+ protected final Number defaultValueForUnreportedSensors;
+ protected final Number valueToReportIfNoSensors;
+ protected final TypeToken<T> typeToken;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public ComputingNumber(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
+ this.defaultValueForUnreportedSensors = defaultValueForUnreportedSensors;
+ this.valueToReportIfNoSensors = valueToReportIfNoSensors;
+ if (typeToken!=null && TypeToken.of(Number.class).isAssignableFrom(typeToken.getType())) {
+ this.typeToken = typeToken;
+ } else if (typeToken==null || typeToken.isAssignableFrom(Number.class)) {
+ // use double if e.g. Object is supplied
+ this.typeToken = (TypeToken)TypeToken.of(Double.class);
+ } else {
+ throw new IllegalArgumentException("Type "+typeToken+" is not valid for "+this);
+ }
+ }
+ @Override public abstract T apply(Collection<T> input);
+ }
+
+ @Beta
+ public static class ComputingSum<T extends Number> extends ComputingNumber<T> {
+ public ComputingSum(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
+ super(defaultValueForUnreportedSensors, valueToReportIfNoSensors, typeToken);
+ }
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override public T apply(Collection<T> input) {
+ return (T) sum((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, typeToken);
+ }
+ }
+
+ @Beta
+ public static class ComputingAverage<T extends Number> extends ComputingNumber<T> {
+ public ComputingAverage(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
+ super(defaultValueForUnreportedSensors, valueToReportIfNoSensors, typeToken);
+ }
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override public T apply(Collection<T> input) {
+ return (T) average((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, typeToken);
+ }
+ }
+
+ protected static <T extends Number> T average(Collection<T> vals, Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> type) {
+ Double doubleValueToReportIfNoSensors = (valueToReportIfNoSensors == null) ? null : valueToReportIfNoSensors.doubleValue();
+ int count = count(vals, defaultValueForUnreportedSensors!=null);
+ Double result = (count==0) ? doubleValueToReportIfNoSensors :
+ (Double) ((sum(vals, defaultValueForUnreportedSensors, 0, TypeToken.of(Double.class)) / count));
+
+ return cast(result, type);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static <N extends Number> N cast(Number n, TypeToken<? extends N> numberType) {
+ return (N) TypeCoercions.castPrimitive(n, numberType.getRawType());
+ }
+
+ @Beta //may be moved
+ public static <N extends Number> N sum(Iterable<? extends Number> vals, Number valueIfNull, Number valueIfNone, TypeToken<N> type) {
+ double result = 0d;
+ int count = 0;
+ if (vals!=null) {
+ for (Number val : vals) {
+ if (val!=null) {
+ result += val.doubleValue();
+ count++;
+ } else if (valueIfNull!=null) {
+ result += valueIfNull.doubleValue();
+ count++;
+ }
+ }
+ }
+ if (count==0) return cast(valueIfNone, type);
+ return cast(result, type);
+ }
+
+ protected static int count(Iterable<? extends Object> vals, boolean includeNullValues) {
+ int result = 0;
+ if (vals != null)
+ for (Object val : vals)
+ if (val!=null || includeNullValues) result++;
+ return result;
+ }
+
+ private static <T> Map<T,T> newIdentityMap(Set<T> keys) {
+ Map<T,T> result = Maps.newLinkedHashMap();
+ for (T key : keys) {
+ result.put(key, key);
+ }
+ return result;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/Joiner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Joiner.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Joiner.java
new file mode 100644
index 0000000..5cd2071
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Joiner.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.text.StringEscapes;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.reflect.TypeToken;
+
+//@Catalog(name="Transformer", description="Transforms attributes of an entity; see Enrichers.builder().transforming(...)")
+@SuppressWarnings("serial")
+public class Joiner<T> extends AbstractEnricher implements SensorEventListener<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Joiner.class);
+
+ public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
+ public static ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
+ public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+ @SetFromFlag("separator")
+ public static ConfigKey<String> SEPARATOR = ConfigKeys.newStringConfigKey("enricher.joiner.separator", "Separator string to insert between each argument", ",");
+ @SetFromFlag("quote")
+ public static ConfigKey<Boolean> QUOTE = ConfigKeys.newBooleanConfigKey("enricher.joiner.quote", "Whether to bash-escape each parameter and wrap in double-quotes, defaulting to true", true);
+ @SetFromFlag("minimum")
+ public static ConfigKey<Integer> MINIMUM = ConfigKeys.newIntegerConfigKey("enricher.joiner.minimum", "Minimum number of elements to join; if fewer than this, sets null; default 0 (no minimum)");
+ @SetFromFlag("maximum")
+ public static ConfigKey<Integer> MAXIMUM = ConfigKeys.newIntegerConfigKey("enricher.joiner.maximum", "Maximum number of elements to join; default null means all elements always taken");
+
+ protected Entity producer;
+ protected AttributeSensor<T> sourceSensor;
+ protected Sensor<String> targetSensor;
+
+ public Joiner() {
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+
+ this.producer = getConfig(PRODUCER) == null ? entity: getConfig(PRODUCER);
+ this.sourceSensor = (AttributeSensor<T>) getRequiredConfig(SOURCE_SENSOR);
+ this.targetSensor = (Sensor<String>) getRequiredConfig(TARGET_SENSOR);
+
+ subscribe(producer, sourceSensor, this);
+
+ Object value = producer.getAttribute((AttributeSensor<?>)sourceSensor);
+ // TODO would be useful to have a convenience to "subscribeAndThenIfItIsAlreadySetRunItOnce"
+ if (value!=null) {
+ onEvent(new BasicSensorEvent(sourceSensor, producer, value, -1));
+ }
+ }
+
+ @Override
+ public void onEvent(SensorEvent<T> event) {
+ emit(targetSensor, compute(event));
+ }
+
+ protected Object compute(SensorEvent<T> event) {
+ Object v = event.getValue();
+ Object result = null;
+ if (v!=null) {
+ if (v instanceof Map) {
+ v = ((Map<?,?>)v).values();
+ }
+ if (!(v instanceof Iterable)) {
+ LOG.warn("Enricher "+this+" received a non-iterable value "+v.getClass()+" "+v+"; refusing to join");
+ } else {
+ MutableList<Object> c1 = MutableList.of();
+ Integer maximum = getConfig(MAXIMUM);
+ for (Object ci: (Iterable<?>)v) {
+ if (maximum!=null && maximum>=0) {
+ if (c1.size()>=maximum) break;
+ }
+ c1.appendIfNotNull(Strings.toString(ci));
+ }
+ Integer minimum = getConfig(MINIMUM);
+ if (minimum!=null && c1.size() < minimum) {
+ // use default null return value
+ } else {
+ if (getConfig(QUOTE)) {
+ MutableList<Object> c2 = MutableList.of();
+ for (Object ci: c1) {
+ c2.add(StringEscapes.BashStringEscapes.wrapBash((String)ci));
+ }
+ c1 = c2;
+ }
+ result = Strings.join(c1, getConfig(SEPARATOR));
+ }
+ }
+ }
+ if (LOG.isTraceEnabled())
+ LOG.trace("Enricher "+this+" computed "+result+" from "+event);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/Propagator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Propagator.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Propagator.java
new file mode 100644
index 0000000..e6050fd
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Propagator.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ValueResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+@SuppressWarnings("serial")
+//@Catalog(name="Propagator", description="Propagates attributes from one entity to another; see Enrichers.builder().propagating(...)")
+public class Propagator extends AbstractEnricher implements SensorEventListener<Object> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Propagator.class);
+
+ public static final Set<Sensor<?>> SENSORS_NOT_USUALLY_PROPAGATED = ImmutableSet.<Sensor<?>>of(
+ Attributes.SERVICE_UP, Attributes.SERVICE_NOT_UP_INDICATORS,
+ Attributes.SERVICE_STATE_ACTUAL, Attributes.SERVICE_STATE_EXPECTED, Attributes.SERVICE_PROBLEMS);
+
+ @SetFromFlag("producer")
+ public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
+
+ @SetFromFlag("propagatingAllBut")
+ public static ConfigKey<Collection<Sensor<?>>> PROPAGATING_ALL_BUT = ConfigKeys.newConfigKey(new TypeToken<Collection<Sensor<?>>>() {}, "enricher.propagating.propagatingAllBut");
+
+ @SetFromFlag("propagatingAll")
+ public static ConfigKey<Boolean> PROPAGATING_ALL = ConfigKeys.newBooleanConfigKey("enricher.propagating.propagatingAll");
+
+ @SetFromFlag("propagating")
+ public static ConfigKey<Collection<? extends Sensor<?>>> PROPAGATING = ConfigKeys.newConfigKey(new TypeToken<Collection<? extends Sensor<?>>>() {}, "enricher.propagating.inclusions");
+
+ @SetFromFlag("sensorMapping")
+ public static ConfigKey<Map<? extends Sensor<?>, ? extends Sensor<?>>> SENSOR_MAPPING = ConfigKeys.newConfigKey(new TypeToken<Map<? extends Sensor<?>, ? extends Sensor<?>>>() {}, "enricher.propagating.sensorMapping");
+
+ protected Entity producer;
+ protected Map<? extends Sensor<?>, ? extends Sensor<?>> sensorMapping;
+ protected boolean propagatingAll;
+ protected Collection<Sensor<?>> propagatingAllBut;
+ protected Predicate<Sensor<?>> sensorFilter;
+
+ public Propagator() {
+ }
+
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+
+ this.producer = getConfig(PRODUCER) == null ? entity : getConfig(PRODUCER);
+ boolean sensorMappingSet = getConfig(SENSOR_MAPPING)!=null;
+ MutableMap<Sensor<?>,Sensor<?>> sensorMappingTemp = MutableMap.copyOf(getConfig(SENSOR_MAPPING));
+ this.propagatingAll = Boolean.TRUE.equals(getConfig(PROPAGATING_ALL)) || getConfig(PROPAGATING_ALL_BUT)!=null;
+
+ if (getConfig(PROPAGATING) != null) {
+ if (propagatingAll) {
+ throw new IllegalStateException("Propagator enricher "+this+" must not have 'propagating' set at same time as either 'propagatingAll' or 'propagatingAllBut'");
+ }
+
+ for (Object sensorO : getConfig(PROPAGATING)) {
+ Sensor<?> sensor = Tasks.resolving(sensorO).as(Sensor.class).timeout(ValueResolver.REAL_QUICK_WAIT).context(producer).get();
+ if (!sensorMappingTemp.containsKey(sensor)) {
+ sensorMappingTemp.put(sensor, sensor);
+ }
+ }
+ this.sensorMapping = ImmutableMap.copyOf(sensorMappingTemp);
+ this.sensorFilter = new Predicate<Sensor<?>>() {
+ @Override public boolean apply(Sensor<?> input) {
+ // TODO kept for deserialization of inner classes, but shouldn't be necessary, as with other inner classes (qv);
+ // NB: previously this did this check:
+// return input != null && sensorMapping.keySet().contains(input);
+ // but those clauses seems wrong (when would input be null?) and unnecessary (we are doing an explicit subscribe in this code path)
+ return true;
+ }
+ };
+ } else if (sensorMappingSet) {
+ if (propagatingAll) {
+ throw new IllegalStateException("Propagator enricher "+this+" must not have 'sensorMapping' set at same time as either 'propagatingAll' or 'propagatingAllBut'");
+ }
+ this.sensorMapping = ImmutableMap.copyOf(sensorMappingTemp);
+ this.sensorFilter = Predicates.alwaysTrue();
+ } else {
+ this.sensorMapping = ImmutableMap.<Sensor<?>, Sensor<?>>of();
+ if (!propagatingAll) {
+ // default if nothing specified is to do all but the ones not usually propagated
+ propagatingAll = true;
+ // user specified nothing, so *set* the all_but to the default set
+ // if desired, we could allow this to be dynamically reconfigurable, remove this field and always look up;
+ // slight performance hit (always looking up), and might need to recompute subscriptions, so not supported currently
+ // TODO this default is @Beta behaviour! -- maybe better to throw?
+ propagatingAllBut = SENSORS_NOT_USUALLY_PROPAGATED;
+ } else {
+ propagatingAllBut = getConfig(PROPAGATING_ALL_BUT);
+ }
+ this.sensorFilter = new Predicate<Sensor<?>>() {
+ @Override public boolean apply(Sensor<?> input) {
+ Collection<Sensor<?>> exclusions = propagatingAllBut;
+ // TODO this anonymous inner class and getConfig check kept should be removed / confirmed for rebind compatibility.
+ // we *should* be regenerating these fields on each rebind (calling to this method),
+ // so serialization of this class shouldn't be needed (and should be skipped), but that needs to be checked.
+ if (propagatingAllBut==null) exclusions = getConfig(PROPAGATING_ALL_BUT);
+ return input != null && (exclusions==null || !exclusions.contains(input));
+ }
+ };
+ }
+
+ Preconditions.checkState(propagatingAll ^ sensorMapping.size() > 0,
+ "Nothing to propagate; detected: propagatingAll (%s, excluding %s), sensorMapping (%s)", propagatingAll, getConfig(PROPAGATING_ALL_BUT), sensorMapping);
+
+ if (propagatingAll) {
+ subscribe(producer, null, this);
+ } else {
+ for (Sensor<?> sensor : sensorMapping.keySet()) {
+ subscribe(producer, sensor, this);
+ }
+ }
+
+ emitAllAttributes();
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public void onEvent(SensorEvent<Object> event) {
+ // propagate upwards
+ Sensor<?> sourceSensor = event.getSensor();
+ Sensor<?> destinationSensor = getDestinationSensor(sourceSensor);
+
+ if (!sensorFilter.apply(sourceSensor)) {
+ return; // ignoring excluded sensor
+ }
+
+ if (LOG.isTraceEnabled()) LOG.trace("enricher {} got {}, propagating via {}{}",
+ new Object[] {this, event, entity, (sourceSensor == destinationSensor ? "" : " (as "+destinationSensor+")")});
+
+ emit((Sensor)destinationSensor, event.getValue());
+ }
+
+ /** useful once sensors are added to emit all values */
+ public void emitAllAttributes() {
+ emitAllAttributes(false);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void emitAllAttributes(boolean includeNullValues) {
+ Iterable<? extends Sensor<?>> sensorsToPopulate = propagatingAll
+ ? Iterables.filter(producer.getEntityType().getSensors(), sensorFilter)
+ : sensorMapping.keySet();
+
+ for (Sensor<?> s : sensorsToPopulate) {
+ if (s instanceof AttributeSensor) {
+ AttributeSensor destinationSensor = (AttributeSensor<?>) getDestinationSensor(s);
+ Object v = producer.getAttribute((AttributeSensor<?>)s);
+ // TODO we should keep a timestamp for the source sensor and echo it
+ // (this pretends timestamps are current, which probably isn't the case when we are propagating)
+ if (v != null || includeNullValues) entity.setAttribute(destinationSensor, v);
+ }
+ }
+ }
+
+ private Sensor<?> getDestinationSensor(Sensor<?> sourceSensor) {
+ return sensorMapping.containsKey(sourceSensor) ? sensorMapping.get(sourceSensor): sourceSensor;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricher.java
new file mode 100644
index 0000000..4c198f8
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/SensorPropagatingEnricher.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+/**
+ * an enricher policy which just listens for the target sensor(s) on a child entity and passes it up.
+ * now superseded by syntax such as:
+ *
+ * <pre>{@code Enrichers.builder().propagating(XXX).from(source).build()}</pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ *
+ * @see Propagator if need to sub-class
+ */
+public class SensorPropagatingEnricher extends AbstractEnricher implements SensorEventListener<Object> {
+
+ public static final Logger log = LoggerFactory.getLogger(SensorPropagatingEnricher.class);
+
+ /** the entity to listen to */
+ private final Entity source;
+
+ /** the sensors to listen to */
+ private final Set<Sensor<?>> sensors;
+
+ /** the sensors to listen to */
+ private final Map<Sensor<?>, Sensor<?>> sensorMappings;
+
+ public static SensorPropagatingEnricher newInstanceListeningToAllSensors(Entity source) {
+ return newInstanceListeningToAllSensorsBut(source);
+ }
+ public static SensorPropagatingEnricher newInstanceListeningToAllSensorsBut(Entity source, Sensor<?>... excludes) {
+ Set<Sensor<?>> excluded = ImmutableSet.copyOf(excludes);
+ Set<Sensor<?>> includes = Sets.newLinkedHashSet();
+
+ for (Sensor<?> it : source.getEntityType().getSensors()) {
+ if (!excluded.contains(it)) includes.add(it);
+ }
+ return new SensorPropagatingEnricher(source, includes);
+ }
+
+ public static SensorPropagatingEnricher newInstanceListeningTo(Entity source, Sensor<?>... includes) {
+ return new SensorPropagatingEnricher(source, includes);
+ }
+
+ /**
+ * listens to sensors from source, propagates them here renamed according to the map
+ *
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * addEnricher(Enrichers.builder()
+ * .propagating(mapOfOldSensorNamesToNewSensorNames)
+ * .from(source)
+ * .build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public static SensorPropagatingEnricher newInstanceRenaming(Entity source, Map<? extends Sensor<?>, ? extends Sensor<?>> sensors) {
+ return new SensorPropagatingEnricher(source, sensors);
+ }
+
+ /**
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public SensorPropagatingEnricher(Entity source, Sensor<?>... sensors) {
+ this(source, ImmutableList.copyOf(sensors));
+ }
+
+ /**
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * addEnricher(Enrichers.builder()
+ * .propagating(sensors)
+ * .from(source)
+ * .build());
+ * }
+ * </pre>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers#builder()}
+ */
+ public SensorPropagatingEnricher(Entity source, Collection<Sensor<?>> sensors) {
+ this.source = source;
+ this.sensors = ImmutableSet.copyOf(sensors);
+ this.sensorMappings = ImmutableMap.of();
+ }
+
+ public SensorPropagatingEnricher(Entity source, Map<? extends Sensor<?>, ? extends Sensor<?>> sensors) {
+ this.source = source;
+ this.sensors = ImmutableSet.copyOf(sensors.keySet());
+ this.sensorMappings = ImmutableMap.copyOf(sensors);
+ }
+
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ for (Sensor<?> s: sensors) {
+ subscribe(source, s, this);
+ }
+ }
+
+ @Override
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void onEvent(SensorEvent<Object> event) {
+ // propagate upwards
+ Sensor<?> sourceSensor = event.getSensor();
+ Sensor<?> destinationSensor = getDestinationSensor(sourceSensor);
+
+ if (log.isTraceEnabled()) log.trace("policy {} got {}, propagating via {}{}",
+ new Object[] {this, event, entity, (sourceSensor == destinationSensor ? "" : " (as "+destinationSensor+")")});
+
+ if (event.getSensor() instanceof AttributeSensor) {
+ entity.setAttribute((AttributeSensor)destinationSensor, event.getValue());
+ } else {
+ entity.emit((Sensor)destinationSensor, event.getValue());
+ }
+ }
+
+ /** useful post-addition to emit current values */
+ public void emitAllAttributes() {
+ emitAllAttributes(false);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void emitAllAttributes(boolean includeNullValues) {
+ for (Sensor s: sensors) {
+ if (s instanceof AttributeSensor) {
+ AttributeSensor destinationSensor = (AttributeSensor<?>) getDestinationSensor(s);
+ Object v = source.getAttribute((AttributeSensor)s);
+ if (v != null || includeNullValues) entity.setAttribute(destinationSensor, v);
+ }
+ }
+ }
+
+ /** convenience, to be called by the host */
+ public SensorPropagatingEnricher addToEntityAndEmitAll(Entity host) {
+ host.addEnricher(this);
+ emitAllAttributes();
+ return this;
+ }
+
+ private Sensor<?> getDestinationSensor(Sensor<?> sourceSensor) {
+ return sensorMappings.containsKey(sourceSensor) ? sensorMappings.get(sourceSensor): sourceSensor;
+ }
+}
[26/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
new file mode 100644
index 0000000..e8cfc9f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpFeed.java
@@ -0,0 +1,382 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.DelegatingPollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.core.http.HttpTool.HttpClientBuilder;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Provides a feed of attribute values, by polling over http.
+ *
+ * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
+ * <pre>
+ * {@code
+ * private HttpFeed feed;
+ *
+ * //@Override
+ * protected void connectSensors() {
+ * super.connectSensors();
+ *
+ * feed = HttpFeed.builder()
+ * .entity(this)
+ * .period(200)
+ * .baseUri(String.format("http://%s:%s/management/subsystem/web/connector/http/read-resource", host, port))
+ * .baseUriVars(ImmutableMap.of("include-runtime","true"))
+ * .poll(new HttpPollConfig<Boolean>(SERVICE_UP)
+ * .onSuccess(HttpValueFunctions.responseCodeEquals(200))
+ * .onError(Functions.constant(false)))
+ * .poll(new HttpPollConfig<Integer>(REQUEST_COUNT)
+ * .onSuccess(HttpValueFunctions.jsonContents("requestCount", Integer.class)))
+ * .build();
+ * }
+ *
+ * {@literal @}Override
+ * protected void disconnectSensors() {
+ * super.disconnectSensors();
+ * if (feed != null) feed.stop();
+ * }
+ * }
+ * </pre>
+ * <p>
+ *
+ * This also supports giving a Supplier for the URL
+ * (e.g. {@link Entities#attributeSupplier(org.apache.brooklyn.api.entity.Entity, org.apache.brooklyn.api.event.AttributeSensor)})
+ * from a sensor. Note however that if a Supplier-based sensor is *https*,
+ * https-specific initialization may not occur if the URL is not available at start time,
+ * and it may report errors if that sensor is not available.
+ * Some guidance for controlling enablement of a feed based on availability of a sensor
+ * can be seen in HttpLatencyDetector (in brooklyn-policy).
+ *
+ * @author aled
+ */
+public class HttpFeed extends AbstractFeed {
+
+ public static final Logger log = LoggerFactory.getLogger(HttpFeed.class);
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<SetMultimap<HttpPollIdentifier, HttpPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<HttpPollIdentifier, HttpPollConfig<?>>>() {},
+ "polls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private boolean onlyIfServiceUp = false;
+ private Supplier<URI> baseUriProvider;
+ private Duration period = Duration.millis(500);
+ private List<HttpPollConfig<?>> polls = Lists.newArrayList();
+ private URI baseUri;
+ private Map<String, String> baseUriVars = Maps.newLinkedHashMap();
+ private Map<String, String> headers = Maps.newLinkedHashMap();
+ private boolean suspended = false;
+ private Credentials credentials;
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = val;
+ return this;
+ }
+ public Builder onlyIfServiceUp() { return onlyIfServiceUp(true); }
+ public Builder onlyIfServiceUp(boolean onlyIfServiceUp) {
+ this.onlyIfServiceUp = onlyIfServiceUp;
+ return this;
+ }
+ public Builder baseUri(Supplier<URI> val) {
+ if (baseUri!=null && val!=null)
+ throw new IllegalStateException("Builder cannot take both a URI and a URI Provider");
+ this.baseUriProvider = val;
+ return this;
+ }
+ public Builder baseUri(URI val) {
+ if (baseUriProvider!=null && val!=null)
+ throw new IllegalStateException("Builder cannot take both a URI and a URI Provider");
+ this.baseUri = val;
+ return this;
+ }
+ public Builder baseUrl(URL val) {
+ return baseUri(URI.create(val.toString()));
+ }
+ public Builder baseUri(String val) {
+ return baseUri(URI.create(val));
+ }
+ public Builder baseUriVars(Map<String,String> vals) {
+ baseUriVars.putAll(vals);
+ return this;
+ }
+ public Builder baseUriVar(String key, String val) {
+ baseUriVars.put(key, val);
+ return this;
+ }
+ public Builder headers(Map<String,String> vals) {
+ headers.putAll(vals);
+ return this;
+ }
+ public Builder header(String key, String val) {
+ headers.put(key, val);
+ return this;
+ }
+ public Builder period(Duration duration) {
+ this.period = duration;
+ return this;
+ }
+ public Builder period(long millis) {
+ return period(millis, TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long val, TimeUnit units) {
+ return period(Duration.of(val, units));
+ }
+ public Builder poll(HttpPollConfig<?> config) {
+ polls.add(config);
+ return this;
+ }
+ public Builder suspended() {
+ return suspended(true);
+ }
+ public Builder suspended(boolean startsSuspended) {
+ this.suspended = startsSuspended;
+ return this;
+ }
+ public Builder credentials(String username, String password) {
+ this.credentials = new UsernamePasswordCredentials(username, password);
+ return this;
+ }
+ public Builder credentialsIfNotNull(String username, String password) {
+ if (username != null && password != null) {
+ this.credentials = new UsernamePasswordCredentials(username, password);
+ }
+ return this;
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public HttpFeed build() {
+ built = true;
+ HttpFeed result = new HttpFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ if (suspended) result.suspend();
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("HttpFeed.Builder created, but build() never called");
+ }
+ }
+
+ private static class HttpPollIdentifier {
+ final String method;
+ final Supplier<URI> uriProvider;
+ final Map<String,String> headers;
+ final byte[] body;
+ final Optional<Credentials> credentials;
+ final Duration connectionTimeout;
+ final Duration socketTimeout;
+ private HttpPollIdentifier(String method, Supplier<URI> uriProvider, Map<String, String> headers, byte[] body,
+ Optional<Credentials> credentials, Duration connectionTimeout, Duration socketTimeout) {
+ this.method = checkNotNull(method, "method").toLowerCase();
+ this.uriProvider = checkNotNull(uriProvider, "uriProvider");
+ this.headers = checkNotNull(headers, "headers");
+ this.body = body;
+ this.credentials = checkNotNull(credentials, "credentials");
+ this.connectionTimeout = connectionTimeout;
+ this.socketTimeout = socketTimeout;
+
+ if (!(this.method.equals("get") || this.method.equals("post"))) {
+ throw new IllegalArgumentException("Unsupported HTTP method (only supports GET and POST): "+method);
+ }
+ if (body != null && method.equalsIgnoreCase("get")) {
+ throw new IllegalArgumentException("Must not set body for http GET method");
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(method, uriProvider, headers, body, credentials);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof HttpPollIdentifier)) {
+ return false;
+ }
+ HttpPollIdentifier o = (HttpPollIdentifier) other;
+ return Objects.equal(method, o.method) &&
+ Objects.equal(uriProvider, o.uriProvider) &&
+ Objects.equal(headers, o.headers) &&
+ Objects.equal(body, o.body) &&
+ Objects.equal(credentials, o.credentials);
+ }
+ }
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public HttpFeed() {
+ }
+
+ protected HttpFeed(Builder builder) {
+ setConfig(ONLY_IF_SERVICE_UP, builder.onlyIfServiceUp);
+ Map<String,String> baseHeaders = ImmutableMap.copyOf(checkNotNull(builder.headers, "headers"));
+
+ SetMultimap<HttpPollIdentifier, HttpPollConfig<?>> polls = HashMultimap.<HttpPollIdentifier,HttpPollConfig<?>>create();
+ for (HttpPollConfig<?> config : builder.polls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ HttpPollConfig<?> configCopy = new HttpPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
+ String method = config.getMethod();
+ Map<String,String> headers = config.buildHeaders(baseHeaders);
+ byte[] body = config.getBody();
+ Duration connectionTimeout = config.getConnectionTimeout();
+ Duration socketTimeout = config.getSocketTimeout();
+
+ Optional<Credentials> credentials = Optional.fromNullable(builder.credentials);
+
+ Supplier<URI> baseUriProvider = builder.baseUriProvider;
+ if (builder.baseUri!=null) {
+ if (baseUriProvider!=null)
+ throw new IllegalStateException("Not permitted to supply baseUri and baseUriProvider");
+ Map<String,String> baseUriVars = ImmutableMap.copyOf(checkNotNull(builder.baseUriVars, "baseUriVars"));
+ URI uri = config.buildUri(builder.baseUri, baseUriVars);
+ baseUriProvider = Suppliers.ofInstance(uri);
+ } else if (!builder.baseUriVars.isEmpty()) {
+ throw new IllegalStateException("Not permitted to supply URI vars when using a URI provider; pass the vars to the provider instead");
+ }
+ checkNotNull(baseUriProvider);
+
+ polls.put(new HttpPollIdentifier(method, baseUriProvider, headers, body, credentials, connectionTimeout, socketTimeout), configCopy);
+ }
+ setConfig(POLLS, polls);
+ initUniqueTag(builder.uniqueTag, polls.values());
+ }
+
+ @Override
+ protected void preStart() {
+ SetMultimap<HttpPollIdentifier, HttpPollConfig<?>> polls = getConfig(POLLS);
+
+ for (final HttpPollIdentifier pollInfo : polls.keySet()) {
+ // Though HttpClients are thread safe and can take advantage of connection pooling
+ // and authentication caching, the httpcomponents documentation says:
+ // "While HttpClient instances are thread safe and can be shared between multiple
+ // threads of execution, it is highly recommended that each thread maintains its
+ // own dedicated instance of HttpContext.
+ // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html
+ final HttpClient httpClient = createHttpClient(pollInfo);
+
+ Set<HttpPollConfig<?>> configs = polls.get(pollInfo);
+ long minPeriod = Integer.MAX_VALUE;
+ Set<AttributePollHandler<? super HttpToolResponse>> handlers = Sets.newLinkedHashSet();
+
+ for (HttpPollConfig<?> config : configs) {
+ handlers.add(new AttributePollHandler<HttpToolResponse>(config, entity, this));
+ if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
+ }
+
+ Callable<HttpToolResponse> pollJob;
+
+ if (pollInfo.method.equals("get")) {
+ pollJob = new Callable<HttpToolResponse>() {
+ public HttpToolResponse call() throws Exception {
+ if (log.isTraceEnabled()) log.trace("http polling for {} sensors at {}", entity, pollInfo);
+ return HttpTool.httpGet(httpClient, pollInfo.uriProvider.get(), pollInfo.headers);
+ }};
+ } else if (pollInfo.method.equals("post")) {
+ pollJob = new Callable<HttpToolResponse>() {
+ public HttpToolResponse call() throws Exception {
+ if (log.isTraceEnabled()) log.trace("http polling for {} sensors at {}", entity, pollInfo);
+ return HttpTool.httpPost(httpClient, pollInfo.uriProvider.get(), pollInfo.headers, pollInfo.body);
+ }};
+ } else if (pollInfo.method.equals("head")) {
+ pollJob = new Callable<HttpToolResponse>() {
+ public HttpToolResponse call() throws Exception {
+ if (log.isTraceEnabled()) log.trace("http polling for {} sensors at {}", entity, pollInfo);
+ return HttpTool.httpHead(httpClient, pollInfo.uriProvider.get(), pollInfo.headers);
+ }};
+ } else {
+ throw new IllegalStateException("Unexpected http method: "+pollInfo.method);
+ }
+
+ getPoller().scheduleAtFixedRate(pollJob, new DelegatingPollHandler<HttpToolResponse>(handlers), minPeriod);
+ }
+ }
+
+ // TODO Should we really trustAll for https? Make configurable?
+ private HttpClient createHttpClient(HttpPollIdentifier pollIdentifier) {
+ URI uri = pollIdentifier.uriProvider.get();
+ HttpClientBuilder builder = HttpTool.httpClientBuilder()
+ .trustAll()
+ .laxRedirect(true);
+ if (uri != null) builder.uri(uri);
+ if (uri != null) builder.credential(pollIdentifier.credentials);
+ if (pollIdentifier.connectionTimeout != null) {
+ builder.connectionTimeout(pollIdentifier.connectionTimeout);
+ }
+ if (pollIdentifier.socketTimeout != null) {
+ builder.socketTimeout(pollIdentifier.socketTimeout);
+ }
+ return builder.build();
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Poller<HttpToolResponse> getPoller() {
+ return (Poller<HttpToolResponse>) super.getPoller();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
new file mode 100644
index 0000000..e019293
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollConfig.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import java.net.URI;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.PollConfig;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+
+public class HttpPollConfig<T> extends PollConfig<HttpToolResponse, T, HttpPollConfig<T>> {
+
+ private String method = "GET";
+ private String suburl = "";
+ private Map<String, String> vars = ImmutableMap.<String,String>of();
+ private Map<String, String> headers = ImmutableMap.<String,String>of();
+ private byte[] body;
+ private Duration connectionTimeout;
+ private Duration socketTimeout;
+
+ public static final Predicate<HttpToolResponse> DEFAULT_SUCCESS = new Predicate<HttpToolResponse>() {
+ @Override
+ public boolean apply(@Nullable HttpToolResponse input) {
+ return input != null && input.getResponseCode() >= 200 && input.getResponseCode() <= 399;
+ }};
+
+ public static <T> HttpPollConfig<T> forSensor(AttributeSensor<T> sensor) {
+ return new HttpPollConfig<T>(sensor);
+ }
+
+ public static HttpPollConfig<Void> forMultiple() {
+ return new HttpPollConfig<Void>(PollConfig.NO_SENSOR);
+ }
+
+ public HttpPollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ super.checkSuccess(DEFAULT_SUCCESS);
+ }
+
+ public HttpPollConfig(HttpPollConfig<T> other) {
+ super(other);
+ suburl = other.suburl;
+ vars = other.vars;
+ method = other.method;
+ headers = other.headers;
+ }
+
+ public String getSuburl() {
+ return suburl;
+ }
+
+ public Map<String, String> getVars() {
+ return vars;
+ }
+
+ public Duration getConnectionTimeout() {
+ return connectionTimeout;
+ }
+
+ public Duration getSocketTimeout() {
+ return socketTimeout;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public byte[] getBody() {
+ return body;
+ }
+
+ public HttpPollConfig<T> method(String val) {
+ this.method = val; return this;
+ }
+
+ public HttpPollConfig<T> suburl(String val) {
+ this.suburl = val; return this;
+ }
+
+ public HttpPollConfig<T> vars(Map<String,String> val) {
+ this.vars = val; return this;
+ }
+
+ public HttpPollConfig<T> headers(Map<String,String> val) {
+ this.headers = val; return this;
+ }
+
+ public HttpPollConfig<T> body(byte[] val) {
+ this.body = val; return this;
+ }
+ public HttpPollConfig<T> connectionTimeout(Duration val) {
+ this.connectionTimeout = val;
+ return this;
+ }
+ public HttpPollConfig<T> socketTimeout(Duration val) {
+ this.socketTimeout = val;
+ return this;
+ }
+ public URI buildUri(URI baseUri, Map<String,String> baseUriVars) {
+ String uri = (baseUri != null ? baseUri.toString() : "") + (suburl != null ? suburl : "");
+ Map<String,String> allvars = concat(baseUriVars, vars);
+
+ if (allvars != null && allvars.size() > 0) {
+ uri += "?" + HttpTool.encodeUrlParams(allvars);
+ }
+
+ return URI.create(uri);
+ }
+
+ public Map<String, String> buildHeaders(Map<String, String> baseHeaders) {
+ return MutableMap.<String,String>builder()
+ .putAll(baseHeaders)
+ .putAll(headers)
+ .build();
+ }
+
+ @SuppressWarnings("unchecked")
+ private <K,V> Map<K,V> concat(Map<? extends K,? extends V> map1, Map<? extends K,? extends V> map2) {
+ if (map1 == null || map1.isEmpty()) return (Map<K,V>) map2;
+ if (map2 == null || map2.isEmpty()) return (Map<K,V>) map1;
+
+ // TODO Not using Immutable builder, because that fails if duplicates in map1 and map2
+ return MutableMap.<K,V>builder().putAll(map1).putAll(map2).build();
+ }
+
+ @Override protected String toStringBaseName() { return "http"; }
+ @Override protected String toStringPollSource() { return suburl; }
+ @Override
+ protected MutableList<Object> equalsFields() {
+ return super.equalsFields().appendIfNotNull(method).appendIfNotNull(vars).appendIfNotNull(headers)
+ .appendIfNotNull(body).appendIfNotNull(connectionTimeout).appendIfNotNull(socketTimeout);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
new file mode 100644
index 0000000..5414cc4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPollValue.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+
+/** @deprecated since 0.7.0, use {@link HttpToolResponse}.
+ * the old {@link HttpPollValue} concrete class has been renamed {@link HttpToolResponse}
+ * because it has nothing specific to polls. this is now just a transitional interface. */
+@Deprecated
+public interface HttpPollValue {
+
+ public int getResponseCode();
+ public String getReasonPhrase();
+ public long getStartTime();
+ public long getLatencyFullContent();
+ public long getLatencyFirstResponse();
+ public Map<String, List<String>> getHeaderLists();
+ public byte[] getContent();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
new file mode 100644
index 0000000..10c3b3e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpPolls.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import java.net.URI;
+
+import org.apache.brooklyn.util.core.http.HttpTool;
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.http.impl.client.DefaultHttpClient;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * @deprecated since 0.7; use {@link HttpTool}
+ */
+@Deprecated
+public class HttpPolls {
+
+ public static HttpToolResponse executeSimpleGet(URI uri) {
+ return HttpTool.httpGet(new DefaultHttpClient(), uri, ImmutableMap.<String,String>of());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java b/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
new file mode 100644
index 0000000..75dab74
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/HttpValueFunctions.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import java.util.List;
+
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.guava.Functionals;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Lists;
+import com.google.gson.JsonElement;
+
+public class HttpValueFunctions {
+
+ private HttpValueFunctions() {} // instead use static utility methods
+
+ public static Function<HttpToolResponse, Integer> responseCode() {
+ return new ResponseCode();
+ }
+
+ /** @deprecated since 0.7.0; only here for deserialization of persisted state */
+ private static Function<HttpToolResponse, Integer> responseCodeLegacy() {
+ return new Function<HttpToolResponse, Integer>() {
+ @Override public Integer apply(HttpToolResponse input) {
+ return input.getResponseCode();
+ }
+ };
+ }
+
+ private static class ResponseCode implements Function<HttpToolResponse, Integer> {
+ @Override public Integer apply(HttpToolResponse input) {
+ return input.getResponseCode();
+ }
+ }
+
+ public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int expected) {
+ return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.equalTo(expected)));
+ }
+
+ public static Function<HttpToolResponse, Boolean> responseCodeEquals(final int... expected) {
+ List<Integer> expectedList = Lists.newArrayList();
+ for (int e : expected) {
+ expectedList.add((Integer)e);
+ }
+ return Functionals.chain(HttpValueFunctions.responseCode(), Functions.forPredicate(Predicates.in(expectedList)));
+ }
+
+ public static Function<HttpToolResponse, String> stringContentsFunction() {
+ return new StringContents();
+ }
+
+ /** @deprecated since 0.7.0; only here for deserialization of persisted state */
+ private static Function<HttpToolResponse, String> stringContentsFunctionLegacy() {
+ return new Function<HttpToolResponse, String>() {
+ @Override public String apply(HttpToolResponse input) {
+ return input.getContentAsString();
+ }
+ };
+ }
+
+ private static class StringContents implements Function<HttpToolResponse, String> {
+ @Override public String apply(HttpToolResponse input) {
+ return input.getContentAsString();
+ }
+ }
+
+ public static Function<HttpToolResponse, JsonElement> jsonContents() {
+ return Functionals.chain(stringContentsFunction(), JsonFunctions.asJson());
+ }
+
+ public static <T> Function<HttpToolResponse, T> jsonContents(String element, Class<T> expected) {
+ return jsonContents(new String[] {element}, expected);
+ }
+
+ public static <T> Function<HttpToolResponse, T> jsonContents(String[] elements, Class<T> expected) {
+ return Functionals.chain(jsonContents(), JsonFunctions.walk(elements), JsonFunctions.cast(expected));
+ }
+
+ public static <T> Function<HttpToolResponse, T> jsonContentsFromPath(String path){
+ return Functionals.chain(jsonContents(), JsonFunctions.<T>getPath(path));
+ }
+
+ public static Function<HttpToolResponse, Long> latency() {
+ return new Latency();
+ }
+
+ /** @deprecated since 0.7.0; only here for deserialization of persisted state */
+ private static Function<HttpToolResponse, Long> latencyLegacy() {
+ return new Function<HttpToolResponse, Long>() {
+ public Long apply(HttpToolResponse input) {
+ return input.getLatencyFullContent();
+ }
+ };
+ }
+
+ private static class Latency implements Function<HttpToolResponse, Long> {
+ public Long apply(HttpToolResponse input) {
+ return input.getLatencyFullContent();
+ }
+ };
+
+ public static Function<HttpToolResponse, Boolean> containsHeader(String header) {
+ return new ContainsHeader(header);
+ }
+
+ private static class ContainsHeader implements Function<HttpToolResponse, Boolean> {
+ private final String header;
+
+ public ContainsHeader(String header) {
+ this.header = header;
+ }
+ @Override
+ public Boolean apply(HttpToolResponse input) {
+ List<String> actual = input.getHeaderLists().get(header);
+ return actual != null && actual.size() > 0;
+ }
+ }
+
+
+ /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function)} */ @Deprecated
+ public static <A,B,C> Function<A,C> chain(final Function<A,? extends B> f1, final Function<B,C> f2) {
+ return Functionals.chain(f1, f2);
+ }
+
+ /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function, Function)} */ @Deprecated
+ public static <A,B,C,D> Function<A,D> chain(final Function<A,? extends B> f1, final Function<B,? extends C> f2, final Function<C,D> f3) {
+ return Functionals.chain(f1, f2, f3);
+ }
+
+ /** @deprecated since 0.7.0 use {@link Functionals#chain(Function, Function, Function, Function)} */ @Deprecated
+ public static <A,B,C,D,E> Function<A,E> chain(final Function<A,? extends B> f1, final Function<B,? extends C> f2, final Function<C,? extends D> f3, final Function<D,E> f4) {
+ return Functionals.chain(f1, f2, f3, f4);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/http/JsonFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/http/JsonFunctions.java b/core/src/main/java/org/apache/brooklyn/feed/http/JsonFunctions.java
new file mode 100644
index 0000000..a3e04cd
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/http/JsonFunctions.java
@@ -0,0 +1,235 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.guava.MaybeFunctions;
+
+import com.google.common.base.Function;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+import com.google.gson.*;
+import com.jayway.jsonpath.JsonPath;
+
+public class JsonFunctions {
+
+ private JsonFunctions() {} // instead use static utility methods
+
+ public static Function<String, JsonElement> asJson() {
+ return new Function<String, JsonElement>() {
+ @Override public JsonElement apply(String input) {
+ return new JsonParser().parse(input);
+ }
+ };
+ }
+
+ public static <T> Function<JsonElement, List<T>> forEach(final Function<JsonElement, T> func) {
+ return new Function<JsonElement, List<T>>() {
+ @Override public List<T> apply(JsonElement input) {
+ JsonArray array = (JsonArray) input;
+ List<T> result = Lists.newArrayList();
+ for (int i = 0; i < array.size(); i++) {
+ result.add(func.apply(array.get(i)));
+ }
+ return result;
+ }
+ };
+ }
+
+
+ /** as {@link #walkM(Iterable)} taking a single string consisting of a dot separated path */
+ public static Function<JsonElement, JsonElement> walk(String elementOrDotSeparatedElements) {
+ return walk( Splitter.on('.').split(elementOrDotSeparatedElements) );
+ }
+
+ /** as {@link #walkM(Iterable)} taking a series of strings (dot separators not respected here) */
+ public static Function<JsonElement, JsonElement> walk(final String... elements) {
+ return walk(Arrays.asList(elements));
+ }
+
+ /** returns a function which traverses the supplied path of entries in a json object (maps of maps of maps...),
+ * @throws NoSuchElementException if any path is not present as a key in that map */
+ public static Function<JsonElement, JsonElement> walk(final Iterable<String> elements) {
+ // could do this instead, pointing at Maybe for this, and for walkN, but it's slightly less efficient
+// return Functionals.chain(MaybeFunctions.<JsonElement>wrap(), walkM(elements), MaybeFunctions.<JsonElement>get());
+
+ return new Function<JsonElement, JsonElement>() {
+ @Override public JsonElement apply(JsonElement input) {
+ JsonElement curr = input;
+ for (String element : elements) {
+ JsonObject jo = curr.getAsJsonObject();
+ curr = jo.get(element);
+ if (curr==null)
+ throw new NoSuchElementException("No element '"+element+" in JSON, when walking "+elements);
+ }
+ return curr;
+ }
+ };
+ }
+
+
+ /** as {@link #walk(String)} but if any element is not found it simply returns null */
+ public static Function<JsonElement, JsonElement> walkN(@Nullable String elements) {
+ return walkN( Splitter.on('.').split(elements) );
+ }
+
+ /** as {@link #walk(String...))} but if any element is not found it simply returns null */
+ public static Function<JsonElement, JsonElement> walkN(final String... elements) {
+ return walkN(Arrays.asList(elements));
+ }
+
+ /** as {@link #walk(Iterable))} but if any element is not found it simply returns null */
+ public static Function<JsonElement, JsonElement> walkN(final Iterable<String> elements) {
+ return new Function<JsonElement, JsonElement>() {
+ @Override public JsonElement apply(JsonElement input) {
+ JsonElement curr = input;
+ for (String element : elements) {
+ if (curr==null) return null;
+ JsonObject jo = curr.getAsJsonObject();
+ curr = jo.get(element);
+ }
+ return curr;
+ }
+ };
+ }
+
+ /** as {@link #walk(String))} and {@link #walk(Iterable)} */
+ public static Function<Maybe<JsonElement>, Maybe<JsonElement>> walkM(@Nullable String elements) {
+ return walkM( Splitter.on('.').split(elements) );
+ }
+
+ /** as {@link #walk(String...))} and {@link #walk(Iterable)} */
+ public static Function<Maybe<JsonElement>, Maybe<JsonElement>> walkM(final String... elements) {
+ return walkM(Arrays.asList(elements));
+ }
+
+ /** as {@link #walk(Iterable))} but working with objects which {@link Maybe} contain {@link JsonElement},
+ * simply preserving a {@link Maybe#absent()} object if additional walks are requested upon it
+ * (cf jquery) */
+ public static Function<Maybe<JsonElement>, Maybe<JsonElement>> walkM(final Iterable<String> elements) {
+ return new Function<Maybe<JsonElement>, Maybe<JsonElement>>() {
+ @Override public Maybe<JsonElement> apply(Maybe<JsonElement> input) {
+ Maybe<JsonElement> curr = input;
+ for (String element : elements) {
+ if (curr.isAbsent()) return curr;
+ JsonObject jo = curr.get().getAsJsonObject();
+ JsonElement currO = jo.get(element);
+ if (currO==null) return Maybe.absent("No element '"+element+" in JSON, when walking "+elements);
+ curr = Maybe.of(currO);
+ }
+ return curr;
+ }
+ };
+ }
+
+ /**
+ * returns an element from a single json primitive value given a full path {@link com.jayway.jsonpath.JsonPath}
+ */
+ public static <T> Function<JsonElement,T> getPath(final String path) {
+ return new Function<JsonElement, T>() {
+ @SuppressWarnings("unchecked")
+ @Override public T apply(JsonElement input) {
+ String jsonString = input.toString();
+ Object rawElement = JsonPath.read(jsonString, path);
+ return (T) rawElement;
+ }
+ };
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> Function<JsonElement, T> cast(final Class<T> expected) {
+ return new Function<JsonElement, T>() {
+ @Override public T apply(JsonElement input) {
+ if (input == null) {
+ return (T) null;
+ } else if (input.isJsonNull()) {
+ return (T) null;
+ } else if (expected == boolean.class || expected == Boolean.class) {
+ return (T) (Boolean) input.getAsBoolean();
+ } else if (expected == char.class || expected == Character.class) {
+ return (T) (Character) input.getAsCharacter();
+ } else if (expected == byte.class || expected == Byte.class) {
+ return (T) (Byte) input.getAsByte();
+ } else if (expected == short.class || expected == Short.class) {
+ return (T) (Short) input.getAsShort();
+ } else if (expected == int.class || expected == Integer.class) {
+ return (T) (Integer) input.getAsInt();
+ } else if (expected == long.class || expected == Long.class) {
+ return (T) (Long) input.getAsLong();
+ } else if (expected == float.class || expected == Float.class) {
+ return (T) (Float) input.getAsFloat();
+ } else if (expected == double.class || expected == Double.class) {
+ return (T) (Double) input.getAsDouble();
+ } else if (expected == BigDecimal.class) {
+ return (T) input.getAsBigDecimal();
+ } else if (expected == BigInteger.class) {
+ return (T) input.getAsBigInteger();
+ } else if (Number.class.isAssignableFrom(expected)) {
+ // TODO Will result in a class-cast if it's an unexpected sub-type of Number not handled above
+ return (T) input.getAsNumber();
+ } else if (expected == String.class) {
+ return (T) input.getAsString();
+ } else if (expected.isArray()) {
+ JsonArray array = input.getAsJsonArray();
+ Class<?> componentType = expected.getComponentType();
+ if (JsonElement.class.isAssignableFrom(componentType)) {
+ JsonElement[] result = new JsonElement[array.size()];
+ for (int i = 0; i < array.size(); i++) {
+ result[i] = array.get(i);
+ }
+ return (T) result;
+ } else {
+ Object[] result = (Object[]) Array.newInstance(componentType, array.size());
+ for (int i = 0; i < array.size(); i++) {
+ result[i] = cast(componentType).apply(array.get(i));
+ }
+ return (T) result;
+ }
+ } else {
+ throw new IllegalArgumentException("Cannot cast json element to type "+expected);
+ }
+ }
+ };
+ }
+
+ public static <T> Function<Maybe<JsonElement>, T> castM(final Class<T> expected) {
+ return Functionals.chain(MaybeFunctions.<JsonElement>get(), cast(expected));
+ }
+
+ public static <T> Function<Maybe<JsonElement>, T> castM(final Class<T> expected, final T defaultValue) {
+ return new Function<Maybe<JsonElement>, T>() {
+ @Override
+ public T apply(Maybe<JsonElement> input) {
+ if (input.isAbsent()) return defaultValue;
+ return cast(expected).apply(input.get());
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/shell/ShellFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/shell/ShellFeed.java b/core/src/main/java/org/apache/brooklyn/feed/shell/ShellFeed.java
new file mode 100644
index 0000000..caeb21a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/shell/ShellFeed.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.shell;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.DelegatingPollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.internal.SystemProcessTaskFactory.ConcreteSystemProcessTaskFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Provides a feed of attribute values, by executing shell commands (on the local machine where
+ * this instance of brooklyn is running). Useful e.g. for paas tools such as Cloud Foundry vmc
+ * which operate against a remote target.
+ *
+ * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
+ * <pre>
+ * {@code
+ * private ShellFeed feed;
+ *
+ * //@Override
+ * protected void connectSensors() {
+ * super.connectSensors();
+ *
+ * feed = ShellFeed.builder()
+ * .entity(this)
+ * .machine(mySshMachineLachine)
+ * .poll(new ShellPollConfig<Long>(DISK_USAGE)
+ * .command("df -P | grep /dev")
+ * .failOnNonZeroResultCode(true)
+ * .onSuccess(new Function<SshPollValue, Long>() {
+ * public Long apply(SshPollValue input) {
+ * String[] parts = input.getStdout().split("[ \\t]+");
+ * return Long.parseLong(parts[2]);
+ * }}))
+ * .build();
+ * }
+ *
+ * {@literal @}Override
+ * protected void disconnectSensors() {
+ * super.disconnectSensors();
+ * if (feed != null) feed.stop();
+ * }
+ * }
+ * </pre>
+ *
+ * @see SshFeed (to run on remote machines)
+ * @see FunctionFeed (for arbitrary functions)
+ *
+ * @author aled
+ */
+public class ShellFeed extends AbstractFeed {
+
+ public static final Logger log = LoggerFactory.getLogger(ShellFeed.class);
+
+ @SuppressWarnings("serial")
+ private static final ConfigKey<SetMultimap<ShellPollIdentifier, ShellPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<ShellPollIdentifier, ShellPollConfig<?>>>() {},
+ "polls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private long period = 500;
+ private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
+ private List<ShellPollConfig<?>> polls = Lists.newArrayList();
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = val;
+ return this;
+ }
+ public Builder period(long millis) {
+ return period(millis, TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long val, TimeUnit units) {
+ this.period = val;
+ this.periodUnits = units;
+ return this;
+ }
+ public Builder poll(ShellPollConfig<?> config) {
+ polls.add(config);
+ return this;
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public ShellFeed build() {
+ built = true;
+ ShellFeed result = new ShellFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("ShellFeed.Builder created, but build() never called");
+ }
+ }
+
+ private static class ShellPollIdentifier {
+ final String command;
+ final Map<String, String> env;
+ final File dir;
+ final String input;
+ final String context;
+ final long timeout;
+
+ private ShellPollIdentifier(String command, Map<String, String> env, File dir, String input, String context, long timeout) {
+ this.command = checkNotNull(command, "command");
+ this.env = checkNotNull(env, "env");
+ this.dir = dir;
+ this.input = input;
+ this.context = checkNotNull(context, "context");
+ this.timeout = timeout;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(command, env, dir, input, timeout);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof ShellPollIdentifier)) {
+ return false;
+ }
+ ShellPollIdentifier o = (ShellPollIdentifier) other;
+ return Objects.equal(command, o.command) &&
+ Objects.equal(env, o.env) &&
+ Objects.equal(dir, o.dir) &&
+ Objects.equal(input, o.input) &&
+ Objects.equal(timeout, o.timeout);
+ }
+ }
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public ShellFeed() {
+ }
+
+ protected ShellFeed(Builder builder) {
+ super();
+
+ SetMultimap<ShellPollIdentifier, ShellPollConfig<?>> polls = HashMultimap.<ShellPollIdentifier,ShellPollConfig<?>>create();
+ for (ShellPollConfig<?> config : builder.polls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ ShellPollConfig<?> configCopy = new ShellPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
+ String command = config.getCommand();
+ Map<String, String> env = config.getEnv();
+ File dir = config.getDir();
+ String input = config.getInput();
+ String context = config.getSensor().getName();
+ long timeout = config.getTimeout();
+
+ polls.put(new ShellPollIdentifier(command, env, dir, input, context, timeout), configCopy);
+ }
+ setConfig(POLLS, polls);
+ initUniqueTag(builder.uniqueTag, polls.values());
+ }
+
+ @Override
+ protected void preStart() {
+ SetMultimap<ShellPollIdentifier, ShellPollConfig<?>> polls = getConfig(POLLS);
+
+ for (final ShellPollIdentifier pollInfo : polls.keySet()) {
+ Set<ShellPollConfig<?>> configs = polls.get(pollInfo);
+ long minPeriod = Integer.MAX_VALUE;
+ Set<AttributePollHandler<? super SshPollValue>> handlers = Sets.newLinkedHashSet();
+
+ for (ShellPollConfig<?> config : configs) {
+ handlers.add(new AttributePollHandler<SshPollValue>(config, entity, this));
+ if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
+ }
+
+ final ProcessTaskFactory<?> taskFactory = newTaskFactory(pollInfo.command, pollInfo.env, pollInfo.dir,
+ pollInfo.input, pollInfo.context, pollInfo.timeout);
+ final ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext();
+
+ getPoller().scheduleAtFixedRate(
+ new Callable<SshPollValue>() {
+ @Override public SshPollValue call() throws Exception {
+ ProcessTaskWrapper<?> taskWrapper = taskFactory.newTask();
+ executionContext.submit(taskWrapper);
+ taskWrapper.block();
+ Optional<Integer> exitCode = Optional.fromNullable(taskWrapper.getExitCode());
+ return new SshPollValue(null, exitCode.or(-1), taskWrapper.getStdout(), taskWrapper.getStderr());
+ }},
+ new DelegatingPollHandler<SshPollValue>(handlers),
+ minPeriod);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Poller<SshPollValue> getPoller() {
+ return (Poller<SshPollValue>) super.getPoller();
+ }
+
+ /**
+ * Executes the given command (using `bash -l -c $command`, so as to have a good path set).
+ *
+ * @param command The command to execute
+ * @param env Environment variable settings, in format name=value
+ * @param dir Working directory, or null to inherit from current process
+ * @param input Input to send to the command (if not null)
+ */
+ protected ProcessTaskFactory<?> newTaskFactory(final String command, Map<String,String> env, File dir, String input, final String summary, final long timeout) {
+ // FIXME Add generic timeout() support to task ExecutionManager
+ if (timeout > 0) {
+ log.warn("Timeout ({}ms) not currently supported for ShellFeed {}", timeout, this);
+ }
+
+ return new ConcreteSystemProcessTaskFactory<Object>(command)
+ .environmentVariables(env)
+ .loginShell(true)
+ .directory(dir)
+ .runAsCommand()
+ .summary(summary);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/shell/ShellPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/shell/ShellPollConfig.java b/core/src/main/java/org/apache/brooklyn/feed/shell/ShellPollConfig.java
new file mode 100644
index 0000000..e1147c3
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/shell/ShellPollConfig.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.shell;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.PollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.util.collections.MutableList;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Maps;
+
+public class ShellPollConfig<T> extends PollConfig<SshPollValue, T, ShellPollConfig<T>> {
+
+ private String command;
+ private Map<String,String> env = Maps.newLinkedHashMap();
+ private long timeout = -1;
+ private File dir;
+ private String input;
+
+ public static final Predicate<SshPollValue> DEFAULT_SUCCESS = new Predicate<SshPollValue>() {
+ @Override
+ public boolean apply(@Nullable SshPollValue input) {
+ return input != null && input.getExitStatus() == 0;
+ }};
+
+ public ShellPollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ super.checkSuccess(DEFAULT_SUCCESS);
+ }
+
+ public ShellPollConfig(ShellPollConfig<T> other) {
+ super(other);
+ command = other.command;
+ env = other.env;
+ timeout = other.timeout;
+ dir = other.dir;
+ input = other.input;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+
+ public Map<String, String> getEnv() {
+ return env;
+ }
+
+ public File getDir() {
+ return dir;
+ }
+
+ public String getInput() {
+ return input;
+ }
+
+ public long getTimeout() {
+ return timeout;
+ }
+
+ public ShellPollConfig<T> command(String val) {
+ this.command = val;
+ return this;
+ }
+
+ public ShellPollConfig<T> env(String key, String val) {
+ env.put(checkNotNull(key, "key"), checkNotNull(val, "val"));
+ return this;
+ }
+
+ public ShellPollConfig<T> env(Map<String,String> val) {
+ for (Map.Entry<String, String> entry : checkNotNull(val, "map").entrySet()) {
+ env(entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+
+ public ShellPollConfig<T> dir(File val) {
+ this.dir = val;
+ return this;
+ }
+
+ public ShellPollConfig<T> input(String val) {
+ this.input = val;
+ return this;
+ }
+
+ public ShellPollConfig<T> timeout(long timeout) {
+ return timeout(timeout, TimeUnit.MILLISECONDS);
+ }
+
+ public ShellPollConfig<T> timeout(long timeout, TimeUnit units) {
+ this.timeout = units.toMillis(timeout);
+ return this;
+ }
+
+ @Override protected String toStringBaseName() { return "shell"; }
+ @Override protected String toStringPollSource() { return command; }
+ @Override protected MutableList<Object> equalsFields() { return super.equalsFields().appendIfNotNull(command); }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
new file mode 100644
index 0000000..8663137
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.ssh;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.DelegatingPollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.core.location.Locations;
+import org.apache.brooklyn.core.location.Machines;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Provides a feed of attribute values, by polling over ssh.
+ *
+ * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
+ * <pre>
+ * {@code
+ * private SshFeed feed;
+ *
+ * //@Override
+ * protected void connectSensors() {
+ * super.connectSensors();
+ *
+ * feed = SshFeed.builder()
+ * .entity(this)
+ * .machine(mySshMachineLachine)
+ * .poll(new SshPollConfig<Boolean>(SERVICE_UP)
+ * .command("rabbitmqctl -q status")
+ * .onSuccess(new Function<SshPollValue, Boolean>() {
+ * public Boolean apply(SshPollValue input) {
+ * return (input.getExitStatus() == 0);
+ * }}))
+ * .build();
+ * }
+ *
+ * {@literal @}Override
+ * protected void disconnectSensors() {
+ * super.disconnectSensors();
+ * if (feed != null) feed.stop();
+ * }
+ * }
+ * </pre>
+ *
+ * @author aled
+ */
+public class SshFeed extends AbstractFeed {
+
+ public static final Logger log = LoggerFactory.getLogger(SshFeed.class);
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<Supplier<SshMachineLocation>> MACHINE = ConfigKeys.newConfigKey(
+ new TypeToken<Supplier<SshMachineLocation>>() {},
+ "machine");
+
+ public static final ConfigKey<Boolean> EXEC_AS_COMMAND = ConfigKeys.newBooleanConfigKey("execAsCommand");
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<SetMultimap<SshPollIdentifier, SshPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<SshPollIdentifier, SshPollConfig<?>>>() {},
+ "polls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private boolean onlyIfServiceUp = false;
+ private Supplier<SshMachineLocation> machine;
+ private Duration period = Duration.of(500, TimeUnit.MILLISECONDS);
+ private List<SshPollConfig<?>> polls = Lists.newArrayList();
+ private boolean execAsCommand = false;
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = val;
+ return this;
+ }
+ public Builder onlyIfServiceUp() { return onlyIfServiceUp(true); }
+ public Builder onlyIfServiceUp(boolean onlyIfServiceUp) {
+ this.onlyIfServiceUp = onlyIfServiceUp;
+ return this;
+ }
+ /** optional, to force a machine; otherwise it is inferred from the entity */
+ public Builder machine(SshMachineLocation val) { return machine(Suppliers.ofInstance(val)); }
+ /** optional, to force a machine; otherwise it is inferred from the entity */
+ public Builder machine(Supplier<SshMachineLocation> val) {
+ this.machine = val;
+ return this;
+ }
+ public Builder period(Duration period) {
+ this.period = period;
+ return this;
+ }
+ public Builder period(long millis) {
+ return period(Duration.of(millis, TimeUnit.MILLISECONDS));
+ }
+ public Builder period(long val, TimeUnit units) {
+ return period(Duration.of(val, units));
+ }
+ public Builder poll(SshPollConfig<?> config) {
+ polls.add(config);
+ return this;
+ }
+ public Builder execAsCommand() {
+ execAsCommand = true;
+ return this;
+ }
+ public Builder execAsScript() {
+ execAsCommand = false;
+ return this;
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public SshFeed build() {
+ built = true;
+ SshFeed result = new SshFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("SshFeed.Builder created, but build() never called");
+ }
+ }
+
+ private static class SshPollIdentifier {
+ final Supplier<String> command;
+ final Supplier<Map<String, String>> env;
+
+ private SshPollIdentifier(Supplier<String> command, Supplier<Map<String, String>> env) {
+ this.command = checkNotNull(command, "command");
+ this.env = checkNotNull(env, "env");
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(command, env);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof SshPollIdentifier)) {
+ return false;
+ }
+ SshPollIdentifier o = (SshPollIdentifier) other;
+ return Objects.equal(command, o.command) &&
+ Objects.equal(env, o.env);
+ }
+ }
+
+ /** @deprecated since 0.7.0, use static convenience on {@link Locations} */
+ @Deprecated
+ public static SshMachineLocation getMachineOfEntity(Entity entity) {
+ return Machines.findUniqueSshMachineLocation(entity.getLocations()).orNull();
+ }
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public SshFeed() {
+ }
+
+ protected SshFeed(final Builder builder) {
+ setConfig(ONLY_IF_SERVICE_UP, builder.onlyIfServiceUp);
+ setConfig(MACHINE, builder.machine != null ? builder.machine : null);
+ setConfig(EXEC_AS_COMMAND, builder.execAsCommand);
+
+ SetMultimap<SshPollIdentifier, SshPollConfig<?>> polls = HashMultimap.<SshPollIdentifier,SshPollConfig<?>>create();
+ for (SshPollConfig<?> config : builder.polls) {
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ SshPollConfig<?> configCopy = new SshPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
+ polls.put(new SshPollIdentifier(config.getCommandSupplier(), config.getEnvSupplier()), configCopy);
+ }
+ setConfig(POLLS, polls);
+ initUniqueTag(builder.uniqueTag, polls.values());
+ }
+
+ protected SshMachineLocation getMachine() {
+ Supplier<SshMachineLocation> supplier = getConfig(MACHINE);
+ if (supplier != null) {
+ return supplier.get();
+ } else {
+ return Locations.findUniqueSshMachineLocation(entity.getLocations()).get();
+ }
+ }
+
+ @Override
+ protected void preStart() {
+ SetMultimap<SshPollIdentifier, SshPollConfig<?>> polls = getConfig(POLLS);
+
+ for (final SshPollIdentifier pollInfo : polls.keySet()) {
+ Set<SshPollConfig<?>> configs = polls.get(pollInfo);
+ long minPeriod = Integer.MAX_VALUE;
+ Set<AttributePollHandler<? super SshPollValue>> handlers = Sets.newLinkedHashSet();
+
+ for (SshPollConfig<?> config : configs) {
+ handlers.add(new AttributePollHandler<SshPollValue>(config, entity, this));
+ if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
+ }
+
+ getPoller().scheduleAtFixedRate(
+ new Callable<SshPollValue>() {
+ public SshPollValue call() throws Exception {
+ return exec(pollInfo.command.get(), pollInfo.env.get());
+ }},
+ new DelegatingPollHandler<SshPollValue>(handlers),
+ minPeriod);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Poller<SshPollValue> getPoller() {
+ return (Poller<SshPollValue>) super.getPoller();
+ }
+
+ private SshPollValue exec(String command, Map<String,String> env) throws IOException {
+ SshMachineLocation machine = getMachine();
+ Boolean execAsCommand = getConfig(EXEC_AS_COMMAND);
+ if (log.isTraceEnabled()) log.trace("Ssh polling for {}, executing {} with env {}", new Object[] {machine, command, env});
+ ByteArrayOutputStream stdout = new ByteArrayOutputStream();
+ ByteArrayOutputStream stderr = new ByteArrayOutputStream();
+
+ int exitStatus;
+ ConfigBag flags = ConfigBag.newInstance()
+ .configure(SshTool.PROP_NO_EXTRA_OUTPUT, true)
+ .configure(SshTool.PROP_OUT_STREAM, stdout)
+ .configure(SshTool.PROP_ERR_STREAM, stderr);
+ if (Boolean.TRUE.equals(execAsCommand)) {
+ exitStatus = machine.execCommands(flags.getAllConfig(),
+ "ssh-feed", ImmutableList.of(command), env);
+ } else {
+ exitStatus = machine.execScript(flags.getAllConfig(),
+ "ssh-feed", ImmutableList.of(command), env);
+ }
+
+ return new SshPollValue(machine, exitStatus, new String(stdout.toByteArray()), new String(stderr.toByteArray()));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollConfig.java b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollConfig.java
new file mode 100644
index 0000000..8fec87f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollConfig.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.ssh;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.PollConfig;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
+
+public class SshPollConfig<T> extends PollConfig<SshPollValue, T, SshPollConfig<T>> {
+
+ private Supplier<String> commandSupplier;
+ private List<Supplier<Map<String,String>>> dynamicEnvironmentSupplier = MutableList.of();
+
+ public static final Predicate<SshPollValue> DEFAULT_SUCCESS = new Predicate<SshPollValue>() {
+ @Override
+ public boolean apply(@Nullable SshPollValue input) {
+ return input != null && input.getExitStatus() == 0;
+ }};
+
+ public SshPollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ super.checkSuccess(DEFAULT_SUCCESS);
+ }
+
+ public SshPollConfig(SshPollConfig<T> other) {
+ super(other);
+ commandSupplier = other.commandSupplier;
+ }
+
+ /** @deprecated since 0.7.0; use {@link #getCommandSupplier()} and resolve just-in-time */
+ public String getCommand() {
+ return getCommandSupplier().get();
+ }
+ public Supplier<String> getCommandSupplier() {
+ return commandSupplier;
+ }
+
+ /** @deprecated since 0.7.0; use {@link #getEnvSupplier()} and resolve just-in-time */
+ public Map<String, String> getEnv() {
+ return getEnvSupplier().get();
+ }
+ public Supplier<Map<String,String>> getEnvSupplier() {
+ return new Supplier<Map<String,String>>() {
+ @Override
+ public Map<String, String> get() {
+ Map<String,String> result = MutableMap.of();
+ for (Supplier<Map<String, String>> envS: dynamicEnvironmentSupplier) {
+ if (envS!=null) {
+ Map<String, String> envM = envS.get();
+ if (envM!=null) {
+ mergeEnvMaps(envM, result);
+ }
+ }
+ }
+ return result;
+ }
+ };
+ }
+
+ protected void mergeEnvMaps(Map<String,String> supplied, Map<String,String> target) {
+ if (supplied==null) return;
+ // as the value is a string there is no need to look at deep merge behaviour
+ target.putAll(supplied);
+ }
+
+ public SshPollConfig<T> command(String val) { return command(Suppliers.ofInstance(val)); }
+ public SshPollConfig<T> command(Supplier<String> val) {
+ this.commandSupplier = val;
+ return this;
+ }
+
+ /** add the given env param; sequence is as per {@link #env(Supplier)} */
+ public SshPollConfig<T> env(String key, String val) {
+ return env(Collections.singletonMap(key, val));
+ }
+
+ /** add the given env params; sequence is as per {@link #env(Supplier)}.
+ * behaviour is undefined if the map supplied here is subsequently changed.
+ * <p>
+ * if a map's contents might change, use {@link #env(Supplier)} */
+ public SshPollConfig<T> env(Map<String,String> val) {
+ if (val==null) return this;
+ return env(Suppliers.ofInstance(val));
+ }
+
+ /**
+ * adds the given dynamic supplier of environment variables.
+ * <p>
+ * use of a supplier allows env vars to be computed on each execution,
+ * for example to take the most recent sensor values.
+ * <p>
+ * in the case of multiple map suppliers, static maps, or static {@link #env(String, String)}
+ * key value pairs, the order in which they are specified here is the order
+ * in which they are computed and applied.
+ **/
+ public SshPollConfig<T> env(Supplier<Map<String,String>> val) {
+ Preconditions.checkNotNull(val);
+ dynamicEnvironmentSupplier.add(val);
+ return this;
+ }
+
+ @Override protected String toStringBaseName() { return "ssh"; }
+ @Override protected Object toStringPollSource() {
+ if (getCommandSupplier()==null) return null;
+ String command = getCommandSupplier().get();
+ return command;
+ }
+ @Override protected MutableList<Object> equalsFields() {
+ return super.equalsFields()
+ .appendIfNotNull(getCommandSupplier()!=null ? getCommandSupplier().get() : null)
+ .appendIfNotNull(getEnvSupplier()!=null ? getEnvSupplier().get() : null);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollValue.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollValue.java b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollValue.java
new file mode 100644
index 0000000..af0a8a6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshPollValue.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.ssh;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+public class SshPollValue {
+
+ private final SshMachineLocation machine;
+ private final int exitStatus;
+ private final String stdout;
+ private final String stderr;
+
+ public SshPollValue(SshMachineLocation machine, int exitStatus, String stdout, String stderr) {
+ this.machine = machine;
+ this.exitStatus = exitStatus;
+ this.stdout = stdout;
+ this.stderr = stderr;
+ }
+
+ /** The machine the command will run on. */
+ public SshMachineLocation getMachine() {
+ return machine;
+ }
+
+ /** Command exit status, or -1 if error is set. */
+ public int getExitStatus() {
+ return exitStatus;
+ }
+
+ /** Command standard output; may be null if no content available. */
+ @Nullable
+ public String getStdout() {
+ return stdout;
+ }
+
+ /** Command standard error; may be null if no content available. */
+ @Nullable
+ public String getStderr() {
+ return stderr;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/ssh/SshValueFunctions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/ssh/SshValueFunctions.java b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshValueFunctions.java
new file mode 100644
index 0000000..370c3ce
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshValueFunctions.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.ssh;
+
+import javax.annotation.Nullable;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicates;
+
+public class SshValueFunctions {
+
+ public static Function<SshPollValue, Integer> exitStatus() {
+ return new Function<SshPollValue, Integer>() {
+ @Override public Integer apply(SshPollValue input) {
+ return input.getExitStatus();
+ }
+ };
+ }
+
+ public static Function<SshPollValue, String> stdout() {
+ return new Function<SshPollValue, String>() {
+ @Override public String apply(SshPollValue input) {
+ return input.getStdout();
+ }
+ };
+ }
+
+ public static Function<SshPollValue, String> stderr() {
+ return new Function<SshPollValue, String>() {
+ @Override public String apply(SshPollValue input) {
+ return input.getStderr();
+ }
+ };
+ }
+
+ public static Function<SshPollValue, Boolean> exitStatusEquals(final int expected) {
+ return chain(SshValueFunctions.exitStatus(), Functions.forPredicate(Predicates.equalTo(expected)));
+ }
+
+ // TODO Do we want these chain methods? Does guava have them already? Duplicated in HttpValueFunctions.
+ public static <A,B,C> Function<A,C> chain(final Function<A,? extends B> f1, final Function<B,C> f2) {
+ return new Function<A,C>() {
+ @Override public C apply(@Nullable A input) {
+ return f2.apply(f1.apply(input));
+ }
+ };
+ }
+
+ public static <A,B,C,D> Function<A,D> chain(final Function<A,? extends B> f1, final Function<B,? extends C> f2, final Function<C,D> f3) {
+ return new Function<A,D>() {
+ @Override public D apply(@Nullable A input) {
+ return f3.apply(f2.apply(f1.apply(input)));
+ }
+ };
+ }
+}
[18/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxFeedTest.java
new file mode 100644
index 0000000..3975e68
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxFeedTest.java
@@ -0,0 +1,422 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import static org.apache.brooklyn.test.TestUtils.executeUntilSucceeds;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.StandardEmitterMBean;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
+import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.core.test.entity.TestEntityImpl;
+import org.apache.brooklyn.entity.java.JmxSupport;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
+import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
+import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxNotificationFilters;
+import org.apache.brooklyn.feed.jmx.JmxNotificationSubscriptionConfig;
+import org.apache.brooklyn.feed.jmx.JmxOperationPollConfig;
+import org.apache.brooklyn.feed.jmx.JmxValueFunctions;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.TestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test the operation of the {@link JmxFeed} class.
+ * <p>
+ * Also confirm some of the JMX setup done by {@link JmxSupport} and {@link JmxHelper},
+ * based on ports in {@link UsesJmx}.
+ * <p>
+ * TODO tests of other JMX_AGENT_MODE are done in ActiveMqIntegrationTest;
+ * would be nice to promote some to live here
+ */
+public class JmxFeedTest {
+
+ // FIXME Move out the JmxHelper tests into the JmxHelperTest class
+
+ // FIXME Also test that setting poll period takes effect
+
+ private static final Logger log = LoggerFactory.getLogger(JmxFeedTest.class);
+
+ private static final int TIMEOUT_MS = 5000;
+ private static final int SHORT_WAIT_MS = 250;
+
+ private JmxService jmxService;
+ private TestApplication app;
+ private TestEntity entity;
+ private JmxFeed feed;
+ private JmxHelper jmxHelper;
+
+ private AttributeSensor<Integer> intAttribute = Sensors.newIntegerSensor("brooklyn.test.intAttribute", "Brooklyn testing int attribute");
+ private AttributeSensor<String> stringAttribute = Sensors.newStringSensor("brooklyn.test.stringAttribute", "Brooklyn testing string attribute");
+ private BasicAttributeSensor<Map> mapAttribute = new BasicAttributeSensor<Map>(Map.class, "brooklyn.test.mapAttribute", "Brooklyn testing map attribute");
+ private String objectName = "Brooklyn:type=MyTestMBean,name=myname";
+ private ObjectName jmxObjectName;
+ private String attributeName = "myattrib";
+ private String opName = "myop";
+
+ public static class TestEntityWithJmx extends TestEntityImpl {
+ @Override public void init() {
+ setAttribute(Attributes.HOSTNAME, "localhost");
+ setAttribute(UsesJmx.JMX_PORT,
+ LocalhostMachineProvisioningLocation.obtainPort(PortRanges.fromString("40123+")));
+ // only supports no-agent, at the moment
+ setConfig(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
+ setAttribute(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
+ ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
+ }
+ }
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ jmxObjectName = new ObjectName(objectName);
+
+ // Create an entity and configure it with the above JMX service
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).impl(TestEntityWithJmx.class));
+ app.start(ImmutableList.of(new SimulatedLocation()));
+
+ jmxHelper = new JmxHelper(entity);
+
+ jmxService = new JmxService(entity);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ if (jmxHelper != null) jmxHelper.disconnect();
+ if (jmxService != null) jmxService.shutdown();
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ feed = null;
+ }
+
+ @Test
+ public void testJmxAttributePollerReturnsMBeanAttribute() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, 42), objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollAttribute(new JmxAttributePollConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .period(50)
+ .attributeName(attributeName))
+ .build();
+
+ // Starts with value defined when registering...
+ assertSensorEventually(intAttribute, 42, TIMEOUT_MS);
+
+ // Change the value and check it updates
+ mbean.updateAttributeValue(attributeName, 64);
+ assertSensorEventually(intAttribute, 64, TIMEOUT_MS);
+ }
+
+ @Test
+ public void testJmxAttributeOfTypeTabularDataProviderConvertedToMap() throws Exception {
+ // Create the CompositeType and TabularData
+ CompositeType compositeType = new CompositeType(
+ "typeName",
+ "description",
+ new String[] {"myint", "mystring", "mybool"}, // item names
+ new String[] {"myint", "mystring", "mybool"}, // item descriptions, can't be null or empty string
+ new OpenType<?>[] {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN}
+ );
+ TabularType tt = new TabularType(
+ "typeName",
+ "description",
+ compositeType,
+ new String[] {"myint"}
+ );
+ TabularDataSupport tds = new TabularDataSupport(tt);
+ tds.put(new CompositeDataSupport(
+ compositeType,
+ new String[] {"mybool", "myint", "mystring"},
+ new Object[] {true, 1234, "on"}
+ ));
+
+ // Create MBean
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, tds), objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollAttribute(new JmxAttributePollConfig<Map>(mapAttribute)
+ .objectName(objectName)
+ .attributeName(attributeName)
+ .onSuccess((Function)JmxValueFunctions.tabularDataToMap()))
+ .build();
+
+ // Starts with value defined when registering...
+ assertSensorEventually(
+ mapAttribute,
+ ImmutableMap.of("myint", 1234, "mystring", "on", "mybool", Boolean.TRUE),
+ TIMEOUT_MS);
+ }
+
+ @Test
+ public void testJmxOperationPolledForSensor() throws Exception {
+ // This is awful syntax...
+ final int opReturnVal = 123;
+ final AtomicInteger invocationCount = new AtomicInteger();
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], Integer.class.getName(), MBeanOperationInfo.ACTION);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(
+ Collections.emptyMap(),
+ ImmutableMap.of(opInfo, new Function<Object[], Integer>() {
+ public Integer apply(Object[] args) {
+ invocationCount.incrementAndGet(); return opReturnVal;
+ }}),
+ objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollOperation(new JmxOperationPollConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .operationName(opName))
+ .build();
+
+ TestUtils.executeUntilSucceeds(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ assertTrue(invocationCount.get() > 0, "invocationCount="+invocationCount);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)opReturnVal);
+ }});
+ }
+
+ @Test
+ public void testJmxOperationWithArgPolledForSensor() throws Exception {
+ // This is awful syntax...
+ MBeanParameterInfo paramInfo = new MBeanParameterInfo("param1", String.class.getName(), "my param1");
+ MBeanParameterInfo[] paramInfos = new MBeanParameterInfo[] {paramInfo};
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", paramInfos, String.class.getName(), MBeanOperationInfo.ACTION);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(
+ Collections.emptyMap(),
+ ImmutableMap.of(opInfo, new Function<Object[], String>() {
+ public String apply(Object[] args) {
+ return args[0]+"suffix";
+ }}),
+ objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollOperation(new JmxOperationPollConfig<String>(stringAttribute)
+ .objectName(objectName)
+ .operationName(opName)
+ .operationParams(ImmutableList.of("myprefix")))
+ .build();
+
+ assertSensorEventually(stringAttribute, "myprefix"+"suffix", TIMEOUT_MS);
+ }
+
+ @Test
+ public void testJmxNotificationSubscriptionForSensor() throws Exception {
+ final String one = "notification.one", two = "notification.two";
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .notificationFilter(JmxNotificationFilters.matchesType(one)))
+ .build();
+
+ // Notification updates the sensor
+ // Note that subscription is done async, so can't just send notification immediately during test.
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, one, sequence.getAndIncrement(), 123);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+
+ // But other notification types are ignored
+ sendNotification(mbean, two, sequence.getAndIncrement(), -1);
+
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+ }
+
+ @Test
+ public void testJmxNotificationSubscriptionForSensorParsingNotification() throws Exception {
+ final String one = "notification.one", two = "notification.two";
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .notificationFilter(JmxNotificationFilters.matchesType(one))
+ .onNotification(new Function<Notification, Integer>() {
+ public Integer apply(Notification notif) {
+ return (Integer) notif.getUserData();
+ }
+ }))
+ .build();
+
+
+ // Notification updates the sensor
+ // Note that subscription is done async, so can't just send notification immediately during test.
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, one, sequence.getAndIncrement(), 123);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+ }
+
+ @Test
+ public void testJmxNotificationMultipleSubscriptionUsingListener() throws Exception {
+ final String one = "notification.one";
+ final String two = "notification.two";
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .notificationFilter(JmxNotificationFilters.matchesTypes(one, two)))
+ .build();
+
+ // Notification updates the sensor
+ // Note that subscription is done async, so can't just send notification immediately during test.
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, one, sequence.getAndIncrement(), 123);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+
+ // And wildcard means other notifications also received
+ sendNotification(mbean, two, sequence.getAndIncrement(), 456);
+ assertSensorEventually(intAttribute, 456, TIMEOUT_MS);
+ }
+
+ // Test reproduces functionality used in Monterey, for Venue entity being told of requestActor
+ @Test
+ public void testSubscribeToJmxNotificationAndEmitCorrespondingNotificationSensor() throws Exception {
+ TestApplication app2 = new TestApplicationImpl();
+ final EntityWithEmitter entity = new EntityWithEmitter(app2);
+ Entities.startManagement(app2);
+ try {
+ app2.start(ImmutableList.of(new SimulatedLocation()));
+
+ final List<SensorEvent<String>> received = Lists.newArrayList();
+ app2.subscribe(null, EntityWithEmitter.MY_NOTIF, new SensorEventListener<String>() {
+ public void onEvent(SensorEvent<String> event) {
+ received.add(event);
+ }});
+
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ jmxHelper.connect(TIMEOUT_MS);
+ jmxHelper.addNotificationListener(jmxObjectName, new NotificationListener() {
+ public void handleNotification(Notification notif, Object callback) {
+ if (notif.getType().equals("one")) {
+ entity.emit(EntityWithEmitter.MY_NOTIF, (String) notif.getUserData());
+ }
+ }});
+
+
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, "one", sequence.getAndIncrement(), "abc");
+ assertTrue(received.size() > 0, "received size should be bigger than 0");
+ assertEquals(received.get(0).getValue(), "abc");
+ }});
+ } finally {
+ Entities.destroyAll(app2.getManagementContext());
+ }
+ }
+
+ public static class EntityWithEmitter extends AbstractEntity {
+ public static final BasicNotificationSensor<String> MY_NOTIF = new BasicNotificationSensor<String>(String.class, "test.myNotif", "My notif");
+
+ public EntityWithEmitter(Entity owner) {
+ super(owner);
+ }
+ public EntityWithEmitter(Map flags) {
+ super(flags);
+ }
+ public EntityWithEmitter(Map flags, Entity owner) {
+ super(flags, owner);
+ }
+ }
+
+ private Notification sendNotification(StandardEmitterMBean mbean, String type, long seq, Object userData) {
+ Notification notif = new Notification(type, mbean, seq);
+ notif.setUserData(userData);
+ mbean.sendNotification(notif);
+ return notif;
+ }
+
+ private <T> void assertSensorEventually(final AttributeSensor<T> sensor, final T expectedVal, long timeout) {
+ executeUntilSucceeds(ImmutableMap.of("timeout", timeout), new Callable<Void>() {
+ public Void call() {
+ assertEquals(entity.getAttribute(sensor), expectedVal);
+ return null;
+ }});
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxHelperTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxHelperTest.java b/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxHelperTest.java
new file mode 100644
index 0000000..3470166
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/feed/jmx/JmxHelperTest.java
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.management.DynamicMBean;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.StandardEmitterMBean;
+
+import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
+import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
+import org.apache.brooklyn.test.TestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.jclouds.util.Throwables2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class JmxHelperTest {
+
+ private static final Logger log = LoggerFactory.getLogger(JmxHelperTest.class);
+
+ private static final String LOCALHOST_NAME = "localhost";
+
+ private static final int TIMEOUT_MS = 5000;
+ private static final int SHORT_WAIT_MS = 250;
+
+ private JmxService jmxService;
+ private JmxHelper jmxHelper;
+
+ private String objectName = "Brooklyn:type=MyTestMBean,name=myname";
+ private String objectNameWithWildcard = "Brooklyn:type=MyTestMBean,name=mynam*";
+ private ObjectName jmxObjectName;
+ private ObjectName jmxObjectNameWithWildcard;
+ private String attributeName = "myattrib";
+ private String opName = "myop";
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ jmxObjectName = new ObjectName(objectName);
+ jmxObjectNameWithWildcard = new ObjectName(objectNameWithWildcard);
+ jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
+ jmxHelper = new JmxHelper(jmxService.getUrl());
+ jmxHelper.setMinTimeBetweenReconnectAttempts(0);
+ jmxHelper.connect(TIMEOUT_MS);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (jmxHelper != null) jmxHelper.disconnect();
+ if (jmxService != null) jmxService.shutdown();
+ jmxHelper = null;
+ jmxService = null;
+ }
+
+ @Test
+ public void testGetAttribute() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval");
+ }
+
+ @Test
+ public void testGetAttributeUsingObjectNameWildcard() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectNameWithWildcard, "myattr"), "myval");
+ }
+
+ @Test
+ public void testSetAttribute() throws Exception {
+ DynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+
+ jmxHelper.setAttribute(jmxObjectName, "myattr", "abc");
+ Object actual = jmxHelper.getAttribute(jmxObjectName, "myattr");
+ assertEquals(actual, "abc");
+ }
+
+ @Test
+ public void testSetAttributeUsingObjectNameWildcard() throws Exception {
+ DynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+
+ jmxHelper.setAttribute(jmxObjectNameWithWildcard, "myattr", "abc");
+ Object actual = jmxHelper.getAttribute(jmxObjectName, "myattr");
+ assertEquals(actual, "abc");
+ }
+
+ @Test
+ public void testInvokeOperationWithNoArgs() throws Exception {
+ final String opReturnVal = "my result";
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], String.class.getName(), MBeanOperationInfo.ACTION);
+ Function<Object[], String> opImpl = new Function<Object[], String>() {
+ @Override public String apply(Object[] args) {
+ assertEquals(args.length, 0, "args="+args);
+ return opReturnVal;
+ }
+ };
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
+
+ assertEquals(jmxHelper.operation(objectName, opName), opReturnVal);
+ }
+
+ @Test
+ public void testInvokeOperationUsingObjectNameWildcard() throws Exception {
+ final String opReturnVal = "my result";
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], String.class.getName(), MBeanOperationInfo.ACTION);
+ Function<Object[], String> opImpl = new Function<Object[], String>() {
+ @Override public String apply(Object[] args) {
+ assertEquals(args.length, 0, "args="+args);
+ return opReturnVal;
+ }
+ };
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
+
+ assertEquals(jmxHelper.operation(objectNameWithWildcard, opName), opReturnVal);
+ }
+
+ @Test
+ public void testInvokeOperationWithArgs() throws Exception {
+ final String opReturnPrefix = "my result prefix/";
+ String opParam1 = "my param 1";
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(
+ opName,
+ "my descr",
+ new MBeanParameterInfo[] {new MBeanParameterInfo("myParam1", String.class.getName(), "my param1 descr")},
+ String.class.getName(),
+ MBeanOperationInfo.ACTION);
+ Function<Object[],String> opImpl = new Function<Object[],String>() {
+ public String apply(Object[] input) {
+ return opReturnPrefix+input[0];
+ }
+ };
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
+
+ assertEquals(jmxHelper.operation(objectName, opName, opParam1), opReturnPrefix+opParam1);
+ }
+
+ @Test
+ public void testReconnectsOnJmxServerTemporaryFailure() throws Exception {
+ int port = jmxService.getJmxPort();
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval");
+
+ // Simulate temporary network-failure
+ jmxService.shutdown();
+
+ // Ensure that we have a failed query while the "network is down"
+ try {
+ jmxHelper.getAttribute(jmxObjectName, attributeName);
+ fail();
+ } catch (Exception e) {
+ if (Throwables2.getFirstThrowableOfType(e, IOException.class) == null) {
+ throw e;
+ }
+ }
+
+ // Simulate the network restarting
+ jmxService = new JmxService(LOCALHOST_NAME, port);
+
+ GeneralisedDynamicMBean mbean2 = jmxService.registerMBean(MutableMap.of("myattr", "myval2"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval2");
+ }
+
+ @Test(expectedExceptions = {IllegalStateException.class})
+ public void testJmxCheckInstanceExistsEventuallyThrowsIfNotFound() throws Exception {
+ jmxHelper.assertMBeanExistsEventually(new ObjectName("Brooklyn:type=DoesNotExist,name=doesNotExist"), 1L);
+ }
+
+ @Test
+ public void testJmxObjectCheckExistsEventuallyReturnsIfFoundImmediately() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
+ jmxHelper.assertMBeanExistsEventually(jmxObjectName, 1L);
+ }
+
+ @Test
+ public void testJmxObjectCheckExistsEventuallyTakingLongReturnsIfFoundImmediately() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
+ jmxHelper.assertMBeanExistsEventually(jmxObjectName, 1L);
+ }
+
+ @Test
+ public void testJmxObjectCheckExistsEventuallyReturnsIfCreatedDuringPolling() throws Exception {
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(SHORT_WAIT_MS);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
+ } catch (InterruptedException e) {
+ return; // graceful return
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
+ }});
+ try {
+ t.start();
+
+ jmxHelper.assertMBeanExistsEventually(jmxObjectName, TIMEOUT_MS);
+ } finally {
+ t.interrupt();
+ t.join(TIMEOUT_MS);
+ assertFalse(t.isAlive());
+ }
+ }
+
+ @Test
+ public void testSubscribeToJmxNotificationsDirectlyWithJmxHelper() throws Exception {
+ StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName);
+ int sequence = 0;
+ final List<Notification> received = Lists.newArrayList();
+
+ jmxHelper.addNotificationListener(jmxObjectName, new NotificationListener() {
+ public void handleNotification(Notification notif, Object callback) {
+ received.add(notif);
+ }});
+
+
+ final Notification notif = sendNotification(mbean, "one", sequence++, "abc");
+
+ TestUtils.executeUntilSucceeds(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ assertEquals(received.size(), 1);
+ assertNotificationsEqual(received.get(0), notif);
+ }});
+ }
+
+ // Visual-inspection test that LOG.warn happens only once; TODO setup a listener to the logging output
+ @Test
+ public void testMBeanNotFoundLoggedOnlyOncePerUrl() throws Exception {
+ ObjectName wrongObjectName = new ObjectName("DoesNotExist:type=DoesNotExist");
+
+ // Expect just one log message about:
+ // JMX object DoesNotExist:type=DoesNotExist not found at service:jmx:rmi://localhost:1099/jndi/rmi://localhost:9001/jmxrmi"
+ for (int i = 0; i < 10; i++) {
+ jmxHelper.findMBean(wrongObjectName);
+ }
+
+ jmxService.shutdown();
+ jmxHelper.disconnect();
+
+ jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
+ jmxHelper = new JmxHelper(jmxService.getUrl());
+ jmxHelper.connect();
+
+ // Expect just one log message about:
+ // JMX object DoesNotExist:type=DoesNotExist not found at service:jmx:rmi://localhost:1099/jndi/rmi://localhost:9001/jmxrmi"
+ for (int i = 0; i < 10; i++) {
+ jmxHelper.findMBean(wrongObjectName);
+ }
+ }
+
+ private JmxService newJmxServiceRetrying(String host, int retries) throws Exception {
+ Exception lastexception = null;
+ for (int i = 0; i < retries; i++) {
+ try {
+ return new JmxService(host, (int)(11000+(500*Math.random())));
+ } catch (Exception e) {
+ log.debug("Unable to create JMX service during test - "+retries+" retries remaining");
+ lastexception = e;
+ }
+ }
+ throw lastexception;
+ }
+
+ private Notification sendNotification(StandardEmitterMBean mbean, String type, long seq, Object userData) {
+ Notification notif = new Notification(type, mbean, seq);
+ notif.setUserData(userData);
+ mbean.sendNotification(notif);
+ return notif;
+ }
+
+ private void assertNotificationsEqual(Notification n1, Notification n2) {
+ assertEquals(n1.getType(), n2.getType());
+ assertEquals(n1.getSequenceNumber(), n2.getSequenceNumber());
+ assertEquals(n1.getUserData(), n2.getUserData());
+ assertEquals(n1.getTimeStamp(), n2.getTimeStamp());
+ assertEquals(n1.getMessage(), n2.getMessage());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/feed/jmx/RebindJmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/feed/jmx/RebindJmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/feed/jmx/RebindJmxFeedTest.java
new file mode 100644
index 0000000..f521932
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/feed/jmx/RebindJmxFeedTest.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Collection;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Feed;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
+import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.core.test.entity.TestEntityImpl;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
+import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
+import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class RebindJmxFeedTest extends RebindTestFixtureWithApp {
+
+ private static final Logger log = LoggerFactory.getLogger(RebindJmxFeedTest.class);
+
+ private static final String LOCALHOST_NAME = "localhost";
+
+ static final AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ static final AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor( "aLong", "");
+
+ static final String JMX_ATTRIBUTE_NAME = "myattr";
+ static final String OBJECT_NAME = "Brooklyn:type=MyTestMBean,name=myname";
+
+ private JmxService jmxService;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Create an entity and configure it with the above JMX service
+ //jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (jmxService != null) jmxService.shutdown();
+ super.tearDown();
+ }
+
+ @Test
+ public void testJmxFeedIsPersisted() throws Exception {
+ runJmxFeedIsPersisted(false);
+ }
+
+ @Test
+ public void testJmxFeedIsPersistedWithPreCreatedJmxHelper() throws Exception {
+ runJmxFeedIsPersisted(true);
+ }
+
+ protected void runJmxFeedIsPersisted(boolean preCreateJmxHelper) throws Exception {
+ TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityWithJmxFeedImpl.class)
+ .configure(MyEntityWithJmxFeedImpl.PRE_CREATE_JMX_HELPER, preCreateJmxHelper));
+ origApp.start(ImmutableList.<Location>of());
+
+ jmxService = new JmxService(origEntity);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of(JMX_ATTRIBUTE_NAME, "myval"), OBJECT_NAME);
+
+ EntityTestUtils.assertAttributeEqualsEventually(origEntity, SENSOR_STRING, "myval");
+ assertEquals(origEntity.feeds().getFeeds().size(), 1);
+
+ newApp = rebind();
+ TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+
+ Collection<Feed> newFeeds = newEntity.feeds().getFeeds();
+ assertEquals(newFeeds.size(), 1);
+
+ // Expect the feed to still be polling
+ newEntity.setAttribute(SENSOR_STRING, null);
+ EntityTestUtils.assertAttributeEqualsEventually(newEntity, SENSOR_STRING, "myval");
+ }
+
+ public static class MyEntityWithJmxFeedImpl extends TestEntityImpl {
+ public static final ConfigKey<Boolean> PRE_CREATE_JMX_HELPER = ConfigKeys.newBooleanConfigKey("test.rebindjmx.preCreateJmxHelper", "", false);
+
+ @Override
+ public void start(Collection<? extends Location> locs) {
+ // TODO Auto-generated method stub
+ super.start(locs);
+
+ setAttribute(Attributes.HOSTNAME, "localhost");
+ setAttribute(UsesJmx.JMX_PORT,
+ LocalhostMachineProvisioningLocation.obtainPort(PortRanges.fromString("40123+")));
+ // only supports no-agent, at the moment
+ setConfig(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
+ setAttribute(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
+ ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
+
+ JmxFeed.Builder feedBuilder = JmxFeed.builder()
+ .entity(this)
+ .pollAttribute(new JmxAttributePollConfig<String>(SENSOR_STRING)
+ .objectName(OBJECT_NAME)
+ .period(50)
+ .attributeName(JMX_ATTRIBUTE_NAME));
+ if (getConfig(PRE_CREATE_JMX_HELPER)) {
+ JmxHelper jmxHelper = new JmxHelper(this);
+ feedBuilder.helper(jmxHelper);
+ }
+ addFeed(feedBuilder.build());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
deleted file mode 100644
index 8f722b2..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import static org.apache.brooklyn.test.TestUtils.executeUntilSucceeds;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.StandardEmitterMBean;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.core.location.SimulatedLocation;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.entity.java.JmxSupport;
-import org.apache.brooklyn.entity.java.UsesJmx;
-import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
-import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
-import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
-import org.apache.brooklyn.sensor.feed.jmx.JmxNotificationFilters;
-import org.apache.brooklyn.sensor.feed.jmx.JmxNotificationSubscriptionConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxOperationPollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxValueFunctions;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.TestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.testng.collections.Lists;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * Test the operation of the {@link JmxFeed} class.
- * <p>
- * Also confirm some of the JMX setup done by {@link JmxSupport} and {@link JmxHelper},
- * based on ports in {@link UsesJmx}.
- * <p>
- * TODO tests of other JMX_AGENT_MODE are done in ActiveMqIntegrationTest;
- * would be nice to promote some to live here
- */
-public class JmxFeedTest {
-
- // FIXME Move out the JmxHelper tests into the JmxHelperTest class
-
- // FIXME Also test that setting poll period takes effect
-
- private static final Logger log = LoggerFactory.getLogger(JmxFeedTest.class);
-
- private static final int TIMEOUT_MS = 5000;
- private static final int SHORT_WAIT_MS = 250;
-
- private JmxService jmxService;
- private TestApplication app;
- private TestEntity entity;
- private JmxFeed feed;
- private JmxHelper jmxHelper;
-
- private AttributeSensor<Integer> intAttribute = Sensors.newIntegerSensor("brooklyn.test.intAttribute", "Brooklyn testing int attribute");
- private AttributeSensor<String> stringAttribute = Sensors.newStringSensor("brooklyn.test.stringAttribute", "Brooklyn testing string attribute");
- private BasicAttributeSensor<Map> mapAttribute = new BasicAttributeSensor<Map>(Map.class, "brooklyn.test.mapAttribute", "Brooklyn testing map attribute");
- private String objectName = "Brooklyn:type=MyTestMBean,name=myname";
- private ObjectName jmxObjectName;
- private String attributeName = "myattrib";
- private String opName = "myop";
-
- public static class TestEntityWithJmx extends TestEntityImpl {
- @Override public void init() {
- setAttribute(Attributes.HOSTNAME, "localhost");
- setAttribute(UsesJmx.JMX_PORT,
- LocalhostMachineProvisioningLocation.obtainPort(PortRanges.fromString("40123+")));
- // only supports no-agent, at the moment
- setConfig(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
- setAttribute(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
- ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
- }
- }
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- jmxObjectName = new ObjectName(objectName);
-
- // Create an entity and configure it with the above JMX service
- app = TestApplication.Factory.newManagedInstanceForTests();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).impl(TestEntityWithJmx.class));
- app.start(ImmutableList.of(new SimulatedLocation()));
-
- jmxHelper = new JmxHelper(entity);
-
- jmxService = new JmxService(entity);
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (feed != null) feed.stop();
- if (jmxHelper != null) jmxHelper.disconnect();
- if (jmxService != null) jmxService.shutdown();
- if (app != null) Entities.destroyAll(app.getManagementContext());
- feed = null;
- }
-
- @Test
- public void testJmxAttributePollerReturnsMBeanAttribute() throws Exception {
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, 42), objectName);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .pollAttribute(new JmxAttributePollConfig<Integer>(intAttribute)
- .objectName(objectName)
- .period(50)
- .attributeName(attributeName))
- .build();
-
- // Starts with value defined when registering...
- assertSensorEventually(intAttribute, 42, TIMEOUT_MS);
-
- // Change the value and check it updates
- mbean.updateAttributeValue(attributeName, 64);
- assertSensorEventually(intAttribute, 64, TIMEOUT_MS);
- }
-
- @Test
- public void testJmxAttributeOfTypeTabularDataProviderConvertedToMap() throws Exception {
- // Create the CompositeType and TabularData
- CompositeType compositeType = new CompositeType(
- "typeName",
- "description",
- new String[] {"myint", "mystring", "mybool"}, // item names
- new String[] {"myint", "mystring", "mybool"}, // item descriptions, can't be null or empty string
- new OpenType<?>[] {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN}
- );
- TabularType tt = new TabularType(
- "typeName",
- "description",
- compositeType,
- new String[] {"myint"}
- );
- TabularDataSupport tds = new TabularDataSupport(tt);
- tds.put(new CompositeDataSupport(
- compositeType,
- new String[] {"mybool", "myint", "mystring"},
- new Object[] {true, 1234, "on"}
- ));
-
- // Create MBean
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, tds), objectName);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .pollAttribute(new JmxAttributePollConfig<Map>(mapAttribute)
- .objectName(objectName)
- .attributeName(attributeName)
- .onSuccess((Function)JmxValueFunctions.tabularDataToMap()))
- .build();
-
- // Starts with value defined when registering...
- assertSensorEventually(
- mapAttribute,
- ImmutableMap.of("myint", 1234, "mystring", "on", "mybool", Boolean.TRUE),
- TIMEOUT_MS);
- }
-
- @Test
- public void testJmxOperationPolledForSensor() throws Exception {
- // This is awful syntax...
- final int opReturnVal = 123;
- final AtomicInteger invocationCount = new AtomicInteger();
- MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], Integer.class.getName(), MBeanOperationInfo.ACTION);
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(
- Collections.emptyMap(),
- ImmutableMap.of(opInfo, new Function<Object[], Integer>() {
- public Integer apply(Object[] args) {
- invocationCount.incrementAndGet(); return opReturnVal;
- }}),
- objectName);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .pollOperation(new JmxOperationPollConfig<Integer>(intAttribute)
- .objectName(objectName)
- .operationName(opName))
- .build();
-
- TestUtils.executeUntilSucceeds(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- assertTrue(invocationCount.get() > 0, "invocationCount="+invocationCount);
- assertEquals(entity.getAttribute(intAttribute), (Integer)opReturnVal);
- }});
- }
-
- @Test
- public void testJmxOperationWithArgPolledForSensor() throws Exception {
- // This is awful syntax...
- MBeanParameterInfo paramInfo = new MBeanParameterInfo("param1", String.class.getName(), "my param1");
- MBeanParameterInfo[] paramInfos = new MBeanParameterInfo[] {paramInfo};
- MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", paramInfos, String.class.getName(), MBeanOperationInfo.ACTION);
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(
- Collections.emptyMap(),
- ImmutableMap.of(opInfo, new Function<Object[], String>() {
- public String apply(Object[] args) {
- return args[0]+"suffix";
- }}),
- objectName);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .pollOperation(new JmxOperationPollConfig<String>(stringAttribute)
- .objectName(objectName)
- .operationName(opName)
- .operationParams(ImmutableList.of("myprefix")))
- .build();
-
- assertSensorEventually(stringAttribute, "myprefix"+"suffix", TIMEOUT_MS);
- }
-
- @Test
- public void testJmxNotificationSubscriptionForSensor() throws Exception {
- final String one = "notification.one", two = "notification.two";
- final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
- final AtomicInteger sequence = new AtomicInteger(0);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
- .objectName(objectName)
- .notificationFilter(JmxNotificationFilters.matchesType(one)))
- .build();
-
- // Notification updates the sensor
- // Note that subscription is done async, so can't just send notification immediately during test.
- Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- sendNotification(mbean, one, sequence.getAndIncrement(), 123);
- assertEquals(entity.getAttribute(intAttribute), (Integer)123);
- }});
-
- // But other notification types are ignored
- sendNotification(mbean, two, sequence.getAndIncrement(), -1);
-
- Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- assertEquals(entity.getAttribute(intAttribute), (Integer)123);
- }});
- }
-
- @Test
- public void testJmxNotificationSubscriptionForSensorParsingNotification() throws Exception {
- final String one = "notification.one", two = "notification.two";
- final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
- final AtomicInteger sequence = new AtomicInteger(0);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
- .objectName(objectName)
- .notificationFilter(JmxNotificationFilters.matchesType(one))
- .onNotification(new Function<Notification, Integer>() {
- public Integer apply(Notification notif) {
- return (Integer) notif.getUserData();
- }
- }))
- .build();
-
-
- // Notification updates the sensor
- // Note that subscription is done async, so can't just send notification immediately during test.
- Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- sendNotification(mbean, one, sequence.getAndIncrement(), 123);
- assertEquals(entity.getAttribute(intAttribute), (Integer)123);
- }});
- }
-
- @Test
- public void testJmxNotificationMultipleSubscriptionUsingListener() throws Exception {
- final String one = "notification.one";
- final String two = "notification.two";
- final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
- final AtomicInteger sequence = new AtomicInteger(0);
-
- feed = JmxFeed.builder()
- .entity(entity)
- .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
- .objectName(objectName)
- .notificationFilter(JmxNotificationFilters.matchesTypes(one, two)))
- .build();
-
- // Notification updates the sensor
- // Note that subscription is done async, so can't just send notification immediately during test.
- Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- sendNotification(mbean, one, sequence.getAndIncrement(), 123);
- assertEquals(entity.getAttribute(intAttribute), (Integer)123);
- }});
-
- // And wildcard means other notifications also received
- sendNotification(mbean, two, sequence.getAndIncrement(), 456);
- assertSensorEventually(intAttribute, 456, TIMEOUT_MS);
- }
-
- // Test reproduces functionality used in Monterey, for Venue entity being told of requestActor
- @Test
- public void testSubscribeToJmxNotificationAndEmitCorrespondingNotificationSensor() throws Exception {
- TestApplication app2 = new TestApplicationImpl();
- final EntityWithEmitter entity = new EntityWithEmitter(app2);
- Entities.startManagement(app2);
- try {
- app2.start(ImmutableList.of(new SimulatedLocation()));
-
- final List<SensorEvent<String>> received = Lists.newArrayList();
- app2.subscribe(null, EntityWithEmitter.MY_NOTIF, new SensorEventListener<String>() {
- public void onEvent(SensorEvent<String> event) {
- received.add(event);
- }});
-
- final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName);
- final AtomicInteger sequence = new AtomicInteger(0);
-
- jmxHelper.connect(TIMEOUT_MS);
- jmxHelper.addNotificationListener(jmxObjectName, new NotificationListener() {
- public void handleNotification(Notification notif, Object callback) {
- if (notif.getType().equals("one")) {
- entity.emit(EntityWithEmitter.MY_NOTIF, (String) notif.getUserData());
- }
- }});
-
-
- Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- sendNotification(mbean, "one", sequence.getAndIncrement(), "abc");
- assertTrue(received.size() > 0, "received size should be bigger than 0");
- assertEquals(received.get(0).getValue(), "abc");
- }});
- } finally {
- Entities.destroyAll(app2.getManagementContext());
- }
- }
-
- public static class EntityWithEmitter extends AbstractEntity {
- public static final BasicNotificationSensor<String> MY_NOTIF = new BasicNotificationSensor<String>(String.class, "test.myNotif", "My notif");
-
- public EntityWithEmitter(Entity owner) {
- super(owner);
- }
- public EntityWithEmitter(Map flags) {
- super(flags);
- }
- public EntityWithEmitter(Map flags, Entity owner) {
- super(flags, owner);
- }
- }
-
- private Notification sendNotification(StandardEmitterMBean mbean, String type, long seq, Object userData) {
- Notification notif = new Notification(type, mbean, seq);
- notif.setUserData(userData);
- mbean.sendNotification(notif);
- return notif;
- }
-
- private <T> void assertSensorEventually(final AttributeSensor<T> sensor, final T expectedVal, long timeout) {
- executeUntilSucceeds(ImmutableMap.of("timeout", timeout), new Callable<Void>() {
- public Void call() {
- assertEquals(entity.getAttribute(sensor), expectedVal);
- return null;
- }});
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java
deleted file mode 100644
index 058947c..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.io.IOException;
-import java.util.List;
-
-import javax.management.DynamicMBean;
-import javax.management.MBeanOperationInfo;
-import javax.management.MBeanParameterInfo;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-import javax.management.StandardEmitterMBean;
-
-import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
-import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
-import org.apache.brooklyn.test.TestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.jclouds.util.Throwables2;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.testng.collections.Lists;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class JmxHelperTest {
-
- private static final Logger log = LoggerFactory.getLogger(JmxHelperTest.class);
-
- private static final String LOCALHOST_NAME = "localhost";
-
- private static final int TIMEOUT_MS = 5000;
- private static final int SHORT_WAIT_MS = 250;
-
- private JmxService jmxService;
- private JmxHelper jmxHelper;
-
- private String objectName = "Brooklyn:type=MyTestMBean,name=myname";
- private String objectNameWithWildcard = "Brooklyn:type=MyTestMBean,name=mynam*";
- private ObjectName jmxObjectName;
- private ObjectName jmxObjectNameWithWildcard;
- private String attributeName = "myattrib";
- private String opName = "myop";
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- jmxObjectName = new ObjectName(objectName);
- jmxObjectNameWithWildcard = new ObjectName(objectNameWithWildcard);
- jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
- jmxHelper = new JmxHelper(jmxService.getUrl());
- jmxHelper.setMinTimeBetweenReconnectAttempts(0);
- jmxHelper.connect(TIMEOUT_MS);
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (jmxHelper != null) jmxHelper.disconnect();
- if (jmxService != null) jmxService.shutdown();
- jmxHelper = null;
- jmxService = null;
- }
-
- @Test
- public void testGetAttribute() throws Exception {
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
- assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval");
- }
-
- @Test
- public void testGetAttributeUsingObjectNameWildcard() throws Exception {
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
- assertEquals(jmxHelper.getAttribute(jmxObjectNameWithWildcard, "myattr"), "myval");
- }
-
- @Test
- public void testSetAttribute() throws Exception {
- DynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
-
- jmxHelper.setAttribute(jmxObjectName, "myattr", "abc");
- Object actual = jmxHelper.getAttribute(jmxObjectName, "myattr");
- assertEquals(actual, "abc");
- }
-
- @Test
- public void testSetAttributeUsingObjectNameWildcard() throws Exception {
- DynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
-
- jmxHelper.setAttribute(jmxObjectNameWithWildcard, "myattr", "abc");
- Object actual = jmxHelper.getAttribute(jmxObjectName, "myattr");
- assertEquals(actual, "abc");
- }
-
- @Test
- public void testInvokeOperationWithNoArgs() throws Exception {
- final String opReturnVal = "my result";
- MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], String.class.getName(), MBeanOperationInfo.ACTION);
- Function<Object[], String> opImpl = new Function<Object[], String>() {
- @Override public String apply(Object[] args) {
- assertEquals(args.length, 0, "args="+args);
- return opReturnVal;
- }
- };
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
-
- assertEquals(jmxHelper.operation(objectName, opName), opReturnVal);
- }
-
- @Test
- public void testInvokeOperationUsingObjectNameWildcard() throws Exception {
- final String opReturnVal = "my result";
- MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], String.class.getName(), MBeanOperationInfo.ACTION);
- Function<Object[], String> opImpl = new Function<Object[], String>() {
- @Override public String apply(Object[] args) {
- assertEquals(args.length, 0, "args="+args);
- return opReturnVal;
- }
- };
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
-
- assertEquals(jmxHelper.operation(objectNameWithWildcard, opName), opReturnVal);
- }
-
- @Test
- public void testInvokeOperationWithArgs() throws Exception {
- final String opReturnPrefix = "my result prefix/";
- String opParam1 = "my param 1";
- MBeanOperationInfo opInfo = new MBeanOperationInfo(
- opName,
- "my descr",
- new MBeanParameterInfo[] {new MBeanParameterInfo("myParam1", String.class.getName(), "my param1 descr")},
- String.class.getName(),
- MBeanOperationInfo.ACTION);
- Function<Object[],String> opImpl = new Function<Object[],String>() {
- public String apply(Object[] input) {
- return opReturnPrefix+input[0];
- }
- };
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
-
- assertEquals(jmxHelper.operation(objectName, opName, opParam1), opReturnPrefix+opParam1);
- }
-
- @Test
- public void testReconnectsOnJmxServerTemporaryFailure() throws Exception {
- int port = jmxService.getJmxPort();
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
- assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval");
-
- // Simulate temporary network-failure
- jmxService.shutdown();
-
- // Ensure that we have a failed query while the "network is down"
- try {
- jmxHelper.getAttribute(jmxObjectName, attributeName);
- fail();
- } catch (Exception e) {
- if (Throwables2.getFirstThrowableOfType(e, IOException.class) == null) {
- throw e;
- }
- }
-
- // Simulate the network restarting
- jmxService = new JmxService(LOCALHOST_NAME, port);
-
- GeneralisedDynamicMBean mbean2 = jmxService.registerMBean(MutableMap.of("myattr", "myval2"), objectName);
- assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval2");
- }
-
- @Test(expectedExceptions = {IllegalStateException.class})
- public void testJmxCheckInstanceExistsEventuallyThrowsIfNotFound() throws Exception {
- jmxHelper.assertMBeanExistsEventually(new ObjectName("Brooklyn:type=DoesNotExist,name=doesNotExist"), 1L);
- }
-
- @Test
- public void testJmxObjectCheckExistsEventuallyReturnsIfFoundImmediately() throws Exception {
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
- jmxHelper.assertMBeanExistsEventually(jmxObjectName, 1L);
- }
-
- @Test
- public void testJmxObjectCheckExistsEventuallyTakingLongReturnsIfFoundImmediately() throws Exception {
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
- jmxHelper.assertMBeanExistsEventually(jmxObjectName, 1L);
- }
-
- @Test
- public void testJmxObjectCheckExistsEventuallyReturnsIfCreatedDuringPolling() throws Exception {
- Thread t = new Thread(new Runnable() {
- public void run() {
- try {
- Thread.sleep(SHORT_WAIT_MS);
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
- } catch (InterruptedException e) {
- return; // graceful return
- } catch (Exception e) {
- throw Exceptions.propagate(e);
- }
- }});
- try {
- t.start();
-
- jmxHelper.assertMBeanExistsEventually(jmxObjectName, TIMEOUT_MS);
- } finally {
- t.interrupt();
- t.join(TIMEOUT_MS);
- assertFalse(t.isAlive());
- }
- }
-
- @Test
- public void testSubscribeToJmxNotificationsDirectlyWithJmxHelper() throws Exception {
- StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName);
- int sequence = 0;
- final List<Notification> received = Lists.newArrayList();
-
- jmxHelper.addNotificationListener(jmxObjectName, new NotificationListener() {
- public void handleNotification(Notification notif, Object callback) {
- received.add(notif);
- }});
-
-
- final Notification notif = sendNotification(mbean, "one", sequence++, "abc");
-
- TestUtils.executeUntilSucceeds(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
- public void run() {
- assertEquals(received.size(), 1);
- assertNotificationsEqual(received.get(0), notif);
- }});
- }
-
- // Visual-inspection test that LOG.warn happens only once; TODO setup a listener to the logging output
- @Test
- public void testMBeanNotFoundLoggedOnlyOncePerUrl() throws Exception {
- ObjectName wrongObjectName = new ObjectName("DoesNotExist:type=DoesNotExist");
-
- // Expect just one log message about:
- // JMX object DoesNotExist:type=DoesNotExist not found at service:jmx:rmi://localhost:1099/jndi/rmi://localhost:9001/jmxrmi"
- for (int i = 0; i < 10; i++) {
- jmxHelper.findMBean(wrongObjectName);
- }
-
- jmxService.shutdown();
- jmxHelper.disconnect();
-
- jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
- jmxHelper = new JmxHelper(jmxService.getUrl());
- jmxHelper.connect();
-
- // Expect just one log message about:
- // JMX object DoesNotExist:type=DoesNotExist not found at service:jmx:rmi://localhost:1099/jndi/rmi://localhost:9001/jmxrmi"
- for (int i = 0; i < 10; i++) {
- jmxHelper.findMBean(wrongObjectName);
- }
- }
-
- private JmxService newJmxServiceRetrying(String host, int retries) throws Exception {
- Exception lastexception = null;
- for (int i = 0; i < retries; i++) {
- try {
- return new JmxService(host, (int)(11000+(500*Math.random())));
- } catch (Exception e) {
- log.debug("Unable to create JMX service during test - "+retries+" retries remaining");
- lastexception = e;
- }
- }
- throw lastexception;
- }
-
- private Notification sendNotification(StandardEmitterMBean mbean, String type, long seq, Object userData) {
- Notification notif = new Notification(type, mbean, seq);
- notif.setUserData(userData);
- mbean.sendNotification(notif);
- return notif;
- }
-
- private void assertNotificationsEqual(Notification n1, Notification n2) {
- assertEquals(n1.getType(), n2.getType());
- assertEquals(n1.getSequenceNumber(), n2.getSequenceNumber());
- assertEquals(n1.getUserData(), n2.getUserData());
- assertEquals(n1.getTimeStamp(), n2.getTimeStamp());
- assertEquals(n1.getMessage(), n2.getMessage());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
deleted file mode 100644
index 9ed0031..0000000
--- a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Feed;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.entity.java.UsesJmx;
-import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
-import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
-import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
-public class RebindJmxFeedTest extends RebindTestFixtureWithApp {
-
- private static final Logger log = LoggerFactory.getLogger(RebindJmxFeedTest.class);
-
- private static final String LOCALHOST_NAME = "localhost";
-
- static final AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
- static final AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor( "aLong", "");
-
- static final String JMX_ATTRIBUTE_NAME = "myattr";
- static final String OBJECT_NAME = "Brooklyn:type=MyTestMBean,name=myname";
-
- private JmxService jmxService;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
-
- // Create an entity and configure it with the above JMX service
- //jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (jmxService != null) jmxService.shutdown();
- super.tearDown();
- }
-
- @Test
- public void testJmxFeedIsPersisted() throws Exception {
- runJmxFeedIsPersisted(false);
- }
-
- @Test
- public void testJmxFeedIsPersistedWithPreCreatedJmxHelper() throws Exception {
- runJmxFeedIsPersisted(true);
- }
-
- protected void runJmxFeedIsPersisted(boolean preCreateJmxHelper) throws Exception {
- TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityWithJmxFeedImpl.class)
- .configure(MyEntityWithJmxFeedImpl.PRE_CREATE_JMX_HELPER, preCreateJmxHelper));
- origApp.start(ImmutableList.<Location>of());
-
- jmxService = new JmxService(origEntity);
- GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of(JMX_ATTRIBUTE_NAME, "myval"), OBJECT_NAME);
-
- EntityTestUtils.assertAttributeEqualsEventually(origEntity, SENSOR_STRING, "myval");
- assertEquals(origEntity.feeds().getFeeds().size(), 1);
-
- newApp = rebind();
- TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
-
- Collection<Feed> newFeeds = newEntity.feeds().getFeeds();
- assertEquals(newFeeds.size(), 1);
-
- // Expect the feed to still be polling
- newEntity.setAttribute(SENSOR_STRING, null);
- EntityTestUtils.assertAttributeEqualsEventually(newEntity, SENSOR_STRING, "myval");
- }
-
- public static class MyEntityWithJmxFeedImpl extends TestEntityImpl {
- public static final ConfigKey<Boolean> PRE_CREATE_JMX_HELPER = ConfigKeys.newBooleanConfigKey("test.rebindjmx.preCreateJmxHelper", "", false);
-
- @Override
- public void start(Collection<? extends Location> locs) {
- // TODO Auto-generated method stub
- super.start(locs);
-
- setAttribute(Attributes.HOSTNAME, "localhost");
- setAttribute(UsesJmx.JMX_PORT,
- LocalhostMachineProvisioningLocation.obtainPort(PortRanges.fromString("40123+")));
- // only supports no-agent, at the moment
- setConfig(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
- setAttribute(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
- ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
-
- JmxFeed.Builder feedBuilder = JmxFeed.builder()
- .entity(this)
- .pollAttribute(new JmxAttributePollConfig<String>(SENSOR_STRING)
- .objectName(OBJECT_NAME)
- .period(50)
- .attributeName(JMX_ATTRIBUTE_NAME));
- if (getConfig(PRE_CREATE_JMX_HELPER)) {
- JmxHelper jmxHelper = new JmxHelper(this);
- feedBuilder.helper(jmxHelper);
- }
- addFeed(feedBuilder.build());
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
index 8b544c4..f78ddba 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
@@ -22,11 +22,11 @@ import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.apache.brooklyn.util.guava.Functionals;
public class CrateNodeImpl extends SoftwareProcessImpl implements CrateNode{
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
index 3d8c982..c23c616 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
@@ -23,10 +23,10 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.text.Identifiers;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
index e106728..d6527ca 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
@@ -39,9 +39,9 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpL
import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskBuilder;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
index 71c73c6..5346fcb 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
@@ -24,12 +24,12 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.guava.Maybe;
[15/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java b/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
new file mode 100644
index 0000000..b909856
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java
@@ -0,0 +1,823 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import groovy.lang.Closure;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.util.collections.CollectionFunctionals;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.BasicExecutionContext;
+import org.apache.brooklyn.util.core.task.BasicTask;
+import org.apache.brooklyn.util.core.task.DeferredSupplier;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ParallelTask;
+import org.apache.brooklyn.util.core.task.TaskInternal;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ValueResolver;
+import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.exceptions.NotManagedException;
+import org.apache.brooklyn.util.exceptions.RuntimeTimeoutException;
+import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.text.Strings;
+import org.apache.brooklyn.util.time.CountdownTimer;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+/** Conveniences for making tasks which run in entity {@link ExecutionContext}s, subscribing to attributes from other entities, possibly transforming those;
+ * these {@link Task} instances are typically passed in {@link EntityLocal#setConfig(ConfigKey, Object)}.
+ * <p>
+ * If using a lot it may be useful to:
+ * <pre>
+ * {@code
+ * import static brooklyn.event.basic.DependentConfiguration.*;
+ * }
+ * </pre>
+ */
+public class DependentConfiguration {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DependentConfiguration.class);
+
+ //not instantiable, only a static helper
+ private DependentConfiguration() {}
+
+ /**
+ * Default readiness is Groovy truth.
+ *
+ * @see #attributeWhenReady(Entity, AttributeSensor, Predicate)
+ */
+ public static <T> Task<T> attributeWhenReady(Entity source, AttributeSensor<T> sensor) {
+ return attributeWhenReady(source, sensor, GroovyJavaMethods.truthPredicate());
+ }
+
+ public static <T> Task<T> attributeWhenReady(Entity source, AttributeSensor<T> sensor, Closure<Boolean> ready) {
+ Predicate<Object> readyPredicate = (ready != null) ? GroovyJavaMethods.<Object>predicateFromClosure(ready) : GroovyJavaMethods.truthPredicate();
+ return attributeWhenReady(source, sensor, readyPredicate);
+ }
+
+ /** returns an unsubmitted {@link Task} which blocks until the given sensor on the given source entity gives a value that satisfies ready, then returns that value;
+ * particular useful in Entity configuration where config will block until Tasks have a value
+ */
+ public static <T> Task<T> attributeWhenReady(final Entity source, final AttributeSensor<T> sensor, final Predicate<? super T> ready) {
+ Builder<T, T> builder = builder().attributeWhenReady(source, sensor);
+ if (ready != null) builder.readiness(ready);
+ return builder.build();
+
+ }
+
+ public static <T,V> Task<V> attributePostProcessedWhenReady(Entity source, AttributeSensor<T> sensor, Closure<Boolean> ready, Closure<V> postProcess) {
+ Predicate<? super T> readyPredicate = (ready != null) ? GroovyJavaMethods.predicateFromClosure(ready) : GroovyJavaMethods.truthPredicate();
+ Function<? super T, V> postProcessFunction = GroovyJavaMethods.<T,V>functionFromClosure(postProcess);
+ return attributePostProcessedWhenReady(source, sensor, readyPredicate, postProcessFunction);
+ }
+
+ public static <T,V> Task<V> attributePostProcessedWhenReady(Entity source, AttributeSensor<T> sensor, Closure<V> postProcess) {
+ return attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), GroovyJavaMethods.<T,V>functionFromClosure(postProcess));
+ }
+
+ public static <T> Task<T> valueWhenAttributeReady(Entity source, AttributeSensor<T> sensor, T value) {
+ return DependentConfiguration.<T,T>attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), Functions.constant(value));
+ }
+
+ public static <T,V> Task<V> valueWhenAttributeReady(Entity source, AttributeSensor<T> sensor, Function<? super T,V> valueProvider) {
+ return attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), valueProvider);
+ }
+
+ public static <T,V> Task<V> valueWhenAttributeReady(Entity source, AttributeSensor<T> sensor, Closure<V> valueProvider) {
+ return attributePostProcessedWhenReady(source, sensor, GroovyJavaMethods.truthPredicate(), valueProvider);
+ }
+
+ public static <T,V> Task<V> attributePostProcessedWhenReady(final Entity source, final AttributeSensor<T> sensor, final Predicate<? super T> ready, final Closure<V> postProcess) {
+ return attributePostProcessedWhenReady(source, sensor, ready, GroovyJavaMethods.<T,V>functionFromClosure(postProcess));
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T,V> Task<V> attributePostProcessedWhenReady(final Entity source, final AttributeSensor<T> sensor, final Predicate<? super T> ready, final Function<? super T,V> postProcess) {
+ Builder<T,T> builder1 = DependentConfiguration.builder().attributeWhenReady(source, sensor);
+ // messy generics here to support null postProcess; would be nice to disallow that here
+ Builder<T,V> builder;
+ if (postProcess != null) {
+ builder = builder1.postProcess(postProcess);
+ } else {
+ builder = (Builder<T,V>)builder1;
+ }
+ if (ready != null) builder.readiness(ready);
+
+ return builder.build();
+ }
+
+ public static <T> T waitInTaskForAttributeReady(Entity source, AttributeSensor<T> sensor, Predicate<? super T> ready) {
+ return waitInTaskForAttributeReady(source, sensor, ready, ImmutableList.<AttributeAndSensorCondition<?>>of());
+ }
+
+ public static <T> T waitInTaskForAttributeReady(final Entity source, final AttributeSensor<T> sensor, Predicate<? super T> ready, List<AttributeAndSensorCondition<?>> abortConditions) {
+ String blockingDetails = "Waiting for ready from "+source+" "+sensor+" (subscription)";
+ return waitInTaskForAttributeReady(source, sensor, ready, abortConditions, blockingDetails);
+ }
+
+ // TODO would be nice to have an easy semantics for whenServiceUp (cf DynamicWebAppClusterImpl.whenServiceUp)
+
+ public static <T> T waitInTaskForAttributeReady(final Entity source, final AttributeSensor<T> sensor, Predicate<? super T> ready, List<AttributeAndSensorCondition<?>> abortConditions, String blockingDetails) {
+ return new WaitInTaskForAttributeReady<T,T>(source, sensor, ready, abortConditions, blockingDetails).call();
+ }
+
+ protected static class WaitInTaskForAttributeReady<T,V> implements Callable<V> {
+
+ /* This is a change since before Oct 2014. Previously it would continue to poll,
+ * (maybe finding a different error) if the target entity becomes unmanaged.
+ * Now it actively checks unmanaged by default, and still throws although it might
+ * now find a different problem. */
+ private final static boolean DEFAULT_IGNORE_UNMANAGED = false;
+
+ protected final Entity source;
+ protected final AttributeSensor<T> sensor;
+ protected final Predicate<? super T> ready;
+ protected final List<AttributeAndSensorCondition<?>> abortSensorConditions;
+ protected final String blockingDetails;
+ protected final Function<? super T,? extends V> postProcess;
+ protected final Duration timeout;
+ protected final Maybe<V> onTimeout;
+ protected final boolean ignoreUnmanaged;
+ protected final Maybe<V> onUnmanaged;
+ // TODO onError Continue / Throw / Return(V)
+
+ protected WaitInTaskForAttributeReady(Builder<T, V> builder) {
+ this.source = builder.source;
+ this.sensor = builder.sensor;
+ this.ready = builder.readiness;
+ this.abortSensorConditions = builder.abortSensorConditions;
+ this.blockingDetails = builder.blockingDetails;
+ this.postProcess = builder.postProcess;
+ this.timeout = builder.timeout;
+ this.onTimeout = builder.onTimeout;
+ this.ignoreUnmanaged = builder.ignoreUnmanaged;
+ this.onUnmanaged = builder.onUnmanaged;
+ }
+
+ private WaitInTaskForAttributeReady(Entity source, AttributeSensor<T> sensor, Predicate<? super T> ready,
+ List<AttributeAndSensorCondition<?>> abortConditions, String blockingDetails) {
+ this.source = source;
+ this.sensor = sensor;
+ this.ready = ready;
+ this.abortSensorConditions = abortConditions;
+ this.blockingDetails = blockingDetails;
+
+ this.timeout = Duration.PRACTICALLY_FOREVER;
+ this.onTimeout = Maybe.absent();
+ this.ignoreUnmanaged = DEFAULT_IGNORE_UNMANAGED;
+ this.onUnmanaged = Maybe.absent();
+ this.postProcess = null;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected V postProcess(T value) {
+ if (this.postProcess!=null) return postProcess.apply(value);
+ // if no post-processing assume the types are correct
+ return (V) value;
+ }
+
+ protected boolean ready(T value) {
+ if (ready!=null) return ready.apply(value);
+ return GroovyJavaMethods.truth(value);
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public V call() {
+ T value = source.getAttribute(sensor);
+
+ // return immediately if either the ready predicate or the abort conditions hold
+ if (ready(value)) return postProcess(value);
+
+ final List<Exception> abortionExceptions = Lists.newCopyOnWriteArrayList();
+ long start = System.currentTimeMillis();
+
+ for (AttributeAndSensorCondition abortCondition : abortSensorConditions) {
+ Object abortValue = abortCondition.source.getAttribute(abortCondition.sensor);
+ if (abortCondition.predicate.apply(abortValue)) {
+ abortionExceptions.add(new Exception("Abort due to "+abortCondition.source+" -> "+abortCondition.sensor));
+ }
+ }
+ if (abortionExceptions.size() > 0) {
+ throw new CompoundRuntimeException("Aborted waiting for ready from "+source+" "+sensor, abortionExceptions);
+ }
+
+ TaskInternal<?> current = (TaskInternal<?>) Tasks.current();
+ if (current == null) throw new IllegalStateException("Should only be invoked in a running task");
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(current);
+ if (entity == null) throw new IllegalStateException("Should only be invoked in a running task with an entity tag; "+
+ current+" has no entity tag ("+current.getStatusDetail(false)+")");
+
+ final LinkedList<T> publishedValues = new LinkedList<T>();
+ final Semaphore semaphore = new Semaphore(0); // could use Exchanger
+ SubscriptionHandle subscription = null;
+ List<SubscriptionHandle> abortSubscriptions = Lists.newArrayList();
+
+ try {
+ subscription = ((EntityInternal)entity).getSubscriptionContext().subscribe(source, sensor, new SensorEventListener<T>() {
+ @Override public void onEvent(SensorEvent<T> event) {
+ synchronized (publishedValues) { publishedValues.add(event.getValue()); }
+ semaphore.release();
+ }});
+ for (final AttributeAndSensorCondition abortCondition : abortSensorConditions) {
+ abortSubscriptions.add(((EntityInternal)entity).getSubscriptionContext().subscribe(abortCondition.source, abortCondition.sensor, new SensorEventListener<Object>() {
+ @Override public void onEvent(SensorEvent<Object> event) {
+ if (abortCondition.predicate.apply(event.getValue())) {
+ abortionExceptions.add(new Exception("Abort due to "+abortCondition.source+" -> "+abortCondition.sensor));
+ semaphore.release();
+ }
+ }}));
+ Object abortValue = abortCondition.source.getAttribute(abortCondition.sensor);
+ if (abortCondition.predicate.apply(abortValue)) {
+ abortionExceptions.add(new Exception("Abort due to "+abortCondition.source+" -> "+abortCondition.sensor));
+ }
+ }
+ if (abortionExceptions.size() > 0) {
+ throw new CompoundRuntimeException("Aborted waiting for ready from "+source+" "+sensor, abortionExceptions);
+ }
+
+ CountdownTimer timer = timeout!=null ? timeout.countdownTimer() : null;
+ Duration maxPeriod = ValueResolver.PRETTY_QUICK_WAIT;
+ Duration nextPeriod = ValueResolver.REAL_QUICK_PERIOD;
+ while (true) {
+ // check the source on initial run (could be done outside the loop)
+ // and also (optionally) on each iteration in case it is more recent
+ value = source.getAttribute(sensor);
+ if (ready(value)) break;
+
+ if (timer!=null) {
+ if (timer.getDurationRemaining().isShorterThan(nextPeriod)) {
+ nextPeriod = timer.getDurationRemaining();
+ }
+ if (timer.isExpired()) {
+ if (onTimeout.isPresent()) return onTimeout.get();
+ throw new RuntimeTimeoutException("Unsatisfied after "+Duration.sinceUtc(start));
+ }
+ }
+
+ String prevBlockingDetails = current.setBlockingDetails(blockingDetails);
+ try {
+ if (semaphore.tryAcquire(nextPeriod.toMilliseconds(), TimeUnit.MILLISECONDS)) {
+ // immediately release so we are available for the next check
+ semaphore.release();
+ // if other permits have been made available (e.g. multiple notifications) drain them all as no point running multiple times
+ semaphore.drainPermits();
+ }
+ } finally {
+ current.setBlockingDetails(prevBlockingDetails);
+ }
+
+ // check any subscribed values which have come in first
+ while (true) {
+ synchronized (publishedValues) {
+ if (publishedValues.isEmpty()) break;
+ value = publishedValues.pop();
+ }
+ if (ready(value)) break;
+ }
+
+ // if unmanaged then ignore the other abort conditions
+ if (!ignoreUnmanaged && Entities.isNoLongerManaged(entity)) {
+ if (onUnmanaged.isPresent()) return onUnmanaged.get();
+ throw new NotManagedException(entity);
+ }
+
+ if (abortionExceptions.size() > 0) {
+ throw new CompoundRuntimeException("Aborted waiting for ready from "+source+" "+sensor, abortionExceptions);
+ }
+
+ nextPeriod = nextPeriod.times(2).upperBound(maxPeriod);
+ }
+ if (LOG.isDebugEnabled()) LOG.debug("Attribute-ready for {} in entity {}", sensor, source);
+ return postProcess(value);
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ } finally {
+ if (subscription != null) {
+ ((EntityInternal)entity).getSubscriptionContext().unsubscribe(subscription);
+ }
+ for (SubscriptionHandle handle : abortSubscriptions) {
+ ((EntityInternal)entity).getSubscriptionContext().unsubscribe(handle);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a {@link Task} which blocks until the given job returns, then returns the value of that job.
+ *
+ * @deprecated since 0.7; code will be moved into test utilities
+ */
+ @Deprecated
+ public static <T> Task<T> whenDone(Callable<T> job) {
+ return new BasicTask<T>(MutableMap.of("tag", "whenDone", "displayName", "waiting for job"), job);
+ }
+
+ /**
+ * Returns a {@link Task} which waits for the result of first parameter, then applies the function in the second
+ * parameter to it, returning that result.
+ *
+ * Particular useful in Entity configuration where config will block until Tasks have completed,
+ * allowing for example an {@link #attributeWhenReady(Entity, AttributeSensor, Predicate)} expression to be
+ * passed in the first argument then transformed by the function in the second argument to generate
+ * the value that is used for the configuration
+ */
+ public static <U,T> Task<T> transform(final Task<U> task, final Function<U,T> transformer) {
+ return transform(MutableMap.of("displayName", "transforming "+task), task, transformer);
+ }
+
+ /** @see #transform(Task, Function) */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <U,T> Task<T> transform(Task<U> task, Closure transformer) {
+ return transform(task, GroovyJavaMethods.functionFromClosure(transformer));
+ }
+
+ /** @see #transform(Task, Function) */
+ @SuppressWarnings({ "rawtypes" })
+ public static <U,T> Task<T> transform(final Map flags, final TaskAdaptable<U> task, final Function<U,T> transformer) {
+ return new BasicTask<T>(flags, new Callable<T>() {
+ public T call() throws Exception {
+ if (!task.asTask().isSubmitted()) {
+ BasicExecutionContext.getCurrentExecutionContext().submit(task);
+ }
+ return transformer.apply(task.asTask().get());
+ }});
+ }
+
+ /** Returns a task which waits for multiple other tasks (submitting if necessary)
+ * and performs arbitrary computation over the List of results.
+ * @see #transform(Task, Function) but note argument order is reversed (counterintuitive) to allow for varargs */
+ public static <U,T> Task<T> transformMultiple(Function<List<U>,T> transformer, @SuppressWarnings("unchecked") TaskAdaptable<U> ...tasks) {
+ return transformMultiple(MutableMap.of("displayName", "transforming multiple"), transformer, tasks);
+ }
+
+ /** @see #transformMultiple(Function, TaskAdaptable...) */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <U,T> Task<T> transformMultiple(Closure transformer, TaskAdaptable<U> ...tasks) {
+ return transformMultiple(GroovyJavaMethods.functionFromClosure(transformer), tasks);
+ }
+
+ /** @see #transformMultiple(Function, TaskAdaptable...) */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <U,T> Task<T> transformMultiple(Map flags, Closure transformer, TaskAdaptable<U> ...tasks) {
+ return transformMultiple(flags, GroovyJavaMethods.functionFromClosure(transformer), tasks);
+ }
+
+ /** @see #transformMultiple(Function, TaskAdaptable...) */
+ @SuppressWarnings({ "rawtypes" })
+ public static <U,T> Task<T> transformMultiple(Map flags, final Function<List<U>,T> transformer, @SuppressWarnings("unchecked") TaskAdaptable<U> ...tasks) {
+ return transformMultiple(flags, transformer, Arrays.asList(tasks));
+ }
+ @SuppressWarnings({ "rawtypes" })
+ public static <U,T> Task<T> transformMultiple(Map flags, final Function<List<U>,T> transformer, Collection<? extends TaskAdaptable<U>> tasks) {
+ if (tasks.size()==1) {
+ return transform(flags, Iterables.getOnlyElement(tasks), new Function<U,T>() {
+ @Override
+ @Nullable
+ public T apply(@Nullable U input) {
+ return transformer.apply(ImmutableList.of(input));
+ }
+ });
+ }
+ return transform(flags, new ParallelTask<U>(tasks), transformer);
+ }
+
+
+ /** Method which returns a Future containing a string formatted using String.format,
+ * where the arguments can be normal objects or tasks;
+ * tasks will be waited on (submitted if necessary) and their results substituted in the call
+ * to String.format.
+ * <p>
+ * Example:
+ * <pre>
+ * {@code
+ * setConfig(URL, DependentConfiguration.formatString("%s:%s",
+ * DependentConfiguration.attributeWhenReady(target, Target.HOSTNAME),
+ * DependentConfiguration.attributeWhenReady(target, Target.PORT) ) );
+ * }
+ * </pre>
+ */
+ @SuppressWarnings("unchecked")
+ public static Task<String> formatString(final String spec, final Object ...args) {
+ List<TaskAdaptable<Object>> taskArgs = Lists.newArrayList();
+ for (Object arg: args) {
+ if (arg instanceof TaskAdaptable) taskArgs.add((TaskAdaptable<Object>)arg);
+ else if (arg instanceof TaskFactory) taskArgs.add( ((TaskFactory<TaskAdaptable<Object>>)arg).newTask() );
+ }
+
+ return transformMultiple(
+ MutableMap.<String,String>of("displayName", "formatting '"+spec+"' with "+taskArgs.size()+" task"+(taskArgs.size()!=1?"s":"")),
+ new Function<List<Object>, String>() {
+ @Override public String apply(List<Object> input) {
+ Iterator<?> tri = input.iterator();
+ Object[] vv = new Object[args.length];
+ int i=0;
+ for (Object arg : args) {
+ if (arg instanceof TaskAdaptable || arg instanceof TaskFactory) vv[i] = tri.next();
+ else if (arg instanceof DeferredSupplier) vv[i] = ((DeferredSupplier<?>) arg).get();
+ else vv[i] = arg;
+ i++;
+ }
+ return String.format(spec, vv);
+ }},
+ taskArgs);
+ }
+
+ /** returns a task for parallel execution returning a list of values for the given sensor for the given entity list,
+ * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
+ public static <T> Task<List<T>> listAttributesWhenReady(AttributeSensor<T> sensor, Iterable<Entity> entities) {
+ return listAttributesWhenReady(sensor, entities, GroovyJavaMethods.truthPredicate());
+ }
+
+ public static <T> Task<List<T>> listAttributesWhenReady(AttributeSensor<T> sensor, Iterable<Entity> entities, Closure<Boolean> readiness) {
+ Predicate<Object> readinessPredicate = (readiness != null) ? GroovyJavaMethods.<Object>predicateFromClosure(readiness) : GroovyJavaMethods.truthPredicate();
+ return listAttributesWhenReady(sensor, entities, readinessPredicate);
+ }
+
+ /** returns a task for parallel execution returning a list of values of the given sensor list on the given entity,
+ * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
+ public static <T> Task<List<T>> listAttributesWhenReady(final AttributeSensor<T> sensor, Iterable<Entity> entities, Predicate<? super T> readiness) {
+ if (readiness == null) readiness = GroovyJavaMethods.truthPredicate();
+ return builder().attributeWhenReadyFromMultiple(entities, sensor, readiness).build();
+ }
+
+ /** @see #waitForTask(Task, Entity, String) */
+ public static <T> T waitForTask(Task<T> t, Entity context) throws InterruptedException {
+ return waitForTask(t, context, null);
+ }
+
+ /** blocks until the given task completes, submitting if necessary, returning the result of that task;
+ * optional contextMessage is available in status if this is running in a task
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T waitForTask(Task<T> t, Entity context, String contextMessage) throws InterruptedException {
+ try {
+ return (T) Tasks.resolveValue(t, Object.class, ((EntityInternal)context).getExecutionContext(), contextMessage);
+ } catch (ExecutionException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ public static class AttributeAndSensorCondition<T> {
+ protected final Entity source;
+ protected final AttributeSensor<T> sensor;
+ protected final Predicate<? super T> predicate;
+
+ public AttributeAndSensorCondition(Entity source, AttributeSensor<T> sensor, Predicate<? super T> predicate) {
+ this.source = checkNotNull(source, "source");
+ this.sensor = checkNotNull(sensor, "sensor");
+ this.predicate = checkNotNull(predicate, "predicate");
+ }
+ }
+
+ public static ProtoBuilder builder() {
+ return new ProtoBuilder();
+ }
+
+ /**
+ * Builder for producing variants of attributeWhenReady.
+ */
+ @Beta
+ public static class ProtoBuilder {
+ /**
+ * Will wait for the attribute on the given entity.
+ * If that entity reports {@link Lifecycle#ON_FIRE} for its {@link Attributes#SERVICE_STATE} then it will abort.
+ */
+ public <T2> Builder<T2,T2> attributeWhenReady(Entity source, AttributeSensor<T2> sensor) {
+ return new Builder<T2,T2>(source, sensor).abortIfOnFire();
+ }
+
+ /**
+ * Will wait for the attribute on the given entity, not aborting when it goes {@link Lifecycle#ON_FIRE}.
+ */
+ public <T2> Builder<T2,T2> attributeWhenReadyAllowingOnFire(Entity source, AttributeSensor<T2> sensor) {
+ return new Builder<T2,T2>(source, sensor);
+ }
+
+ /** Constructs a builder for task for parallel execution returning a list of values of the given sensor list on the given entity,
+ * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
+ @Beta
+ public <T> MultiBuilder<T, T, List<T>> attributeWhenReadyFromMultiple(Iterable<? extends Entity> sources, AttributeSensor<T> sensor) {
+ return attributeWhenReadyFromMultiple(sources, sensor, GroovyJavaMethods.truthPredicate());
+ }
+ /** As {@link #attributeWhenReadyFromMultiple(Iterable, AttributeSensor)} with an explicit readiness test. */
+ @Beta
+ public <T> MultiBuilder<T, T, List<T>> attributeWhenReadyFromMultiple(Iterable<? extends Entity> sources, AttributeSensor<T> sensor, Predicate<? super T> readiness) {
+ return new MultiBuilder<T, T, List<T>>(sources, sensor, readiness);
+ }
+ }
+
+ /**
+ * Builder for producing variants of attributeWhenReady.
+ */
+ public static class Builder<T,V> {
+ protected Entity source;
+ protected AttributeSensor<T> sensor;
+ protected Predicate<? super T> readiness;
+ protected Function<? super T, ? extends V> postProcess;
+ protected List<AttributeAndSensorCondition<?>> abortSensorConditions = Lists.newArrayList();
+ protected String blockingDetails;
+ protected Duration timeout;
+ protected Maybe<V> onTimeout;
+ protected boolean ignoreUnmanaged = WaitInTaskForAttributeReady.DEFAULT_IGNORE_UNMANAGED;
+ protected Maybe<V> onUnmanaged;
+
+ protected Builder(Entity source, AttributeSensor<T> sensor) {
+ this.source = source;
+ this.sensor = sensor;
+ }
+
+ /**
+ * Will wait for the attribute on the given entity.
+ * If that entity report {@link Lifecycle#ON_FIRE} for its {@link Attributes#SERVICE_STATE_ACTUAL} then it will abort.
+ * @deprecated since 0.7.0 use {@link DependentConfiguration#builder()} then {@link ProtoBuilder#attributeWhenReady(Entity, AttributeSensor)} then {@link #abortIfOnFire()}
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <T2> Builder<T2,T2> attributeWhenReady(Entity source, AttributeSensor<T2> sensor) {
+ this.source = checkNotNull(source, "source");
+ this.sensor = (AttributeSensor) checkNotNull(sensor, "sensor");
+ abortIfOnFire();
+ return (Builder<T2, T2>) this;
+ }
+ public Builder<T,V> readiness(Closure<Boolean> val) {
+ this.readiness = GroovyJavaMethods.predicateFromClosure(checkNotNull(val, "val"));
+ return this;
+ }
+ public Builder<T,V> readiness(Predicate<? super T> val) {
+ this.readiness = checkNotNull(val, "ready");
+ return this;
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <V2> Builder<T,V2> postProcess(Closure<V2> val) {
+ this.postProcess = (Function) GroovyJavaMethods.<T,V2>functionFromClosure(checkNotNull(val, "postProcess"));
+ return (Builder<T,V2>) this;
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public <V2> Builder<T,V2> postProcess(final Function<? super T, V2> val) {
+ this.postProcess = (Function) checkNotNull(val, "postProcess");
+ return (Builder<T,V2>) this;
+ }
+ public <T2> Builder<T,V> abortIf(Entity source, AttributeSensor<T2> sensor) {
+ return abortIf(source, sensor, GroovyJavaMethods.truthPredicate());
+ }
+ public <T2> Builder<T,V> abortIf(Entity source, AttributeSensor<T2> sensor, Predicate<? super T2> predicate) {
+ abortSensorConditions.add(new AttributeAndSensorCondition<T2>(source, sensor, predicate));
+ return this;
+ }
+ public Builder<T,V> abortIfOnFire() {
+ abortIf(source, Attributes.SERVICE_STATE_ACTUAL, Predicates.equalTo(Lifecycle.ON_FIRE));
+ return this;
+ }
+ public Builder<T,V> blockingDetails(String val) {
+ blockingDetails = val;
+ return this;
+ }
+ /** specifies an optional timeout; by default it waits forever, or until unmanaged or other abort condition */
+ public Builder<T,V> timeout(Duration val) {
+ timeout = val;
+ return this;
+ }
+ public Builder<T,V> onTimeoutReturn(V val) {
+ onTimeout = Maybe.of(val);
+ return this;
+ }
+ public Builder<T,V> onTimeoutThrow() {
+ onTimeout = Maybe.<V>absent();
+ return this;
+ }
+ public Builder<T,V> onUnmanagedReturn(V val) {
+ onUnmanaged = Maybe.of(val);
+ return this;
+ }
+ public Builder<T,V> onUnmanagedThrow() {
+ onUnmanaged = Maybe.<V>absent();
+ return this;
+ }
+ /** @since 0.7.0 included in case old behaviour of not checking whether the entity is managed is required
+ * (I can't see why it is; polling will likely give errors, once it is unmanaged this will never completed,
+ * and before management the current code will continue, so long as there are no other errors) */ @Deprecated
+ public Builder<T,V> onUnmanagedContinue() {
+ ignoreUnmanaged = true;
+ return this;
+ }
+ /** take advantage of the fact that this builder can build multiple times, allowing subclasses
+ * to change the source along the way */
+ protected Builder<T,V> source(Entity source) {
+ this.source = source;
+ return this;
+ }
+ /** as {@link #source(Entity)} */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ protected Builder<T,V> sensor(AttributeSensor<? extends T> sensor) {
+ this.sensor = (AttributeSensor) sensor;
+ return this;
+ }
+ public Task<V> build() {
+ validate();
+
+ return Tasks.<V>builder().dynamic(false)
+ .name("waiting on "+sensor.getName())
+ .description("Waiting on sensor "+sensor.getName()+" from "+source)
+ .tag("attributeWhenReady")
+ .body(new WaitInTaskForAttributeReady<T,V>(this))
+ .build();
+ }
+
+ public V runNow() {
+ validate();
+ return new WaitInTaskForAttributeReady<T,V>(this).call();
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private void validate() {
+ checkNotNull(source, "Entity source");
+ checkNotNull(sensor, "Sensor");
+ if (readiness == null) readiness = GroovyJavaMethods.truthPredicate();
+ if (postProcess == null) postProcess = (Function) Functions.identity();
+ }
+ }
+
+ /**
+ * Builder for producing variants of attributeWhenReady.
+ */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Beta
+ public static class MultiBuilder<T, V, V2> {
+ protected final String name;
+ protected final String descriptionBase;
+ protected final Builder<T,V> builder;
+ // if desired, the use of this multiSource could allow different conditions;
+ // but probably an easier API just for the caller to build the parallel task
+ protected final List<AttributeAndSensorCondition<?>> multiSource = Lists.newArrayList();
+ protected Function<? super List<V>, V2> postProcessFromMultiple;
+
+ /** returns a task for parallel execution returning a list of values of the given sensor list on the given entity,
+ * optionally when the values satisfy a given readiness predicate (defaulting to groovy truth if not supplied) */
+ @Beta
+ protected MultiBuilder(Iterable<? extends Entity> sources, AttributeSensor<T> sensor) {
+ this(sources, sensor, GroovyJavaMethods.truthPredicate());
+ }
+ @Beta
+ protected MultiBuilder(Iterable<? extends Entity> sources, AttributeSensor<T> sensor, Predicate<? super T> readiness) {
+ builder = new Builder<T,V>(null, sensor);
+ builder.readiness(readiness);
+
+ for (Entity s : checkNotNull(sources, "sources")) {
+ multiSource.add(new AttributeAndSensorCondition<T>(s, sensor, readiness));
+ }
+ this.name = "waiting on "+sensor.getName();
+ this.descriptionBase = "waiting on "+sensor.getName()+" "+readiness
+ +" from "+Iterables.size(sources)+" entit"+Strings.ies(sources);
+ }
+
+ /** Apply post-processing to the entire list of results */
+ public <V2b> MultiBuilder<T, V, V2b> postProcessFromMultiple(final Function<? super List<V>, V2b> val) {
+ this.postProcessFromMultiple = (Function) checkNotNull(val, "postProcessFromMulitple");
+ return (MultiBuilder<T,V, V2b>) this;
+ }
+ /** Apply post-processing to the entire list of results
+ * See {@link CollectionFunctionals#all(Predicate)} and {@link CollectionFunctionals#quorum(org.apache.brooklyn.util.collections.QuorumCheck, Predicate)
+ * which allow useful arguments. */
+ public MultiBuilder<T, V, Boolean> postProcessFromMultiple(final Predicate<? super List<V>> val) {
+ return postProcessFromMultiple(Functions.forPredicate(val));
+ }
+
+ public <V1> MultiBuilder<T, V1, V2> postProcess(Closure<V1> val) {
+ builder.postProcess(val);
+ return (MultiBuilder<T, V1, V2>) this;
+ }
+ public <V1> MultiBuilder<T, V1, V2> postProcess(final Function<? super T, V1> val) {
+ builder.postProcess(val);
+ return (MultiBuilder<T, V1, V2>) this;
+ }
+ public <T2> MultiBuilder<T, V, V2> abortIf(Entity source, AttributeSensor<T2> sensor) {
+ builder.abortIf(source, sensor);
+ return this;
+ }
+ public <T2> MultiBuilder<T, V, V2> abortIf(Entity source, AttributeSensor<T2> sensor, Predicate<? super T2> predicate) {
+ builder.abortIf(source, sensor, predicate);
+ return this;
+ }
+ public MultiBuilder<T, V, V2> abortIfOnFire() {
+ builder.abortIfOnFire();
+ return this;
+ }
+ public MultiBuilder<T, V, V2> blockingDetails(String val) {
+ builder.blockingDetails(val);
+ return this;
+ }
+ public MultiBuilder<T, V, V2> timeout(Duration val) {
+ builder.timeout(val);
+ return this;
+ }
+ public MultiBuilder<T, V, V2> onTimeoutReturn(V val) {
+ builder.onTimeoutReturn(val);
+ return this;
+ }
+ public MultiBuilder<T, V, V2> onTimeoutThrow() {
+ builder.onTimeoutThrow();
+ return this;
+ }
+ public MultiBuilder<T, V, V2> onUnmanagedReturn(V val) {
+ builder.onUnmanagedReturn(val);
+ return this;
+ }
+ public MultiBuilder<T, V, V2> onUnmanagedThrow() {
+ builder.onUnmanagedThrow();
+ return this;
+ }
+
+ public Task<V2> build() {
+ List<Task<V>> tasks = MutableList.of();
+ for (AttributeAndSensorCondition<?> source: multiSource) {
+ builder.source(source.source);
+ builder.sensor((AttributeSensor)source.sensor);
+ builder.readiness((Predicate)source.predicate);
+ tasks.add(builder.build());
+ }
+ final Task<List<V>> parallelTask = Tasks.<List<V>>builder().parallel(true).addAll(tasks)
+ .name(name)
+ .description(descriptionBase+
+ (builder.timeout!=null ? ", timeout "+builder.timeout : ""))
+ .build();
+
+ if (postProcessFromMultiple == null) {
+ // V2 should be the right type in normal operations
+ return (Task<V2>) parallelTask;
+ } else {
+ return Tasks.<V2>builder().name(name).description(descriptionBase)
+ .tag("attributeWhenReady")
+ .body(new Callable<V2>() {
+ @Override public V2 call() throws Exception {
+ List<V> prePostProgress = DynamicTasks.queue(parallelTask).get();
+ return DynamicTasks.queue(
+ Tasks.<V2>builder().name("post-processing").description("Applying "+postProcessFromMultiple)
+ .body(Functionals.callable(postProcessFromMultiple, prePostProgress))
+ .build()).get();
+ }
+ })
+ .build();
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
new file mode 100644
index 0000000..79660ce
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/HttpRequestSensor.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import java.net.URI;
+
+import net.minidev.json.JSONObject;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.AddSensor;
+import org.apache.brooklyn.sensor.feed.http.HttpFeed;
+import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
+import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Functions;
+import com.google.common.base.Supplier;
+
+/**
+ * Configurable {@link org.apache.brooklyn.api.entity.EntityInitializer} which adds an HTTP sensor feed to retrieve the
+ * {@link JSONObject} from a JSON response in order to populate the sensor with the data at the {@code jsonPath}.
+ *
+ * @see SshCommandSensor
+ * @see JmxAttributeSensor
+ */
+@Beta
+public final class HttpRequestSensor<T> extends AddSensor<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(HttpRequestSensor.class);
+
+ public static final ConfigKey<String> SENSOR_URI = ConfigKeys.newStringConfigKey("uri", "HTTP URI to poll for JSON");
+ public static final ConfigKey<String> JSON_PATH = ConfigKeys.newStringConfigKey("jsonPath", "JSON path to select in HTTP response; default $", "$");
+ public static final ConfigKey<String> USERNAME = ConfigKeys.newStringConfigKey("username", "Username for HTTP request, if required");
+ public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password", "Password for HTTP request, if required");
+
+ protected final Supplier<URI> uri;
+ protected final String jsonPath;
+ protected final String username;
+ protected final String password;
+
+ public HttpRequestSensor(final ConfigBag params) {
+ super(params);
+
+ uri = new Supplier<URI>() {
+ @Override
+ public URI get() {
+ return URI.create(params.get(SENSOR_URI));
+ }
+ };
+ jsonPath = params.get(JSON_PATH);
+ username = params.get(USERNAME);
+ password = params.get(PASSWORD);
+ }
+
+ @Override
+ public void apply(final EntityLocal entity) {
+ super.apply(entity);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Adding HTTP JSON sensor {} to {}", name, entity);
+ }
+
+ HttpPollConfig<T> pollConfig = new HttpPollConfig<T>(sensor)
+ .checkSuccess(HttpValueFunctions.responseCodeEquals(200))
+ .onFailureOrException(Functions.constant((T) null))
+ .onSuccess(HttpValueFunctions.<T>jsonContentsFromPath(jsonPath))
+ .period(period);
+
+ HttpFeed.builder().entity(entity)
+ .baseUri(uri)
+ .credentialsIfNotNull(username, password)
+ .poll(pollConfig)
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/PortAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/PortAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/core/sensor/PortAttributeSensorAndConfigKey.java
new file mode 100644
index 0000000..3de0de6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/PortAttributeSensorAndConfigKey.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.api.location.PortSupplier;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.core.internal.BrooklynInitialization;
+import org.apache.brooklyn.core.location.Locations;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+/**
+ * A {@link Sensor} describing a port on a system,
+ * with a {@link ConfigKey} which can be configured with a port range
+ * (either a number e.g. 80, or a string e.g. "80" or "8080-8089" or even "80, 8080-8089, 8800+", or a list of these).
+ * <p>
+ * To convert at runtime a single port is chosen, respecting the entity.
+ */
+public class PortAttributeSensorAndConfigKey extends AttributeSensorAndConfigKey<PortRange,Integer> {
+
+ private static final long serialVersionUID = 4680651022807491321L;
+
+ public static final Logger LOG = LoggerFactory.getLogger(PortAttributeSensorAndConfigKey.class);
+
+ static { BrooklynInitialization.initAll(); }
+
+ public PortAttributeSensorAndConfigKey(String name) {
+ this(name, name, null);
+ }
+ public PortAttributeSensorAndConfigKey(String name, String description) {
+ this(name, description, null);
+ }
+ public PortAttributeSensorAndConfigKey(String name, String description, Object defaultValue) {
+ super(PortRange.class, Integer.class, name, description, defaultValue);
+ }
+ public PortAttributeSensorAndConfigKey(PortAttributeSensorAndConfigKey orig, Object defaultValue) {
+ super(orig, TypeCoercions.coerce(defaultValue, PortRange.class));
+ }
+ @Override
+ protected Integer convertConfigToSensor(PortRange value, Entity entity) {
+ if (value==null) return null;
+ Collection<? extends Location> locations = entity.getLocations();
+ if (!locations.isEmpty()) {
+ Maybe<? extends Location> lo = Locations.findUniqueMachineLocation(locations);
+ if (!lo.isPresent()) {
+ // Try a unique location which isn't a machine provisioner
+ Iterator<? extends Location> li = Iterables.filter(locations,
+ Predicates.not(Predicates.instanceOf(MachineProvisioningLocation.class))).iterator();
+ if (li.hasNext()) lo = Maybe.of(li.next());
+ if (li.hasNext()) lo = Maybe.absent();
+ }
+ // Fall back to selecting the single location
+ if (!lo.isPresent() && locations.size() == 1) {
+ lo = Maybe.of(locations.iterator().next());
+ }
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Convert config to sensor for {} found locations: {}. Selected: {}", new Object[] {entity, locations, lo});
+ }
+ if (lo.isPresent()) {
+ Location l = lo.get();
+ Optional<Boolean> locationRunning = Optional.fromNullable(l.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START_IF_RUNNING));
+ Optional<Boolean> entityRunning = Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START_IF_RUNNING));
+ Optional<Boolean> locationInstalled = Optional.fromNullable(l.getConfig(BrooklynConfigKeys.SKIP_ENTITY_INSTALLATION));
+ Optional<Boolean> entityInstalled = Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_INSTALLATION));
+ Optional<Boolean> entityStarted = Optional.fromNullable(entity.getConfig(BrooklynConfigKeys.SKIP_ENTITY_START));
+ boolean skipCheck = locationRunning.or(entityRunning).or(locationInstalled).or(entityInstalled).or(entityStarted).or(false);
+ if (l instanceof PortSupplier) {
+ int p = ((PortSupplier) l).obtainPort(value);
+ if (p != -1) {
+ LOG.debug("{}: choosing port {} for {}", new Object[] { entity, p, getName() });
+ return p;
+ }
+ // If we are not skipping install or already started, fail now
+ if (!skipCheck) {
+ int rangeSize = Iterables.size(value);
+ if (rangeSize == 0) {
+ LOG.warn("{}: no port available for {} (empty range {})", new Object[] { entity, getName(), value });
+ } else if (rangeSize == 1) {
+ Integer pp = value.iterator().next();
+ if (pp > 1024) {
+ LOG.warn("{}: port {} not available for {}", new Object[] { entity, pp, getName() });
+ } else {
+ LOG.warn("{}: port {} not available for {} (root may be required?)", new Object[] { entity, pp, getName() });
+ }
+ } else {
+ LOG.warn("{}: no port available for {} (tried range {})", new Object[] { entity, getName(), value });
+ }
+ return null; // Definitively, no ports available
+ }
+ }
+ // Ports may be available, we just can't tell from the location
+ Integer v = (value.isEmpty() ? null : value.iterator().next());
+ LOG.debug("{}: choosing port {} (unconfirmed) for {}", new Object[] { entity, v, getName() });
+ return v;
+ } else {
+ LOG.warn("{}: ports not applicable, or not yet applicable, because has multiple locations {}; ignoring ", new Object[] { entity, locations, getName() });
+ }
+ } else {
+ LOG.warn("{}: ports not applicable, or not yet applicable, bacause has no locations; ignoring {}", entity, getName());
+ }
+ return null;
+ }
+
+ @Override
+ protected Integer convertConfigToSensor(PortRange value, ManagementContext managementContext) {
+ LOG.warn("ports not applicable, because given managementContext rather than entity; ignoring {}", getName());
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java b/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java
new file mode 100644
index 0000000..05227d0
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/Sensors.java
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URL;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.AttributeSensor.SensorPersistenceMode;
+import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.util.net.UserAndHostAndPort;
+import org.apache.brooklyn.util.text.StringFunctions;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.net.HostAndPort;
+import com.google.common.reflect.TypeToken;
+
+public class Sensors {
+
+ @Beta
+ public static <T> Builder<T> builder(TypeToken<T> type, String name) {
+ return new Builder<T>().type(type).name(name);
+ }
+
+ @Beta
+ public static <T> Builder<T> builder(Class<T> type, String name) {
+ return new Builder<T>().type(type).name(name);
+ }
+
+ @Beta
+ public static class Builder<T> {
+ private String name;
+ private TypeToken<T> type;
+ private String description;
+ private SensorPersistenceMode persistence;
+
+ protected Builder() { // use builder(type, name) instead
+ }
+ public Builder<T> name(String val) {
+ this.name = checkNotNull(val, "name"); return this;
+ }
+ public Builder<T> type(Class<T> val) {
+ return type(TypeToken.of(val));
+ }
+ public Builder<T> type(TypeToken<T> val) {
+ this.type = checkNotNull(val, "type"); return this;
+ }
+ public Builder<T> description(String val) {
+ this.description = val; return this;
+ }
+ public Builder<T> persistence(SensorPersistenceMode val) {
+ this.persistence = val; return this;
+ }
+ public AttributeSensor<T> build() {
+ return new BasicAttributeSensor<T>(type, name, description, persistence);
+ }
+ }
+
+ public static <T> AttributeSensor<T> newSensor(Class<T> type, String name) {
+ return new BasicAttributeSensor<T>(type, name);
+ }
+
+ public static <T> AttributeSensor<T> newSensor(Class<T> type, String name, String description) {
+ return new BasicAttributeSensor<T>(type, name, description);
+ }
+
+ public static <T> AttributeSensor<T> newSensor(TypeToken<T> type, String name, String description) {
+ return new BasicAttributeSensor<T>(type, name, description);
+ }
+
+ public static AttributeSensor<String> newStringSensor(String name) {
+ return newSensor(String.class, name);
+ }
+
+ public static AttributeSensor<String> newStringSensor(String name, String description) {
+ return newSensor(String.class, name, description);
+ }
+
+ public static AttributeSensor<Integer> newIntegerSensor(String name) {
+ return newSensor(Integer.class, name);
+ }
+
+ public static AttributeSensor<Integer> newIntegerSensor(String name, String description) {
+ return newSensor(Integer.class, name, description);
+ }
+
+ public static AttributeSensor<Long> newLongSensor(String name) {
+ return newSensor(Long.class, name);
+ }
+
+ public static AttributeSensor<Long> newLongSensor(String name, String description) {
+ return newSensor(Long.class, name, description);
+ }
+
+ public static AttributeSensor<Double> newDoubleSensor(String name) {
+ return newSensor(Double.class, name);
+ }
+
+ public static AttributeSensor<Double> newDoubleSensor(String name, String description) {
+ return newSensor(Double.class, name, description);
+ }
+
+ public static AttributeSensor<Boolean> newBooleanSensor(String name) {
+ return newSensor(Boolean.class, name);
+ }
+
+ public static AttributeSensor<Boolean> newBooleanSensor(String name, String description) {
+ return newSensor(Boolean.class, name, description);
+ }
+
+ // Extensions to sensors
+
+ public static <T> AttributeSensor<T> newSensorRenamed(String newName, AttributeSensor<T> sensor) {
+ return new BasicAttributeSensor<T>(sensor.getTypeToken(), newName, sensor.getDescription());
+ }
+
+ public static <T> AttributeSensor<T> newSensorWithPrefix(String prefix, AttributeSensor<T> sensor) {
+ return newSensorRenamed(prefix+sensor.getName(), sensor);
+ }
+
+ // Display hints for common utility objects
+
+ static {
+ RendererHints.register(Duration.class, RendererHints.displayValue(Time.fromDurationToTimeStringRounded()));
+ RendererHints.register(HostAndPort.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
+ RendererHints.register(UserAndHostAndPort.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
+ RendererHints.register(InetAddress.class, RendererHints.displayValue(new Function<InetAddress,String>() {
+ @Override
+ public String apply(@Nullable InetAddress input) {
+ return input == null ? null : input.getHostAddress();
+ }
+ }));
+
+ RendererHints.register(URL.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
+ RendererHints.register(URL.class, RendererHints.openWithUrl(StringFunctions.toStringFunction()));
+ RendererHints.register(URI.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
+ RendererHints.register(URI.class, RendererHints.openWithUrl(StringFunctions.toStringFunction()));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
new file mode 100644
index 0000000..4a7b1d4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.AddSensor;
+import org.apache.brooklyn.sensor.enricher.Propagator;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ValueResolver;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Supplier;
+
+/**
+ * Provides an initializer/feed which simply sets a given value.
+ * <p>
+ * {@link Task}/{@link Supplier} values are resolved when written,
+ * unlike config values which are resolved on each read.
+ * <p>
+ * This supports a {@link StaticSensor#SENSOR_PERIOD}
+ * which can be useful if the supplied value is such a function.
+ * However when the source is another sensor,
+ * consider using {@link Propagator} which listens for changes instead. */
+public class StaticSensor<T> extends AddSensor<T> {
+
+ private static final Logger log = LoggerFactory.getLogger(StaticSensor.class);
+
+ public static final ConfigKey<Object> STATIC_VALUE = ConfigKeys.newConfigKey(Object.class, "static.value");
+
+ private final Object value;
+
+ public StaticSensor(ConfigBag params) {
+ super(params);
+ value = params.get(STATIC_VALUE);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void apply(EntityLocal entity) {
+ super.apply(entity);
+
+ Maybe<T> v = Tasks.resolving(value).as((Class<T>)sensor.getType()).timeout(ValueResolver.PRETTY_QUICK_WAIT).getMaybe();
+ if (v.isPresent()) {
+ log.debug(this+" setting sensor "+sensor+" to "+v.get());
+ entity.setAttribute(sensor, v.get());
+ } else {
+ log.debug(this+" not setting sensor "+sensor+"; cannot resolve "+value);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/TemplatedStringAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/TemplatedStringAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/core/sensor/TemplatedStringAttributeSensorAndConfigKey.java
new file mode 100644
index 0000000..953b7d8
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/TemplatedStringAttributeSensorAndConfigKey.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.util.core.text.TemplateProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * A {@link ConfigKey} which takes a freemarker-templated string,
+ * and whose value is converted to a sensor by processing the template
+ * with access to config and methods on the entity where it is set.
+ */
+public class TemplatedStringAttributeSensorAndConfigKey extends BasicAttributeSensorAndConfigKey<String> {
+ private static final long serialVersionUID = 4680651022807491321L;
+
+ public static final Logger LOG = LoggerFactory.getLogger(TemplatedStringAttributeSensorAndConfigKey.class);
+
+ public TemplatedStringAttributeSensorAndConfigKey(String name) {
+ this(name, name, null);
+ }
+ public TemplatedStringAttributeSensorAndConfigKey(String name, String description) {
+ this(name, description, null);
+ }
+ public TemplatedStringAttributeSensorAndConfigKey(String name, String description, String defaultValue) {
+ super(String.class, name, description, defaultValue);
+ }
+ public TemplatedStringAttributeSensorAndConfigKey(TemplatedStringAttributeSensorAndConfigKey orig, String defaultValue) {
+ super(orig, defaultValue);
+ }
+
+ @Override
+ protected String convertConfigToSensor(String value, Entity entity) {
+ if (value == null) return null;
+ return TemplateProcessor.processTemplateContents(value, (EntityInternal)entity, ImmutableMap.<String,Object>of());
+ }
+
+ @Override
+ protected String convertConfigToSensor(String value, ManagementContext managementContext) {
+ if (value == null) return null;
+ return TemplateProcessor.processTemplateContents(value, (ManagementContextInternal)managementContext, ImmutableMap.<String,Object>of());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/server/entity/BrooklynMetrics.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/server/entity/BrooklynMetrics.java b/core/src/main/java/org/apache/brooklyn/core/server/entity/BrooklynMetrics.java
index 5f060c2..6e9cef5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/server/entity/BrooklynMetrics.java
+++ b/core/src/main/java/org/apache/brooklyn/core/server/entity/BrooklynMetrics.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.core.server.entity;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@ImplementedBy(BrooklynMetricsImpl.class)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
index 00710ca..aa9ca90 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/AbstractGroup.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
import org.apache.brooklyn.core.entity.trait.Changeable;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.collections.QuorumCheck;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
index bf39663..b6ee23a 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
@@ -38,11 +38,11 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.factory.EntityFactory;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.MemberReplaceable;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.zoneaware.BalancingNodePlacementStrategy;
import org.apache.brooklyn.entity.group.zoneaware.ProportionalZoneFailureDetector;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabric.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabric.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabric.java
index fc53c21..943ed9b 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabric.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabric.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.factory.EntityFactory;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
index bb43d3b..c06aa58 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.base.Predicate;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroup.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroup.java
index 5e9b75f..048a304 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroup.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicMultiGroup.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntity.java b/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntity.java
index 645426a..793bac6 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/stock/DelegateEntity.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.render.RendererHints;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import com.google.common.base.Function;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java b/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
index 0d5828d..0945407 100644
--- a/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
+++ b/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.core.Sensors;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeMap.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeMap.java b/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeMap.java
deleted file mode 100644
index 4125a96..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/AttributeMap.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.BrooklynLogging;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-
-/**
- * A {@link Map} of {@link Entity} attribute values.
- */
-public final class AttributeMap implements Serializable {
-
- private static final long serialVersionUID = -6834883734250888344L;
-
- static final Logger log = LoggerFactory.getLogger(AttributeMap.class);
-
- private static enum Marker {
- NULL;
- }
-
- private final AbstractEntity entity;
-
- // Assumed to be something like a ConcurrentMap passed in.
- private final Map<Collection<String>, Object> values;
-
- /**
- * Creates a new AttributeMap.
- *
- * @param entity the EntityLocal this AttributeMap belongs to.
- * @throws IllegalArgumentException if entity is null
- */
- public AttributeMap(AbstractEntity entity, Map<Collection<String>, Object> storage) {
- this.entity = checkNotNull(entity, "entity must be specified");
- this.values = checkNotNull(storage, "storage map must not be null");
- }
-
- public Map<Collection<String>, Object> asRawMap() {
- return ImmutableMap.copyOf(values);
- }
-
- public Map<String, Object> asMap() {
- Map<String, Object> result = Maps.newLinkedHashMap();
- for (Map.Entry<Collection<String>, Object> entry : values.entrySet()) {
- String sensorName = Joiner.on('.').join(entry.getKey());
- Object val = (isNull(entry.getValue())) ? null : entry.getValue();
- result.put(sensorName, val);
- }
- return result;
- }
-
- /**
- * Updates the value.
- *
- * @param path the path to the value.
- * @param newValue the new value
- * @return the old value.
- * @throws IllegalArgumentException if path is null or empty
- */
- // TODO path must be ordered(and legal to contain duplicates like "a.b.a"; list would be better
- public <T> T update(Collection<String> path, T newValue) {
- checkPath(path);
-
- if (newValue == null) {
- newValue = typedNull();
- }
-
- if (log.isTraceEnabled()) {
- log.trace("setting sensor {}={} for {}", new Object[] {path, newValue, entity});
- }
-
- @SuppressWarnings("unchecked")
- T oldValue = (T) values.put(path, newValue);
- return (isNull(oldValue)) ? null : oldValue;
- }
-
- private void checkPath(Collection<String> path) {
- Preconditions.checkNotNull(path, "path can't be null");
- Preconditions.checkArgument(!path.isEmpty(), "path can't be empty");
- }
-
- public <T> T update(AttributeSensor<T> attribute, T newValue) {
- T oldValue = updateWithoutPublishing(attribute, newValue);
- entity.emitInternal(attribute, newValue);
- return oldValue;
- }
-
- public <T> T updateWithoutPublishing(AttributeSensor<T> attribute, T newValue) {
- if (log.isTraceEnabled()) {
- Object oldValue = getValue(attribute);
- if (!Objects.equal(oldValue, newValue != null)) {
- log.trace("setting attribute {} to {} (was {}) on {}", new Object[] {attribute.getName(), newValue, oldValue, entity});
- } else {
- log.trace("setting attribute {} to {} (unchanged) on {}", new Object[] {attribute.getName(), newValue, this});
- }
- }
-
- T oldValue = (T) update(attribute.getNameParts(), newValue);
-
- return (isNull(oldValue)) ? null : oldValue;
- }
-
- /**
- * Where atomicity is desired, the methods in this class synchronize on the {@link #values} map.
- */
- public <T> T modify(AttributeSensor<T> attribute, Function<? super T, Maybe<T>> modifier) {
- synchronized (values) {
- T oldValue = getValue(attribute);
- Maybe<? extends T> newValue = modifier.apply(oldValue);
-
- if (newValue.isPresent()) {
- if (log.isTraceEnabled()) log.trace("modified attribute {} to {} (was {}) on {}", new Object[] {attribute.getName(), newValue, oldValue, entity});
- return update(attribute, newValue.get());
- } else {
- if (log.isTraceEnabled()) log.trace("modified attribute {} unchanged; not emitting on {}", new Object[] {attribute.getName(), newValue, this});
- return oldValue;
- }
- }
- }
-
- public void remove(AttributeSensor<?> attribute) {
- BrooklynLogging.log(log, BrooklynLogging.levelDebugOrTraceIfReadOnly(entity),
- "removing attribute {} on {}", attribute.getName(), entity);
-
- remove(attribute.getNameParts());
- }
-
- // TODO path must be ordered(and legal to contain duplicates like "a.b.a"; list would be better
- public void remove(Collection<String> path) {
- checkPath(path);
-
- if (log.isTraceEnabled()) {
- log.trace("removing sensor {} for {}", new Object[] {path, entity});
- }
-
- values.remove(path);
- }
-
- /**
- * Gets the value
- *
- * @param path the path of the value to get
- * @return the value
- * @throws IllegalArgumentException path is null or empty.
- */
- public Object getValue(Collection<String> path) {
- // TODO previously this would return a map of the sub-tree if the path matched a prefix of a group of sensors,
- // or the leaf value if only one value. Arguably that is not required - what is/was the use-case?
- //
- checkPath(path);
- Object result = values.get(path);
- return (isNull(result)) ? null : result;
- }
-
- @SuppressWarnings("unchecked")
- public <T> T getValue(AttributeSensor<T> sensor) {
- return (T) TypeCoercions.coerce(getValue(sensor.getNameParts()), sensor.getType());
- }
-
- @SuppressWarnings("unchecked")
- private <T> T typedNull() {
- return (T) Marker.NULL;
- }
-
- private boolean isNull(Object t) {
- return t == Marker.NULL;
- }
-}
[25/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
new file mode 100644
index 0000000..d34d0a5
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
@@ -0,0 +1,412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.windows;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.PollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * A sensor feed that retrieves performance counters from a Windows host and posts the values to sensors.
+ *
+ * <p>To use this feed, you must provide the entity, and a collection of mappings between Windows performance counter
+ * names and Brooklyn attribute sensors.</p>
+ *
+ * <p>This feed uses SSH to invoke the windows utility <tt>typeperf</tt> to query for a specific set of performance
+ * counters, by name. The values are extracted from the response, and published to the entity's sensors.</p>
+ *
+ * <p>Example:</p>
+ *
+ * {@code
+ * @Override
+ * protected void connectSensors() {
+ * WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
+ * .entity(entity)
+ * .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
+ * .addSensor("\\Memory\\Available MBytes", AVAILABLE_MEMORY)
+ * .build();
+ * }
+ * }
+ *
+ * @since 0.6.0
+ * @author richardcloudsoft
+ */
+public class WindowsPerformanceCounterFeed extends AbstractFeed {
+
+ private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeed.class);
+
+ // This pattern matches CSV line(s) with the date in the first field, and at least one further field.
+ protected static final Pattern lineWithPerfData = Pattern.compile("^\"[\\d:/\\-. ]+\",\".*\"$", Pattern.MULTILINE);
+ private static final Joiner JOINER_ON_SPACE = Joiner.on(' ');
+ private static final Joiner JOINER_ON_COMMA = Joiner.on(',');
+ private static final int OUTPUT_COLUMN_WIDTH = 100;
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<Collection<WindowsPerformanceCounterPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<Collection<WindowsPerformanceCounterPollConfig<?>>>() {},
+ "polls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private Set<WindowsPerformanceCounterPollConfig<?>> polls = Sets.newLinkedHashSet();
+ private Duration period = Duration.of(30, TimeUnit.SECONDS);
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = checkNotNull(val, "entity");
+ return this;
+ }
+ public Builder addSensor(WindowsPerformanceCounterPollConfig<?> config) {
+ polls.add(config);
+ return this;
+ }
+ public Builder addSensor(String performanceCounterName, AttributeSensor<?> sensor) {
+ return addSensor(new WindowsPerformanceCounterPollConfig(sensor).performanceCounterName(checkNotNull(performanceCounterName, "performanceCounterName")));
+ }
+ public Builder addSensors(Map<String, AttributeSensor> sensors) {
+ for (Map.Entry<String, AttributeSensor> entry : sensors.entrySet()) {
+ addSensor(entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+ public Builder period(Duration period) {
+ this.period = checkNotNull(period, "period");
+ return this;
+ }
+ public Builder period(long millis) {
+ return period(millis, TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long val, TimeUnit units) {
+ return period(Duration.of(val, units));
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public WindowsPerformanceCounterFeed build() {
+ built = true;
+ WindowsPerformanceCounterFeed result = new WindowsPerformanceCounterFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("WindowsPerformanceCounterFeed.Builder created, but build() never called");
+ }
+ }
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public WindowsPerformanceCounterFeed() {
+ }
+
+ protected WindowsPerformanceCounterFeed(Builder builder) {
+ List<WindowsPerformanceCounterPollConfig<?>> polls = Lists.newArrayList();
+ for (WindowsPerformanceCounterPollConfig<?> config : builder.polls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ WindowsPerformanceCounterPollConfig<?> configCopy = new WindowsPerformanceCounterPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
+ polls.add(configCopy);
+ }
+ config().set(POLLS, polls);
+ initUniqueTag(builder.uniqueTag, polls);
+ }
+
+ @Override
+ protected void preStart() {
+ Collection<WindowsPerformanceCounterPollConfig<?>> polls = getConfig(POLLS);
+
+ long minPeriod = Integer.MAX_VALUE;
+ List<String> performanceCounterNames = Lists.newArrayList();
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ minPeriod = Math.min(minPeriod, config.getPeriod());
+ performanceCounterNames.add(config.getPerformanceCounterName());
+ }
+
+ Iterable<String> allParams = ImmutableList.<String>builder()
+ .add("(Get-Counter")
+ .add("-Counter")
+ .add(JOINER_ON_COMMA.join(Iterables.transform(performanceCounterNames, QuoteStringFunction.INSTANCE)))
+ .add("-SampleInterval")
+ .add("2") // TODO: extract SampleInterval as a config key
+ .add(").CounterSamples")
+ .add("|")
+ .add("Format-Table")
+ .add(String.format("@{Expression={$_.Path};width=%d},@{Expression={$_.CookedValue};width=%<d}", OUTPUT_COLUMN_WIDTH))
+ .add("-HideTableHeaders")
+ .add("|")
+ .add("Out-String")
+ .add("-Width")
+ .add(String.valueOf(OUTPUT_COLUMN_WIDTH * 2))
+ .build();
+ String command = JOINER_ON_SPACE.join(allParams);
+ log.debug("Windows performance counter poll command for {} will be: {}", entity, command);
+
+ GetPerformanceCountersJob<WinRmToolResponse> job = new GetPerformanceCountersJob(getEntity(), command);
+ getPoller().scheduleAtFixedRate(
+ new CallInEntityExecutionContext(entity, job),
+ new SendPerfCountersToSensors(getEntity(), polls),
+ minPeriod);
+ }
+
+ private static class GetPerformanceCountersJob<T> implements Callable<T> {
+
+ private final Entity entity;
+ private final String command;
+
+ GetPerformanceCountersJob(Entity entity, String command) {
+ this.entity = entity;
+ this.command = command;
+ }
+
+ @Override
+ public T call() throws Exception {
+ WinRmMachineLocation machine = EffectorTasks.getWinRmMachine(entity);
+ WinRmToolResponse response = machine.executePsScript(command);
+ return (T)response;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Poller<WinRmToolResponse> getPoller() {
+ return (Poller<WinRmToolResponse>) super.getPoller();
+ }
+
+ /**
+ * A {@link java.util.concurrent.Callable} that wraps another {@link java.util.concurrent.Callable}, where the
+ * inner {@link java.util.concurrent.Callable} is executed in the context of a
+ * specific entity.
+ *
+ * @param <T> The type of the {@link java.util.concurrent.Callable}.
+ */
+ private static class CallInEntityExecutionContext<T> implements Callable<T> {
+ private final Callable<T> job;
+ private EntityLocal entity;
+
+ private CallInEntityExecutionContext(EntityLocal entity, Callable<T> job) {
+ this.job = job;
+ this.entity = entity;
+ }
+
+ @Override
+ public T call() throws Exception {
+ ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext();
+ return executionContext.submit(Maps.newHashMap(), job).get();
+ }
+ }
+
+ @VisibleForTesting
+ static class SendPerfCountersToSensors implements PollHandler<WinRmToolResponse> {
+ private final EntityLocal entity;
+ private final List<WindowsPerformanceCounterPollConfig<?>> polls;
+ private final Set<AttributeSensor<?>> failedAttributes = Sets.newLinkedHashSet();
+ private static final Pattern MACHINE_NAME_LOOKBACK_PATTERN = Pattern.compile(String.format("(?<=\\\\\\\\.{0,%d})\\\\.*", OUTPUT_COLUMN_WIDTH));
+
+ public SendPerfCountersToSensors(EntityLocal entity, Collection<WindowsPerformanceCounterPollConfig<?>> polls) {
+ this.entity = entity;
+ this.polls = ImmutableList.copyOf(polls);
+ }
+
+ @Override
+ public boolean checkSuccess(WinRmToolResponse val) {
+ // TODO not just using statusCode; also looking at absence of stderr.
+ // Status code is (empirically) unreliable: it returns 0 sometimes even when failed
+ // (but never returns non-zero on success).
+ if (val.getStatusCode() != 0) return false;
+ String stderr = val.getStdErr();
+ if (stderr == null || stderr.length() != 0) return false;
+ String out = val.getStdOut();
+ if (out == null || out.length() == 0) return false;
+ return true;
+ }
+
+ @Override
+ public void onSuccess(WinRmToolResponse val) {
+ for (String pollResponse : val.getStdOut().split("\r\n")) {
+ if (Strings.isNullOrEmpty(pollResponse)) {
+ continue;
+ }
+ String path = pollResponse.substring(0, OUTPUT_COLUMN_WIDTH - 1);
+ // The performance counter output prepends the sensor name with "\\<machinename>" so we need to remove it
+ Matcher machineNameLookbackMatcher = MACHINE_NAME_LOOKBACK_PATTERN.matcher(path);
+ if (!machineNameLookbackMatcher.find()) {
+ continue;
+ }
+ String name = machineNameLookbackMatcher.group(0).trim();
+ String rawValue = pollResponse.substring(OUTPUT_COLUMN_WIDTH).replaceAll("^\\s+", "");
+ WindowsPerformanceCounterPollConfig<?> config = getPollConfig(name);
+ Class<?> clazz = config.getSensor().getType();
+ AttributeSensor<Object> attribute = (AttributeSensor<Object>) Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
+ try {
+ Object value = TypeCoercions.coerce(rawValue, TypeToken.of(clazz));
+ entity.setAttribute(attribute, value);
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ if (failedAttributes.add(attribute)) {
+ log.warn("Failed to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
+ } else {
+ if (log.isTraceEnabled()) log.trace("Failed (repeatedly) to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(WinRmToolResponse val) {
+ log.error("Windows Performance Counter query did not respond as expected. exitcode={} stdout={} stderr={}",
+ new Object[]{val.getStatusCode(), val.getStdOut(), val.getStdErr()});
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ Class<?> clazz = config.getSensor().getType();
+ AttributeSensor<?> attribute = Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
+ entity.setAttribute(attribute, null);
+ }
+ }
+
+ @Override
+ public void onException(Exception exception) {
+ log.error("Detected exception while retrieving Windows Performance Counters from entity " +
+ entity.getDisplayName(), exception);
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ entity.setAttribute(Sensors.newSensor(config.getSensor().getClass(), config.getPerformanceCounterName(), config.getDescription()), null);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "" + polls;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString()+"["+getDescription()+"]";
+ }
+
+ private WindowsPerformanceCounterPollConfig<?> getPollConfig(String sensorName) {
+ for (WindowsPerformanceCounterPollConfig<?> poll : polls) {
+ if (poll.getPerformanceCounterName().equalsIgnoreCase(sensorName)) {
+ return poll;
+ }
+ }
+ throw new IllegalStateException(String.format("%s not found in configured polls: %s", sensorName, polls));
+ }
+ }
+
+ static class PerfCounterValueIterator implements Iterator<String> {
+
+ // This pattern matches the contents of the first field, and optionally matches the rest of the line as
+ // further fields. Feed the second match back into the pattern again to get the next field, and repeat until
+ // all fields are discovered.
+ protected static final Pattern splitPerfData = Pattern.compile("^\"([^\\\"]*)\"((,\"[^\\\"]*\")*)$");
+
+ private Matcher matcher;
+
+ public PerfCounterValueIterator(String input) {
+ matcher = splitPerfData.matcher(input);
+ // Throw away the first element (the timestamp) (and also confirm that we have a pattern match)
+ checkArgument(hasNext(), "input "+input+" does not match expected pattern "+splitPerfData.pattern());
+ next();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return matcher != null && matcher.find();
+ }
+
+ @Override
+ public String next() {
+ String next = matcher.group(1);
+
+ String remainder = matcher.group(2);
+ if (!Strings.isNullOrEmpty(remainder)) {
+ assert remainder.startsWith(",");
+ remainder = remainder.substring(1);
+ matcher = splitPerfData.matcher(remainder);
+ } else {
+ matcher = null;
+ }
+
+ return next;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private static enum QuoteStringFunction implements Function<String, String> {
+ INSTANCE;
+
+ @Nullable
+ @Override
+ public String apply(@Nullable String input) {
+ return input != null ? "\"" + input + "\"" : null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterPollConfig.java b/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterPollConfig.java
new file mode 100644
index 0000000..1391c3e
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterPollConfig.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.windows;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.PollConfig;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+
+public class WindowsPerformanceCounterPollConfig<T> extends PollConfig<Object, T, WindowsPerformanceCounterPollConfig<T>>{
+
+ private String performanceCounterName;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public WindowsPerformanceCounterPollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ description(sensor.getDescription());
+ onSuccess((Function)Functions.identity());
+ }
+
+ public WindowsPerformanceCounterPollConfig(WindowsPerformanceCounterPollConfig<T> other) {
+ super(other);
+ this.performanceCounterName = other.performanceCounterName;
+ }
+
+ public String getPerformanceCounterName() {
+ return performanceCounterName;
+ }
+
+ public WindowsPerformanceCounterPollConfig<T> performanceCounterName(String val) {
+ this.performanceCounterName = val; return this;
+ }
+
+ @Override protected String toStringPollSource() { return performanceCounterName; }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/AbstractFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/AbstractFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/AbstractFeed.java
deleted file mode 100644
index 327181a..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/AbstractFeed.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
-import org.apache.brooklyn.api.mgmt.rebind.mementos.FeedMemento;
-import org.apache.brooklyn.api.sensor.Feed;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.BrooklynFeatureEnablement;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.mgmt.rebind.BasicFeedRebindSupport;
-import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
-import org.apache.brooklyn.util.javalang.JavaClassNames;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Captures common fields and processes for sensor feeds.
- * These generally poll or subscribe to get sensor values for an entity.
- * They make it easy to poll over http, jmx, etc.
- */
-public abstract class AbstractFeed extends AbstractEntityAdjunct implements Feed {
-
- private static final Logger log = LoggerFactory.getLogger(AbstractFeed.class);
-
- public static final ConfigKey<Boolean> ONLY_IF_SERVICE_UP = ConfigKeys.newBooleanConfigKey("feed.onlyIfServiceUp", "", false);
-
- private final Object pollerStateMutex = new Object();
- private transient volatile Poller<?> poller;
- private transient volatile boolean activated;
- private transient volatile boolean suspended;
-
- public AbstractFeed() {
- }
-
- /**
- * @deprecated since 0.7.0; use no-arg constructor; call {@link #setEntity(EntityLocal)}
- */
- @Deprecated
- public AbstractFeed(EntityLocal entity) {
- this(entity, false);
- }
-
- /**
- * @deprecated since 0.7.0; use no-arg constructor; call {@link #setEntity(EntityLocal)} and {@code setConfig(ONLY_IF_SERVICE_UP, onlyIfServiceUp)}
- */
- @Deprecated
- public AbstractFeed(EntityLocal entity, boolean onlyIfServiceUp) {
- this.entity = checkNotNull(entity, "entity");
- setConfig(ONLY_IF_SERVICE_UP, onlyIfServiceUp);
- }
-
- // Ensure idempotent, as called in builders (in case not registered with entity), and also called
- // when registering with entity
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- if (BrooklynFeatureEnablement.isEnabled(BrooklynFeatureEnablement.FEATURE_FEED_REGISTRATION_PROPERTY)) {
- ((EntityInternal)entity).feeds().addFeed(this);
- }
- }
-
- protected void initUniqueTag(String uniqueTag, Object ...valsForDefault) {
- if (Strings.isNonBlank(uniqueTag)) this.uniqueTag = uniqueTag;
- else this.uniqueTag = getDefaultUniqueTag(valsForDefault);
- }
-
- protected String getDefaultUniqueTag(Object ...valsForDefault) {
- StringBuilder sb = new StringBuilder();
- sb.append(JavaClassNames.simpleClassName(this));
- if (valsForDefault.length==0) {
- sb.append("@");
- sb.append(hashCode());
- } else if (valsForDefault.length==1 && valsForDefault[0] instanceof Collection){
- sb.append(Strings.toUniqueString(valsForDefault[0], 80));
- } else {
- sb.append("[");
- boolean first = true;
- for (Object x: valsForDefault) {
- if (!first) sb.append(";");
- else first = false;
- sb.append(Strings.toUniqueString(x, 80));
- }
- sb.append("]");
- }
- return sb.toString();
- }
-
- @Override
- public void start() {
- if (log.isDebugEnabled()) log.debug("Starting feed {} for {}", this, entity);
- if (activated) {
- throw new IllegalStateException(String.format("Attempt to start feed %s of entity %s when already running",
- this, entity));
- }
- if (poller != null) {
- throw new IllegalStateException(String.format("Attempt to re-start feed %s of entity %s", this, entity));
- }
-
- poller = new Poller<Object>(entity, getConfig(ONLY_IF_SERVICE_UP));
- activated = true;
- preStart();
- synchronized (pollerStateMutex) {
- // don't start poller if we are suspended
- if (!suspended) {
- poller.start();
- }
- }
- }
-
- @Override
- public void suspend() {
- synchronized (pollerStateMutex) {
- if (activated && !suspended) {
- poller.stop();
- }
- suspended = true;
- }
- }
-
- @Override
- public void resume() {
- synchronized (pollerStateMutex) {
- if (activated && suspended) {
- poller.start();
- }
- suspended = false;
- }
- }
-
- @Override
- public void destroy() {
- stop();
- }
-
- @Override
- public void stop() {
- if (!activated) {
- log.debug("Ignoring attempt to stop feed {} of entity {} when not running", this, entity);
- return;
- }
- if (log.isDebugEnabled()) log.debug("stopping feed {} for {}", this, entity);
-
- activated = false;
- preStop();
- synchronized (pollerStateMutex) {
- if (!suspended) {
- poller.stop();
- }
- }
- postStop();
- super.destroy();
- }
-
- @Override
- public boolean isActivated() {
- return activated;
- }
-
- public EntityLocal getEntity() {
- return entity;
- }
-
- protected boolean isConnected() {
- // TODO Default impl will result in multiple logs for same error if becomes unreachable
- // (e.g. if ssh gets NoRouteToHostException, then every AttributePollHandler for that
- // feed will log.warn - so if polling for 10 sensors/attributes will get 10 log messages).
- // Would be nice if reduced this logging duplication.
- // (You can reduce it by providing a better 'isConnected' implementation of course.)
- return isRunning() && entity!=null && !((EntityInternal)entity).getManagementSupport().isNoLongerManaged();
- }
-
- @Override
- public boolean isSuspended() {
- return suspended;
- }
-
- @Override
- public boolean isRunning() {
- return isActivated() && !isSuspended() && !isDestroyed() && getPoller()!=null && getPoller().isRunning();
- }
-
- @Override
- public RebindSupport<FeedMemento> getRebindSupport() {
- return new BasicFeedRebindSupport(this);
- }
-
- @Override
- protected void onChanged() {
- // TODO Auto-generated method stub
- }
-
- /**
- * For overriding.
- */
- protected void preStart() {
- }
-
- /**
- * For overriding.
- */
- protected void preStop() {
- }
-
- /**
- * For overriding.
- */
- protected void postStop() {
- }
-
- /**
- * For overriding, where sub-class can change return-type generics!
- */
- protected Poller<?> getPoller() {
- return poller;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/AttributePollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/AttributePollHandler.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/AttributePollHandler.java
deleted file mode 100644
index eac972e..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/AttributePollHandler.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle.Transition;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-
-/**
- * Handler for when polling an entity's attribute. On each poll result the entity's attribute is set.
- *
- * Calls to onSuccess and onError will happen sequentially, but may be called from different threads
- * each time. Note that no guarantees of a synchronized block exist, so additional synchronization
- * would be required for the Java memory model's "happens before" relationship.
- *
- * @author aled
- */
-public class AttributePollHandler<V> implements PollHandler<V> {
-
- public static final Logger log = LoggerFactory.getLogger(AttributePollHandler.class);
-
- private final FeedConfig<V,?,?> config;
- private final EntityLocal entity;
- @SuppressWarnings("rawtypes")
- private final AttributeSensor sensor;
- private final AbstractFeed feed;
- private final boolean suppressDuplicates;
-
- // allow 30 seconds before logging at WARN, if there has been no success yet;
- // after success WARN immediately
- // TODO these should both be configurable
- private Duration logWarningGraceTimeOnStartup = Duration.THIRTY_SECONDS;
- private Duration logWarningGraceTime = Duration.millis(0);
-
- // internal state to look after whether to log warnings
- private volatile Long lastSuccessTime = null;
- private volatile Long currentProblemStartTime = null;
- private volatile boolean currentProblemLoggedAsWarning = false;
- private volatile boolean lastWasProblem = false;
-
-
- public AttributePollHandler(FeedConfig<V,?,?> config, EntityLocal entity, AbstractFeed feed) {
- this.config = checkNotNull(config, "config");
- this.entity = checkNotNull(entity, "entity");
- this.sensor = checkNotNull(config.getSensor(), "sensor");
- this.feed = checkNotNull(feed, "feed");
- this.suppressDuplicates = config.getSupressDuplicates();
- }
-
- @Override
- public boolean checkSuccess(V val) {
- // Always true if no checkSuccess predicate was configured.
- return !config.hasCheckSuccessHandler() || config.getCheckSuccess().apply(val);
- }
-
- @Override
- public void onSuccess(V val) {
- if (lastWasProblem) {
- if (currentProblemLoggedAsWarning) {
- log.info("Success (following previous problem) reading "+getBriefDescription());
- } else {
- log.debug("Success (following previous problem) reading "+getBriefDescription());
- }
- lastWasProblem = false;
- currentProblemStartTime = null;
- currentProblemLoggedAsWarning = false;
- }
- lastSuccessTime = System.currentTimeMillis();
- if (log.isTraceEnabled()) log.trace("poll for {} got: {}", new Object[] {getBriefDescription(), val});
-
- try {
- setSensor(transformValueOnSuccess(val));
- } catch (Exception e) {
- if (feed.isConnected()) {
- log.warn("unable to compute "+getBriefDescription()+"; on val="+val, e);
- } else {
- if (log.isDebugEnabled()) log.debug("unable to compute "+getBriefDescription()+"; val="+val+" (when inactive)", e);
- }
- }
- }
-
- /** allows post-processing, such as applying a success handler;
- * default applies the onSuccess handler (which is recommended) */
- protected Object transformValueOnSuccess(V val) {
- return config.hasSuccessHandler() ? config.getOnSuccess().apply(val) : val;
- }
-
- @Override
- public void onFailure(V val) {
- if (!config.hasFailureHandler()) {
- onException(new Exception("checkSuccess of "+this+" for "+getBriefDescription()+" was false but poller has no failure handler"));
- } else {
- logProblem("failure", val);
-
- try {
- setSensor(config.hasFailureHandler() ? config.getOnFailure().apply((V)val) : val);
- } catch (Exception e) {
- if (feed.isConnected()) {
- log.warn("Error computing " + getBriefDescription() + "; val=" + val+": "+ e, e);
- } else {
- if (log.isDebugEnabled())
- log.debug("Error computing " + getBriefDescription() + "; val=" + val + " (when inactive)", e);
- }
- }
- }
- }
-
- @Override
- public void onException(Exception exception) {
- if (!feed.isConnected()) {
- if (log.isTraceEnabled()) log.trace("Read of {} in {} gave exception (while not connected or not yet connected): {}", new Object[] {this, getBriefDescription(), exception});
- } else {
- logProblem("exception", exception);
- }
-
- if (config.hasExceptionHandler()) {
- try {
- setSensor( config.getOnException().apply(exception) );
- } catch (Exception e) {
- if (feed.isConnected()) {
- log.warn("unable to compute "+getBriefDescription()+"; on exception="+exception, e);
- } else {
- if (log.isDebugEnabled()) log.debug("unable to compute "+getBriefDescription()+"; exception="+exception+" (when inactive)", e);
- }
- }
- }
- }
-
- protected void logProblem(String type, Object val) {
- if (lastWasProblem && currentProblemLoggedAsWarning) {
- if (log.isTraceEnabled())
- log.trace("Recurring {} reading {} in {}: {}", new Object[] {type, this, getBriefDescription(), val});
- } else {
- long nowTime = System.currentTimeMillis();
- // get a non-volatile value
- Long currentProblemStartTimeCache = currentProblemStartTime;
- long expiryTime =
- (lastSuccessTime!=null && !isTransitioningOrStopped()) ? lastSuccessTime+logWarningGraceTime.toMilliseconds() :
- currentProblemStartTimeCache!=null ? currentProblemStartTimeCache+logWarningGraceTimeOnStartup.toMilliseconds() :
- nowTime+logWarningGraceTimeOnStartup.toMilliseconds();
- if (!lastWasProblem) {
- if (expiryTime <= nowTime) {
- currentProblemLoggedAsWarning = true;
- if (entity==null || !Entities.isNoLongerManaged(entity)) {
- log.warn("Read of " + getBriefDescription() + " gave " + type + ": " + val);
- } else {
- log.debug("Read of " + getBriefDescription() + " gave " + type + ": " + val);
- }
- if (log.isDebugEnabled() && val instanceof Throwable)
- log.debug("Trace for "+type+" reading "+getBriefDescription()+": "+val, (Throwable)val);
- } else {
- if (log.isDebugEnabled())
- log.debug("Read of " + getBriefDescription() + " gave " + type + " (in grace period): " + val);
- }
- lastWasProblem = true;
- currentProblemStartTime = nowTime;
- } else {
- if (expiryTime <= nowTime) {
- currentProblemLoggedAsWarning = true;
- log.warn("Read of " + getBriefDescription() + " gave " + type +
- " (grace period expired, occurring for "+Duration.millis(nowTime - currentProblemStartTimeCache)+
- (config.hasExceptionHandler() ? "" : ", no exception handler set for sensor")+
- ")"+
- ": " + val);
- if (log.isDebugEnabled() && val instanceof Throwable)
- log.debug("Trace for "+type+" reading "+getBriefDescription()+": "+val, (Throwable)val);
- } else {
- if (log.isDebugEnabled())
- log.debug("Recurring {} reading {} in {} (still in grace period): {}", new Object[] {type, this, getBriefDescription(), val});
- }
- }
- }
- }
-
- protected boolean isTransitioningOrStopped() {
- if (entity==null) return false;
- Transition expected = entity.getAttribute(Attributes.SERVICE_STATE_EXPECTED);
- if (expected==null) return false;
- return (expected.getState()==Lifecycle.STARTING || expected.getState()==Lifecycle.STOPPING || expected.getState()==Lifecycle.STOPPED);
- }
-
- @SuppressWarnings("unchecked")
- protected void setSensor(Object v) {
- if (Entities.isNoLongerManaged(entity)) {
- if (Tasks.isInterrupted()) return;
- log.warn(""+entity+" is not managed; feed "+this+" setting "+sensor+" to "+v+" at this time is not supported ("+Tasks.current()+")");
- }
-
- if (v == FeedConfig.UNCHANGED) {
- // nothing
- } else if (v == FeedConfig.REMOVE) {
- ((EntityInternal)entity).removeAttribute(sensor);
- } else if (sensor == FeedConfig.NO_SENSOR) {
- // nothing
- } else {
- Object coercedV = TypeCoercions.coerce(v, sensor.getType());
- if (suppressDuplicates && Objects.equal(coercedV, entity.getAttribute(sensor))) {
- // no change; nothing
- } else {
- entity.setAttribute(sensor, coercedV);
- }
- }
- }
-
- @Override
- public String toString() {
- return super.toString()+"["+getDescription()+"]";
- }
-
- @Override
- public String getDescription() {
- return sensor.getName()+" @ "+entity.getId()+" <- "+config;
- }
-
- protected String getBriefDescription() {
- return ""+entity+"->"+(sensor==FeedConfig.NO_SENSOR ? "(dynamic sensors)" : ""+sensor);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
deleted file mode 100644
index 7938cc4..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
-
-
-/** Simple config adapter for setting {@link AttributeSensorAndConfigKey} sensor values from the config value or config default */
-public class ConfigToAttributes {
-
- //normally just applied once, statically, not registered...
- public static void apply(EntityLocal entity) {
- for (Sensor<?> it : entity.getEntityType().getSensors()) {
- if (it instanceof AttributeSensorAndConfigKey) {
- apply(entity, (AttributeSensorAndConfigKey<?,?>)it);
- }
- }
- }
-
- /**
- * Convenience for ensuring an individual sensor is set from its config key
- * (e.g. sub-classes of DynamicWebAppCluster that don't want to set HTTP_PORT etc!)
- */
- public static <T> T apply(EntityLocal entity, AttributeSensorAndConfigKey<?,T> key) {
- T v = entity.getAttribute(key);
- if (v!=null) return v;
- v = key.getAsSensorValue(entity);
- if (v!=null) entity.setAttribute(key, v);
- return v;
- }
-
- /**
- * Convenience for transforming a config value (e.g. processing a {@link TemplatedStringAttributeSensorAndConfigKey}),
- * outside of the context of an entity.
- */
- public static <T> T transform(ManagementContext managementContext, AttributeSensorAndConfigKey<?,T> key) {
- return key.getAsSensorValue(managementContext);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/DelegatingPollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/DelegatingPollHandler.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/DelegatingPollHandler.java
deleted file mode 100644
index 4433e83..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/DelegatingPollHandler.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import java.util.List;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * A poll handler that delegates each call to a set of poll handlers.
- *
- * @author aled
- */
-public class DelegatingPollHandler<V> implements PollHandler<V> {
-
- private final List<AttributePollHandler<? super V>> delegates;
-
- public DelegatingPollHandler(Iterable<AttributePollHandler<? super V>> delegates) {
- super();
- this.delegates = ImmutableList.copyOf(delegates);
- }
-
- @Override
- public boolean checkSuccess(V val) {
- for (AttributePollHandler<? super V> delegate : delegates) {
- if (!delegate.checkSuccess(val))
- return false;
- }
- return true;
- }
-
- @Override
- public void onSuccess(V val) {
- for (AttributePollHandler<? super V> delegate : delegates) {
- delegate.onSuccess(val);
- }
- }
-
- @Override
- public void onFailure(V val) {
- for (AttributePollHandler<? super V> delegate : delegates) {
- delegate.onFailure(val);
- }
- }
-
- @Override
- public void onException(Exception exception) {
- for (AttributePollHandler<? super V> delegate : delegates) {
- delegate.onException(exception);
- }
- }
-
- @Override
- public String toString() {
- return super.toString()+"["+getDescription()+"]";
- }
-
- @Override
- public String getDescription() {
- if (delegates.isEmpty())
- return "(empty delegate list)";
- if (delegates.size()==1)
- return delegates.get(0).getDescription();
- StringBuilder sb = new StringBuilder();
- sb.append("[");
- int count = 0;
- for (AttributePollHandler<? super V> delegate : delegates) {
- if (count>0) sb.append("; ");
- sb.append(delegate.getDescription());
- if (count>2) {
- sb.append("; ...");
- break;
- }
- count++;
- }
- sb.append("]");
- return sb.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
deleted file mode 100644
index 32ea2ab..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.javalang.JavaClassNames;
-import org.apache.brooklyn.util.text.Strings;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-
-/**
- * Configuration for a poll, or a subscription etc, that is being added to a feed.
- *
- * @author aled
- */
-public class FeedConfig<V, T, F extends FeedConfig<V, T, F>> {
-
- /** The onSuccess or onError functions can return this value to indicate that the sensor should not change.
- * @deprecated since 0.7.0 use UNCHANGED */
- public static final Object UNSET = Entities.UNCHANGED;
- /** The onSuccess or onError functions can return this value to indicate that the sensor should not change. */
- public static final Object UNCHANGED = Entities.UNCHANGED;
- /** The onSuccess or onError functions can return this value to indicate that the sensor value should be removed
- * (cf 'null', but useful in dynamic situations) */
- public static final Object REMOVE = Entities.REMOVE;
-
- /** Indicates that no sensor is being used here. This sensor is suppressed,
- * but is useful where you want to use the feeds with custom success/exception/failure functions
- * which directly set multiple sensors, e.g. dynamically based on the poll response.
- * <p>
- * See {@link HttpPollConfig#forMultiple()} and its usages.
- * (It can work for any poll config, but conveniences have not been supplied for others.) */
- public static final AttributeSensor<Void> NO_SENSOR = Sensors.newSensor(Void.class, "brooklyn.no.sensor");
-
- private final AttributeSensor<T> sensor;
- private Function<? super V, T> onsuccess;
- private Function<? super V, T> onfailure;
- private Function<? super Exception, T> onexception;
- private Predicate<? super V> checkSuccess;
- private boolean suppressDuplicates;
- private boolean enabled = true;
-
- public FeedConfig(AttributeSensor<T> sensor) {
- this.sensor = checkNotNull(sensor, "sensor");
- }
-
- public FeedConfig(FeedConfig<V, T, F> other) {
- this.sensor = other.sensor;
- this.onsuccess = other.onsuccess;
- this.onfailure = other.onfailure;
- this.onexception = other.onexception;
- this.checkSuccess = other.checkSuccess;
- this.suppressDuplicates = other.suppressDuplicates;
- this.enabled = other.enabled;
- }
-
- @SuppressWarnings("unchecked")
- protected F self() {
- return (F) this;
- }
-
- public AttributeSensor<T> getSensor() {
- return sensor;
- }
-
- public Predicate<? super V> getCheckSuccess() {
- return checkSuccess;
- }
-
- public Function<? super V, T> getOnSuccess() {
- return onsuccess;
- }
-
- public Function<? super V, T> getOnFailure() {
- return onfailure;
- }
-
- public Function<? super Exception, T> getOnException() {
- return onexception;
- }
-
- public boolean getSupressDuplicates() {
- return suppressDuplicates;
- }
-
- public boolean isEnabled() {
- return enabled;
- }
-
- /** sets the predicate used to check whether a feed run is successful */
- public F checkSuccess(Predicate<? super V> val) {
- this.checkSuccess = checkNotNull(val, "checkSuccess");
- return self();
- }
- /** as {@link #checkSuccess(Predicate)} */
- public F checkSuccess(final Function<? super V,Boolean> val) {
- return checkSuccess(Functionals.predicate(val));
- }
- @SuppressWarnings("unused")
- /** @deprecated since 0.7.0, kept for rebind */ @Deprecated
- private F checkSuccessLegacy(final Function<? super V,Boolean> val) {
- return checkSuccess(new Predicate<V>() {
- @Override
- public boolean apply(V input) {
- return val.apply(input);
- }
- });
- }
-
- public F onSuccess(Function<? super V,T> val) {
- this.onsuccess = checkNotNull(val, "onSuccess");
- return self();
- }
-
- public F setOnSuccess(T val) {
- return onSuccess(Functions.constant(val));
- }
-
- /** a failure is when the connection is fine (no exception) but the other end returns a result object V
- * which the feed can tell indicates a failure (e.g. HTTP code 404) */
- public F onFailure(Function<? super V,T> val) {
- this.onfailure = checkNotNull(val, "onFailure");
- return self();
- }
-
- public F setOnFailure(T val) {
- return onFailure(Functions.constant(val));
- }
-
- /** registers a callback to be used {@link #onSuccess(Function)} and {@link #onFailure(Function)},
- * i.e. whenever a result comes back, but not in case of exceptions being thrown (ie problems communicating) */
- public F onResult(Function<? super V, T> val) {
- onSuccess(val);
- return onFailure(val);
- }
-
- public F setOnResult(T val) {
- return onResult(Functions.constant(val));
- }
-
- /** an exception is when there is an error in the communication */
- public F onException(Function<? super Exception,T> val) {
- this.onexception = checkNotNull(val, "onException");
- return self();
- }
-
- public F setOnException(T val) {
- return onException(Functions.constant(val));
- }
-
- /** convenience for indicating a behaviour to occur for both
- * {@link #onException(Function)}
- * (error connecting) and
- * {@link #onFailure(Function)}
- * (successful communication but failure report from remote end) */
- public F onFailureOrException(Function<Object,T> val) {
- onFailure(val);
- return onException(val);
- }
-
- public F setOnFailureOrException(T val) {
- return onFailureOrException(Functions.constant(val));
- }
-
- public F suppressDuplicates(boolean val) {
- suppressDuplicates = val;
- return self();
- }
-
- /**
- * Whether this feed is enabled (defaulting to true).
- */
- public F enabled(boolean val) {
- enabled = val;
- return self();
- }
-
- public boolean hasSuccessHandler() {
- return this.onsuccess != null;
- }
-
- public boolean hasFailureHandler() {
- return this.onfailure != null;
- }
-
- public boolean hasExceptionHandler() {
- return this.onexception != null;
- }
-
- public boolean hasCheckSuccessHandler() {
- return this.checkSuccess != null;
- }
-
-
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder();
- result.append(toStringBaseName());
- result.append("[");
- boolean contents = false;
- Object source = toStringPollSource();
- AttributeSensor<T> s = getSensor();
- if (Strings.isNonBlank(Strings.toString(source))) {
- result.append(Strings.toUniqueString(source, 40));
- if (s!=null) {
- result.append("->");
- result.append(s.getName());
- }
- contents = true;
- } else if (s!=null) {
- result.append(s.getName());
- contents = true;
- }
- MutableList<Object> fields = toStringOtherFields();
- if (fields!=null) {
- for (Object field: fields) {
- if (Strings.isNonBlank(Strings.toString(field))) {
- if (contents) result.append(";");
- contents = true;
- result.append(field);
- }
- }
- }
- result.append("]");
- return result.toString();
- }
-
- /** can be overridden to supply a simpler base name than the class name */
- protected String toStringBaseName() {
- return JavaClassNames.simpleClassName(this);
- }
- /** can be overridden to supply add'l info for the {@link #toString()}; subclasses can add to the returned value */
- protected MutableList<Object> toStringOtherFields() {
- return MutableList.<Object>of();
- }
- /** can be overridden to supply add'l info for the {@link #toString()}, placed before the sensor with -> */
- protected Object toStringPollSource() {
- return null;
- }
- /** all configs should supply a unique tag element, inserted into the feed */
- protected String getUniqueTag() {
- return toString();
- }
-
- /** returns fields which should be used for equality, including by default {@link #toStringOtherFields()} and {@link #toStringPollSource()};
- * subclasses can add to the returned value */
- protected MutableList<Object> equalsFields() {
- MutableList<Object> result = MutableList.of().appendIfNotNull(getSensor()).appendIfNotNull(toStringPollSource());
- for (Object field: toStringOtherFields()) result.appendIfNotNull(field);
- return result;
- }
-
- @Override
- public int hashCode() {
- int hc = super.hashCode();
- for (Object f: equalsFields())
- hc = Objects.hashCode(hc, f);
- return hc;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!super.equals(obj)) return false;
- PollConfig<?,?,?> other = (PollConfig<?,?,?>) obj;
- if (!Objects.equal(getUniqueTag(), other.getUniqueTag())) return false;
- if (!Objects.equal(equalsFields(), other.equalsFields())) return false;
- return true;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/PollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/PollConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/PollConfig.java
deleted file mode 100644
index 01a561b..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/PollConfig.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.time.Duration;
-
-/**
- * Configuration for polling, which is being added to a feed (e.g. to poll a given URL over http).
- *
- * @author aled
- */
-public class PollConfig<V, T, F extends PollConfig<V, T, F>> extends FeedConfig<V, T, F> {
-
- private long period = -1;
- private String description;
-
- public PollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- }
-
- public PollConfig(PollConfig<V,T,F> other) {
- super(other);
- this.period = other.period;
- }
-
- public long getPeriod() {
- return period;
- }
-
- public F period(Duration val) {
- checkArgument(val.toMilliseconds() >= 0, "period must be greater than or equal to zero");
- this.period = val.toMilliseconds();
- return self();
- }
-
- public F period(long val) {
- checkArgument(val >= 0, "period must be greater than or equal to zero");
- this.period = val; return self();
- }
-
- public F period(long val, TimeUnit units) {
- checkArgument(val >= 0, "period must be greater than or equal to zero");
- return period(units.toMillis(val));
- }
-
- public F description(String description) {
- this.description = description;
- return self();
- }
-
- public String getDescription() {
- return description;
- }
-
- @Override protected MutableList<Object> toStringOtherFields() {
- return super.toStringOtherFields().appendIfNotNull(description);
- }
-
- @Override
- protected MutableList<Object> equalsFields() {
- return super.equalsFields().appendIfNotNull(period);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/PollHandler.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/PollHandler.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/PollHandler.java
deleted file mode 100644
index 175c76f..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/PollHandler.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-/**
- * Notified by the Poller of the result for each job, on each poll.
- *
- * @author aled
- */
-public interface PollHandler<V> {
-
- public boolean checkSuccess(V val);
-
- public void onSuccess(V val);
-
- public void onFailure(V val);
-
- public void onException(Exception exception);
-
- public String getDescription();
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/Poller.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/Poller.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/Poller.java
deleted file mode 100644
index f6e8e24..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/Poller.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
-import org.apache.brooklyn.util.core.task.ScheduledTask;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-
-
-/**
- * For executing periodic polls.
- * Jobs are added to the schedule, and then the poller is started.
- * The jobs will then be executed periodically, and the handler called for the result/failure.
- *
- * Assumes the schedule+start will be done single threaded, and that stop will not be done concurrently.
- */
-public class Poller<V> {
- public static final Logger log = LoggerFactory.getLogger(Poller.class);
-
- private final EntityLocal entity;
- private final boolean onlyIfServiceUp;
- private final Set<Callable<?>> oneOffJobs = new LinkedHashSet<Callable<?>>();
- private final Set<PollJob<V>> pollJobs = new LinkedHashSet<PollJob<V>>();
- private final Set<Task<?>> oneOffTasks = new LinkedHashSet<Task<?>>();
- private final Set<ScheduledTask> tasks = new LinkedHashSet<ScheduledTask>();
- private volatile boolean started = false;
-
- private static class PollJob<V> {
- final PollHandler<? super V> handler;
- final Duration pollPeriod;
- final Runnable wrappedJob;
- private boolean loggedPreviousException = false;
-
- PollJob(final Callable<V> job, final PollHandler<? super V> handler, Duration period) {
- this.handler = handler;
- this.pollPeriod = period;
-
- wrappedJob = new Runnable() {
- public void run() {
- try {
- V val = job.call();
- loggedPreviousException = false;
- if (handler.checkSuccess(val)) {
- handler.onSuccess(val);
- } else {
- handler.onFailure(val);
- }
- } catch (Exception e) {
- if (loggedPreviousException) {
- if (log.isTraceEnabled()) log.trace("PollJob for {}, repeated consecutive failures, handling {} using {}", new Object[] {job, e, handler});
- } else {
- if (log.isDebugEnabled()) log.debug("PollJob for {} handling {} using {}", new Object[] {job, e, handler});
- loggedPreviousException = true;
- }
- handler.onException(e);
- }
- }
- };
- }
- }
-
- /** @deprecated since 0.7.0, pass in whether should run onlyIfServiceUp */
- @Deprecated
- public Poller(EntityLocal entity) {
- this(entity, false);
- }
- public Poller(EntityLocal entity, boolean onlyIfServiceUp) {
- this.entity = entity;
- this.onlyIfServiceUp = onlyIfServiceUp;
- }
-
- /** Submits a one-off poll job; recommended that callers supply to-String so that task has a decent description */
- public void submit(Callable<?> job) {
- if (started) {
- throw new IllegalStateException("Cannot submit additional tasks after poller has started");
- }
- oneOffJobs.add(job);
- }
-
- public void scheduleAtFixedRate(Callable<V> job, PollHandler<? super V> handler, long period) {
- scheduleAtFixedRate(job, handler, Duration.millis(period));
- }
- public void scheduleAtFixedRate(Callable<V> job, PollHandler<? super V> handler, Duration period) {
- if (started) {
- throw new IllegalStateException("Cannot schedule additional tasks after poller has started");
- }
- PollJob<V> foo = new PollJob<V>(job, handler, period);
- pollJobs.add(foo);
- }
-
- @SuppressWarnings({ "unchecked" })
- public void start() {
- // TODO Previous incarnation of this logged this logged polledSensors.keySet(), but we don't know that anymore
- // Is that ok, are can we do better?
-
- if (log.isDebugEnabled()) log.debug("Starting poll for {} (using {})", new Object[] {entity, this});
- if (started) {
- throw new IllegalStateException(String.format("Attempt to start poller %s of entity %s when already running",
- this, entity));
- }
-
- started = true;
-
- for (final Callable<?> oneOffJob : oneOffJobs) {
- Task<?> task = Tasks.builder().dynamic(false).body((Callable<Object>) oneOffJob).name("Poll").description("One-time poll job "+oneOffJob).build();
- oneOffTasks.add(((EntityInternal)entity).getExecutionContext().submit(task));
- }
-
- for (final PollJob<V> pollJob : pollJobs) {
- final String scheduleName = pollJob.handler.getDescription();
- if (pollJob.pollPeriod.compareTo(Duration.ZERO) > 0) {
- Callable<Task<?>> pollingTaskFactory = new Callable<Task<?>>() {
- public Task<?> call() {
- DynamicSequentialTask<Void> task = new DynamicSequentialTask<Void>(MutableMap.of("displayName", scheduleName, "entity", entity),
- new Callable<Void>() { public Void call() {
- if (onlyIfServiceUp && !Boolean.TRUE.equals(entity.getAttribute(Attributes.SERVICE_UP))) {
- return null;
- }
- pollJob.wrappedJob.run();
- return null;
- } } );
- BrooklynTaskTags.setTransient(task);
- return task;
- }
- };
- ScheduledTask task = new ScheduledTask(MutableMap.of("period", pollJob.pollPeriod, "displayName", "scheduled:"+scheduleName), pollingTaskFactory);
- tasks.add((ScheduledTask)Entities.submit(entity, task));
- } else {
- if (log.isDebugEnabled()) log.debug("Activating poll (but leaving off, as period {}) for {} (using {})", new Object[] {pollJob.pollPeriod, entity, this});
- }
- }
- }
-
- public void stop() {
- if (log.isDebugEnabled()) log.debug("Stopping poll for {} (using {})", new Object[] {entity, this});
- if (!started) {
- throw new IllegalStateException(String.format("Attempt to stop poller %s of entity %s when not running",
- this, entity));
- }
-
- started = false;
- for (Task<?> task : oneOffTasks) {
- if (task != null) task.cancel(true);
- }
- for (ScheduledTask task : tasks) {
- if (task != null) task.cancel();
- }
- oneOffTasks.clear();
- tasks.clear();
- }
-
- public boolean isRunning() {
- boolean hasActiveTasks = false;
- for (Task<?> task: tasks) {
- if (task.isBegun() && !task.isDone()) {
- hasActiveTasks = true;
- break;
- }
- }
- if (!started && hasActiveTasks) {
- log.warn("Poller should not be running, but has active tasks, tasks: "+tasks);
- }
- return started && hasActiveTasks;
- }
-
- protected boolean isEmpty() {
- return pollJobs.isEmpty();
- }
-
- public String toString() {
- return Objects.toStringHelper(this).add("entity", entity).toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionFeed.java
deleted file mode 100644
index 1cb6861..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionFeed.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.function;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Provides a feed of attribute values, by periodically invoking functions.
- *
- * Example usage (e.g. in an entity that extends SoftwareProcessImpl):
- * <pre>
- * {@code
- * private FunctionFeed feed;
- *
- * //@Override
- * protected void connectSensors() {
- * super.connectSensors();
- *
- * feed = FunctionFeed.builder()
- * .entity(this)
- * .poll(new FunctionPollConfig<Object, Boolean>(SERVICE_UP)
- * .period(500, TimeUnit.MILLISECONDS)
- * .callable(new Callable<Boolean>() {
- * public Boolean call() throws Exception {
- * return getDriver().isRunning();
- * }
- * })
- * .onExceptionOrFailure(Functions.constant(Boolan.FALSE))
- * .build();
- * }
- *
- * {@literal @}Override
- * protected void disconnectSensors() {
- * super.disconnectSensors();
- * if (feed != null) feed.stop();
- * }
- * }
- * </pre>
- *
- * @author aled
- */
-public class FunctionFeed extends AbstractFeed {
-
- private static final Logger log = LoggerFactory.getLogger(FunctionFeed.class);
-
- // Treat as immutable once built
- @SuppressWarnings("serial")
- public static final ConfigKey<SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>>>() {},
- "polls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static Builder builder(String uniqueTag) {
- return new Builder().uniqueTag(uniqueTag);
- }
-
- public static class Builder {
- private EntityLocal entity;
- private boolean onlyIfServiceUp = false;
- private long period = 500;
- private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
- private List<FunctionPollConfig<?,?>> polls = Lists.newArrayList();
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = val;
- return this;
- }
- public Builder onlyIfServiceUp() { return onlyIfServiceUp(true); }
- public Builder onlyIfServiceUp(boolean onlyIfServiceUp) {
- this.onlyIfServiceUp = onlyIfServiceUp;
- return this;
- }
- public Builder period(Duration d) {
- return period(d.toMilliseconds(), TimeUnit.MILLISECONDS);
- }
- public Builder period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public Builder period(long val, TimeUnit units) {
- this.period = val;
- this.periodUnits = units;
- return this;
- }
- public Builder poll(FunctionPollConfig<?,?> config) {
- polls.add(config);
- return this;
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public FunctionFeed build() {
- built = true;
- FunctionFeed result = new FunctionFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("FunctionFeed.Builder created, but build() never called");
- }
- }
-
- private static class FunctionPollIdentifier {
- final Callable<?> job;
-
- private FunctionPollIdentifier(Callable<?> job) {
- this.job = checkNotNull(job, "job");
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(job);
- }
-
- @Override
- public boolean equals(Object other) {
- return (other instanceof FunctionPollIdentifier) && Objects.equal(job, ((FunctionPollIdentifier)other).job);
- }
- }
-
- /**
- * For rebind; do not call directly; use builder
- */
- public FunctionFeed() {
- }
-
- protected FunctionFeed(Builder builder) {
- setConfig(ONLY_IF_SERVICE_UP, builder.onlyIfServiceUp);
-
- SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?,?>> polls = HashMultimap.<FunctionPollIdentifier,FunctionPollConfig<?,?>>create();
- for (FunctionPollConfig<?,?> config : builder.polls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "rawtypes", "unchecked" })
- FunctionPollConfig<?,?> configCopy = new FunctionPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
- Callable<?> job = config.getCallable();
- polls.put(new FunctionPollIdentifier(job), configCopy);
- }
- setConfig(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls.values());
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- protected void preStart() {
- SetMultimap<FunctionPollIdentifier, FunctionPollConfig<?, ?>> polls = getConfig(POLLS);
- for (final FunctionPollIdentifier pollInfo : polls.keySet()) {
- Set<FunctionPollConfig<?,?>> configs = polls.get(pollInfo);
- long minPeriod = Integer.MAX_VALUE;
- Set<AttributePollHandler<?>> handlers = Sets.newLinkedHashSet();
-
- for (FunctionPollConfig<?,?> config : configs) {
- handlers.add(new AttributePollHandler(config, entity, this));
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- }
-
- getPoller().scheduleAtFixedRate(
- (Callable)pollInfo.job,
- new DelegatingPollHandler(handlers),
- minPeriod);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionPollConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionPollConfig.java
deleted file mode 100644
index 7b91988..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/function/FunctionPollConfig.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.function;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import groovy.lang.Closure;
-
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.FeedConfig;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.javalang.JavaClassNames;
-
-import com.google.common.base.Supplier;
-
-public class FunctionPollConfig<S, T> extends PollConfig<S, T, FunctionPollConfig<S, T>> {
-
- private Callable<?> callable;
-
- public static <T> FunctionPollConfig<?, T> forSensor(AttributeSensor<T> sensor) {
- return new FunctionPollConfig<Object, T>(sensor);
- }
-
- public FunctionPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- }
-
- public FunctionPollConfig(FunctionPollConfig<S, T> other) {
- super(other);
- callable = other.callable;
- }
-
- public Callable<? extends Object> getCallable() {
- return callable;
- }
-
- /**
- * The {@link Callable} to be invoked on each poll.
- * <p>
- * Note this <em>must</em> use generics, otherwise the return type of subsequent chained
- * calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
- * return the wrong type.
- */
- @SuppressWarnings("unchecked")
- public <newS> FunctionPollConfig<newS, T> callable(Callable<? extends newS> val) {
- this.callable = checkNotNull(val, "callable");
- return (FunctionPollConfig<newS, T>) this;
- }
-
- /**
- * Supplies the value to be returned by each poll.
- * <p>
- * Note this <em>must</em> use generics, otherwise the return type of subsequent chained
- * calls will (e.g. to {@link FeedConfig#onException(com.google.common.base.Function)} will
- * return the wrong type.
- */
- @SuppressWarnings("unchecked")
- public <newS> FunctionPollConfig<newS, T> supplier(final Supplier<? extends newS> val) {
- this.callable = Functionals.callable( checkNotNull(val, "supplier") );
- return (FunctionPollConfig<newS, T>) this;
- }
-
- /** @deprecated since 0.7.0, kept for legacy compatibility when deserializing */
- @SuppressWarnings({ "unchecked", "unused" })
- private <newS> FunctionPollConfig<newS, T> supplierLegacy(final Supplier<? extends newS> val) {
- checkNotNull(val, "supplier");
- this.callable = new Callable<newS>() {
- @Override
- public newS call() throws Exception {
- return val.get();
- }
- };
- return (FunctionPollConfig<newS, T>) this;
- }
-
- public FunctionPollConfig<S, T> closure(Closure<?> val) {
- this.callable = GroovyJavaMethods.callableFromClosure(checkNotNull(val, "closure"));
- return this;
- }
-
- @Override protected String toStringBaseName() { return "fn"; }
- @Override protected String toStringPollSource() {
- if (callable==null) return null;
- String cs = callable.toString();
- if (!cs.contains( ""+Integer.toHexString(callable.hashCode()) )) {
- return cs;
- }
- // if hashcode is in callable it's probably a custom internal; return class name
- return JavaClassNames.simpleClassName(callable);
- }
-
-}
[32/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
deleted file mode 100644
index 823b8b7..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-@SuppressWarnings("serial")
-//@Catalog(name="Combiner", description="Combines attributes; see Enrichers.builder().combining(...)")
-public class Combiner<T,U> extends AbstractEnricher implements SensorEventListener<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(Combiner.class);
-
- public static ConfigKey<Function<?, ?>> TRANSFORMATION = ConfigKeys.newConfigKey(new TypeToken<Function<?, ?>>() {}, "enricher.transformation");
-
- public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
-
- public static ConfigKey<Set<Sensor<?>>> SOURCE_SENSORS = ConfigKeys.newConfigKey(new TypeToken<Set<Sensor<?>>>() {}, "enricher.sourceSensors");
-
- public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
-
- public static final ConfigKey<Predicate<?>> VALUE_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<?>>() {}, "enricher.aggregating.valueFilter");
-
- protected Function<? super Collection<T>, ? extends U> transformation;
- protected Entity producer;
- protected Set<Sensor<T>> sourceSensors;
- protected Sensor<U> targetSensor;
- protected Predicate<? super T> valueFilter;
-
- /**
- * Users of values should either on it synchronize when iterating over its entries or use
- * copyOfValues to obtain an immutable copy of the map.
- */
- // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
- protected final Map<Sensor<T>, T> values = Collections.synchronizedMap(new LinkedHashMap<Sensor<T>, T>());
-
- public Combiner() {
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- this.transformation = (Function<? super Collection<T>, ? extends U>) getRequiredConfig(TRANSFORMATION);
- this.producer = getConfig(PRODUCER) == null ? entity: getConfig(PRODUCER);
- this.sourceSensors = (Set) getRequiredConfig(SOURCE_SENSORS);
- this.targetSensor = (Sensor<U>) getRequiredConfig(TARGET_SENSOR);
- this.valueFilter = (Predicate<? super T>) (getConfig(VALUE_FILTER) == null ? Predicates.alwaysTrue() : getConfig(VALUE_FILTER));
-
- checkState(sourceSensors.size() > 0, "must specify at least one sourceSensor");
-
- for (Sensor<T> sourceSensor : sourceSensors) {
- subscribe(producer, sourceSensor, this);
- }
-
- for (Sensor<T> sourceSensor : sourceSensors) {
- if (sourceSensor instanceof AttributeSensor) {
- Object value = producer.getAttribute((AttributeSensor<?>)sourceSensor);
- // TODO Aled didn't you write a convenience to "subscribeAndRunIfSet" ? (-Alex)
- // Unfortunately not yet!
- if (value != null) {
- onEvent(new BasicSensorEvent(sourceSensor, producer, value, -1));
- }
- }
- }
- }
-
- @Override
- public void onEvent(SensorEvent<T> event) {
- synchronized (values) {
- values.put(event.getSensor(), event.getValue());
- }
- onUpdated();
- }
-
- /**
- * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
- */
- protected void onUpdated() {
- try {
- emit(targetSensor, compute());
- } catch (Throwable t) {
- LOG.warn("Error calculating and setting combination for enricher "+this, t);
- throw Exceptions.propagate(t);
- }
- }
-
- protected Object compute() {
- synchronized (values) {
- // TODO Could avoid copying when filter not needed
- List<T> vs = MutableList.copyOf(Iterables.filter(values.values(), valueFilter));
- return transformation.apply(vs);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricher.java
deleted file mode 100644
index c11b83a..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricher.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import groovy.lang.Closure;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.base.Throwables;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Subscribes to events from producers with a sensor of type T, aggregates them with the
- * provided closure and emits the result on the target sensor V.
- * @param <T>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
-public class CustomAggregatingEnricher<S,T> extends AbstractAggregatingEnricher<S,T> implements SensorEventListener<S> {
-
- private static final Logger LOG = LoggerFactory.getLogger(CustomAggregatingEnricher.class);
-
- protected final Function<Collection<S>, T> aggregator;
-
- /**
- * The valid keys for the flags are:
- * - producers: a collection of entities to be aggregated
- * - allMembers: indicates that should track members of the entity that the aggregator is associated with,
- * to aggregate across all those members.
- * - filter: a Predicate or Closure, indicating which entities to include
- *
- * @param flags
- * @param source
- * @param target
- * @param aggregator Aggregates a collection of values, to return a single value for the target sensor
- * @param defaultIniitalValueForUnreportedSensors Default value to populate the collection given to aggregator,
- * where sensors are null or not present initially, defaults to null (note however that subsequent null reports will put an explicit null)
- */
- public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
- Function<Collection<S>, T> aggregator, S defaultIniitalValueForUnreportedSensors) {
- super(flags, source, target, defaultIniitalValueForUnreportedSensors);
- this.aggregator = aggregator;
- }
-
- public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
- Function<Collection<S>, T> aggregator) {
- this(flags, source, target, aggregator, null);
- }
-
- public CustomAggregatingEnricher(AttributeSensor<? extends S> source, AttributeSensor<T> target,
- Function<Collection<S>, T> aggregator, S defaultValue) {
- this(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultValue);
- }
-
- public CustomAggregatingEnricher(AttributeSensor<? extends S> source, AttributeSensor<T> target,
- Function<Collection<S>, T> aggregator) {
- this(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
- }
-
- /**
- * @param flags
- * @param source
- * @param target
- * @param aggregator Should take a collection of values and return a single, aggregate value
- * @param defaultValueForUnreportedSensors
- *
- * @see #CustomAggregatingEnricher(Map, AttributeSensor, AttributeSensor, Function, Object)
- */
- @SuppressWarnings("unchecked")
- public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target,
- Closure<?> aggregator, S defaultValueForUnreportedSensors) {
- this(flags, source, target, GroovyJavaMethods.<Collection<S>, T>functionFromClosure((Closure<T>)aggregator), defaultValueForUnreportedSensors);
- }
-
- public CustomAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target, Closure<?> aggregator) {
- this(flags, source, target, aggregator, null);
- }
-
- public CustomAggregatingEnricher(AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultValueForUnreportedSensors) {
- this(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultValueForUnreportedSensors);
- }
-
- public CustomAggregatingEnricher(AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
- this(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
- }
-
- @Override
- public void onUpdated() {
- try {
- entity.setAttribute(target, getAggregate());
- } catch (Throwable t) {
- LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
- throw Throwables.propagate(t);
- }
- }
-
- public T getAggregate() {
- synchronized (values) {
- return (T) aggregator.apply(values.values());
- }
- }
-
- /**
- * Instead, consider calling:
- * <pre>
- * {@code
- * Enrichers.Builder builder = Enrichers.builder()
- * .aggregating(source)
- * .publishing(target)
- * .computing(GroovyJavaMethods.<Collection<S>, T>functionFromClosure((Closure<T>)aggregator))
- * .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors);
- *
- * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
- * if (filter != null) builder.entityFilter(filter);
- * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
- *
- * addEnricher(builder.build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultVal) {
- return new CustomAggregatingEnricher<S,T>(flags, source, target, aggregator, defaultVal);
- }
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
- return newEnricher(flags, source, target, aggregator, null);
- }
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator, S defaultVal) {
- return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultVal);
- }
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- AttributeSensor<S> source, AttributeSensor<T> target, Closure<?> aggregator) {
- return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
- }
-
- /**
- * Instead, consider calling:
- * <pre>
- * {@code
- * Enrichers.Builder builder = Enrichers.builder()
- * .aggregating(source)
- * .publishing(target)
- * .computing(aggregator)
- * .defaultValueForUnreportedSensors(defaultVal);
- *
- * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
- * if (filter != null) builder.entityFilter(filter);
- * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
- *
- * addEnricher(builder.build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator, S defaultVal) {
- return new CustomAggregatingEnricher<S,T>(flags, source, target, aggregator, defaultVal);
- }
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- Map<String,?> flags, AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator) {
- return newEnricher(flags, source, target, aggregator, null);
- }
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator, S defaultVal) {
- return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, defaultVal);
- }
- public static <S,T> CustomAggregatingEnricher<S,T> newEnricher(
- AttributeSensor<S> source, AttributeSensor<T> target, Function<Collection<S>, T> aggregator) {
- return newEnricher(Collections.<String,Object>emptyMap(), source, target, aggregator, null);
- }
-
- /**
- * creates an enricher which sums over all children/members,
- * defaulting to excluding sensors which have not published anything (or published null), and null if there are no sensors;
- * this behaviour can be customised, both default value for sensors, and what to report if no sensors
- *
- * Instead, consider calling:
- * <pre>
- * {@code
- * Enrichers.Builder builder = Enrichers.builder()
- * .aggregating(source)
- * .publishing(target)
- * .computingSum()
- * .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors)
- * .valueToReportIfNoSensors(valueToReportIfNoSensors);
- *
- * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
- * if (filter != null) builder.entityFilter(filter);
- * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
- *
- * addEnricher(builder.build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public static <N extends Number, T extends Number> CustomAggregatingEnricher<N,T> newSummingEnricher(
- Map<String,?> flags, AttributeSensor<N> source, final AttributeSensor<T> target,
- final N defaultValueForUnreportedSensors, final T valueToReportIfNoSensors) {
-
- Function<Collection<N>, T> aggregator = new Function<Collection<N>, T>() {
- @Override public T apply(Collection<N> vals) {
- return sum(vals, defaultValueForUnreportedSensors, valueToReportIfNoSensors, target.getTypeToken());
- }
- };
- return new CustomAggregatingEnricher<N,T>(flags, source, target, aggregator, defaultValueForUnreportedSensors);
- }
-
- /** @see {@link #newSummingEnricher(Map, AttributeSensor, AttributeSensor, Number, Number)} */
- public static <N extends Number> CustomAggregatingEnricher<N,N> newSummingEnricher(
- AttributeSensor<N> source, AttributeSensor<N> target) {
- return newSummingEnricher(Collections.<String,Object>emptyMap(), source, target, null, null);
- }
-
- /** creates an enricher which averages over all children/members,
- * defaulting to excluding sensors which have not published anything (or published null), and null if there are no sensors;
- * this behaviour can be customised, both default value for sensors, and what to report if no sensors
- *
- * Instead, consider calling:
- * <pre>
- * {@code
- * Enrichers.Builder builder = Enrichers.builder()
- * .aggregating(source)
- * .publishing(target)
- * .computingAverage()
- * .defaultValueForUnreportedSensors(defaultValueForUnreportedSensors)
- * .valueToReportIfNoSensors(valueToReportIfNoSensors);
- *
- * if (Boolean.TRUE.equals(allMembers)) builder.fromMembers();
- * if (filter != null) builder.entityFilter(filter);
- * if (hardCodedProducers != null) builder.fromHardcodedProducers(hardCodedProducers);
- *
- * addEnricher(builder.build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public static <N extends Number> CustomAggregatingEnricher<N,Double> newAveragingEnricher(
- Map<String,?> flags, AttributeSensor<? extends N> source, final AttributeSensor<Double> target,
- final N defaultValueForUnreportedSensors, final Double valueToReportIfNoSensors) {
- Function<Collection<N>, Double> aggregator = new Function<Collection<N>, Double>() {
- @Override public Double apply(Collection<N> vals) {
- int count = count(vals, defaultValueForUnreportedSensors!=null);
- return (count==0) ? valueToReportIfNoSensors :
- (Double) ((sum(vals, defaultValueForUnreportedSensors, 0, TypeToken.of(Double.class)) / count));
- }
- };
- return new CustomAggregatingEnricher<N,Double>(flags, source, target, aggregator, defaultValueForUnreportedSensors);
- }
-
- /** @see #newAveragingEnricher(Map, AttributeSensor, AttributeSensor, Number, Double) */
- public static <N extends Number> CustomAggregatingEnricher<N,Double> newAveragingEnricher(
- AttributeSensor<N> source, AttributeSensor<Double> target) {
- return newAveragingEnricher(Collections.<String,Object>emptyMap(), source, target, null, null);
- }
-
- @SuppressWarnings("unchecked")
- private static <N extends Number> N cast(Number n, TypeToken<? extends N> numberType) {
- return (N) TypeCoercions.castPrimitive(n, numberType.getRawType());
- }
-
- private static <N extends Number> N sum(Iterable<? extends Number> vals, Number valueIfNull, Number valueIfNone, TypeToken<N> type) {
- double result = 0d;
- int count = 0;
- if (vals!=null) {
- for (Number val : vals) {
- if (val!=null) {
- result += val.doubleValue();
- count++;
- } else if (valueIfNull!=null) {
- result += valueIfNull.doubleValue();
- count++;
- }
- }
- }
- if (count==0) return cast(valueIfNone, type);
- return cast(result, type);
- }
-
- private static int count(Iterable<? extends Object> vals, boolean includeNullValues) {
- int result = 0;
- if (vals!=null)
- for (Object val : vals)
- if (val!=null || includeNullValues) result++;
- return result;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherDynamicType.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherDynamicType.java
deleted file mode 100644
index 1363617..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherDynamicType.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.sensor.Enricher;
-import org.apache.brooklyn.api.sensor.EnricherType;
-import org.apache.brooklyn.core.objs.BrooklynDynamicType;
-
-public class EnricherDynamicType extends BrooklynDynamicType<Enricher, AbstractEnricher> {
-
- public EnricherDynamicType(Class<? extends Enricher> type) {
- super(type);
- }
-
- public EnricherDynamicType(AbstractEnricher enricher) {
- super(enricher);
- }
-
- public EnricherType getSnapshot() {
- return (EnricherType) super.getSnapshot();
- }
-
- @Override
- protected EnricherTypeSnapshot newSnapshot() {
- return new EnricherTypeSnapshot(name, value(configKeys));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherTypeSnapshot.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherTypeSnapshot.java
deleted file mode 100644
index ed06de3..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/EnricherTypeSnapshot.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.sensor.EnricherType;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.objs.BrooklynTypeSnapshot;
-
-public class EnricherTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {
- private static final long serialVersionUID = 4670930188951106009L;
-
- EnricherTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
- super(name, configKeys);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- return (obj instanceof EnricherTypeSnapshot) && super.equals(obj);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/Enrichers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Enrichers.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Enrichers.java
deleted file mode 100644
index 84e541d..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Enrichers.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Enricher;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.text.StringPredicates;
-import org.apache.brooklyn.util.text.Strings;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.reflect.TypeToken;
-
-public class Enrichers {
-
- private Enrichers() {}
-
- public static InitialBuilder builder() {
- return new InitialBuilder();
- }
-
- public abstract static class Builder<B extends Builder<B>> {
- @SuppressWarnings("unchecked")
- protected B self() {
- return (B) this;
- }
- }
-
- public abstract static class AbstractEnricherBuilder<B extends AbstractEnricherBuilder<B>> extends Builder<B> {
- final Class<? extends Enricher> enricherType;
- Boolean suppressDuplicates;
- String uniqueTag;
- Set<Object> tags = MutableSet.of();
-
- public AbstractEnricherBuilder(Class<? extends Enricher> enricherType) {
- this.enricherType = enricherType;
- }
-
- public B uniqueTag(String tag) {
- uniqueTag = Preconditions.checkNotNull(tag);
- return self();
- }
- public B addTag(Object tag) {
- tags.add(Preconditions.checkNotNull(tag));
- return self();
- }
- public B suppressDuplicates(Boolean suppressDuplicates) {
- this.suppressDuplicates = suppressDuplicates;
- return self();
- }
-
- protected abstract String getDefaultUniqueTag();
-
- protected EnricherSpec<? extends Enricher> build() {
- EnricherSpec<? extends Enricher> spec = EnricherSpec.create(enricherType);
-
- String uniqueTag2 = uniqueTag;
- if (uniqueTag2==null)
- uniqueTag2 = getDefaultUniqueTag();
- if (uniqueTag2!=null)
- spec.uniqueTag(uniqueTag2);
-
- if (!tags.isEmpty()) spec.tags(tags);
- if (suppressDuplicates!=null)
- spec.configure(AbstractEnricher.SUPPRESS_DUPLICATES, suppressDuplicates);
-
- return spec;
- }
- }
-
- protected abstract static class AbstractInitialBuilder<B extends AbstractInitialBuilder<B>> extends Builder<B> {
- public PropagatorBuilder propagating(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) {
- return new PropagatorBuilder(vals);
- }
- public PropagatorBuilder propagating(Iterable<? extends Sensor<?>> vals) {
- return new PropagatorBuilder(vals);
- }
- public PropagatorBuilder propagating(Sensor<?>... vals) {
- return new PropagatorBuilder(vals);
- }
- public PropagatorBuilder propagatingAll() {
- return new PropagatorBuilder(true, null);
- }
- public PropagatorBuilder propagatingAllButUsualAnd(Sensor<?>... vals) {
- return new PropagatorBuilder(true, ImmutableSet.<Sensor<?>>builder().addAll(Propagator.SENSORS_NOT_USUALLY_PROPAGATED).add(vals).build());
- }
- public PropagatorBuilder propagatingAllBut(Sensor<?>... vals) {
- return new PropagatorBuilder(true, ImmutableSet.copyOf(vals));
- }
- public PropagatorBuilder propagatingAllBut(Iterable<? extends Sensor<?>> vals) {
- return new PropagatorBuilder(true, vals);
- }
-
- /**
- * Builds an enricher which transforms a given sensor:
- * <li> applying a (required) function ({@link TransformerBuilder#computing(Function)}, or
- * {@link AbstractAggregatorBuilder#computingAverage()}/
- * {@link AbstractAggregatorBuilder#computingSum()}, mandatory);
- * <li> and publishing it on the entity where the enricher is attached;
- * <li> optionally taking the sensor from a different source entity ({@link TransformerBuilder#from(Entity)});
- * <li> and optionally publishing it as a different sensor ({@link TransformerBuilder#publishing(AttributeSensor)});
- * <p> You must supply at least one of the optional values, of course, otherwise the enricher may loop endlessly!
- */
- public <S> TransformerBuilder<S, Object> transforming(AttributeSensor<S> val) {
- return new TransformerBuilder<S, Object>(val);
- }
- /** as {@link #transforming(AttributeSensor)} but accepting multiple sensors, with the function acting on the set of values */
- public <S> CombinerBuilder<S, Object> combining(Collection<AttributeSensor<? extends S>> vals) {
- return new CombinerBuilder<S, Object>(vals);
- }
- /** as {@link #combining(Collection)} */
- @SafeVarargs
- public final <S> CombinerBuilder<S, Object> combining(AttributeSensor<? extends S>... vals) {
- return new CombinerBuilder<S, Object>(vals);
- }
- /** as {@link #combining(Collection)} but the collection of values comes from the given sensor on multiple entities */
- public <S> AggregatorBuilder<S, Object> aggregating(AttributeSensor<S> val) {
- return new AggregatorBuilder<S,Object>(val);
- }
- /** creates an {@link UpdatingMap} enricher:
- * {@link UpdatingMapBuilder#from(AttributeSensor)} and {@link UpdatingMapBuilder#computing(Function)} are required
- **/
- public <S,TKey,TVal> UpdatingMapBuilder<S, TKey, TVal> updatingMap(AttributeSensor<Map<TKey,TVal>> target) {
- return new UpdatingMapBuilder<S, TKey, TVal>(target);
- }
- /** creates a {@link org.apache.brooklyn.sensor.enricher.Joiner} enricher builder
- * which joins entries in a list to produce a String
- **/
- public JoinerBuilder joining(AttributeSensor<?> source) {
- return new JoinerBuilder(source);
- }
- }
-
-
- protected abstract static class AbstractAggregatorBuilder<S, T, B extends AbstractAggregatorBuilder<S, T, B>> extends AbstractEnricherBuilder<B> {
- protected final AttributeSensor<S> aggregating;
- protected AttributeSensor<T> publishing;
- protected Entity fromEntity;
- /** @deprecated since 0.7.0, kept for backwards compatibility for rebind, but not used otherwise */
- @Deprecated protected Function<? super Collection<S>, ? extends T> computing;
- // use supplier so latest values of other fields can be used
- protected Supplier<Function<? super Collection<S>, ? extends T>> computingSupplier;
- protected Boolean fromMembers;
- protected Boolean fromChildren;
- protected Boolean excludingBlank;
- protected ImmutableSet<Entity> fromHardcodedProducers;
- protected Predicate<? super Entity> entityFilter;
- protected Predicate<Object> valueFilter;
- protected Object defaultValueForUnreportedSensors;
- protected Object valueToReportIfNoSensors;
-
- public AbstractAggregatorBuilder(AttributeSensor<S> aggregating) {
- super(Aggregator.class);
- this.aggregating = aggregating;
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <T2 extends T> AggregatorBuilder<S,T2> publishing(AttributeSensor<? extends T2> val) {
- this.publishing = (AttributeSensor) checkNotNull(val);
- return (AggregatorBuilder) self();
- }
- public B from(Entity val) {
- this.fromEntity = checkNotNull(val);
- return self();
- }
- public B fromMembers() {
- this.fromMembers = true;
- return self();
- }
- public B fromChildren() {
- this.fromChildren = true;
- return self();
- }
- public B fromHardcodedProducers(Iterable<? extends Entity> val) {
- this.fromHardcodedProducers = ImmutableSet.copyOf(val);
- return self();
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public B computing(Function<? super Collection<S>, ? extends T> val) {
- this.computingSupplier = (Supplier)Suppliers.ofInstance(checkNotNull(val));
- return self();
- }
- @SuppressWarnings({ "unchecked", "rawtypes", "unused" })
- private B computingSumLegacy() {
- // since 0.7.0, kept in case we need to rebind to this
- Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
- @Override public Number apply(Collection<S> input) {
- return sum((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
- }};
- this.computing((Function)function);
- return self();
- }
- @SuppressWarnings({ "unchecked", "rawtypes", "unused" })
- private B computingAverageLegacy() {
- // since 0.7.0, kept in case we need to rebind to this
- Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
- @Override public Number apply(Collection<S> input) {
- return average((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
- }};
- this.computing((Function)function);
- return self();
- }
- public B computingSum() {
- this.computingSupplier = new Supplier<Function<? super Collection<S>, ? extends T>>() {
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public Function<? super Collection<S>, ? extends T> get() {
- // relies on TypeCoercion of result from Number to T, and type erasure for us to get away with it!
- return (Function)new ComputingSum((Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, publishing.getTypeToken());
- }
- };
- return self();
- }
-
- public B computingAverage() {
- this.computingSupplier = new Supplier<Function<? super Collection<S>, ? extends T>>() {
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public Function<? super Collection<S>, ? extends T> get() {
- // relies on TypeCoercion of result from Number to T, and type erasure for us to get away with it!
- return (Function)new ComputingAverage((Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, publishing.getTypeToken());
- }
- };
- return self();
- }
- public B defaultValueForUnreportedSensors(S val) {
- this.defaultValueForUnreportedSensors = val;
- return self();
- }
- public B valueToReportIfNoSensors(Object val) {
- this.valueToReportIfNoSensors = val;
- return self();
- }
- public B entityFilter(Predicate<? super Entity> val) {
- this.entityFilter = val;
- return self();
- }
- public B excludingBlank() {
- this.excludingBlank = true;
- return self();
- }
- @Override
- protected String getDefaultUniqueTag() {
- if (publishing==null) return null;
- return "aggregator:"+publishing.getName();
- }
- public EnricherSpec<?> build() {
- Predicate<Object> valueFilter;
- if (Boolean.TRUE.equals(excludingBlank)) {
- valueFilter = new Predicate<Object>() {
- @Override public boolean apply(Object input) {
- return (input != null) &&
- ((input instanceof CharSequence) ? Strings.isNonBlank((CharSequence)input) : true);
- }
- };
- // above kept for deserialization; not sure necessary
- valueFilter = StringPredicates.isNonBlank();
- } else {
- valueFilter = null;
- }
- // FIXME excludingBlank; use valueFilter? exclude means ignored entirely or substituted for defaultMemberValue?
- return super.build().configure(MutableMap.builder()
- .putIfNotNull(Aggregator.PRODUCER, fromEntity)
- .put(Aggregator.TARGET_SENSOR, publishing)
- .put(Aggregator.SOURCE_SENSOR, aggregating)
- .putIfNotNull(Aggregator.FROM_CHILDREN, fromChildren)
- .putIfNotNull(Aggregator.FROM_MEMBERS, fromMembers)
- .putIfNotNull(Aggregator.TRANSFORMATION, computingSupplier.get())
- .putIfNotNull(Aggregator.FROM_HARDCODED_PRODUCERS, fromHardcodedProducers)
- .putIfNotNull(Aggregator.ENTITY_FILTER, entityFilter)
- .putIfNotNull(Aggregator.VALUE_FILTER, valueFilter)
- .putIfNotNull(Aggregator.DEFAULT_MEMBER_VALUE, defaultValueForUnreportedSensors)
- .build());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .omitNullValues()
- .add("aggregating", aggregating)
- .add("publishing", publishing)
- .add("fromEntity", fromEntity)
- .add("computing", computingSupplier)
- .add("fromMembers", fromMembers)
- .add("fromChildren", fromChildren)
- .add("excludingBlank", excludingBlank)
- .add("fromHardcodedProducers", fromHardcodedProducers)
- .add("entityFilter", entityFilter)
- .add("valueFilter", valueFilter)
- .add("defaultValueForUnreportedSensors", defaultValueForUnreportedSensors)
- .add("valueToReportIfNoSensors", valueToReportIfNoSensors)
- .toString();
- }
- }
-
- protected abstract static class AbstractCombinerBuilder<S, T, B extends AbstractCombinerBuilder<S, T, B>> extends AbstractEnricherBuilder<B> {
- protected final List<AttributeSensor<? extends S>> combining;
- protected AttributeSensor<T> publishing;
- protected Entity fromEntity;
- protected Function<? super Collection<S>, ? extends T> computing;
- protected Boolean excludingBlank;
- protected Object valueToReportIfNoSensors;
- protected Predicate<Object> valueFilter;
-
- // For summing/averaging
- protected Object defaultValueForUnreportedSensors;
-
- @SafeVarargs
- public AbstractCombinerBuilder(AttributeSensor<? extends S>... vals) {
- this(ImmutableList.copyOf(vals));
- }
- public AbstractCombinerBuilder(Collection<AttributeSensor<? extends S>> vals) {
- super(Combiner.class);
- checkArgument(checkNotNull(vals).size() > 0, "combining-sensors must be non-empty");
- this.combining = ImmutableList.<AttributeSensor<? extends S>>copyOf(vals);
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <T2 extends T> CombinerBuilder<S,T2> publishing(AttributeSensor<? extends T2> val) {
- this.publishing = (AttributeSensor) checkNotNull(val);
- return (CombinerBuilder) this;
- }
- public B from(Entity val) {
- this.fromEntity = checkNotNull(val);
- return self();
- }
- public B computing(Function<? super Collection<S>, ? extends T> val) {
- this.computing = checkNotNull(val);
- return self();
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public B computingSum() {
- Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
- @Override public Number apply(Collection<S> input) {
- return sum((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
- }};
- this.computing((Function)function);
- return self();
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public B computingAverage() {
- Function<Collection<S>, Number> function = new Function<Collection<S>, Number>() {
- @Override public Number apply(Collection<S> input) {
- return average((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, (TypeToken) publishing.getTypeToken());
- }};
- this.computing((Function)function);
- return self();
- }
- public B defaultValueForUnreportedSensors(Object val) {
- this.defaultValueForUnreportedSensors = val;
- return self();
- }
- public B valueToReportIfNoSensors(Object val) {
- this.valueToReportIfNoSensors = val;
- return self();
- }
- public B excludingBlank() {
- this.excludingBlank = true;
- return self();
- }
- @Override
- protected String getDefaultUniqueTag() {
- if (publishing==null) return null;
- return "combiner:"+publishing.getName();
- }
- public EnricherSpec<?> build() {
- return super.build().configure(MutableMap.builder()
- .putIfNotNull(Combiner.PRODUCER, fromEntity)
- .put(Combiner.TARGET_SENSOR, publishing)
- .put(Combiner.SOURCE_SENSORS, combining)
- .putIfNotNull(Combiner.TRANSFORMATION, computing)
- .putIfNotNull(Combiner.VALUE_FILTER, valueFilter)
- .build());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .omitNullValues()
- .add("combining", combining)
- .add("publishing", publishing)
- .add("fromEntity", fromEntity)
- .add("computing", computing)
- .add("excludingBlank", excludingBlank)
- .add("valueToReportIfNoSensors", valueToReportIfNoSensors)
- .add("valueFilter", valueFilter)
- .toString();
- }
- }
-
- protected abstract static class AbstractTransformerBuilder<S, T, B extends AbstractTransformerBuilder<S, T, B>> extends AbstractEnricherBuilder<B> {
- protected final AttributeSensor<S> transforming;
- protected AttributeSensor<T> publishing;
- protected Entity fromEntity;
- protected Function<? super S, ?> computing;
- protected Function<? super SensorEvent<S>, ?> computingFromEvent;
-
- public AbstractTransformerBuilder(AttributeSensor<S> val) {
- super(Transformer.class);
- this.transforming = checkNotNull(val);
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <T2 extends T> TransformerBuilder<S,T2> publishing(AttributeSensor<? extends T2> val) {
- this.publishing = (AttributeSensor) checkNotNull(val);
- return (TransformerBuilder) this;
- }
- public B from(Entity val) {
- this.fromEntity = checkNotNull(val);
- return self();
- }
- public B computing(Function<? super S, ? extends T> val) {
- this.computing = checkNotNull(val);
- return self();
- }
- public B computingFromEvent(Function<? super SensorEvent<S>, ? extends T> val) {
- this.computingFromEvent = checkNotNull(val);
- return self();
- }
- @Override
- protected String getDefaultUniqueTag() {
- if (publishing==null) return null;
- return "transformer:"+publishing.getName();
- }
- public EnricherSpec<?> build() {
- return super.build().configure(MutableMap.builder()
- .putIfNotNull(Transformer.PRODUCER, fromEntity)
- .put(Transformer.TARGET_SENSOR, publishing)
- .put(Transformer.SOURCE_SENSOR, transforming)
- .putIfNotNull(Transformer.TRANSFORMATION_FROM_VALUE, computing)
- .putIfNotNull(Transformer.TRANSFORMATION_FROM_EVENT, computingFromEvent)
- .build());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .omitNullValues()
- .add("publishing", publishing)
- .add("transforming", transforming)
- .add("fromEntity", fromEntity)
- .add("computing", computing)
- .toString();
- }
- }
-
- protected abstract static class AbstractPropagatorBuilder<B extends AbstractPropagatorBuilder<B>> extends AbstractEnricherBuilder<B> {
- protected final Map<? extends Sensor<?>, ? extends Sensor<?>> propagating;
- protected final Boolean propagatingAll;
- protected final Iterable<? extends Sensor<?>> propagatingAllBut;
- protected Entity fromEntity;
-
- public AbstractPropagatorBuilder(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) {
- super(Propagator.class);
- checkArgument(checkNotNull(vals).size() > 0, "propagating-sensors must be non-empty");
- this.propagating = vals;
- this.propagatingAll = null;
- this.propagatingAllBut = null;
- }
- public AbstractPropagatorBuilder(Iterable<? extends Sensor<?>> vals) {
- this(newIdentityMap(ImmutableSet.copyOf(vals)));
- }
- public AbstractPropagatorBuilder(Sensor<?>... vals) {
- this(newIdentityMap(ImmutableSet.copyOf(vals)));
- }
- AbstractPropagatorBuilder(boolean propagatingAll, Iterable<? extends Sensor<?>> butVals) {
- super(Propagator.class);
- // Ugly constructor! Taking boolean to differentiate it from others; could use a static builder
- // but feels like overkill having a builder for a builder, being called by a builder!
- checkArgument(propagatingAll, "Not propagating all; use PropagatingAll(vals)");
- this.propagating = null;
- this.propagatingAll = true;
- this.propagatingAllBut = (butVals == null || Iterables.isEmpty(butVals)) ? null: butVals;
- }
- public B from(Entity val) {
- this.fromEntity = checkNotNull(val);
- return self();
- }
- @Override
- protected String getDefaultUniqueTag() {
- List<String> summary = MutableList.of();
- if (propagating!=null) {
- for (Map.Entry<? extends Sensor<?>, ? extends Sensor<?>> entry: propagating.entrySet()) {
- if (entry.getKey().getName().equals(entry.getValue().getName()))
- summary.add(entry.getKey().getName());
- else
- summary.add(entry.getKey().getName()+"->"+entry.getValue().getName());
- }
- }
- if (Boolean.TRUE.equals(propagatingAll))
- summary.add("ALL");
- if (propagatingAllBut!=null && !Iterables.isEmpty(propagatingAllBut)) {
- List<String> allBut = MutableList.of();
- for (Sensor<?> s: propagatingAllBut) allBut.add(s.getName());
- summary.add("ALL_BUT:"+com.google.common.base.Joiner.on(",").join(allBut));
- }
-
- return "propagating["+fromEntity.getId()+":"+com.google.common.base.Joiner.on(",").join(summary)+"]";
- }
- public EnricherSpec<? extends Enricher> build() {
- return super.build().configure(MutableMap.builder()
- .putIfNotNull(Propagator.PRODUCER, fromEntity)
- .putIfNotNull(Propagator.SENSOR_MAPPING, propagating)
- .putIfNotNull(Propagator.PROPAGATING_ALL, propagatingAll)
- .putIfNotNull(Propagator.PROPAGATING_ALL_BUT, propagatingAllBut)
- .build());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .omitNullValues()
- .add("fromEntity", fromEntity)
- .add("propagating", propagating)
- .add("propagatingAll", propagatingAll)
- .add("propagatingAllBut", propagatingAllBut)
- .toString();
- }
- }
-
- public abstract static class AbstractUpdatingMapBuilder<S, TKey, TVal, B extends AbstractUpdatingMapBuilder<S, TKey, TVal, B>> extends AbstractEnricherBuilder<B> {
- protected AttributeSensor<Map<TKey,TVal>> targetSensor;
- protected AttributeSensor<? extends S> fromSensor;
- protected TKey key;
- protected Function<S, ? extends TVal> computing;
- protected Boolean removingIfResultIsNull;
-
- public AbstractUpdatingMapBuilder(AttributeSensor<Map<TKey,TVal>> target) {
- super(UpdatingMap.class);
- this.targetSensor = target;
- }
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public <S2 extends S> UpdatingMapBuilder<S2,TKey,TVal> from(AttributeSensor<S2> fromSensor) {
- this.fromSensor = checkNotNull(fromSensor);
- return (UpdatingMapBuilder) this;
- }
- public B computing(Function<S,? extends TVal> val) {
- this.computing = checkNotNull(val);
- return self();
- }
- /** sets an explicit key to use; defaults to using the name of the source sensor specified in {@link #from(AttributeSensor)} */
- public B key(TKey key) {
- this.key = key;
- return self();
- }
- /** sets explicit behaviour for treating <code>null</code> return values;
- * default is to remove */
- public B removingIfResultIsNull(boolean val) {
- this.removingIfResultIsNull = val;
- return self();
- }
- @Override
- protected String getDefaultUniqueTag() {
- if (targetSensor==null || fromSensor==null) return null;
- return "updating:"+targetSensor.getName()+"<-"+fromSensor.getName();
- }
- public EnricherSpec<?> build() {
- return super.build().configure(MutableMap.builder()
- .put(UpdatingMap.TARGET_SENSOR, targetSensor)
- .put(UpdatingMap.SOURCE_SENSOR, fromSensor)
- .putIfNotNull(UpdatingMap.KEY_IN_TARGET_SENSOR, key)
- .put(UpdatingMap.COMPUTING, computing)
- .putIfNotNull(UpdatingMap.REMOVING_IF_RESULT_IS_NULL, removingIfResultIsNull)
- .build());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .omitNullValues()
- .add("publishing", targetSensor)
- .add("fromSensor", fromSensor)
- .add("key", key)
- .add("computing", computing)
- .add("removingIfResultIsNull", removingIfResultIsNull)
- .toString();
- }
- }
-
- protected abstract static class AbstractJoinerBuilder<B extends AbstractJoinerBuilder<B>> extends AbstractEnricherBuilder<B> {
- protected final AttributeSensor<?> transforming;
- protected AttributeSensor<String> publishing;
- protected Entity fromEntity;
- protected String separator;
- protected Boolean quote;
- protected Integer minimum;
- protected Integer maximum;
-
- public AbstractJoinerBuilder(AttributeSensor<?> source) {
- super(Joiner.class);
- this.transforming = checkNotNull(source);
- }
- public B publishing(AttributeSensor<String> target) {
- this.publishing = checkNotNull(target);
- return self();
- }
- public B separator(String separator) {
- this.separator = separator;
- return self();
- }
- public B quote(Boolean quote) {
- this.quote = quote;
- return self();
- }
- public B minimum(Integer minimum) {
- this.minimum = minimum;
- return self();
- }
- public B maximum(Integer maximum) {
- this.maximum = maximum;
- return self();
- }
- @Override
- protected String getDefaultUniqueTag() {
- if (transforming==null || publishing==null) return null;
- return "joiner:"+transforming.getName()+"->"+publishing.getName();
- }
- public EnricherSpec<?> build() {
- return super.build().configure(MutableMap.builder()
- .putIfNotNull(Joiner.PRODUCER, fromEntity)
- .put(Joiner.TARGET_SENSOR, publishing)
- .put(Joiner.SOURCE_SENSOR, transforming)
- .putIfNotNull(Joiner.SEPARATOR, separator)
- .putIfNotNull(Joiner.QUOTE, quote)
- .putIfNotNull(Joiner.MINIMUM, minimum)
- .putIfNotNull(Joiner.MAXIMUM, maximum)
- .build());
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper(this)
- .omitNullValues()
- .add("publishing", publishing)
- .add("transforming", transforming)
- .add("separator", separator)
- .toString();
- }
- }
-
- public static class InitialBuilder extends AbstractInitialBuilder<InitialBuilder> {
- }
-
- public static class AggregatorBuilder<S, T> extends AbstractAggregatorBuilder<S, T, AggregatorBuilder<S, T>> {
- public AggregatorBuilder(AttributeSensor<S> aggregating) {
- super(aggregating);
- }
- }
-
- public static class PropagatorBuilder extends AbstractPropagatorBuilder<PropagatorBuilder> {
- public PropagatorBuilder(Map<? extends Sensor<?>, ? extends Sensor<?>> vals) {
- super(vals);
- }
- public PropagatorBuilder(Iterable<? extends Sensor<?>> vals) {
- super(vals);
- }
- public PropagatorBuilder(Sensor<?>... vals) {
- super(vals);
- }
- PropagatorBuilder(boolean propagatingAll, Iterable<? extends Sensor<?>> butVals) {
- super(propagatingAll, butVals);
- }
- }
-
- public static class CombinerBuilder<S, T> extends AbstractCombinerBuilder<S, T, CombinerBuilder<S, T>> {
- @SafeVarargs
- public CombinerBuilder(AttributeSensor<? extends S>... vals) {
- super(vals);
- }
- public CombinerBuilder(Collection<AttributeSensor<? extends S>> vals) {
- super(vals);
- }
- }
-
- public static class TransformerBuilder<S, T> extends AbstractTransformerBuilder<S, T, TransformerBuilder<S, T>> {
- public TransformerBuilder(AttributeSensor<S> val) {
- super(val);
- }
- }
-
- public static class UpdatingMapBuilder<S, TKey, TVal> extends AbstractUpdatingMapBuilder<S, TKey, TVal, UpdatingMapBuilder<S, TKey, TVal>> {
- public UpdatingMapBuilder(AttributeSensor<Map<TKey,TVal>> val) {
- super(val);
- }
- }
-
- public static class JoinerBuilder extends AbstractJoinerBuilder<JoinerBuilder> {
- public JoinerBuilder(AttributeSensor<?> source) {
- super(source);
- }
- }
-
- @Beta
- private abstract static class ComputingNumber<T extends Number> implements Function<Collection<T>, T> {
- protected final Number defaultValueForUnreportedSensors;
- protected final Number valueToReportIfNoSensors;
- protected final TypeToken<T> typeToken;
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public ComputingNumber(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
- this.defaultValueForUnreportedSensors = defaultValueForUnreportedSensors;
- this.valueToReportIfNoSensors = valueToReportIfNoSensors;
- if (typeToken!=null && TypeToken.of(Number.class).isAssignableFrom(typeToken.getType())) {
- this.typeToken = typeToken;
- } else if (typeToken==null || typeToken.isAssignableFrom(Number.class)) {
- // use double if e.g. Object is supplied
- this.typeToken = (TypeToken)TypeToken.of(Double.class);
- } else {
- throw new IllegalArgumentException("Type "+typeToken+" is not valid for "+this);
- }
- }
- @Override public abstract T apply(Collection<T> input);
- }
-
- @Beta
- public static class ComputingSum<T extends Number> extends ComputingNumber<T> {
- public ComputingSum(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
- super(defaultValueForUnreportedSensors, valueToReportIfNoSensors, typeToken);
- }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override public T apply(Collection<T> input) {
- return (T) sum((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, typeToken);
- }
- }
-
- @Beta
- public static class ComputingAverage<T extends Number> extends ComputingNumber<T> {
- public ComputingAverage(Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> typeToken) {
- super(defaultValueForUnreportedSensors, valueToReportIfNoSensors, typeToken);
- }
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override public T apply(Collection<T> input) {
- return (T) average((Collection)input, (Number)defaultValueForUnreportedSensors, (Number)valueToReportIfNoSensors, typeToken);
- }
- }
-
- protected static <T extends Number> T average(Collection<T> vals, Number defaultValueForUnreportedSensors, Number valueToReportIfNoSensors, TypeToken<T> type) {
- Double doubleValueToReportIfNoSensors = (valueToReportIfNoSensors == null) ? null : valueToReportIfNoSensors.doubleValue();
- int count = count(vals, defaultValueForUnreportedSensors!=null);
- Double result = (count==0) ? doubleValueToReportIfNoSensors :
- (Double) ((sum(vals, defaultValueForUnreportedSensors, 0, TypeToken.of(Double.class)) / count));
-
- return cast(result, type);
- }
-
- @SuppressWarnings("unchecked")
- protected static <N extends Number> N cast(Number n, TypeToken<? extends N> numberType) {
- return (N) TypeCoercions.castPrimitive(n, numberType.getRawType());
- }
-
- @Beta //may be moved
- public static <N extends Number> N sum(Iterable<? extends Number> vals, Number valueIfNull, Number valueIfNone, TypeToken<N> type) {
- double result = 0d;
- int count = 0;
- if (vals!=null) {
- for (Number val : vals) {
- if (val!=null) {
- result += val.doubleValue();
- count++;
- } else if (valueIfNull!=null) {
- result += valueIfNull.doubleValue();
- count++;
- }
- }
- }
- if (count==0) return cast(valueIfNone, type);
- return cast(result, type);
- }
-
- protected static int count(Iterable<? extends Object> vals, boolean includeNullValues) {
- int result = 0;
- if (vals != null)
- for (Object val : vals)
- if (val!=null || includeNullValues) result++;
- return result;
- }
-
- private static <T> Map<T,T> newIdentityMap(Set<T> keys) {
- Map<T,T> result = Maps.newLinkedHashMap();
- for (T key : keys) {
- result.put(key, key);
- }
- return result;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
deleted file mode 100644
index c6d9329..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-import org.apache.brooklyn.util.text.StringEscapes;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.reflect.TypeToken;
-
-//@Catalog(name="Transformer", description="Transforms attributes of an entity; see Enrichers.builder().transforming(...)")
-@SuppressWarnings("serial")
-public class Joiner<T> extends AbstractEnricher implements SensorEventListener<T> {
-
- private static final Logger LOG = LoggerFactory.getLogger(Joiner.class);
-
- public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
- public static ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
- public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
- @SetFromFlag("separator")
- public static ConfigKey<String> SEPARATOR = ConfigKeys.newStringConfigKey("enricher.joiner.separator", "Separator string to insert between each argument", ",");
- @SetFromFlag("quote")
- public static ConfigKey<Boolean> QUOTE = ConfigKeys.newBooleanConfigKey("enricher.joiner.quote", "Whether to bash-escape each parameter and wrap in double-quotes, defaulting to true", true);
- @SetFromFlag("minimum")
- public static ConfigKey<Integer> MINIMUM = ConfigKeys.newIntegerConfigKey("enricher.joiner.minimum", "Minimum number of elements to join; if fewer than this, sets null; default 0 (no minimum)");
- @SetFromFlag("maximum")
- public static ConfigKey<Integer> MAXIMUM = ConfigKeys.newIntegerConfigKey("enricher.joiner.maximum", "Maximum number of elements to join; default null means all elements always taken");
-
- protected Entity producer;
- protected AttributeSensor<T> sourceSensor;
- protected Sensor<String> targetSensor;
-
- public Joiner() {
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
-
- this.producer = getConfig(PRODUCER) == null ? entity: getConfig(PRODUCER);
- this.sourceSensor = (AttributeSensor<T>) getRequiredConfig(SOURCE_SENSOR);
- this.targetSensor = (Sensor<String>) getRequiredConfig(TARGET_SENSOR);
-
- subscribe(producer, sourceSensor, this);
-
- Object value = producer.getAttribute((AttributeSensor<?>)sourceSensor);
- // TODO would be useful to have a convenience to "subscribeAndThenIfItIsAlreadySetRunItOnce"
- if (value!=null) {
- onEvent(new BasicSensorEvent(sourceSensor, producer, value, -1));
- }
- }
-
- @Override
- public void onEvent(SensorEvent<T> event) {
- emit(targetSensor, compute(event));
- }
-
- protected Object compute(SensorEvent<T> event) {
- Object v = event.getValue();
- Object result = null;
- if (v!=null) {
- if (v instanceof Map) {
- v = ((Map<?,?>)v).values();
- }
- if (!(v instanceof Iterable)) {
- LOG.warn("Enricher "+this+" received a non-iterable value "+v.getClass()+" "+v+"; refusing to join");
- } else {
- MutableList<Object> c1 = MutableList.of();
- Integer maximum = getConfig(MAXIMUM);
- for (Object ci: (Iterable<?>)v) {
- if (maximum!=null && maximum>=0) {
- if (c1.size()>=maximum) break;
- }
- c1.appendIfNotNull(Strings.toString(ci));
- }
- Integer minimum = getConfig(MINIMUM);
- if (minimum!=null && c1.size() < minimum) {
- // use default null return value
- } else {
- if (getConfig(QUOTE)) {
- MutableList<Object> c2 = MutableList.of();
- for (Object ci: c1) {
- c2.add(StringEscapes.BashStringEscapes.wrapBash((String)ci));
- }
- c1 = c2;
- }
- result = Strings.join(c1, getConfig(SEPARATOR));
- }
- }
- }
- if (LOG.isTraceEnabled())
- LOG.trace("Enricher "+this+" computed "+result+" from "+event);
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/Propagator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Propagator.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Propagator.java
deleted file mode 100644
index 2d74848..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Propagator.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.reflect.TypeToken;
-
-@SuppressWarnings("serial")
-//@Catalog(name="Propagator", description="Propagates attributes from one entity to another; see Enrichers.builder().propagating(...)")
-public class Propagator extends AbstractEnricher implements SensorEventListener<Object> {
-
- private static final Logger LOG = LoggerFactory.getLogger(Propagator.class);
-
- public static final Set<Sensor<?>> SENSORS_NOT_USUALLY_PROPAGATED = ImmutableSet.<Sensor<?>>of(
- Attributes.SERVICE_UP, Attributes.SERVICE_NOT_UP_INDICATORS,
- Attributes.SERVICE_STATE_ACTUAL, Attributes.SERVICE_STATE_EXPECTED, Attributes.SERVICE_PROBLEMS);
-
- @SetFromFlag("producer")
- public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
-
- @SetFromFlag("propagatingAllBut")
- public static ConfigKey<Collection<Sensor<?>>> PROPAGATING_ALL_BUT = ConfigKeys.newConfigKey(new TypeToken<Collection<Sensor<?>>>() {}, "enricher.propagating.propagatingAllBut");
-
- @SetFromFlag("propagatingAll")
- public static ConfigKey<Boolean> PROPAGATING_ALL = ConfigKeys.newBooleanConfigKey("enricher.propagating.propagatingAll");
-
- @SetFromFlag("propagating")
- public static ConfigKey<Collection<? extends Sensor<?>>> PROPAGATING = ConfigKeys.newConfigKey(new TypeToken<Collection<? extends Sensor<?>>>() {}, "enricher.propagating.inclusions");
-
- @SetFromFlag("sensorMapping")
- public static ConfigKey<Map<? extends Sensor<?>, ? extends Sensor<?>>> SENSOR_MAPPING = ConfigKeys.newConfigKey(new TypeToken<Map<? extends Sensor<?>, ? extends Sensor<?>>>() {}, "enricher.propagating.sensorMapping");
-
- protected Entity producer;
- protected Map<? extends Sensor<?>, ? extends Sensor<?>> sensorMapping;
- protected boolean propagatingAll;
- protected Collection<Sensor<?>> propagatingAllBut;
- protected Predicate<Sensor<?>> sensorFilter;
-
- public Propagator() {
- }
-
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
-
- this.producer = getConfig(PRODUCER) == null ? entity : getConfig(PRODUCER);
- boolean sensorMappingSet = getConfig(SENSOR_MAPPING)!=null;
- MutableMap<Sensor<?>,Sensor<?>> sensorMappingTemp = MutableMap.copyOf(getConfig(SENSOR_MAPPING));
- this.propagatingAll = Boolean.TRUE.equals(getConfig(PROPAGATING_ALL)) || getConfig(PROPAGATING_ALL_BUT)!=null;
-
- if (getConfig(PROPAGATING) != null) {
- if (propagatingAll) {
- throw new IllegalStateException("Propagator enricher "+this+" must not have 'propagating' set at same time as either 'propagatingAll' or 'propagatingAllBut'");
- }
-
- for (Object sensorO : getConfig(PROPAGATING)) {
- Sensor<?> sensor = Tasks.resolving(sensorO).as(Sensor.class).timeout(ValueResolver.REAL_QUICK_WAIT).context(producer).get();
- if (!sensorMappingTemp.containsKey(sensor)) {
- sensorMappingTemp.put(sensor, sensor);
- }
- }
- this.sensorMapping = ImmutableMap.copyOf(sensorMappingTemp);
- this.sensorFilter = new Predicate<Sensor<?>>() {
- @Override public boolean apply(Sensor<?> input) {
- // TODO kept for deserialization of inner classes, but shouldn't be necessary, as with other inner classes (qv);
- // NB: previously this did this check:
-// return input != null && sensorMapping.keySet().contains(input);
- // but those clauses seems wrong (when would input be null?) and unnecessary (we are doing an explicit subscribe in this code path)
- return true;
- }
- };
- } else if (sensorMappingSet) {
- if (propagatingAll) {
- throw new IllegalStateException("Propagator enricher "+this+" must not have 'sensorMapping' set at same time as either 'propagatingAll' or 'propagatingAllBut'");
- }
- this.sensorMapping = ImmutableMap.copyOf(sensorMappingTemp);
- this.sensorFilter = Predicates.alwaysTrue();
- } else {
- this.sensorMapping = ImmutableMap.<Sensor<?>, Sensor<?>>of();
- if (!propagatingAll) {
- // default if nothing specified is to do all but the ones not usually propagated
- propagatingAll = true;
- // user specified nothing, so *set* the all_but to the default set
- // if desired, we could allow this to be dynamically reconfigurable, remove this field and always look up;
- // slight performance hit (always looking up), and might need to recompute subscriptions, so not supported currently
- // TODO this default is @Beta behaviour! -- maybe better to throw?
- propagatingAllBut = SENSORS_NOT_USUALLY_PROPAGATED;
- } else {
- propagatingAllBut = getConfig(PROPAGATING_ALL_BUT);
- }
- this.sensorFilter = new Predicate<Sensor<?>>() {
- @Override public boolean apply(Sensor<?> input) {
- Collection<Sensor<?>> exclusions = propagatingAllBut;
- // TODO this anonymous inner class and getConfig check kept should be removed / confirmed for rebind compatibility.
- // we *should* be regenerating these fields on each rebind (calling to this method),
- // so serialization of this class shouldn't be needed (and should be skipped), but that needs to be checked.
- if (propagatingAllBut==null) exclusions = getConfig(PROPAGATING_ALL_BUT);
- return input != null && (exclusions==null || !exclusions.contains(input));
- }
- };
- }
-
- Preconditions.checkState(propagatingAll ^ sensorMapping.size() > 0,
- "Nothing to propagate; detected: propagatingAll (%s, excluding %s), sensorMapping (%s)", propagatingAll, getConfig(PROPAGATING_ALL_BUT), sensorMapping);
-
- if (propagatingAll) {
- subscribe(producer, null, this);
- } else {
- for (Sensor<?> sensor : sensorMapping.keySet()) {
- subscribe(producer, sensor, this);
- }
- }
-
- emitAllAttributes();
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- public void onEvent(SensorEvent<Object> event) {
- // propagate upwards
- Sensor<?> sourceSensor = event.getSensor();
- Sensor<?> destinationSensor = getDestinationSensor(sourceSensor);
-
- if (!sensorFilter.apply(sourceSensor)) {
- return; // ignoring excluded sensor
- }
-
- if (LOG.isTraceEnabled()) LOG.trace("enricher {} got {}, propagating via {}{}",
- new Object[] {this, event, entity, (sourceSensor == destinationSensor ? "" : " (as "+destinationSensor+")")});
-
- emit((Sensor)destinationSensor, event.getValue());
- }
-
- /** useful once sensors are added to emit all values */
- public void emitAllAttributes() {
- emitAllAttributes(false);
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void emitAllAttributes(boolean includeNullValues) {
- Iterable<? extends Sensor<?>> sensorsToPopulate = propagatingAll
- ? Iterables.filter(producer.getEntityType().getSensors(), sensorFilter)
- : sensorMapping.keySet();
-
- for (Sensor<?> s : sensorsToPopulate) {
- if (s instanceof AttributeSensor) {
- AttributeSensor destinationSensor = (AttributeSensor<?>) getDestinationSensor(s);
- Object v = producer.getAttribute((AttributeSensor<?>)s);
- // TODO we should keep a timestamp for the source sensor and echo it
- // (this pretends timestamps are current, which probably isn't the case when we are propagating)
- if (v != null || includeNullValues) entity.setAttribute(destinationSensor, v);
- }
- }
- }
-
- private Sensor<?> getDestinationSensor(Sensor<?> sourceSensor) {
- return sensorMapping.containsKey(sourceSensor) ? sensorMapping.get(sourceSensor): sourceSensor;
- }
-}
[28/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
deleted file mode 100644
index d020a25..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.location.SimulatedLocation;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.math.MathFunctions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.collect.ImmutableList;
-
-public class TransformingEnricherTest extends BrooklynAppUnitTestSupport {
-
- public static final Logger log = LoggerFactory.getLogger(TransformingEnricherTest.class);
-
- TestEntity producer;
- AttributeSensor<Integer> intSensorA;
- AttributeSensor<Long> target;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a");
- target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target");
-
- app.start(ImmutableList.of(new SimulatedLocation()));
- }
-
- @Test
- public void testTransformingEnricher() throws Exception {
- //ensure previous values get picked up
- producer.setAttribute(intSensorA, 3);
-
- producer.addEnricher(Enrichers.builder()
- .transforming(intSensorA)
- //.computing(MathFunctions.times(2)) // TODO calling it before "publishing" means it doesn't check return type!
- .publishing(target)
- .computing((Function)MathFunctions.times(2)) // TODO doesn't match strongly typed int->long
- .build());
-
- EntityTestUtils.assertAttributeEqualsEventually(producer, target, 6L);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
deleted file mode 100644
index e7fbcd6..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.SubscriptionContext;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.core.entity.AbstractApplication;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.sensor.enricher.YamlRollingTimeWindowMeanEnricher;
-import org.apache.brooklyn.sensor.enricher.YamlTimeWeightedDeltaEnricher;
-import org.apache.brooklyn.sensor.enricher.YamlRollingTimeWindowMeanEnricher.ConfidenceQualifiedNumber;
-import org.apache.brooklyn.util.time.Duration;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class YamlRollingTimeWindowMeanEnricherTest {
-
- AbstractApplication app;
-
- BasicEntity producer;
-
- AttributeSensor<Integer> intSensor;
- AttributeSensor<Double> avgSensor, deltaSensor;
-
- Duration timePeriod = Duration.ONE_SECOND;
-
- YamlTimeWeightedDeltaEnricher<Double> delta;
- YamlRollingTimeWindowMeanEnricher<Double> averager;
-
- ConfidenceQualifiedNumber average;
- SubscriptionContext subscription;
-
- @SuppressWarnings("unchecked")
- @BeforeMethod
- public void before() {
- app = new AbstractApplication() {};
- Entities.startManagement(app);
- producer = app.addChild(EntitySpec.create(BasicEntity.class));
-
- intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor");
- deltaSensor = new BasicAttributeSensor<Double>(Double.class, "delta sensor");
- avgSensor = new BasicAttributeSensor<Double>(Double.class, "avg sensor");
-
- delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class)
- .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer)
- .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor)
- .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor));
-
- averager = producer.addEnricher(EnricherSpec.create(YamlRollingTimeWindowMeanEnricher.class)
- .configure(YamlRollingTimeWindowMeanEnricher.PRODUCER, producer)
- .configure(YamlRollingTimeWindowMeanEnricher.SOURCE_SENSOR, deltaSensor)
- .configure(YamlRollingTimeWindowMeanEnricher.TARGET_SENSOR, avgSensor)
- .configure(YamlRollingTimeWindowMeanEnricher.WINDOW_DURATION, timePeriod));
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (app != null) Entities.destroyAll(app.getManagementContext());
- }
-
- @Test
- public void testDefaultAverageWhenEmpty() {
- ConfidenceQualifiedNumber average = averager.getAverage(0, 0);
- assertEquals(average.value, 0d);
- assertEquals(average.confidence, 0.0d);
- }
-
- protected BasicSensorEvent<Integer> newIntSensorEvent(int value, long timestamp) {
- return new BasicSensorEvent<Integer>(intSensor, producer, value, timestamp);
- }
- protected BasicSensorEvent<Double> newDeltaSensorEvent(double value, long timestamp) {
- return new BasicSensorEvent<Double>(deltaSensor, producer, value, timestamp);
- }
-
- @Test
- public void testNoRecentValuesAverage() {
- averager.onEvent(newDeltaSensorEvent(10, 0));
- average = averager.getAverage(timePeriod.toMilliseconds()+1000, 0);
- assertEquals(average.value, 10d);
- assertEquals(average.confidence, 0d);
- }
-
- @Test
- public void testNoRecentValuesUsesLastForAverage() {
- averager.onEvent(newDeltaSensorEvent(10, 0));
- averager.onEvent(newDeltaSensorEvent(20, 10));
- average = averager.getAverage(timePeriod.toMilliseconds()+1000, 0);
- assertEquals(average.value, 20d);
- assertEquals(average.confidence, 0d);
- }
-
- @Test
- public void testSingleValueTimeAverage() {
- averager.onEvent(newDeltaSensorEvent(10, 1000));
- average = averager.getAverage(1000, 0);
- assertEquals(average.confidence, 0d);
- }
-
- @Test
- public void testTwoValueAverageForPeriod() {
- averager.onEvent(newDeltaSensorEvent(10, 1000));
- averager.onEvent(newDeltaSensorEvent(10, 2000));
- average = averager.getAverage(2000, 0);
- assertEquals(average.value, 10 /1d);
- assertEquals(average.confidence, 1d);
- }
-
- @Test
- public void testMonospacedAverage() {
- averager.onEvent(newDeltaSensorEvent(10, 1000));
- averager.onEvent(newDeltaSensorEvent(20, 1250));
- averager.onEvent(newDeltaSensorEvent(30, 1500));
- averager.onEvent(newDeltaSensorEvent(40, 1750));
- averager.onEvent(newDeltaSensorEvent(50, 2000));
- average = averager.getAverage(2000, 0);
- assertEquals(average.value, (20+30+40+50)/4d);
- assertEquals(average.confidence, 1d);
- }
-
- @Test
- public void testWeightedAverage() {
- averager.onEvent(newDeltaSensorEvent(10, 1000));
- averager.onEvent(newDeltaSensorEvent(20, 1100));
- averager.onEvent(newDeltaSensorEvent(30, 1300));
- averager.onEvent(newDeltaSensorEvent(40, 1600));
- averager.onEvent(newDeltaSensorEvent(50, 2000));
-
- average = averager.getAverage(2000, 0);
- assertEquals(average.value, (20*0.1d)+(30*0.2d)+(40*0.3d)+(50*0.4d));
- assertEquals(average.confidence, 1d);
- }
-
- @Test
- public void testConfidenceDecay() {
- averager.onEvent(newDeltaSensorEvent(10, 1000));
- averager.onEvent(newDeltaSensorEvent(20, 1250));
- averager.onEvent(newDeltaSensorEvent(30, 1500));
- averager.onEvent(newDeltaSensorEvent(40, 1750));
- averager.onEvent(newDeltaSensorEvent(50, 2000));
-
- average = averager.getAverage(2250, 0);
- assertEquals(average.value, (30+40+50)/3d);
- assertEquals(average.confidence, 0.75d);
- average = averager.getAverage(2500, 0);
- assertEquals(average.value, (40+50)/2d);
- assertEquals(average.confidence, 0.5d);
- average = averager.getAverage(2750, 0);
- assertEquals(average.value, 50d);
- assertEquals(average.confidence, 0.25d);
- average = averager.getAverage(3000, 0);
- assertEquals(average.value, 50d);
- assertEquals(average.confidence, 0d);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
deleted file mode 100644
index 5b98168..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.SubscriptionContext;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.EnricherSpec;
-import org.apache.brooklyn.core.entity.AbstractApplication;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.core.sensor.BasicSensorEvent;
-import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.sensor.enricher.YamlTimeWeightedDeltaEnricher;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class YamlTimeWeightedDeltaEnricherTest {
-
- AbstractApplication app;
-
- BasicEntity producer;
-
- AttributeSensor<Integer> intSensor;
- AttributeSensor<Double> avgSensor, deltaSensor;
- SubscriptionContext subscription;
-
- @BeforeMethod
- public void before() {
- app = new AbstractApplication() {};
- Entities.startManagement(app);
- producer = app.addChild(EntitySpec.create(BasicEntity.class));
-
- intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor");
- deltaSensor = new BasicAttributeSensor<Double>(Double.class, "delta sensor");
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (app != null) Entities.destroyAll(app.getManagementContext());
- }
-
- @Test
- public void testMonospaceTimeWeightedDeltaEnricher() {
- @SuppressWarnings("unchecked")
- YamlTimeWeightedDeltaEnricher<Integer> delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class)
- .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer)
- .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor)
- .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor));
-
- delta.onEvent(newIntSensorEvent(0, 0));
- assertEquals(producer.getAttribute(deltaSensor), null);
- delta.onEvent(newIntSensorEvent(0, 1000));
- assertEquals(producer.getAttribute(deltaSensor), 0d);
- delta.onEvent(newIntSensorEvent(1, 2000));
- assertEquals(producer.getAttribute(deltaSensor), 1d);
- delta.onEvent(newIntSensorEvent(3, 3000));
- assertEquals(producer.getAttribute(deltaSensor), 2d);
- delta.onEvent(newIntSensorEvent(8, 4000));
- assertEquals(producer.getAttribute(deltaSensor), 5d);
- }
-
- protected BasicSensorEvent<Integer> newIntSensorEvent(int value, long timestamp) {
- return new BasicSensorEvent<Integer>(intSensor, producer, value, timestamp);
- }
-
- @Test
- public void testVariableTimeWeightedDeltaEnricher() {
- @SuppressWarnings("unchecked")
- YamlTimeWeightedDeltaEnricher<Integer> delta = producer.addEnricher(EnricherSpec.create(YamlTimeWeightedDeltaEnricher.class)
- .configure(YamlTimeWeightedDeltaEnricher.PRODUCER, producer)
- .configure(YamlTimeWeightedDeltaEnricher.SOURCE_SENSOR, intSensor)
- .configure(YamlTimeWeightedDeltaEnricher.TARGET_SENSOR, deltaSensor));
-
- delta.onEvent(newIntSensorEvent(0, 0));
- delta.onEvent(newIntSensorEvent(0, 2000));
- assertEquals(producer.getAttribute(deltaSensor), 0d);
- delta.onEvent(newIntSensorEvent(3, 5000));
- assertEquals(producer.getAttribute(deltaSensor), 1d);
- delta.onEvent(newIntSensorEvent(7, 7000));
- assertEquals(producer.getAttribute(deltaSensor), 2d);
- delta.onEvent(newIntSensorEvent(12, 7500));
- assertEquals(producer.getAttribute(deltaSensor), 10d);
- delta.onEvent(newIntSensorEvent(15, 9500));
- assertEquals(producer.getAttribute(deltaSensor), 1.5d);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
index 24622c0..6b43e7d 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/ResilientMongoDbApp.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
@@ -38,7 +39,6 @@ import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.ha.ServiceFailureDetector;
import org.apache.brooklyn.policy.ha.ServiceReplacer;
import org.apache.brooklyn.policy.ha.ServiceRestarter;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
import com.google.common.collect.Lists;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
index 6c56b5f..0d224bd 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExample.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -43,7 +44,6 @@ import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
index ed8a987..b1d373b 100644
--- a/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
+++ b/examples/simple-web-cluster/src/main/java/org/apache/brooklyn/demo/WebClusterDatabaseExampleApp.java
@@ -37,6 +37,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.JavaWebAppService;
@@ -48,7 +49,6 @@ import org.apache.brooklyn.entity.java.JavaEntityMethods;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
import org.apache.brooklyn.util.core.BrooklynMavenArtifacts;
import org.apache.brooklyn.util.core.ResourceUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
----------------------------------------------------------------------
diff --git a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
index 40fd821..128e6cf 100644
--- a/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
+++ b/examples/simple-web-cluster/src/test/java/org/apache/brooklyn/demo/RebindWebClusterDatabaseExampleAppIntegrationTest.java
@@ -26,11 +26,11 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.mgmt.rebind.RebindOptions;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixture;
+import org.apache.brooklyn.enricher.stock.Propagator;
import org.apache.brooklyn.entity.proxy.nginx.NginxController;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.DynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.tomcat.Tomcat8Server;
-import org.apache.brooklyn.sensor.enricher.Propagator;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.test.HttpTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/policy/src/main/java/org/apache/brooklyn/policy/enricher/DeltaEnricher.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/DeltaEnricher.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/DeltaEnricher.java
index 64b789d..784c709 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/DeltaEnricher.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/DeltaEnricher.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.sensor.enricher.AbstractTransformingEnricher;
+import org.apache.brooklyn.enricher.stock.AbstractTransformingEnricher;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
index c5d7415..58fda00 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/HttpLatencyDetector.java
@@ -34,12 +34,12 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.feed.http.HttpFeed;
import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.AtomicReferences;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.java
index f5ffc35..40243a1 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingMeanEnricher.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.sensor.enricher.AbstractTypeTransformingEnricher;
+import org.apache.brooklyn.enricher.stock.AbstractTypeTransformingEnricher;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.JavaClassNames;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.java
index e91e2a8..ae6d637 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/RollingTimeWindowMeanEnricher.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.enricher.AbstractTypeTransformingEnricher;
-import org.apache.brooklyn.sensor.enricher.YamlRollingTimeWindowMeanEnricher;
+import org.apache.brooklyn.enricher.stock.AbstractTypeTransformingEnricher;
+import org.apache.brooklyn.enricher.stock.YamlRollingTimeWindowMeanEnricher;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.JavaClassNames;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricher.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricher.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricher.java
index ec325fd..3906b7b 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricher.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeFractionDeltaEnricher.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.sensor.enricher.AbstractTypeTransformingEnricher;
+import org.apache.brooklyn.enricher.stock.AbstractTypeTransformingEnricher;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.JavaClassNames;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeWeightedDeltaEnricher.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeWeightedDeltaEnricher.java b/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeWeightedDeltaEnricher.java
index 433c415..7eb4460 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeWeightedDeltaEnricher.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/enricher/TimeWeightedDeltaEnricher.java
@@ -24,8 +24,8 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.sensor.enricher.AbstractTypeTransformingEnricher;
-import org.apache.brooklyn.sensor.enricher.YamlTimeWeightedDeltaEnricher;
+import org.apache.brooklyn.enricher.stock.AbstractTypeTransformingEnricher;
+import org.apache.brooklyn.enricher.stock.YamlTimeWeightedDeltaEnricher;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
import org.apache.brooklyn.util.javalang.JavaClassNames;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
index bbe5bf2..8a9543d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynClusterImpl.java
@@ -27,12 +27,12 @@ import org.apache.brooklyn.core.entity.EntityFunctions;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceProblemsLogic;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.brooklynnode.effector.BrooklynClusterUpgradeEffectorBody;
import org.apache.brooklyn.entity.brooklynnode.effector.SelectMasterEffectorBody;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.feed.function.FunctionFeed;
import org.apache.brooklyn.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 02f5965..df9651e 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -45,6 +45,7 @@ import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient.ResponseCodePredicates;
import org.apache.brooklyn.entity.brooklynnode.effector.BrooklynNodeUpgradeEffectorBody;
import org.apache.brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
@@ -59,7 +60,6 @@ import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
index b67780b..f4e02c4 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
@@ -41,6 +41,7 @@ import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
@@ -56,7 +57,6 @@ import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
index 6470a4b..4b8c5f5 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricher.java
@@ -28,13 +28,13 @@ import org.apache.brooklyn.api.sensor.Enricher;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags.WrappedStream;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.core.task.BasicExecutionManager;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskBuilder;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
index f78ddba..40f0989 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
@@ -20,13 +20,13 @@ package org.apache.brooklyn.entity.database.crate;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.feed.http.HttpFeed;
import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.guava.Functionals;
public class CrateNodeImpl extends SoftwareProcessImpl implements CrateNode{
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
index d6527ca..9a444fd 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
@@ -38,10 +38,10 @@ import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.feed.function.FunctionFeed;
import org.apache.brooklyn.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskBuilder;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
index ceb4422..3daa097 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaClusterImpl.java
@@ -28,11 +28,11 @@ import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.feed.ConfigToAttributes;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormDeploymentImpl.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormDeploymentImpl.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormDeploymentImpl.java
index e8faa7b..61d6a4e 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormDeploymentImpl.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormDeploymentImpl.java
@@ -25,12 +25,12 @@ import static org.apache.brooklyn.entity.messaging.storm.Storm.Role.UI;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.stock.BasicStartableImpl;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperEnsemble;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.core.ResourceUtils;
public class StormDeploymentImpl extends BasicStartableImpl implements StormDeployment {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerIntegrationTest.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerIntegrationTest.java
index a87cc9c..2f68059 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerIntegrationTest.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/BindDnsServerIntegrationTest.java
@@ -31,9 +31,9 @@ import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.mgmt.rebind.RebindOptions;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixture;
import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.test.EntityTestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
index c32e2ce..9c75ace 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
@@ -24,8 +24,8 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
index 13df45b..27f83aa 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
@@ -42,12 +42,12 @@ import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.entity.group.DynamicGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
index 4bff736..3ae6fe9 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
@@ -42,6 +42,7 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
@@ -51,7 +52,6 @@ import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.feed.http.JsonFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.collections.QuorumCheck;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
index 49a1201..399ea91 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSetImpl.java
@@ -44,9 +44,9 @@ import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
index e27cb4b..7817dbc 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
@@ -25,8 +25,8 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.software.base.SameServerEntityImpl;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
index cbebbec..9ef50b9 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
@@ -35,9 +35,9 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
index 838def8..92c7593 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
@@ -30,8 +30,8 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceProblemsLogic;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
index d3a9b70..5002402 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
@@ -39,9 +39,9 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
index 85ac3e8..08773c8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
@@ -33,12 +33,12 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.webapp.WebAppServiceMethods;
import org.apache.brooklyn.feed.http.HttpFeed;
import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.guava.Functionals;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
index 7952c91..eadde49 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxControllerImpl.java
@@ -36,6 +36,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.feed.ConfigToAttributes;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.proxy.AbstractControllerImpl;
import org.apache.brooklyn.entity.proxy.ProxySslConfig;
@@ -43,7 +44,6 @@ import org.apache.brooklyn.entity.proxy.nginx.NginxController.NginxControllerInt
import org.apache.brooklyn.feed.http.HttpFeed;
import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.file.ArchiveUtils;
import org.apache.brooklyn.util.core.http.HttpTool;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
index 7ff08a5..3785a47 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppClusterImpl.java
@@ -38,11 +38,11 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.entity.trait.StartableMethods;
import org.apache.brooklyn.core.feed.ConfigToAttributes;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicGroupImpl;
import org.apache.brooklyn.entity.proxy.LoadBalancer;
import org.apache.brooklyn.entity.proxy.nginx.NginxController;
import org.apache.brooklyn.entity.webapp.tomcat.TomcatServer;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
index 10d21a1..4bc1fd3 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
@@ -33,9 +33,9 @@ import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricImpl.java
index 38bf6f6..2c9747d 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabricImpl.java
@@ -23,8 +23,8 @@ import java.util.List;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicFabricImpl;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
index 7c7173b..2d8bc54 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6ServerImpl.java
@@ -24,10 +24,10 @@ import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
index f32d6a0..09f09c1 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7ServerImpl.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
import org.apache.brooklyn.feed.http.HttpFeed;
import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.guava.Functionals;
import com.google.common.base.Functions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
index d264c66..d8f2433 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6ServerImpl.java
@@ -21,12 +21,12 @@ package org.apache.brooklyn.entity.webapp.jetty;
import java.util.concurrent.TimeUnit;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcessImpl;
import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.feed.jmx.JmxFeed;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
----------------------------------------------------------------------
diff --git a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
index bc53541..11d977f 100644
--- a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
+++ b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
@@ -12,6 +12,8 @@ import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.enricher.stock.SensorPropagatingEnricher;
+import org.apache.brooklyn.enricher.stock.SensorTransformingEnricher;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.group.DynamicCluster;
@@ -23,8 +25,6 @@ import org.apache.brooklyn.entity.webapp.WebAppService;
import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.enricher.SensorPropagatingEnricher;
-import org.apache.brooklyn.sensor.enricher.SensorTransformingEnricher;
import org.apache.brooklyn.util.maven.MavenArtifact;
import org.apache.brooklyn.util.maven.MavenRetriever;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
index 9054088..8f23a44 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersYamlTest.java
@@ -30,7 +30,7 @@ import org.apache.brooklyn.core.entity.EntityAdjuncts;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.policy.TestEnricher;
-import org.apache.brooklyn.sensor.enricher.Propagator;
+import org.apache.brooklyn.enricher.stock.Propagator;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
index 4d8a426..8468014 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestReferencingEnricher.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.camp.brooklyn;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
public class TestReferencingEnricher extends AbstractEnricher {
public static final ConfigKey<Entity> TEST_APPLICATION = new BasicConfigKey<Entity>(Entity.class, "test.reference.app");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/camp/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml b/usage/camp/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
index bc753a5..2b55237 100644
--- a/usage/camp/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
+++ b/usage/camp/src/test/resources/test-app-with-enrichers-slightly-simpler.yaml
@@ -29,14 +29,14 @@ services:
$brooklyn:entitySpec:
type: org.apache.brooklyn.core.test.entity.TestEntity
brooklyn.enrichers:
- - type: org.apache.brooklyn.sensor.enricher.Transformer
+ - type: org.apache.brooklyn.enricher.stock.Transformer
# transform "ip" (which we expect a feed, not shown here, to set) to a URL;
# you can curl an address string to the sensors/ip endpoint an entity to trigger these enrichers
brooklyn.config:
enricher.sourceSensor: $brooklyn:sensor("ip")
enricher.targetSensor: $brooklyn:sensor("url")
enricher.targetValue: $brooklyn:formatString("http://%s/", $brooklyn:attributeWhenReady("ip"))
- - type: org.apache.brooklyn.sensor.enricher.Propagator
+ - type: org.apache.brooklyn.enricher.stock.Propagator
# use propagator to duplicate one sensor as another, giving the supplied sensor mapping;
# the other use of Propagator is where you specify a producer (using $brooklyn:entity(...) as below)
# from which to take sensors; in that mode you can specify `propagate` as a list of sensors whose names are unchanged,
@@ -45,13 +45,13 @@ services:
sensorMapping:
$brooklyn:sensor("url"): $brooklyn:sensor("org.apache.brooklyn.core.entity.Attributes", "main.uri")
brooklyn.enrichers:
- - type: org.apache.brooklyn.sensor.enricher.Aggregator
+ - type: org.apache.brooklyn.enricher.stock.Aggregator
# aggregate `url` sensors from children into a list
brooklyn.config:
enricher.sourceSensor: $brooklyn:sensor("url")
enricher.targetSensor: $brooklyn:sensor("urls.list")
enricher.aggregating.fromMembers: true
- - type: org.apache.brooklyn.sensor.enricher.Joiner
+ - type: org.apache.brooklyn.enricher.stock.Joiner
# create a string from that list, for use e.g. in bash scripts
brooklyn.config:
enricher.sourceSensor: $brooklyn:sensor("urls.list")
@@ -59,7 +59,7 @@ services:
maximum: 2
# TODO infer uniqueTag, name etc
uniqueTag: urls.list.comma_separated.max_2
- - type: org.apache.brooklyn.sensor.enricher.Joiner
+ - type: org.apache.brooklyn.enricher.stock.Joiner
# pick one uri as the main one to use
brooklyn.config:
enricher.sourceSensor: $brooklyn:sensor("urls.list")
@@ -67,7 +67,7 @@ services:
quote: false
maximum: 1
brooklyn.enrichers:
-- type: org.apache.brooklyn.sensor.enricher.Propagator
+- type: org.apache.brooklyn.enricher.stock.Propagator
# if nothing specified for `propagating` or `sensorMapping` then
# Propagator will do all but the usual lifecycle defaults, handy at the root!
brooklyn.config:
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/camp/src/test/resources/test-webapp-with-averaging-enricher.yaml
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/resources/test-webapp-with-averaging-enricher.yaml b/usage/camp/src/test/resources/test-webapp-with-averaging-enricher.yaml
index 73b8eae..9a508cb 100644
--- a/usage/camp/src/test/resources/test-webapp-with-averaging-enricher.yaml
+++ b/usage/camp/src/test/resources/test-webapp-with-averaging-enricher.yaml
@@ -32,7 +32,7 @@ services:
type: org.apache.brooklyn.entity.webapp.DynamicWebAppCluster
id: cluster
brooklyn.enrichers:
- - type: org.apache.brooklyn.sensor.enricher.Aggregator
+ - type: org.apache.brooklyn.enricher.stock.Aggregator
brooklyn.config:
enricher.sourceSensor: $brooklyn:sensor("my.load")
enricher.targetSensor: $brooklyn:sensor("my.load.averaged")
@@ -40,7 +40,7 @@ services:
transformation: average
brooklyn.enrichers:
- - type: org.apache.brooklyn.sensor.enricher.Propagator
+ - type: org.apache.brooklyn.enricher.stock.Propagator
brooklyn.config:
producer: $brooklyn:entity("cluster")
propagating:
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
index bd1bf6d..06c868b 100644
--- a/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
+++ b/usage/cli/src/main/java/org/apache/brooklyn/cli/lister/ClassFinder.java
@@ -31,11 +31,11 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.javalang.UrlClassLoader;
import org.apache.brooklyn.util.net.Urls;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
index 05f40ed..eb55d73 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedJBoss7ServerImpl.java
@@ -25,6 +25,7 @@ import java.util.concurrent.Callable;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7ServerImpl;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7SshDriver;
import org.apache.brooklyn.feed.function.FunctionFeed;
@@ -33,7 +34,6 @@ import org.apache.brooklyn.feed.http.HttpFeed;
import org.apache.brooklyn.feed.http.HttpPollConfig;
import org.apache.brooklyn.feed.http.HttpValueFunctions;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.guava.Functionals;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
index 3c191a1..80daba7 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.java.JavaEntityMethods;
@@ -46,7 +47,6 @@ import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
index 06b1cad..7559420 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/SinusoidalLoadGenerator.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
index f43cdcb..31f5060 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
@@ -28,12 +28,12 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.proxy.nginx.NginxController;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
import com.google.common.collect.Lists;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
index a36854a..c1f6334 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/util/BrooklynRestResourceUtils.java
@@ -59,10 +59,10 @@ import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.StringAndArgument;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.rest.domain.ApplicationSpec;
import org.apache.brooklyn.rest.domain.EntitySpec;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.exceptions.Exceptions;
[22/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java
new file mode 100644
index 0000000..9cf568b
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/shell/ShellFeedIntegrationTest.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.shell;
+
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.function.FunctionFeedTest;
+import org.apache.brooklyn.feed.shell.ShellFeed;
+import org.apache.brooklyn.feed.shell.ShellFeedIntegrationTest;
+import org.apache.brooklyn.feed.shell.ShellPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.stream.Streams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class ShellFeedIntegrationTest extends BrooklynAppUnitTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(ShellFeedIntegrationTest.class);
+
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("anInt", "");
+ final static AttributeSensor<Long> SENSOR_LONG = Sensors.newLongSensor("aLong", "");
+
+ private LocalhostMachineProvisioningLocation loc;
+ private EntityLocal entity;
+ private ShellFeed feed;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = new LocalhostMachineProvisioningLocation();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ super.tearDown();
+ if (loc != null) Streams.closeQuietly(loc);
+ }
+
+ @Test(groups="Integration")
+ public void testReturnsShellExitStatus() throws Exception {
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<Integer>(SENSOR_INT)
+ .command("exit 123")
+ .onFailure(SshValueFunctions.exitStatus()))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 123);
+ }
+
+ @Test(groups="Integration")
+ public void testFeedDeDupe() throws Exception {
+ testReturnsShellExitStatus();
+ entity.addFeed(feed);
+ log.info("Feed 0 is: "+feed);
+
+ testReturnsShellExitStatus();
+ log.info("Feed 1 is: "+feed);
+ entity.addFeed(feed);
+
+ FeedSupport feeds = ((EntityInternal)entity).feeds();
+ Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
+ }
+
+ // TODO timeout no longer supported; would be nice to have a generic task-timeout feature,
+ // now that the underlying impl uses SystemProcessTaskFactory
+ @Test(enabled=false, groups={"Integration", "WIP"})
+ public void testShellTimesOut() throws Exception {
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<String>(SENSOR_STRING)
+ .command("sleep 10")
+ .timeout(1, TimeUnit.MILLISECONDS)
+ .onException(new FunctionFeedTest.ToStringFunction()))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains("timed out after 1ms"), "val=" + val);
+ }});
+ }
+
+ @Test(groups="Integration")
+ public void testShellUsesEnv() throws Exception {
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<String>(SENSOR_STRING)
+ .env(ImmutableMap.of("MYENV", "MYVAL"))
+ .command("echo hello $MYENV")
+ .onSuccess(SshValueFunctions.stdout()))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains("hello MYVAL"), "val="+val);
+ }});
+ }
+
+ @Test(groups="Integration")
+ public void testReturnsShellStdout() throws Exception {
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<String>(SENSOR_STRING)
+ .command("echo hello")
+ .onSuccess(SshValueFunctions.stdout()))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains("hello"), "val="+val);
+ }});
+ }
+
+ @Test(groups="Integration")
+ public void testReturnsShellStderr() throws Exception {
+ final String cmd = "thiscommanddoesnotexist";
+
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<String>(SENSOR_STRING)
+ .command(cmd)
+ .onFailure(SshValueFunctions.stderr()))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains(cmd), "val="+val);
+ }});
+ }
+
+ @Test(groups="Integration")
+ public void testFailsOnNonZero() throws Exception {
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<String>(SENSOR_STRING)
+ .command("exit 123")
+ .onSuccess(new Function<SshPollValue, String>() {
+ @Override
+ public String apply(SshPollValue input) {
+ return "Exit status (on success) " + input.getExitStatus();
+ }})
+ .onFailure(new Function<SshPollValue, String>() {
+ @Override
+ public String apply(SshPollValue input) {
+ return "Exit status (on failure) " + input.getExitStatus();
+ }}))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains("Exit status (on failure) 123"), "val="+val);
+ }});
+ }
+
+ // Example in ShellFeed javadoc
+ @Test(groups="Integration")
+ public void testDiskUsage() throws Exception {
+ feed = ShellFeed.builder()
+ .entity(entity)
+ .poll(new ShellPollConfig<Long>(SENSOR_LONG)
+ .command("df -P | tail -1")
+ .onSuccess(new Function<SshPollValue, Long>() {
+ public Long apply(SshPollValue input) {
+ String[] parts = input.getStdout().split("[ \\t]+");
+ System.out.println("input="+input+"; parts="+Arrays.toString(parts));
+ return Long.parseLong(parts[2]);
+ }}))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ Long val = entity.getAttribute(SENSOR_LONG);
+ assertTrue(val != null && val >= 0, "val="+val);
+ }});
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java
new file mode 100644
index 0000000..fa8e2df
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/ssh/SshFeedIntegrationTest.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.ssh;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshFeedIntegrationTest;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshPollValue;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.text.StringFunctions;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+
+public class SshFeedIntegrationTest extends BrooklynAppUnitTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(SshFeedIntegrationTest.class);
+
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
+
+ private LocalhostMachineProvisioningLocation loc;
+ private SshMachineLocation machine;
+ private EntityLocal entity;
+ private SshFeed feed;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = app.newLocalhostProvisioningLocation();
+ machine = loc.obtain();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ super.tearDown();
+ if (loc != null) Streams.closeQuietly(loc);
+ }
+
+ /** this is one of the most common pattern */
+ @Test(groups="Integration")
+ public void testReturnsSshStdoutAndInfersMachine() throws Exception {
+ final TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+ // inject the machine location, because the app was started with a provisioning location
+ // and TestEntity doesn't provision
+ .location(machine));
+
+ feed = SshFeed.builder()
+ .entity(entity2)
+ .poll(new SshPollConfig<String>(SENSOR_STRING)
+ .command("echo hello")
+ .onSuccess(SshValueFunctions.stdout()))
+ .build();
+
+ EntityTestUtils.assertAttributeEventuallyNonNull(entity2, SENSOR_STRING);
+ String val = entity2.getAttribute(SENSOR_STRING);
+ Assert.assertTrue(val.contains("hello"), "val="+val);
+ Assert.assertEquals(val.trim(), "hello");
+ }
+
+ @Test(groups="Integration")
+ public void testFeedDeDupe() throws Exception {
+ testReturnsSshStdoutAndInfersMachine();
+ entity.addFeed(feed);
+ log.info("Feed 0 is: "+feed);
+
+ testReturnsSshStdoutAndInfersMachine();
+ log.info("Feed 1 is: "+feed);
+ entity.addFeed(feed);
+
+ FeedSupport feeds = ((EntityInternal)entity).feeds();
+ Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
+ }
+
+ @Test(groups="Integration")
+ public void testReturnsSshExitStatus() throws Exception {
+ feed = SshFeed.builder()
+ .entity(entity)
+ .machine(machine)
+ .poll(new SshPollConfig<Integer>(SENSOR_INT)
+ .command("exit 123")
+ .checkSuccess(Predicates.alwaysTrue())
+ .onSuccess(SshValueFunctions.exitStatus()))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 123);
+ }
+
+ @Test(groups="Integration")
+ public void testReturnsSshStdout() throws Exception {
+ feed = SshFeed.builder()
+ .entity(entity)
+ .machine(machine)
+ .poll(new SshPollConfig<String>(SENSOR_STRING)
+ .command("echo hello")
+ .onSuccess(SshValueFunctions.stdout()))
+ .build();
+
+ EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING,
+ Predicates.compose(Predicates.equalTo("hello"), StringFunctions.trim()));
+ }
+
+ @Test(groups="Integration")
+ public void testReturnsSshStderr() throws Exception {
+ final String cmd = "thiscommanddoesnotexist";
+
+ feed = SshFeed.builder()
+ .entity(entity)
+ .machine(machine)
+ .poll(new SshPollConfig<String>(SENSOR_STRING)
+ .command(cmd)
+ .onFailure(SshValueFunctions.stderr()))
+ .build();
+
+ EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, StringPredicates.containsLiteral(cmd));
+ }
+
+ @Test(groups="Integration")
+ public void testFailsOnNonZero() throws Exception {
+ feed = SshFeed.builder()
+ .entity(entity)
+ .machine(machine)
+ .poll(new SshPollConfig<String>(SENSOR_STRING)
+ .command("exit 123")
+ .onFailure(new Function<SshPollValue, String>() {
+ @Override
+ public String apply(SshPollValue input) {
+ return "Exit status " + input.getExitStatus();
+ }}))
+ .build();
+
+ EntityTestUtils.assertAttributeEventually(entity, SENSOR_STRING, StringPredicates.containsLiteral("Exit status 123"));
+ }
+
+ @Test(groups="Integration")
+ public void testAddedEarly() throws Exception {
+ final TestEntity entity2 = app.addChild(EntitySpec.create(TestEntity.class)
+ .location(machine)
+ .addInitializer(new EntityInitializer() {
+ @Override
+ public void apply(EntityLocal entity) {
+ SshFeed.builder()
+ .entity(entity)
+ .onlyIfServiceUp()
+ .poll(new SshPollConfig<String>(SENSOR_STRING)
+ .command("echo hello")
+ .onSuccess(SshValueFunctions.stdout()))
+ .build();
+ }
+ }));
+ Time.sleep(Duration.seconds(2));
+ // would be nice to hook in and assert no errors
+ Assert.assertEquals(entity2.getAttribute(SENSOR_STRING), null);
+ Entities.manage(entity2);
+ Time.sleep(Duration.seconds(2));
+ Assert.assertEquals(entity2.getAttribute(SENSOR_STRING), null);
+ entity2.setAttribute(Attributes.SERVICE_UP, true);
+
+ EntityTestUtils.assertAttributeEventually(entity2, SENSOR_STRING, StringPredicates.containsLiteral("hello"));
+ }
+
+
+ @Test(groups="Integration")
+ public void testDynamicEnvAndCommandSupplier() throws Exception {
+ final TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class).location(machine));
+
+ final AtomicInteger count = new AtomicInteger();
+ Supplier<Map<String, String>> envSupplier = new Supplier<Map<String,String>>() {
+ @Override
+ public Map<String, String> get() {
+ return MutableMap.of("COUNT", ""+count.incrementAndGet());
+ }
+ };
+ Supplier<String> cmdSupplier = new Supplier<String>() {
+ @Override
+ public String get() {
+ return "echo count-"+count.incrementAndGet()+"-$COUNT";
+ }
+ };
+
+ feed = SshFeed.builder()
+ .entity(entity2)
+ .poll(new SshPollConfig<String>(SENSOR_STRING)
+ .env(envSupplier)
+ .command(cmdSupplier)
+ .onSuccess(SshValueFunctions.stdout()))
+ .build();
+
+ EntityTestUtils.assertAttributeEventuallyNonNull(entity2, SENSOR_STRING);
+ final String val1 = assertDifferentOneInOutput(entity2);
+
+ EntityTestUtils.assertAttributeEventually(entity2, SENSOR_STRING, Predicates.not(Predicates.equalTo(val1)));
+ final String val2 = assertDifferentOneInOutput(entity2);
+ log.info("vals from dynamic sensors are: "+val1.trim()+" and "+val2.trim());
+ }
+
+ private String assertDifferentOneInOutput(final TestEntity entity2) {
+ String val = entity2.getAttribute(SENSOR_STRING);
+ Assert.assertTrue(val.startsWith("count"), "val="+val);
+ try {
+ String[] fields = val.trim().split("-");
+ int field1 = Integer.parseInt(fields[1]);
+ int field2 = Integer.parseInt(fields[2]);
+ Assert.assertEquals(Math.abs(field2-field1), 1, "expected difference of 1");
+ } catch (Throwable t) {
+ Exceptions.propagateIfFatal(t);
+ Assert.fail("Wrong output from sensor, got '"+val.trim()+"', giving error: "+t);
+ }
+ return val;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
new file mode 100644
index 0000000..421fff4
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.windows;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * WindowsPerformanceCounterFeed Live Test.
+ * <p>
+ * This test is currently disabled. To run, you must configure a location named {@code WindowsLiveTest}
+ * or adapt the {@link #LOCATION_SPEC} below.
+ * <p>
+ * The location must provide Windows nodes that are running an SSH server on port 22. The login credentials must
+ * be either be auto-detectable or configured in brooklyn.properties in the usual fashion.
+ * <p>
+ * Here is an example configuration from brooklyn.properties for a pre-configured Windows VM
+ * running an SSH server with public key authentication:
+ * <pre>
+ * {@code brooklyn.location.named.WindowsLiveTest=byon:(hosts="ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com")
+ * brooklyn.location.named.WindowsLiveTest.user=Administrator
+ * brooklyn.location.named.WindowsLiveTest.privateKeyFile = ~/.ssh/id_rsa
+ * brooklyn.location.named.WindowsLiveTest.publicKeyFile = ~/.ssh/id_rsa.pub
+ * }</pre>
+ * The location must by {@code byon} or another primitive type. Unfortunately, it's not possible to
+ * use a jclouds location, as adding a dependency on brooklyn-locations-jclouds would cause a
+ * cyclic dependency.
+ */
+public class WindowsPerformanceCounterFeedLiveTest extends BrooklynAppLiveTestSupport {
+
+ final static AttributeSensor<Double> CPU_IDLE_TIME = Sensors.newDoubleSensor("cpu.idleTime", "");
+ final static AttributeSensor<Integer> TELEPHONE_LINES = Sensors.newIntegerSensor("telephone.lines", "");
+
+ private static final String LOCATION_SPEC = "named:WindowsLiveTest";
+
+ private Location loc;
+ private EntityLocal entity;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ super.setUp();
+
+ Map<String,?> allFlags = MutableMap.<String,Object>builder()
+ .put("tags", ImmutableList.of(getClass().getName()))
+ .build();
+ MachineProvisioningLocation<? extends MachineLocation> provisioningLocation =
+ (MachineProvisioningLocation<? extends MachineLocation>)
+ mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
+ loc = provisioningLocation.obtain(ImmutableMap.of());
+
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @Test(groups={"Live","Disabled"}, enabled=false)
+ public void testRetrievesPerformanceCounters() throws Exception {
+ // We can be pretty sure that a Windows instance in the cloud will have zero telephone lines...
+ entity.setAttribute(TELEPHONE_LINES, 42);
+ WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
+ .entity(entity)
+ .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
+ .addSensor("\\Telephony\\Lines", TELEPHONE_LINES)
+ .build();
+ try {
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
+ } finally {
+ feed.stop();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
new file mode 100644
index 0000000..3f4862b
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.windows;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterPollConfig;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class WindowsPerformanceCounterFeedTest extends BrooklynAppUnitTestSupport {
+
+ private Location loc;
+ private EntityLocal entity;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = new LocalhostMachineProvisioningLocation();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeedTest.class);
+
+ @Test
+ public void testIteratorWithSingleValue() {
+ Iterator<?> iterator = new WindowsPerformanceCounterFeed
+ .PerfCounterValueIterator("\"10/14/2013 15:28:24.406\",\"0.000000\"");
+ assertTrue(iterator.hasNext());
+ assertEquals(iterator.next(), "0.000000");
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ public void testIteratorWithMultipleValues() {
+ Iterator<?> iterator = new WindowsPerformanceCounterFeed
+ .PerfCounterValueIterator("\"10/14/2013 15:35:50.582\",\"8803.000000\",\"405622.000000\"");
+ assertTrue(iterator.hasNext());
+ assertEquals(iterator.next(), "8803.000000");
+ assertTrue(iterator.hasNext());
+ assertEquals(iterator.next(), "405622.000000");
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ public void testSendPerfCountersToSensors() {
+ AttributeSensor<String> stringSensor = Sensors.newStringSensor("foo.bar");
+ AttributeSensor<Integer> integerSensor = Sensors.newIntegerSensor("bar.baz");
+ AttributeSensor<Double> doubleSensor = Sensors.newDoubleSensor("baz.quux");
+
+ Collection<WindowsPerformanceCounterPollConfig<?>> polls = ImmutableSet.<WindowsPerformanceCounterPollConfig<?>>of(
+ new WindowsPerformanceCounterPollConfig(stringSensor).performanceCounterName("\\processor information(_total)\\% processor time"),
+ new WindowsPerformanceCounterPollConfig(integerSensor).performanceCounterName("\\integer.sensor"),
+ new WindowsPerformanceCounterPollConfig(doubleSensor).performanceCounterName("\\double\\sensor\\with\\multiple\\sub\\paths")
+ );
+
+ WindowsPerformanceCounterFeed.SendPerfCountersToSensors sendPerfCountersToSensors = new WindowsPerformanceCounterFeed.SendPerfCountersToSensors(entity, polls);
+
+ assertNull(entity.getAttribute(stringSensor));
+
+ StringBuilder responseBuilder = new StringBuilder();
+ // NOTE: This builds the response in a different order to which they are passed to the SendPerfCountersToSensors constructor
+ // this tests that the values are applied correctly even if the (possibly non-deterministic) order in which
+ // they are returned by the Get-Counter scriptlet is different
+ addMockResponse(responseBuilder, "\\\\machine.name\\double\\sensor\\with\\multiple\\sub\\paths", "3.1415926");
+ addMockResponse(responseBuilder, "\\\\win-lge7uj2blau\\processor information(_total)\\% processor time", "99.9");
+ addMockResponse(responseBuilder, "\\\\machine.name\\integer.sensor", "15");
+
+ sendPerfCountersToSensors.onSuccess(new WinRmToolResponse(responseBuilder.toString(), "", 0));
+
+ EntityTestUtils.assertAttributeEquals(entity, stringSensor, "99.9");
+ EntityTestUtils.assertAttributeEquals(entity, integerSensor, 15);
+ EntityTestUtils.assertAttributeEquals(entity, doubleSensor, 3.1415926);
+ }
+
+ private void addMockResponse(StringBuilder responseBuilder, String path, String value) {
+ responseBuilder.append(path);
+ responseBuilder.append(Strings.repeat(" ", 200 - (path.length() + value.length())));
+ responseBuilder.append(value);
+ responseBuilder.append("\r\n");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
deleted file mode 100644
index b82aecf..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class ConfigToAttributesTest {
-
- private ManagementContextInternal managementContext;
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- managementContext = new LocalManagementContext();
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (managementContext != null) Entities.destroyAll(managementContext);
- }
-
- @Test
- public void testApplyTemplatedConfigWithEntity() {
- TestApplication app = managementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)
- .configure(TestEntity.CONF_NAME, "myval"));
- Entities.startManagement(app, managementContext);
-
- BasicAttributeSensorAndConfigKey<String> key = new TemplatedStringAttributeSensorAndConfigKey("mykey", "my descr", "${config['test.confName']!'notfound'}");
- String val = ConfigToAttributes.apply(app, key);
- assertEquals(app.getAttribute(key), val);
- assertEquals(val, "myval");
-
- }
-
- @Test
- public void testApplyTemplatedConfigWithManagementContext() {
- managementContext.getBrooklynProperties().put(TestEntity.CONF_NAME, "myglobalval");
- BasicAttributeSensorAndConfigKey<String> key = new TemplatedStringAttributeSensorAndConfigKey("mykey", "my descr", "${config['test.confName']!'notfound'}");
- String val = ConfigToAttributes.transform(managementContext, key);
- assertEquals(val, "myglobalval");
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java
deleted file mode 100644
index 3f9c29b..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/PollerTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed;
-
-import static org.testng.Assert.assertTrue;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.PollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class PollerTest extends BrooklynAppUnitTestSupport {
-
- private static final Logger LOG = LoggerFactory.getLogger(PollerTest.class);
-
- private TestEntity entity;
- private Poller<Integer> poller;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- poller = new Poller<Integer>(entity, false);
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (poller != null) poller.stop();
- super.tearDown();
- }
-
- @Test(groups={"Integration", "WIP"}) // because takes > 1 second
- public void testPollingSubTaskFailsOnceKeepsGoing() throws Exception {
- final AtomicInteger counter = new AtomicInteger();
- poller.scheduleAtFixedRate(
- new Callable<Integer>() {
- @Override public Integer call() throws Exception {
- int result = counter.incrementAndGet();
- if (result % 2 == 0) {
- DynamicTasks.queue("in-poll", new Runnable() {
- public void run() {
- throw new IllegalStateException("Simulating error in sub-task for poll");
- }});
- }
- return result;
- }
- },
- new PollHandler<Integer>() {
- @Override public boolean checkSuccess(Integer val) {
- return true;
- }
- @Override public void onSuccess(Integer val) {
-
- }
- @Override public void onFailure(Integer val) {
- }
- @Override
- public void onException(Exception exception) {
- LOG.info("Exception in test poller", exception);
- }
- @Override public String getDescription() {
- return "mypollhandler";
- }
- },
- new Duration(10, TimeUnit.MILLISECONDS));
- poller.start();
-
- Asserts.succeedsContinually(MutableMap.of("timeout", 2*1000, "period", 500), new Runnable() {
- int oldCounter = -1;
- @Override public void run() {
- assertTrue(counter.get() > oldCounter);
- oldCounter = counter.get();
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
deleted file mode 100644
index 71b44b8..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.function;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Feed;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeedTest;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicates;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.util.concurrent.Callables;
-
-public class FunctionFeedTest extends BrooklynAppUnitTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(FunctionFeedTest.class);
-
- final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
- final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
-
- private Location loc;
- private EntityLocal entity;
- private FunctionFeed feed;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- loc = new LocalhostMachineProvisioningLocation();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (feed != null) feed.stop();
- super.tearDown();
- }
-
- @Test
- public void testPollsFunctionRepeatedlyToSetAttribute() throws Exception {
- feed = FunctionFeed.builder()
- .entity(entity)
- .poll(new FunctionPollConfig<Integer,Integer>(SENSOR_INT)
- .period(1)
- .callable(new IncrementingCallable())
- //.onSuccess((Function<Object,Integer>)(Function)Functions.identity()))
- )
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- @Override
- public void run() {
- Integer val = entity.getAttribute(SENSOR_INT);
- assertTrue(val != null && val > 2, "val=" + val);
- }
- });
- }
-
- @Test
- public void testFeedDeDupe() throws Exception {
- testPollsFunctionRepeatedlyToSetAttribute();
- entity.addFeed(feed);
- log.info("Feed 0 is: "+feed);
- Feed feed0 = feed;
-
- testPollsFunctionRepeatedlyToSetAttribute();
- entity.addFeed(feed);
- log.info("Feed 1 is: "+feed);
- Feed feed1 = feed;
- Assert.assertFalse(feed1==feed0);
-
- FeedSupport feeds = ((EntityInternal)entity).feeds();
- Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
-
- // a couple extra checks, compared to the de-dupe test in other *FeedTest classes
- Feed feedAdded = Iterables.getOnlyElement(feeds.getFeeds());
- Assert.assertTrue(feedAdded==feed1);
- Assert.assertFalse(feedAdded==feed0);
- }
-
- @Test
- public void testFeedDeDupeIgnoresSameObject() throws Exception {
- testPollsFunctionRepeatedlyToSetAttribute();
- entity.addFeed(feed);
- assertFeedIsPolling();
- entity.addFeed(feed);
- assertFeedIsPollingContinuously();
- }
-
- @Test
- public void testCallsOnSuccessWithResultOfCallable() throws Exception {
- feed = FunctionFeed.builder()
- .entity(entity)
- .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
- .period(1)
- .callable(Callables.returning(123))
- .onSuccess(new AddOneFunction()))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 124);
- }
-
- @Test
- public void testCallsOnExceptionWithExceptionFromCallable() throws Exception {
- final String errMsg = "my err msg";
-
- feed = FunctionFeed.builder()
- .entity(entity)
- .poll(new FunctionPollConfig<Object, String>(SENSOR_STRING)
- .period(1)
- .callable(new ExceptionCallable(errMsg))
- .onException(new ToStringFunction()))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- @Override
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains(errMsg), "val=" + val);
- }
- });
- }
-
- @Test
- public void testCallsOnFailureWithResultOfCallable() throws Exception {
- feed = FunctionFeed.builder()
- .entity(entity)
- .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
- .period(1)
- .callable(Callables.returning(1))
- .checkSuccess(Predicates.alwaysFalse())
- .onSuccess(new AddOneFunction())
- .onFailure(Functions.constant(-1)))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, -1);
- }
-
- @Test
- public void testCallsOnExceptionWhenCheckSuccessIsFalseButNoFailureHandler() throws Exception {
- feed = FunctionFeed.builder()
- .entity(entity)
- .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
- .period(1)
- .callable(Callables.returning(1))
- .checkSuccess(Predicates.alwaysFalse())
- .onSuccess(new AddOneFunction())
- .onException(Functions.constant(-1)))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, -1);
- }
-
- @Test
- public void testSharesFunctionWhenMultiplePostProcessors() throws Exception {
- final IncrementingCallable incrementingCallable = new IncrementingCallable();
- final List<Integer> ints = new CopyOnWriteArrayList<Integer>();
- final List<String> strings = new CopyOnWriteArrayList<String>();
-
- entity.subscribe(entity, SENSOR_INT, new SensorEventListener<Integer>() {
- @Override public void onEvent(SensorEvent<Integer> event) {
- ints.add(event.getValue());
- }});
- entity.subscribe(entity, SENSOR_STRING, new SensorEventListener<String>() {
- @Override public void onEvent(SensorEvent<String> event) {
- strings.add(event.getValue());
- }});
-
- feed = FunctionFeed.builder()
- .entity(entity)
- .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
- .period(10)
- .callable(incrementingCallable))
- .poll(new FunctionPollConfig<Integer, String>(SENSOR_STRING)
- .period(10)
- .callable(incrementingCallable)
- .onSuccess(new ToStringFunction()))
- .build();
-
- Asserts.succeedsEventually(new Runnable() {
- @Override
- public void run() {
- assertEquals(ints.subList(0, 2), ImmutableList.of(0, 1));
- assertTrue(strings.size()>=2, "wrong strings list: "+strings);
- assertEquals(strings.subList(0, 2), ImmutableList.of("0", "1"), "wrong strings list: "+strings);
- }});
- }
-
- @Test
- @SuppressWarnings("unused")
- public void testFunctionPollConfigBuilding() throws Exception {
- FunctionPollConfig<Integer, Integer> typeFromCallable = FunctionPollConfig.forSensor(SENSOR_INT)
- .period(1)
- .callable(Callables.returning(1))
- .onSuccess(Functions.constant(-1));
-
- FunctionPollConfig<Integer, Integer> typeFromSupplier = FunctionPollConfig.forSensor(SENSOR_INT)
- .period(1)
- .supplier(Suppliers.ofInstance(1))
- .onSuccess(Functions.constant(-1));
-
- FunctionPollConfig<Integer, Integer> usingConstructor = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
- .period(1)
- .supplier(Suppliers.ofInstance(1))
- .onSuccess(Functions.constant(-1));
-
- FunctionPollConfig<Integer, Integer> usingConstructorWithFailureOrException = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
- .period(1)
- .supplier(Suppliers.ofInstance(1))
- .onFailureOrException(Functions.<Integer>constant(null));
- }
-
-
- private void assertFeedIsPolling() {
- final Integer val = entity.getAttribute(SENSOR_INT);
- Asserts.succeedsEventually(new Runnable() {
- @Override
- public void run() {
- assertNotEquals(val, entity.getAttribute(SENSOR_INT));
- }
- });
- }
-
- private void assertFeedIsPollingContinuously() {
- Asserts.succeedsContinually(new Runnable() {
- @Override
- public void run() {
- assertFeedIsPolling();
- }
- });
- }
-
- private static class IncrementingCallable implements Callable<Integer> {
- private final AtomicInteger next = new AtomicInteger(0);
-
- @Override public Integer call() {
- return next.getAndIncrement();
- }
- }
-
- private static class AddOneFunction implements Function<Integer, Integer> {
- @Override public Integer apply(@Nullable Integer input) {
- return (input != null) ? (input + 1) : null;
- }
- }
-
- private static class ExceptionCallable implements Callable<Void> {
- private final String msg;
- ExceptionCallable(String msg) {
- this.msg = msg;
- }
- @Override public Void call() {
- throw new RuntimeException(msg);
- }
- }
-
- public static class ToStringFunction implements Function<Object, String> {
- @Override public String apply(@Nullable Object input) {
- return (input != null) ? (input.toString()) : null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
deleted file mode 100644
index 475490b..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedIntegrationTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.net.URI;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.HttpService;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-
-public class HttpFeedIntegrationTest extends BrooklynAppUnitTestSupport {
-
- final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
- final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
-
- private HttpService httpService;
-
- private Location loc;
- private EntityLocal entity;
- private HttpFeed feed;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- loc = new LocalhostMachineProvisioningLocation();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (feed != null) feed.stop();
- if (httpService != null) httpService.shutdown();
- super.tearDown();
- }
-
- @Test(groups = {"Integration"})
- public void testPollsAndParsesHttpGetResponseWithSsl() throws Exception {
- httpService = new HttpService(PortRanges.fromString("9000+"), true).start();
- URI baseUrl = new URI(httpService.getUrl());
-
- assertEquals(baseUrl.getScheme(), "https", "baseUrl="+baseUrl);
-
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUri(baseUrl)
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode()))
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction()))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 200);
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains("Hello, World"), "val="+val);
- }});
- }
-
- @Test(groups = {"Integration"})
- public void testPollsAndParsesHttpGetResponseWithBasicAuthentication() throws Exception {
- final String username = "brooklyn";
- final String password = "hunter2";
- httpService = new HttpService(PortRanges.fromString("9000+"))
- .basicAuthentication(username, password)
- .start();
- URI baseUrl = new URI(httpService.getUrl());
- assertEquals(baseUrl.getScheme(), "http", "baseUrl="+baseUrl);
-
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUri(baseUrl)
- .credentials(username, password)
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode()))
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction()))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 200);
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.contains("Hello, World"), "val="+val);
- }});
- }
-
- @Test(groups = {"Integration"})
- public void testPollWithInvalidCredentialsFails() throws Exception {
- httpService = new HttpService(PortRanges.fromString("9000+"))
- .basicAuthentication("brooklyn", "hunter2")
- .start();
-
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUri(httpService.getUrl())
- .credentials("brooklyn", "9876543210")
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode())
- .onFailure(HttpValueFunctions.responseCode()))
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction())
- .onException(Functions.constant("Failed!")))
- .build();
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 401);
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- String val = entity.getAttribute(SENSOR_STRING);
- assertTrue(val != null && val.equals("Failed!"), "val=" + val);
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
deleted file mode 100644
index f04c855..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpFeedTest.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
-
-import java.net.URL;
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityFunctions;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.FeedConfig;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.test.Asserts;
-import org.apache.brooklyn.util.collections.MutableList;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.http.BetterMockWebServer;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.apache.brooklyn.util.guava.Functionals;
-import org.apache.brooklyn.util.net.Networking;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.mockwebserver.MockResponse;
-import com.google.mockwebserver.SocketPolicy;
-
-public class HttpFeedTest extends BrooklynAppUnitTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(HttpFeedTest.class);
-
- final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
- final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor( "aLong", "");
-
- private static final long TIMEOUT_MS = 10*1000;
-
- private BetterMockWebServer server;
- private URL baseUrl;
-
- private Location loc;
- private EntityLocal entity;
- private HttpFeed feed;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- server = BetterMockWebServer.newInstanceLocalhost();
- for (int i = 0; i < 100; i++) {
- server.enqueue(new MockResponse().setResponseCode(200).addHeader("content-type: application/json").setBody("{\"foo\":\"myfoo\"}"));
- }
- server.play();
- baseUrl = server.getUrl("/");
-
- loc = app.newLocalhostProvisioningLocation();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- if (feed != null) feed.stop();
- if (server != null) server.shutdown();
- feed = null;
- super.tearDown();
- }
-
- @Test
- public void testPollsAndParsesHttpGetResponse() throws Exception {
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
- .poll(HttpPollConfig.forSensor(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode()))
- .poll(HttpPollConfig.forSensor(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction()))
- .build();
-
- assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
- assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
- }
-
- @Test
- public void testFeedDeDupe() throws Exception {
- testPollsAndParsesHttpGetResponse();
- entity.addFeed(feed);
- log.info("Feed 0 is: "+feed);
-
- testPollsAndParsesHttpGetResponse();
- log.info("Feed 1 is: "+feed);
- entity.addFeed(feed);
-
- FeedSupport feeds = ((EntityInternal)entity).feeds();
- Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
- }
-
- @Test
- public void testSetsConnectionTimeout() throws Exception {
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .connectionTimeout(Duration.TEN_SECONDS)
- .socketTimeout(Duration.TEN_SECONDS)
- .onSuccess(HttpValueFunctions.responseCode()))
- .build();
-
- assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
- }
-
- // TODO How to cause the other end to just freeze (similar to aws-ec2 when securityGroup port is not open)?
- @Test
- public void testSetsConnectionTimeoutWhenServerDisconnects() throws Exception {
- if (server != null) server.shutdown();
- server = BetterMockWebServer.newInstanceLocalhost();
- for (int i = 0; i < 100; i++) {
- server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START));
- }
- server.play();
- baseUrl = server.getUrl("/");
-
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .connectionTimeout(Duration.TEN_SECONDS)
- .socketTimeout(Duration.TEN_SECONDS)
- .onSuccess(HttpValueFunctions.responseCode())
- .onException(Functions.constant(-1)))
- .build();
-
- assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
- }
-
-
- @Test
- public void testPollsAndParsesHttpPostResponse() throws Exception {
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .method("post")
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode()))
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .method("post")
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction()))
- .build();
-
- assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
- assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
- }
-
- @Test
- public void testUsesFailureHandlerOn4xx() throws Exception {
- server = BetterMockWebServer.newInstanceLocalhost();
- for (int i = 0; i < 100; i++) {
- server.enqueue(new MockResponse()
- .setResponseCode(401)
- .setBody("Unauthorised"));
- }
- server.play();
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(server.getUrl("/"))
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode())
- .onFailure(HttpValueFunctions.responseCode()))
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction())
- .onFailure(Functions.constant("Failed")))
- .build();
-
- assertSensorEventually(SENSOR_INT, 401, TIMEOUT_MS);
- assertSensorEventually(SENSOR_STRING, "Failed", TIMEOUT_MS);
-
- server.shutdown();
- }
-
- @Test
- public void testUsesExceptionHandlerOn4xxAndNoFailureHandler() throws Exception {
- server = BetterMockWebServer.newInstanceLocalhost();
- for (int i = 0; i < 100; i++) {
- server.enqueue(new MockResponse()
- .setResponseCode(401)
- .setBody("Unauthorised"));
- }
- server.play();
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(server.getUrl("/"))
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode())
- .onException(Functions.constant(-1)))
- .build();
-
- assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
-
- server.shutdown();
- }
-
- @Test(groups="Integration")
- // marked integration as it takes a wee while
- public void testSuspendResume() throws Exception {
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
- .poll(new HttpPollConfig<Integer>(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode()))
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction()))
- .build();
- assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
- feed.suspend();
- final int countWhenSuspended = server.getRequestCount();
-
- Thread.sleep(500);
- if (server.getRequestCount() > countWhenSuspended+1)
- Assert.fail("Request count continued to increment while feed was suspended, from "+countWhenSuspended+" to "+server.getRequestCount());
-
- feed.resume();
- Asserts.succeedsEventually(new Runnable() {
- public void run() {
- assertTrue(server.getRequestCount() > countWhenSuspended + 1,
- "Request count failed to increment when feed was resumed, from " + countWhenSuspended + ", still at " + server.getRequestCount());
- }
- });
- }
-
- @Test(groups="Integration")
- // marked integration as it takes a wee while
- public void testStartSuspended() throws Exception {
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
- .poll(HttpPollConfig.forSensor(SENSOR_INT)
- .period(100)
- .onSuccess(HttpValueFunctions.responseCode()))
- .poll(HttpPollConfig.forSensor(SENSOR_STRING)
- .period(100)
- .onSuccess(HttpValueFunctions.stringContentsFunction()))
- .suspended()
- .build();
- Asserts.continually(MutableMap.of("timeout", 500),
- Entities.attributeSupplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(null));
- int countWhenSuspended = server.getRequestCount();
- feed.resume();
- Asserts.eventually(Entities.attributeSupplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(200));
- if (server.getRequestCount() <= countWhenSuspended)
- Assert.fail("Request count failed to increment when feed was resumed, from "+countWhenSuspended+", still at "+server.getRequestCount());
- log.info("RUN: "+countWhenSuspended+" - "+server.getRequestCount());
- }
-
-
- @Test
- public void testPollsAndParsesHttpErrorResponseLocal() throws Exception {
- int unboundPort = Networking.nextAvailablePort(10000);
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUri("http://localhost:" + unboundPort + "/path/should/not/exist")
- .poll(new HttpPollConfig<String>(SENSOR_STRING)
- .onSuccess(Functions.constant("success"))
- .onFailure(Functions.constant("failure"))
- .onException(Functions.constant("error")))
- .build();
-
- assertSensorEventually(SENSOR_STRING, "error", TIMEOUT_MS);
- }
-
- @Test
- public void testPollsMulti() throws Exception {
- newMultiFeed(baseUrl);
- assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
- assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
- }
-
- // because takes a wee while
- @SuppressWarnings("rawtypes")
- @Test(groups="Integration")
- public void testPollsMultiClearsOnSubsequentFailure() throws Exception {
- server = BetterMockWebServer.newInstanceLocalhost();
- for (int i = 0; i < 10; i++) {
- server.enqueue(new MockResponse()
- .setResponseCode(200)
- .setBody("Hello World"));
- }
- for (int i = 0; i < 10; i++) {
- server.enqueue(new MockResponse()
- .setResponseCode(401)
- .setBody("Unauthorised"));
- }
- server.play();
-
- newMultiFeed(server.getUrl("/"));
-
- assertSensorEventually(SENSOR_INT, 200, TIMEOUT_MS);
- assertSensorEventually(SENSOR_STRING, "Hello World", TIMEOUT_MS);
-
- assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
- assertSensorEventually(SENSOR_STRING, null, TIMEOUT_MS);
-
- List<String> attrs = Lists.transform(MutableList.copyOf( ((EntityInternal)entity).getAllAttributes().keySet() ),
- new Function<AttributeSensor,String>() {
- @Override public String apply(AttributeSensor input) { return input.getName(); } });
- Assert.assertTrue(!attrs.contains(SENSOR_STRING.getName()), "attrs contained "+SENSOR_STRING);
- Assert.assertTrue(!attrs.contains(FeedConfig.NO_SENSOR.getName()), "attrs contained "+FeedConfig.NO_SENSOR);
-
- server.shutdown();
- }
-
- private void newMultiFeed(URL baseUrl) {
- feed = HttpFeed.builder()
- .entity(entity)
- .baseUrl(baseUrl)
-
- .poll(HttpPollConfig.forMultiple()
- .onSuccess(new Function<HttpToolResponse,Void>() {
- public Void apply(HttpToolResponse response) {
- entity.setAttribute(SENSOR_INT, response.getResponseCode());
- if (response.getResponseCode()==200)
- entity.setAttribute(SENSOR_STRING, response.getContentAsString());
- return null;
- }
- })
- .onFailureOrException(Functionals.function(EntityFunctions.settingSensorsConstant(entity, MutableMap.<AttributeSensor<?>,Object>of(
- SENSOR_INT, -1,
- SENSOR_STRING, PollConfig.REMOVE))))
- .period(100))
- .build();
- }
-
-
- private <T> void assertSensorEventually(final AttributeSensor<T> sensor, final T expectedVal, long timeout) {
- Asserts.succeedsEventually(ImmutableMap.of("timeout", timeout), new Callable<Void>() {
- public Void call() {
- assertEquals(entity.getAttribute(sensor), expectedVal);
- return null;
- }
- });
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java
deleted file mode 100644
index 2afcae8..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/http/HttpValueFunctionsTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.http;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.NoSuchElementException;
-
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.util.core.http.HttpToolResponse;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-
-public class HttpValueFunctionsTest {
-
- private int responseCode = 200;
- private long fullLatency = 1000;
- private String headerName = "my_header";
- private String headerVal = "my_header_val";
- private String bodyKey = "mykey";
- private String bodyVal = "myvalue";
- private String body = "{"+bodyKey+":"+bodyVal+"}";
- private long now;
- private HttpToolResponse response;
-
- @BeforeMethod
- public void setUp() throws Exception {
- now = System.currentTimeMillis();
- response = new HttpToolResponse(responseCode, ImmutableMap.of(headerName, ImmutableList.of(headerVal)),
- body.getBytes(), now-fullLatency, fullLatency / 2, fullLatency);
- }
-
- @Test
- public void testResponseCode() throws Exception {
- assertEquals(HttpValueFunctions.responseCode().apply(response), Integer.valueOf(responseCode));
- }
-
- @Test
- public void testContainsHeader() throws Exception {
- assertTrue(HttpValueFunctions.containsHeader(headerName).apply(response));
- assertFalse(HttpValueFunctions.containsHeader("wrong_header").apply(response));
- }
-
- @Test
- public void testStringContents() throws Exception {
- assertEquals(HttpValueFunctions.stringContentsFunction().apply(response), body);
- }
-
- @Test
- public void testJsonContents() throws Exception {
- JsonElement json = HttpValueFunctions.jsonContents().apply(response);
- assertTrue(json.isJsonObject());
- assertEquals(json.getAsJsonObject().entrySet(), ImmutableMap.of(bodyKey, new JsonPrimitive(bodyVal)).entrySet());
- }
-
- @Test
- public void testJsonContentsGettingElement() throws Exception {
- assertEquals(HttpValueFunctions.jsonContents(bodyKey, String.class).apply(response), bodyVal);
- }
-
- @Test(expectedExceptions=NoSuchElementException.class)
- public void testJsonContentsGettingMissingElement() throws Exception {
- assertNull(HttpValueFunctions.jsonContents("wrongkey", String.class).apply(response));
- }
-
- @Test
- public void testLatency() throws Exception {
- assertEquals(HttpValueFunctions.latency().apply(response), Long.valueOf(fullLatency));
- }
-}
[20/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxFeed.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxFeed.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxFeed.java
new file mode 100644
index 0000000..b3b2994
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxFeed.java
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.DelegatingPollHandler;
+import org.apache.brooklyn.core.feed.PollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+
+/**
+ * Provides a feed of attribute values, by polling or subscribing over jmx.
+ *
+ * Example usage (e.g. in an entity that extends {@link SoftwareProcessImpl}):
+ * <pre>
+ * {@code
+ * private JmxFeed feed;
+ *
+ * //@Override
+ * protected void connectSensors() {
+ * super.connectSensors();
+ *
+ * feed = JmxFeed.builder()
+ * .entity(this)
+ * .period(500, TimeUnit.MILLISECONDS)
+ * .pollAttribute(new JmxAttributePollConfig<Integer>(ERROR_COUNT)
+ * .objectName(requestProcessorMbeanName)
+ * .attributeName("errorCount"))
+ * .pollAttribute(new JmxAttributePollConfig<Boolean>(SERVICE_UP)
+ * .objectName(serverMbeanName)
+ * .attributeName("Started")
+ * .onError(Functions.constant(false)))
+ * .build();
+ * }
+ *
+ * {@literal @}Override
+ * protected void disconnectSensors() {
+ * super.disconnectSensors();
+ * if (feed != null) feed.stop();
+ * }
+ * }
+ * </pre>
+ *
+ * @author aled
+ */
+public class JmxFeed extends AbstractFeed {
+
+ public static final Logger log = LoggerFactory.getLogger(JmxFeed.class);
+
+ public static final long JMX_CONNECTION_TIMEOUT_MS = 120*1000;
+
+ public static final ConfigKey<JmxHelper> HELPER = ConfigKeys.newConfigKey(JmxHelper.class, "helper");
+ public static final ConfigKey<Boolean> OWN_HELPER = ConfigKeys.newBooleanConfigKey("ownHelper");
+ public static final ConfigKey<String> JMX_URI = ConfigKeys.newStringConfigKey("jmxUri");
+ public static final ConfigKey<Long> JMX_CONNECTION_TIMEOUT = ConfigKeys.newLongConfigKey("jmxConnectionTimeout");
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<SetMultimap<String, JmxAttributePollConfig<?>>> ATTRIBUTE_POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<String, JmxAttributePollConfig<?>>>() {},
+ "attributePolls");
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<SetMultimap<List<?>, JmxOperationPollConfig<?>>> OPERATION_POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<List<?>, JmxOperationPollConfig<?>>>() {},
+ "operationPolls");
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>>> NOTIFICATION_SUBSCRIPTIONS = ConfigKeys.newConfigKey(
+ new TypeToken<SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>>>() {},
+ "notificationPolls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private JmxHelper helper;
+ private long jmxConnectionTimeout = JMX_CONNECTION_TIMEOUT_MS;
+ private long period = 500;
+ private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
+ private List<JmxAttributePollConfig<?>> attributePolls = Lists.newArrayList();
+ private List<JmxOperationPollConfig<?>> operationPolls = Lists.newArrayList();
+ private List<JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = Lists.newArrayList();
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = val;
+ return this;
+ }
+ public Builder helper(JmxHelper val) {
+ this.helper = val;
+ return this;
+ }
+ public Builder period(Duration duration) {
+ return period(duration.toMilliseconds(), TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long millis) {
+ return period(millis, TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long val, TimeUnit units) {
+ this.period = val;
+ this.periodUnits = units;
+ return this;
+ }
+ public Builder pollAttribute(JmxAttributePollConfig<?> config) {
+ attributePolls.add(config);
+ return this;
+ }
+ public Builder pollOperation(JmxOperationPollConfig<?> config) {
+ operationPolls.add(config);
+ return this;
+ }
+ public Builder subscribeToNotification(JmxNotificationSubscriptionConfig<?> config) {
+ notificationSubscriptions.add(config);
+ return this;
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public JmxFeed build() {
+ built = true;
+ JmxFeed result = new JmxFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("JmxFeed.Builder created, but build() never called");
+ }
+ }
+
+ private final SetMultimap<ObjectName, NotificationListener> notificationListeners = HashMultimap.create();
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public JmxFeed() {
+ }
+
+ protected JmxFeed(Builder builder) {
+ super();
+ if (builder.helper != null) {
+ JmxHelper helper = builder.helper;
+ setConfig(HELPER, helper);
+ setConfig(OWN_HELPER, false);
+ setConfig(JMX_URI, helper.getUrl());
+ }
+ setConfig(JMX_CONNECTION_TIMEOUT, builder.jmxConnectionTimeout);
+
+ SetMultimap<String, JmxAttributePollConfig<?>> attributePolls = HashMultimap.<String,JmxAttributePollConfig<?>>create();
+ for (JmxAttributePollConfig<?> config : builder.attributePolls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ JmxAttributePollConfig<?> configCopy = new JmxAttributePollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
+ attributePolls.put(configCopy.getObjectName().getCanonicalName() + configCopy.getAttributeName(), configCopy);
+ }
+ setConfig(ATTRIBUTE_POLLS, attributePolls);
+
+ SetMultimap<List<?>, JmxOperationPollConfig<?>> operationPolls = HashMultimap.<List<?>,JmxOperationPollConfig<?>>create();
+ for (JmxOperationPollConfig<?> config : builder.operationPolls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ JmxOperationPollConfig<?> configCopy = new JmxOperationPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
+ operationPolls.put(configCopy.buildOperationIdentity(), configCopy);
+ }
+ setConfig(OPERATION_POLLS, operationPolls);
+
+ SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = HashMultimap.create();
+ for (JmxNotificationSubscriptionConfig<?> config : builder.notificationSubscriptions) {
+ if (!config.isEnabled()) continue;
+ notificationSubscriptions.put(config.getNotificationFilter(), config);
+ }
+ setConfig(NOTIFICATION_SUBSCRIPTIONS, notificationSubscriptions);
+ initUniqueTag(builder.uniqueTag, attributePolls, operationPolls, notificationSubscriptions);
+ }
+
+ @Override
+ public void setEntity(EntityLocal entity) {
+ if (getConfig(HELPER) == null) {
+ JmxHelper helper = new JmxHelper(entity);
+ setConfig(HELPER, helper);
+ setConfig(OWN_HELPER, true);
+ setConfig(JMX_URI, helper.getUrl());
+ }
+ super.setEntity(entity);
+ }
+
+ public String getJmxUri() {
+ return getConfig(JMX_URI);
+ }
+
+ protected JmxHelper getHelper() {
+ return getConfig(HELPER);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Poller<Object> getPoller() {
+ return (Poller<Object>) super.getPoller();
+ }
+
+ @Override
+ protected boolean isConnected() {
+ return super.isConnected() && getHelper().isConnected();
+ }
+
+ @Override
+ protected void preStart() {
+ /*
+ * All actions on the JmxHelper are done async (through the poller's threading) so we don't
+ * block on start/rebind if the entity is unreachable
+ * (without this we get a 120s pause in JmxHelper.connect restarting)
+ */
+ final SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = getConfig(NOTIFICATION_SUBSCRIPTIONS);
+ final SetMultimap<List<?>, JmxOperationPollConfig<?>> operationPolls = getConfig(OPERATION_POLLS);
+ final SetMultimap<String, JmxAttributePollConfig<?>> attributePolls = getConfig(ATTRIBUTE_POLLS);
+
+ getPoller().submit(new Callable<Void>() {
+ public Void call() {
+ getHelper().connect(getConfig(JMX_CONNECTION_TIMEOUT));
+ return null;
+ }
+ @Override public String toString() { return "Connect JMX "+getHelper().getUrl(); }
+ });
+
+ for (final NotificationFilter filter : notificationSubscriptions.keySet()) {
+ getPoller().submit(new Callable<Void>() {
+ public Void call() {
+ // TODO Could config.getObjectName have wildcards? Is this code safe?
+ Set<JmxNotificationSubscriptionConfig<?>> configs = notificationSubscriptions.get(filter);
+ NotificationListener listener = registerNotificationListener(configs);
+ ObjectName objectName = Iterables.get(configs, 0).getObjectName();
+ notificationListeners.put(objectName, listener);
+ return null;
+ }
+ @Override public String toString() { return "Register JMX notifications: "+notificationSubscriptions.get(filter); }
+ });
+ }
+
+ // Setup polling of sensors
+ for (final String jmxAttributeName : attributePolls.keys()) {
+ registerAttributePoller(attributePolls.get(jmxAttributeName));
+ }
+
+ // Setup polling of operations
+ for (final List<?> operationIdentifier : operationPolls.keys()) {
+ registerOperationPoller(operationPolls.get(operationIdentifier));
+ }
+ }
+
+ @Override
+ protected void preStop() {
+ super.preStop();
+
+ for (Map.Entry<ObjectName, NotificationListener> entry : notificationListeners.entries()) {
+ unregisterNotificationListener(entry.getKey(), entry.getValue());
+ }
+ notificationListeners.clear();
+ }
+
+ @Override
+ protected void postStop() {
+ super.postStop();
+ JmxHelper helper = getHelper();
+ Boolean ownHelper = getConfig(OWN_HELPER);
+ if (helper != null && ownHelper) helper.terminate();
+ }
+
+ /**
+ * Registers to poll a jmx-operation for an ObjectName, where all the given configs are for the same ObjectName + operation + parameters.
+ */
+ private void registerOperationPoller(Set<JmxOperationPollConfig<?>> configs) {
+ Set<AttributePollHandler<? super Object>> handlers = Sets.newLinkedHashSet();
+ long minPeriod = Integer.MAX_VALUE;
+
+ final ObjectName objectName = Iterables.get(configs, 0).getObjectName();
+ final String operationName = Iterables.get(configs, 0).getOperationName();
+ final List<String> signature = Iterables.get(configs, 0).getSignature();
+ final List<?> params = Iterables.get(configs, 0).getParams();
+
+ for (JmxOperationPollConfig<?> config : configs) {
+ handlers.add(new AttributePollHandler<Object>(config, getEntity(), this));
+ if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
+ }
+
+ getPoller().scheduleAtFixedRate(
+ new Callable<Object>() {
+ public Object call() throws Exception {
+ if (log.isDebugEnabled()) log.debug("jmx operation polling for {} sensors at {} -> {}", new Object[] {getEntity(), getJmxUri(), operationName});
+ if (signature.size() == params.size()) {
+ return getHelper().operation(objectName, operationName, signature, params);
+ } else {
+ return getHelper().operation(objectName, operationName, params.toArray());
+ }
+ }
+ },
+ new DelegatingPollHandler<Object>(handlers), minPeriod);
+ }
+
+ /**
+ * Registers to poll a jmx-attribute for an ObjectName, where all the given configs are for that same ObjectName + attribute.
+ */
+ private void registerAttributePoller(Set<JmxAttributePollConfig<?>> configs) {
+ Set<AttributePollHandler<? super Object>> handlers = Sets.newLinkedHashSet();
+ long minPeriod = Integer.MAX_VALUE;
+
+ final ObjectName objectName = Iterables.get(configs, 0).getObjectName();
+ final String jmxAttributeName = Iterables.get(configs, 0).getAttributeName();
+
+ for (JmxAttributePollConfig<?> config : configs) {
+ handlers.add(new AttributePollHandler<Object>(config, getEntity(), this));
+ if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
+ }
+
+ // TODO Not good calling this holding the synchronization lock
+ getPoller().scheduleAtFixedRate(
+ new Callable<Object>() {
+ public Object call() throws Exception {
+ if (log.isTraceEnabled()) log.trace("jmx attribute polling for {} sensors at {} -> {}", new Object[] {getEntity(), getJmxUri(), jmxAttributeName});
+ return getHelper().getAttribute(objectName, jmxAttributeName);
+ }
+ },
+ new DelegatingPollHandler<Object>(handlers), minPeriod);
+ }
+
+ /**
+ * Registers to subscribe to notifications for an ObjectName, where all the given configs are for that same ObjectName + filter.
+ */
+ private NotificationListener registerNotificationListener(Set<JmxNotificationSubscriptionConfig<?>> configs) {
+ final List<AttributePollHandler<? super javax.management.Notification>> handlers = Lists.newArrayList();
+
+ final ObjectName objectName = Iterables.get(configs, 0).getObjectName();
+ final NotificationFilter filter = Iterables.get(configs, 0).getNotificationFilter();
+
+ for (final JmxNotificationSubscriptionConfig<?> config : configs) {
+ AttributePollHandler<javax.management.Notification> handler = new AttributePollHandler<javax.management.Notification>(config, getEntity(), this) {
+ @Override protected Object transformValueOnSuccess(javax.management.Notification val) {
+ if (config.getOnNotification() != null) {
+ return config.getOnNotification().apply(val);
+ } else {
+ Object result = super.transformValueOnSuccess(val);
+ if (result instanceof javax.management.Notification)
+ return ((javax.management.Notification)result).getUserData();
+ return result;
+ }
+ }
+ };
+ handlers.add(handler);
+ }
+ final PollHandler<javax.management.Notification> compoundHandler = new DelegatingPollHandler<javax.management.Notification>(handlers);
+
+ NotificationListener listener = new NotificationListener() {
+ @Override public void handleNotification(Notification notification, Object handback) {
+ compoundHandler.onSuccess(notification);
+ }
+ };
+ getHelper().addNotificationListener(objectName, listener, filter);
+
+ return listener;
+ }
+
+ private void unregisterNotificationListener(ObjectName objectName, NotificationListener listener) {
+ try {
+ getHelper().removeNotificationListener(objectName, listener);
+ } catch (RuntimeException e) {
+ log.warn("Failed to unregister listener: "+objectName+", "+listener+"; continuing...", e);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "JmxFeed["+(getManagementContext()!=null&&getManagementContext().isRunning()?getJmxUri():"mgmt-not-running")+"]";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxHelper.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxHelper.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxHelper.java
new file mode 100644
index 0000000..652ac76
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxHelper.java
@@ -0,0 +1,724 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth;
+import groovy.time.TimeDuration;
+
+import java.io.IOException;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.JMX;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanServerConnection;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.entity.java.JmxSupport;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.util.core.crypto.SecureKeys;
+import org.apache.brooklyn.util.crypto.SslTrustUtils;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
+import org.apache.brooklyn.util.jmx.jmxmp.JmxmpAgent;
+import org.apache.brooklyn.util.repeat.Repeater;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class JmxHelper {
+
+ private static final Logger LOG = LoggerFactory.getLogger(JmxHelper.class);
+
+ public static final String JMX_URL_FORMAT = "service:jmx:rmi:///jndi/rmi://%s:%d/%s";
+ // first host:port may be ignored, so above is sufficient, but not sure
+ public static final String RMI_JMX_URL_FORMAT = "service:jmx:rmi://%s:%d/jndi/rmi://%s:%d/%s";
+ // jmxmp
+ public static final String JMXMP_URL_FORMAT = "service:jmx:jmxmp://%s:%d";
+
+ // Tracks the MBeans we have failed to find, with a set keyed off the url
+ private static final Map<String, Set<ObjectName>> notFoundMBeansByUrl = Collections.synchronizedMap(new WeakHashMap<String, Set<ObjectName>>());
+
+ public static final Map<String, String> CLASSES = ImmutableMap.<String,String>builder()
+ .put("Integer", Integer.TYPE.getName())
+ .put("Long", Long.TYPE.getName())
+ .put("Boolean", Boolean.TYPE.getName())
+ .put("Byte", Byte.TYPE.getName())
+ .put("Character", Character.TYPE.getName())
+ .put("Double", Double.TYPE.getName())
+ .put("Float", Float.TYPE.getName())
+ .put("GStringImpl", String.class.getName())
+ .put("LinkedHashMap", Map.class.getName())
+ .put("TreeMap", Map.class.getName())
+ .put("HashMap", Map.class.getName())
+ .put("ConcurrentHashMap", Map.class.getName())
+ .put("TabularDataSupport", TabularData.class.getName())
+ .put("CompositeDataSupport", CompositeData.class.getName())
+ .build();
+
+ /** constructs a JMX URL suitable for connecting to the given entity, being smart about JMX/RMI vs JMXMP */
+ public static String toJmxUrl(EntityLocal entity) {
+ String url = entity.getAttribute(UsesJmx.JMX_URL);
+ if (url != null) {
+ return url;
+ } else {
+ new JmxSupport(entity, null).setJmxUrl();
+ url = entity.getAttribute(UsesJmx.JMX_URL);
+ return Preconditions.checkNotNull(url, "Could not find URL for "+entity);
+ }
+ }
+
+ /** constructs an RMI/JMX URL with the given inputs
+ * (where the RMI Registry Port should be non-null, and at least one must be non-null) */
+ public static String toRmiJmxUrl(String host, Integer jmxRmiServerPort, Integer rmiRegistryPort, String context) {
+ if (rmiRegistryPort != null && rmiRegistryPort > 0) {
+ if (jmxRmiServerPort!=null && jmxRmiServerPort > 0 && jmxRmiServerPort!=rmiRegistryPort) {
+ // we have an explicit known JMX RMI server port (e.g. because we are using the agent),
+ // distinct from the RMI registry port
+ // (if the ports are the same, it is a short-hand, and don't use this syntax!)
+ return String.format(RMI_JMX_URL_FORMAT, host, jmxRmiServerPort, host, rmiRegistryPort, context);
+ }
+ return String.format(JMX_URL_FORMAT, host, rmiRegistryPort, context);
+ } else if (jmxRmiServerPort!=null && jmxRmiServerPort > 0) {
+ LOG.warn("No RMI registry port set for "+host+"; attempting to use JMX port for RMI lookup");
+ return String.format(JMX_URL_FORMAT, host, jmxRmiServerPort, context);
+ } else {
+ LOG.warn("No RMI/JMX details set for "+host+"; returning null");
+ return null;
+ }
+ }
+
+ /** constructs a JMXMP URL for connecting to the given host and port */
+ public static String toJmxmpUrl(String host, Integer jmxmpPort) {
+ return "service:jmx:jmxmp://"+host+(jmxmpPort!=null ? ":"+jmxmpPort : "");
+ }
+
+ final EntityLocal entity;
+ final String url;
+ final String user;
+ final String password;
+
+ private volatile transient JMXConnector connector;
+ private volatile transient MBeanServerConnection connection;
+ private transient boolean triedConnecting;
+ private transient boolean failedReconnecting;
+ private transient long failedReconnectingTime;
+ private int minTimeBetweenReconnectAttempts = 1000;
+ private final AtomicBoolean terminated = new AtomicBoolean();
+
+ // Tracks the MBeans we have failed to find for this JmsHelper's connection URL (so can log just once for each)
+ private final Set<ObjectName> notFoundMBeans;
+
+ public JmxHelper(EntityLocal entity) {
+ this(toJmxUrl(entity), entity, entity.getAttribute(UsesJmx.JMX_USER), entity.getAttribute(UsesJmx.JMX_PASSWORD));
+
+ if (entity.getAttribute(UsesJmx.JMX_URL) == null) {
+ entity.setAttribute(UsesJmx.JMX_URL, url);
+ }
+ }
+
+ // TODO split this in to two classes, one for entities, and one entity-neutral
+ // (simplifying set of constructors below)
+
+ public JmxHelper(String url) {
+ this(url, null, null);
+ }
+
+ public JmxHelper(String url, String user, String password) {
+ this(url, null, user, password);
+ }
+
+ public JmxHelper(String url, EntityLocal entity, String user, String password) {
+ this.url = url;
+ this.entity = entity;
+ this.user = user;
+ this.password = password;
+
+ synchronized (notFoundMBeansByUrl) {
+ Set<ObjectName> set = notFoundMBeansByUrl.get(url);
+ if (set == null) {
+ set = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<ObjectName, Boolean>()));
+ notFoundMBeansByUrl.put(url, set);
+ }
+ notFoundMBeans = set;
+ }
+ }
+
+ public void setMinTimeBetweenReconnectAttempts(int val) {
+ minTimeBetweenReconnectAttempts = val;
+ }
+
+ public String getUrl(){
+ return url;
+ }
+
+ // ============== connection related calls =======================
+
+ //for tesing purposes
+ protected MBeanServerConnection getConnection() {
+ return connection;
+ }
+
+ /**
+ * Checks if the JmxHelper is connected. Returned value could be stale as soon
+ * as it is received.
+ *
+ * This method is thread safe.
+ *
+ * @return true if connected, false otherwise.
+ */
+ public boolean isConnected() {
+ return connection!=null;
+ }
+
+ /**
+ * Reconnects. If it already is connected, it disconnects first.
+ *
+ * @throws IOException
+ */
+ public synchronized void reconnectWithRetryDampened() throws IOException {
+ // If we've already tried reconnecting very recently, don't try again immediately
+ if (failedReconnecting) {
+ long timeSince = (System.currentTimeMillis() - failedReconnectingTime);
+ if (timeSince < minTimeBetweenReconnectAttempts) {
+ String msg = "Not reconnecting to JMX at "+url+" because attempt failed "+Time.makeTimeStringRounded(timeSince)+" ago";
+ throw new IllegalStateException(msg);
+ }
+ }
+
+ reconnect();
+ }
+
+ public synchronized void reconnect() throws IOException {
+ disconnect();
+
+ try {
+ connect();
+ failedReconnecting = false;
+ } catch (Exception e) {
+ if (failedReconnecting) {
+ if (LOG.isDebugEnabled()) LOG.debug("unable to re-connect to JMX url (repeated failure): {}: {}", url, e);
+ } else {
+ LOG.debug("unable to re-connect to JMX url {} (rethrowing): {}", url, e);
+ failedReconnecting = true;
+ }
+ failedReconnectingTime = System.currentTimeMillis();
+ throw Throwables.propagate(e);
+ }
+ }
+
+ /** attempts to connect immediately */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public synchronized void connect() throws IOException {
+ if (terminated.get()) throw new IllegalStateException("JMX Helper "+this+" already terminated");
+ if (connection != null) return;
+
+ triedConnecting = true;
+ if (connector != null) connector.close();
+ JMXServiceURL serviceUrl = new JMXServiceURL(url);
+ Map env = getConnectionEnvVars();
+ try {
+ connector = JMXConnectorFactory.connect(serviceUrl, env);
+ } catch (NullPointerException npe) {
+ //some software -- eg WSO2 -- will throw an NPE exception if the JMX connection can't be created, instead of an IOException.
+ //this is a break of contract with the JMXConnectorFactory.connect method, so this code verifies if the NPE is
+ //thrown by a known offender (wso2) and if so replaces the bad exception by a new IOException.
+ //ideally WSO2 will fix this bug and we can remove this code.
+ boolean thrownByWso2 = npe.getStackTrace()[0].toString().contains("org.wso2.carbon.core.security.CarbonJMXAuthenticator.authenticate");
+ if (thrownByWso2) {
+ throw new IOException("Failed to connect to url "+url+". NullPointerException is thrown, but replaced by an IOException to fix a WSO2 JMX problem", npe);
+ } else {
+ throw npe;
+ }
+ } catch (IOException e) {
+ Exceptions.propagateIfFatal(e);
+ if (terminated.get()) {
+ throw new IllegalStateException("JMX Helper "+this+" already terminated", e);
+ } else {
+ throw e;
+ }
+ }
+ connection = connector.getMBeanServerConnection();
+
+ if (terminated.get()) {
+ disconnectNow();
+ throw new IllegalStateException("JMX Helper "+this+" already terminated");
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public Map getConnectionEnvVars() {
+ Map env = new LinkedHashMap();
+
+ if (groovyTruth(user) && groovyTruth(password)) {
+ String[] creds = new String[] {user, password};
+ env.put(JMXConnector.CREDENTIALS, creds);
+ }
+
+ if (entity!=null && groovyTruth(entity.getConfig(UsesJmx.JMX_SSL_ENABLED))) {
+ env.put("jmx.remote.profiles", JmxmpAgent.TLS_JMX_REMOTE_PROFILES);
+
+ PrivateKey key = entity.getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
+ Certificate cert = entity.getConfig(UsesJmx.JMX_SSL_ACCESS_CERT);
+ KeyStore ks = SecureKeys.newKeyStore();
+ try {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ if (key!=null) {
+ ks.setKeyEntry("brooklyn-jmx-access", key, "".toCharArray(), new Certificate[] { cert });
+ }
+ kmf.init(ks, "".toCharArray());
+
+ TrustManager tms =
+ // TODO use root cert for trusting server
+ //trustStore!=null ? SecureKeys.getTrustManager(trustStore) :
+ SslTrustUtils.TRUST_ALL;
+
+ SSLContext ctx = SSLContext.getInstance("TLSv1");
+ ctx.init(kmf.getKeyManagers(), new TrustManager[] { tms }, null);
+ SSLSocketFactory ssf = ctx.getSocketFactory();
+ env.put(JmxmpAgent.TLS_SOCKET_FACTORY_PROPERTY, ssf);
+
+ } catch (Exception e) {
+ LOG.warn("Error setting key "+key+" for "+entity+": "+e, e);
+ }
+ }
+
+ return env;
+ }
+
+ /**
+ * Continuously attempts to connect for at least the indicated amount of time; or indefinitely if -1. This method
+ * is useful when you are not sure if the system you are trying to connect to already is up and running.
+ *
+ * This method doesn't throw an Exception, but returns true on success, false otherwise.
+ *
+ * TODO: What happens if already connected?
+ *
+ * @param timeoutMs
+ * @return
+ */
+ public boolean connect(long timeoutMs) {
+ if (LOG.isDebugEnabled()) LOG.debug("Connecting to JMX URL: {} ({})", url, ((timeoutMs == -1) ? "indefinitely" : timeoutMs+"ms timeout"));
+ long startMs = System.currentTimeMillis();
+ long endMs = (timeoutMs == -1) ? Long.MAX_VALUE : (startMs + timeoutMs);
+ long currentTime = startMs;
+ Throwable lastError = null;
+ int attempt = 0;
+ while (currentTime <= endMs) {
+ currentTime = System.currentTimeMillis();
+ if (attempt != 0) sleep(100); //sleep 100 to prevent thrashing and facilitate interruption
+ if (LOG.isTraceEnabled()) LOG.trace("trying connection to {} at time {}", url, currentTime);
+
+ try {
+ connect();
+ return true;
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ if (!terminated.get() && shouldRetryOn(e)) {
+ if (LOG.isDebugEnabled()) LOG.debug("Attempt {} failed connecting to {} ({})", new Object[] {attempt + 1, url, e.getMessage()});
+ lastError = e;
+ } else {
+ throw Exceptions.propagate(e);
+ }
+ }
+ attempt++;
+ }
+ LOG.warn("unable to connect to JMX url: "+url, lastError);
+ return false;
+ }
+
+ private boolean shouldRetryOn(Exception e) {
+ // Expect SecurityException, IOException, etc.
+ // But can also see things like javax.naming.ServiceUnavailableException with WSO2 app-servers.
+ // So let's not try to second guess strange behaviours that future entities will exhibit.
+ //
+ // However, if it was our request that was invalid then not worth retrying.
+
+ if (e instanceof AttributeNotFoundException) return false;
+ if (e instanceof InstanceAlreadyExistsException) return false;
+ if (e instanceof InstanceNotFoundException) return false;
+ if (e instanceof InvalidAttributeValueException) return false;
+ if (e instanceof ListenerNotFoundException) return false;
+ if (e instanceof MalformedObjectNameException) return false;
+ if (e instanceof NotCompliantMBeanException) return false;
+ if (e instanceof InterruptedException) return false;
+ if (e instanceof RuntimeInterruptedException) return false;
+
+ return true;
+ }
+
+ /**
+ * A thread-safe version of {@link #disconnectNow()}.
+ *
+ * This method is threadsafe.
+ */
+ public synchronized void disconnect() {
+ disconnectNow();
+ }
+
+ /**
+ * Disconnects, preventing subsequent connections to be made. Method doesn't throw an exception.
+ *
+ * Can safely be called if already disconnected.
+ *
+ * This method is not threadsafe, but will thus not block if
+ * another thread is taking a long time for connections to timeout.
+ *
+ * Any concurrent requests will likely get an IOException - see
+ * {@linkplain http://docs.oracle.com/javase/7/docs/api/javax/management/remote/JMXConnector.html#close()}.
+ *
+ */
+ public void terminate() {
+ terminated.set(true);
+ disconnectNow();
+ }
+
+ protected void disconnectNow() {
+ triedConnecting = false;
+ if (connector != null) {
+ if (LOG.isDebugEnabled()) LOG.debug("Disconnecting from JMX URL {}", url);
+ try {
+ connector.close();
+ } catch (Exception e) {
+ // close attempts to connect to close cleanly; and if it can't, it throws;
+ // often we disconnect as part of shutdown, even if the other side has already stopped --
+ // so swallow exceptions (no situations known where we need a clean closure on the remote side)
+ if (LOG.isDebugEnabled()) LOG.debug("Caught exception disconnecting from JMX at {} ({})", url, e.getMessage());
+ if (LOG.isTraceEnabled()) LOG.trace("Details for exception disconnecting JMX", e);
+ } finally {
+ connector = null;
+ connection = null;
+ }
+ }
+ }
+
+ /**
+ * Gets a usable MBeanServerConnection.
+ *
+ * Method is threadsafe.
+ *
+ * @returns the MBeanServerConnection
+ * @throws IllegalStateException if not connected.
+ */
+ private synchronized MBeanServerConnection getConnectionOrFail() {
+ if (isConnected())
+ return getConnection();
+
+ if (triedConnecting) {
+ throw new IllegalStateException("Failed to connect to JMX at "+url);
+ } else {
+ String msg = "Not connected (and not attempted to connect) to JMX at "+url+
+ (failedReconnecting ? (" (last reconnect failure at "+ Time.makeDateString(failedReconnectingTime) + ")") : "");
+ throw new IllegalStateException(msg);
+ }
+ }
+
+ private <T> T invokeWithReconnect(Callable<T> task) {
+ try {
+ return task.call();
+ } catch (Exception e) {
+ if (shouldRetryOn(e)) {
+ try {
+ reconnectWithRetryDampened();
+ return task.call();
+ } catch (Exception e2) {
+ throw Throwables.propagate(e2);
+ }
+ } else {
+ throw Throwables.propagate(e);
+ }
+ }
+ }
+
+ // ====================== query related calls =======================================
+
+ /**
+ * Converts from an object name pattern to a real object name, by querying with findMBean;
+ * if no matching MBean can be found (or if more than one match found) then returns null.
+ * If the supplied object name is not a pattern then just returns that. If the
+ */
+ public ObjectName toLiteralObjectName(ObjectName objectName) {
+ if (checkNotNull(objectName, "objectName").isPattern()) {
+ ObjectInstance bean = findMBean(objectName);
+ return (bean != null) ? bean.getObjectName() : null;
+ } else {
+ return objectName;
+ }
+ }
+
+ public Set<ObjectInstance> findMBeans(final ObjectName objectName) {
+ return invokeWithReconnect(new Callable<Set<ObjectInstance>>() {
+ public Set<ObjectInstance> call() throws Exception {
+ return getConnectionOrFail().queryMBeans(objectName, null);
+ }});
+ }
+
+ public ObjectInstance findMBean(ObjectName objectName) {
+ Set<ObjectInstance> beans = findMBeans(objectName);
+ if (beans.size() == 1) {
+ notFoundMBeans.remove(objectName);
+ return Iterables.getOnlyElement(beans);
+ } else {
+ boolean changed = notFoundMBeans.add(objectName);
+
+ if (beans.size() > 1) {
+ if (changed) {
+ LOG.warn("JMX object name query returned {} values for {} at {}; ignoring all",
+ new Object[] {beans.size(), objectName.getCanonicalName(), url});
+ } else {
+ if (LOG.isDebugEnabled()) LOG.debug("JMX object name query returned {} values for {} at {} (repeating); ignoring all",
+ new Object[] {beans.size(), objectName.getCanonicalName(), url});
+ }
+ } else {
+ if (changed) {
+ LOG.warn("JMX object {} not found at {}", objectName.getCanonicalName(), url);
+ } else {
+ if (LOG.isDebugEnabled()) LOG.debug("JMX object {} not found at {} (repeating)", objectName.getCanonicalName(), url);
+ }
+ }
+ return null;
+ }
+ }
+
+ public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, Duration timeout) {
+ return doesMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
+ }
+ public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, TimeDuration timeout) {
+ return doesMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
+ }
+
+ public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, long timeoutMillis) {
+ return doesMBeanExistsEventually(objectName, timeoutMillis, TimeUnit.MILLISECONDS);
+ }
+
+ public Set<ObjectInstance> doesMBeanExistsEventually(String objectName, Duration timeout) {
+ return doesMBeanExistsEventually(createObjectName(objectName), timeout);
+ }
+ public Set<ObjectInstance> doesMBeanExistsEventually(String objectName, TimeDuration timeout) {
+ return doesMBeanExistsEventually(createObjectName(objectName), timeout);
+ }
+
+ public Set<ObjectInstance> doesMBeanExistsEventually(String objectName, long timeout, TimeUnit timeUnit) {
+ return doesMBeanExistsEventually(createObjectName(objectName), timeout, timeUnit);
+ }
+
+ /** returns set of beans found, with retry, empty set if none after timeout */
+ public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, long timeout, TimeUnit timeUnit) {
+ final long timeoutMillis = timeUnit.toMillis(timeout);
+ final AtomicReference<Set<ObjectInstance>> beans = new AtomicReference<Set<ObjectInstance>>(ImmutableSet.<ObjectInstance>of());
+ try {
+ Repeater.create("Wait for "+objectName)
+ .limitTimeTo(timeout, timeUnit)
+ .every(500, TimeUnit.MILLISECONDS)
+ .until(new Callable<Boolean>() {
+ public Boolean call() {
+ connect(timeoutMillis);
+ beans.set(findMBeans(objectName));
+ return !beans.get().isEmpty();
+ }})
+ .rethrowException()
+ .run();
+ return beans.get();
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+
+ public void assertMBeanExistsEventually(ObjectName objectName, Duration timeout) {
+ assertMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
+ }
+ public void assertMBeanExistsEventually(ObjectName objectName, TimeDuration timeout) {
+ assertMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
+ }
+
+ public void assertMBeanExistsEventually(ObjectName objectName, long timeoutMillis) {
+ assertMBeanExistsEventually(objectName, timeoutMillis, TimeUnit.MILLISECONDS);
+ }
+
+ public void assertMBeanExistsEventually(ObjectName objectName, long timeout, TimeUnit timeUnit) {
+ Set<ObjectInstance> beans = doesMBeanExistsEventually(objectName, timeout, timeUnit);
+ if (beans.size() != 1) {
+ throw new IllegalStateException("MBean "+objectName+" not found within "+timeout+
+ (beans.size() > 1 ? "; found multiple matches: "+beans : ""));
+ }
+ }
+
+ /**
+ * Returns a specific attribute for a JMX {@link ObjectName}.
+ */
+ public Object getAttribute(ObjectName objectName, final String attribute) {
+ final ObjectName realObjectName = toLiteralObjectName(objectName);
+
+ if (realObjectName != null) {
+ Object result = invokeWithReconnect(new Callable<Object>() {
+ public Object call() throws Exception {
+ return getConnectionOrFail().getAttribute(realObjectName, attribute);
+ }});
+
+ if (LOG.isTraceEnabled()) LOG.trace("From {}, for jmx attribute {}.{}, got value {}", new Object[] {url, objectName.getCanonicalName(), attribute, result});
+ return result;
+ } else {
+ return null;
+ }
+ }
+
+ public void setAttribute(String objectName, String attribute, Object val) {
+ setAttribute(createObjectName(objectName), attribute, val);
+ }
+
+ public void setAttribute(ObjectName objectName, final String attribute, final Object val) {
+ final ObjectName realObjectName = toLiteralObjectName(objectName);
+
+ if (realObjectName != null) {
+ invokeWithReconnect(new Callable<Void>() {
+ public Void call() throws Exception {
+ getConnectionOrFail().setAttribute(realObjectName, new javax.management.Attribute(attribute, val));
+ return null;
+ }});
+ if (LOG.isTraceEnabled()) LOG.trace("From {}, for jmx attribute {}.{}, set value {}", new Object[] {url, objectName.getCanonicalName(), attribute, val});
+ } else {
+ if (LOG.isDebugEnabled()) LOG.debug("From {}, cannot set attribute {}.{}, because mbean not found", new Object[] {url, objectName.getCanonicalName(), attribute});
+ }
+ }
+
+ /** @see #operation(ObjectName, String, Object ...) */
+ public Object operation(String objectName, String method, Object... arguments) {
+ return operation(createObjectName(objectName), method, arguments);
+ }
+
+ /**
+ * Executes an operation on a JMX {@link ObjectName}.
+ */
+ public Object operation(ObjectName objectName, final String method, final Object... arguments) {
+ final ObjectName realObjectName = toLiteralObjectName(objectName);
+ final String[] signature = new String[arguments.length];
+ for (int i = 0; i < arguments.length; i++) {
+ Class<?> clazz = arguments[i].getClass();
+ signature[i] = (CLASSES.containsKey(clazz.getSimpleName()) ? CLASSES.get(clazz.getSimpleName()) : clazz.getName());
+ }
+
+ Object result = invokeWithReconnect(new Callable<Object>() {
+ public Object call() throws Exception {
+ return getConnectionOrFail().invoke(realObjectName, method, arguments, signature);
+ }});
+
+ if (LOG.isTraceEnabled()) LOG.trace("From {}, for jmx operation {}.{}({}), got value {}", new Object[] {url, realObjectName.getCanonicalName(), method, Arrays.asList(arguments),
+ result});
+ return result;
+ }
+
+ public void addNotificationListener(String objectName, NotificationListener listener) {
+ addNotificationListener(createObjectName(objectName), listener, null);
+ }
+
+ public void addNotificationListener(String objectName, NotificationListener listener, NotificationFilter filter) {
+ addNotificationListener(createObjectName(objectName), listener, filter);
+ }
+
+ public void addNotificationListener(ObjectName objectName, NotificationListener listener) {
+ addNotificationListener(objectName, listener, null);
+ }
+
+ public void addNotificationListener(final ObjectName objectName, final NotificationListener listener, final NotificationFilter filter) {
+ invokeWithReconnect(new Callable<Void>() {
+ public Void call() throws Exception {
+ getConnectionOrFail().addNotificationListener(objectName, listener, filter, null);
+ return null;
+ }});
+ }
+
+ public void removeNotificationListener(String objectName, NotificationListener listener) {
+ removeNotificationListener(createObjectName(objectName), listener);
+ }
+
+ public void removeNotificationListener(final ObjectName objectName, final NotificationListener listener) {
+ removeNotificationListener(objectName, listener, null);
+ }
+
+ public void removeNotificationListener(final ObjectName objectName, final NotificationListener listener, final NotificationFilter filter) {
+ if (isConnected()) invokeWithReconnect(new Callable<Void>() {
+ public Void call() throws Exception {
+ getConnectionOrFail().removeNotificationListener(objectName, listener, filter, null);
+ return null;
+ }});
+ }
+
+ public <M> M getProxyObject(String objectName, Class<M> mbeanInterface) {
+ return getProxyObject(createObjectName(objectName), mbeanInterface);
+ }
+
+ public <M> M getProxyObject(ObjectName objectName, Class<M> mbeanInterface) {
+ MBeanServerConnection connection = getConnectionOrFail();
+ return JMX.newMBeanProxy(connection, objectName, mbeanInterface, false);
+ }
+
+ public static ObjectName createObjectName(String name) {
+ try {
+ return new ObjectName(name);
+ } catch (MalformedObjectNameException e) {
+ throw Throwables.propagate(e);
+ }
+ }
+
+ private static void sleep(long sleepTimeMillis) {
+ try {
+ Thread.sleep(sleepTimeMillis);
+ } catch (InterruptedException e) {
+ throw new RuntimeInterruptedException(e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationFilters.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationFilters.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationFilters.java
new file mode 100644
index 0000000..4b5d3b6
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationFilters.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationFilterSupport;
+
+public class JmxNotificationFilters {
+
+ private JmxNotificationFilters() {} // instead use static utility methods
+
+ /**
+ * Matches the given notification type.
+ * @see {@link NotificationFilterSupport#enableType(String)}
+ */
+ public static NotificationFilter matchesType(String type) {
+ return matchesTypes(type);
+ }
+
+ /**
+ * Matches any of the given notification types.
+ * @see {@link NotificationFilterSupport#enableType(String)}
+ */
+ public static NotificationFilter matchesTypes(String... types) {
+ NotificationFilterSupport result = new NotificationFilterSupport();
+ for (String type : types) {
+ result.enableType(type);
+ }
+ return result;
+ }
+
+ /**
+ * @deprecated since 0.6.0;
+ * only works if this brooklyn class is on the classpath of the JVM that your
+ * subscribing to notifications on (because it tries to push the filter instance
+ * to that JVM). So of very limited use in real-world java processes to be managed.
+ * Therefore this will be deleted to avoid people hitting this surprising behaviour.
+ */
+ @SuppressWarnings("serial")
+ public static NotificationFilter matchesTypeRegex(final String typeRegex) {
+ return new NotificationFilter() {
+ @Override public boolean isNotificationEnabled(Notification notif) {
+ return notif.getType().matches(typeRegex);
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationSubscriptionConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationSubscriptionConfig.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationSubscriptionConfig.java
new file mode 100644
index 0000000..844bacb
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxNotificationSubscriptionConfig.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.ObjectName;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.FeedConfig;
+import org.apache.brooklyn.util.collections.MutableList;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+
+public class JmxNotificationSubscriptionConfig<T> extends FeedConfig<javax.management.Notification, T, JmxNotificationSubscriptionConfig<T>>{
+
+ private ObjectName objectName;
+ private NotificationFilter notificationFilter;
+ private Function<Notification, T> onNotification;
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public JmxNotificationSubscriptionConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ onSuccess((Function)Functions.identity());
+ }
+
+ public JmxNotificationSubscriptionConfig(JmxNotificationSubscriptionConfig<T> other) {
+ super(other);
+ this.objectName = other.objectName;
+ this.notificationFilter = other.notificationFilter;
+ this.onNotification = other.onNotification;
+ }
+
+ public ObjectName getObjectName() {
+ return objectName;
+ }
+
+ public NotificationFilter getNotificationFilter() {
+ return notificationFilter;
+ }
+
+ public Function<Notification, T> getOnNotification() {
+ return onNotification;
+ }
+
+ public JmxNotificationSubscriptionConfig<T> objectName(ObjectName val) {
+ this.objectName = val; return this;
+ }
+
+ public JmxNotificationSubscriptionConfig<T> objectName(String val) {
+ try {
+ return objectName(new ObjectName(val));
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException("Invalid object name ("+val+")", e);
+ }
+ }
+
+ public JmxNotificationSubscriptionConfig<T> notificationFilter(NotificationFilter val) {
+ this.notificationFilter = val; return this;
+ }
+
+ public JmxNotificationSubscriptionConfig<T> onNotification(Function<Notification,T> val) {
+ this.onNotification = val; return this;
+ }
+
+ @Override
+ protected Object toStringPollSource() {
+ return objectName;
+ }
+
+ @Override
+ protected MutableList<Object> equalsFields() {
+ return super.equalsFields()
+ .appendIfNotNull(notificationFilter).appendIfNotNull(onNotification);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxOperationPollConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxOperationPollConfig.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxOperationPollConfig.java
new file mode 100644
index 0000000..107401d
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxOperationPollConfig.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.feed.PollConfig;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class JmxOperationPollConfig<T> extends PollConfig<Object, T, JmxOperationPollConfig<T>>{
+
+ private ObjectName objectName;
+ private String operationName;
+ private List<String> signature = Collections.emptyList();
+ private List<?> params = Collections.emptyList();
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public JmxOperationPollConfig(AttributeSensor<T> sensor) {
+ super(sensor);
+ onSuccess((Function)Functions.identity());
+ }
+
+ public JmxOperationPollConfig(JmxOperationPollConfig<T> other) {
+ super(other);
+ this.objectName = other.objectName;
+ this.operationName = other.operationName;
+ this.signature = other.signature != null ? ImmutableList.copyOf(other.signature) : null;
+ this.params = other.params != null ? ImmutableList.copyOf(other.params) : null;
+ }
+
+ public ObjectName getObjectName() {
+ return objectName;
+ }
+
+ public String getOperationName() {
+ return operationName;
+ }
+
+ public List<String> getSignature() {
+ return signature;
+ }
+
+ public List<?> getParams() {
+ return params;
+ }
+
+ public JmxOperationPollConfig<T> objectName(ObjectName val) {
+ this.objectName = val; return this;
+ }
+
+ public JmxOperationPollConfig<T> objectName(String val) {
+ try {
+ return objectName(new ObjectName(val));
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException("Invalid object name ("+val+")", e);
+ }
+ }
+
+ public JmxOperationPollConfig<T> operationName(String val) {
+ this.operationName = val; return this;
+ }
+
+ public JmxOperationPollConfig<T> operationSignature(List<String> val) {
+ this.signature = val; return this;
+ }
+
+ public JmxOperationPollConfig<T> operationParams(List<?> val) {
+ this.params = val; return this;
+ }
+
+ public List<?> buildOperationIdentity() {
+ // FIXME Have a build() method for ensuring signature is set, and making class subsequently immutable?
+ return ImmutableList.of(operationName, buildSignature(), params);
+ }
+
+ private List<String> buildSignature() {
+ if (signature != null && signature.size() == params.size()) {
+ return signature;
+ } else {
+ List<String> derivedSignature = Lists.newLinkedList();
+ for (Object param : params) {
+ Class<?> clazz = (param != null) ? param.getClass() : null;
+ String clazzName = (clazz != null) ?
+ (JmxHelper.CLASSES.containsKey(clazz.getSimpleName()) ?
+ JmxHelper.CLASSES.get(clazz.getSimpleName()) : clazz.getName()) :
+ Object.class.getName();
+ derivedSignature.add(clazzName);
+ }
+ return derivedSignature;
+ }
+ }
+
+ @Override protected String toStringBaseName() { return "jmx"; }
+ @Override protected String toStringPollSource() { return objectName+":"+operationName+(params!=null ? params : "[]"); }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxValueFunctions.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxValueFunctions.java b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxValueFunctions.java
new file mode 100644
index 0000000..5741099
--- /dev/null
+++ b/software/base/src/main/java/org/apache/brooklyn/feed/jmx/JmxValueFunctions.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.jmx;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.TabularData;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+public class JmxValueFunctions {
+
+ private static final Logger log = LoggerFactory.getLogger(JmxValueFunctions.class);
+
+ /**
+ * @return a closure that converts a TabularDataSupport to a map.
+ */
+ public static Function<TabularData, Map> tabularDataToMap() {
+ return new Function<TabularData, Map>() {
+ @Override public Map apply(TabularData input) {
+ return tabularDataToMap(input);
+ }};
+ }
+
+ public static Function<TabularData, Map> tabularDataToMapOfMaps() {
+ return new Function<TabularData, Map>() {
+ @Override public Map apply(TabularData input) {
+ return tabularDataToMapOfMaps(input);
+ }};
+ }
+
+ public static Function<CompositeData,Map> compositeDataToMap() {
+ return new Function<CompositeData, Map>() {
+ @Override public Map apply(CompositeData input) {
+ return compositeDataToMap(input);
+ }};
+ }
+
+ public static Map tabularDataToMap(TabularData table) {
+ Map<String, Object> result = Maps.newLinkedHashMap();
+ for (Object entry : table.values()) {
+ CompositeData data = (CompositeData) entry; //.getValue()
+ for (String key : data.getCompositeType().keySet()) {
+ Object old = result.put(key, data.get(key));
+ if (old != null) {
+ log.warn("tablularDataToMap has overwritten key {}", key);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static Map<List<?>, Map<String, Object>> tabularDataToMapOfMaps(TabularData table) {
+ Map<List<?>, Map<String, Object>> result = Maps.newLinkedHashMap();
+ for (Object k : table.keySet()) {
+ final Object[] kValues = ((List<?>)k).toArray();
+ CompositeData v = (CompositeData) table.get(kValues);
+ result.put((List<?>)k, compositeDataToMap(v));
+ }
+ return result;
+ }
+
+ public static Map<String, Object> compositeDataToMap(CompositeData data) {
+ Map<String, Object> result = Maps.newLinkedHashMap();
+ for (String key : data.getCompositeType().keySet()) {
+ Object old = result.put(key, data.get(key));
+ if (old != null) {
+ log.warn("compositeDataToMap has overwritten key {}", key);
+ }
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxAttributePollConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxAttributePollConfig.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxAttributePollConfig.java
deleted file mode 100644
index 02bbbeb..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxAttributePollConfig.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-
-public class JmxAttributePollConfig<T> extends PollConfig<Object, T, JmxAttributePollConfig<T>>{
-
- private ObjectName objectName;
- private String attributeName;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public JmxAttributePollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- onSuccess((Function)Functions.identity());
- }
-
- public JmxAttributePollConfig(JmxAttributePollConfig<T> other) {
- super(other);
- this.objectName = other.objectName;
- this.attributeName = other.attributeName;
- }
-
- public ObjectName getObjectName() {
- return objectName;
- }
-
- public String getAttributeName() {
- return attributeName;
- }
-
- public JmxAttributePollConfig<T> objectName(ObjectName val) {
- this.objectName = val; return this;
- }
-
- public JmxAttributePollConfig<T> objectName(String val) {
- try {
- return objectName(new ObjectName(val));
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException("Invalid object name ("+val+")", e);
- }
- }
-
- public JmxAttributePollConfig<T> attributeName(String val) {
- this.attributeName = val; return this;
- }
-
- @Override protected String toStringBaseName() { return "jmx"; }
- @Override protected String toStringPollSource() { return objectName+":"+attributeName; }
-
-}
[07/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to
o.a.b.core.effector
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/Effectors.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/Effectors.java b/core/src/main/java/org/apache/brooklyn/effector/core/Effectors.java
deleted file mode 100644
index 7f7bed4..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/Effectors.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorBodyTaskFactory;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorMarkingTaskFactory;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-public class Effectors {
-
- private static final Logger log = LoggerFactory.getLogger(Effectors.class);
-
- public static class EffectorBuilder<T> {
- private Class<T> returnType;
- private String effectorName;
- private String description;
- private Map<String,ParameterType<?>> parameters = new LinkedHashMap<String,ParameterType<?>>();
- private EffectorTaskFactory<T> impl;
-
- private EffectorBuilder(Class<T> returnType, String effectorName) {
- this.returnType = returnType;
- this.effectorName = effectorName;
- }
- public EffectorBuilder<T> description(String description) {
- this.description = description;
- return this;
- }
- public EffectorBuilder<T> parameter(Class<?> paramType, String paramName) {
- return parameter(paramType, paramName, null, null);
- }
- public EffectorBuilder<T> parameter(Class<?> paramType, String paramName, String paramDescription) {
- return parameter(paramType, paramName, paramDescription, null);
- }
- public <V> EffectorBuilder<T> parameter(Class<V> paramType, String paramName, String paramDescription, V defaultValue) {
- return parameter(new BasicParameterType<V>(paramName, paramType, paramDescription, defaultValue));
- }
- public <V> EffectorBuilder<T> parameter(ConfigKey<V> key) {
- return parameter(asParameterType(key));
- }
- public EffectorBuilder<T> parameter(ParameterType<?> p) {
- // allow redeclaring, e.g. for the case where we are overriding an existing effector
- parameters.put(p.getName(), p);
- return this;
- }
- public EffectorBuilder<T> impl(EffectorTaskFactory<T> taskFactory) {
- this.impl = new EffectorMarkingTaskFactory<T>(taskFactory);
- return this;
- }
- public EffectorBuilder<T> impl(EffectorBody<T> effectorBody) {
- this.impl = new EffectorBodyTaskFactory<T>(effectorBody);
- return this;
- }
- /** returns the effector, with an implementation (required); @see {@link #buildAbstract()} */
- public Effector<T> build() {
- Preconditions.checkNotNull(impl, "Cannot create effector %s with no impl (did you forget impl? or did you mean to buildAbstract?)", effectorName);
- return new EffectorAndBody<T>(effectorName, returnType, ImmutableList.copyOf(parameters.values()), description, impl);
- }
-
- /** returns an abstract effector, where the body will be defined later/elsewhere
- * (impl must not be set) */
- public Effector<T> buildAbstract() {
- Preconditions.checkArgument(impl==null, "Cannot create abstract effector {} as an impl is defined", effectorName);
- return new EffectorBase<T>(effectorName, returnType, ImmutableList.copyOf(parameters.values()), description);
- }
- }
-
- /** creates a new effector builder with the given name and return type */
- public static <T> EffectorBuilder<T> effector(Class<T> returnType, String effectorName) {
- return new EffectorBuilder<T>(returnType, effectorName);
- }
-
- /** creates a new effector builder to _override_ the given effector */
- public static <T> EffectorBuilder<T> effector(Effector<T> base) {
- EffectorBuilder<T> builder = new EffectorBuilder<T>(base.getReturnType(), base.getName());
- for (ParameterType<?> p: base.getParameters())
- builder.parameter(p);
- builder.description(base.getDescription());
- if (base instanceof EffectorWithBody)
- builder.impl(((EffectorWithBody<T>) base).getBody());
- return builder;
- }
-
- /** as {@link #invocation(Entity, Effector, Map)} but convenience for passing a {@link ConfigBag} */
- public static <T> TaskAdaptable<T> invocation(Entity entity, Effector<T> eff, ConfigBag parameters) {
- return invocation(entity, eff, parameters==null ? ImmutableMap.of() : parameters.getAllConfig());
- }
-
- /** returns an unsubmitted task which invokes the given effector; use {@link Entities#invokeEffector(EntityLocal, Entity, Effector, Map)} for a submitted variant */
- public static <T> TaskAdaptable<T> invocation(Entity entity, Effector<T> eff, @Nullable Map<?,?> parameters) {
- @SuppressWarnings("unchecked")
- Effector<T> eff2 = (Effector<T>) ((EntityInternal)entity).getEffector(eff.getName());
- if (log.isTraceEnabled()) {
- Object eff1Body = (eff instanceof EffectorWithBody<?> ? ((EffectorWithBody<?>) eff).getBody() : "bodyless");
- String message = String.format("Invoking %s/%s on entity %s", eff, eff1Body, entity);
- if (eff != eff2) {
- Object eff2Body = (eff2 instanceof EffectorWithBody<?> ? ((EffectorWithBody<?>) eff2).getBody() : "bodyless");
- message += String.format(" (actually %s/%s)", eff2, eff2Body);
- }
- log.trace(message);
- }
- if (eff2 != null) {
- if (eff2 != eff) {
- if (eff2 instanceof EffectorWithBody) {
- log.debug("Replacing invocation of {} on {} with {} which is the impl defined at that entity", new Object[] { eff, entity, eff2 });
- return ((EffectorWithBody<T>)eff2).getBody().newTask(entity, eff2, ConfigBag.newInstance().putAll(parameters));
- } else {
- log.warn("Effector {} defined on {} has no body; invoking caller-supplied {} instead", new Object[] { eff2, entity, eff });
- }
- }
- } else {
- log.debug("Effector {} does not exist on {}; attempting to invoke anyway", new Object[] { eff, entity });
- }
-
- if (eff instanceof EffectorWithBody) {
- return ((EffectorWithBody<T>)eff).getBody().newTask(entity, eff, ConfigBag.newInstance().putAll(parameters));
- }
-
- throw new UnsupportedOperationException("No implementation registered for effector "+eff+" on "+entity);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <V> ParameterType<V> asParameterType(ConfigKey<V> key) {
- return key.hasDefaultValue()
- ? new BasicParameterType<V>(key.getName(), (Class)key.getType(), key.getDescription(), key.getDefaultValue())
- : new BasicParameterType<V>(key.getName(), (Class)key.getType(), key.getDescription());
- }
-
- public static <V> ConfigKey<V> asConfigKey(ParameterType<V> paramType) {
- return ConfigKeys.newConfigKey(paramType.getParameterClass(), paramType.getName(), paramType.getDescription(), paramType.getDefaultValue());
- }
-
- /** returns an unsubmitted task which will invoke the given effector on the given entities;
- * return type is Task<List<T>> (but haven't put in the blood sweat toil and tears to make the generics work) */
- public static TaskAdaptable<List<?>> invocation(Effector<?> eff, Map<?,?> params, Iterable<? extends Entity> entities) {
- List<TaskAdaptable<?>> tasks = new ArrayList<TaskAdaptable<?>>();
- for (Entity e: entities) tasks.add(invocation(e, eff, params));
- return Tasks.parallel("invoking "+eff+" on "+tasks.size()+" node"+(Strings.s(tasks.size())), tasks.toArray(new TaskAdaptable[tasks.size()]));
- }
-
- /** returns an unsubmitted task which will invoke the given effector on the given entities
- * (this form of method is a convenience for {@link #invocation(Effector, Map, Iterable)}) */
- public static TaskAdaptable<List<?>> invocation(Effector<?> eff, MutableMap<?, ?> params, Entity ...entities) {
- return invocation(eff, params, Arrays.asList(entities));
- }
-
- public static boolean sameSignature(Effector<?> e1, Effector<?> e2) {
- return Objects.equal(e1.getName(), e2.getName()) &&
- Objects.equal(e1.getParameters(), e2.getParameters()) &&
- Objects.equal(e1.getReturnType(), e2.getReturnType());
- }
-
- // TODO sameSignatureAndBody
-
- public static boolean sameInstance(Effector<?> e1, Effector<?> e2) {
- return e1 == e2;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/ExplicitEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/ExplicitEffector.java b/core/src/main/java/org/apache/brooklyn/effector/core/ExplicitEffector.java
deleted file mode 100644
index 46b19ea..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/ExplicitEffector.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import groovy.lang.Closure;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-
-public abstract class ExplicitEffector<I,T> extends AbstractEffector<T> {
- public ExplicitEffector(String name, Class<T> type, String description) {
- this(name, type, ImmutableList.<ParameterType<?>>of(), description);
- }
- public ExplicitEffector(String name, Class<T> type, List<ParameterType<?>> parameters, String description) {
- super(name, type, parameters, description);
- }
-
- public T call(Entity entity, Map parameters) {
- return invokeEffector((I) entity, (Map<String,?>)parameters );
- }
-
- public abstract T invokeEffector(I trait, Map<String,?> parameters);
-
- /** convenience to create an effector supplying a closure; annotations are preferred,
- * and subclass here would be failback, but this is offered as
- * workaround for bug GROOVY-5122, as discussed in test class CanSayHi
- */
- public static <I,T> ExplicitEffector<I,T> create(String name, Class<T> type, List<ParameterType<?>> parameters, String description, Closure body) {
- return new ExplicitEffectorFromClosure<I,T>(name, type, parameters, description, body);
- }
-
- private static class ExplicitEffectorFromClosure<I,T> extends ExplicitEffector<I,T> {
- private static final long serialVersionUID = -5771188171702382236L;
- final Closure<T> body;
- public ExplicitEffectorFromClosure(String name, Class<T> type, List<ParameterType<?>> parameters, String description, Closure<T> body) {
- super(name, type, parameters, description);
- this.body = body;
- }
- public T invokeEffector(I trait, Map<String,?> parameters) { return body.call(trait, parameters); }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(super.hashCode(), body);
- }
-
- @Override
- public boolean equals(Object other) {
- return super.equals(other) && Objects.equal(body, ((ExplicitEffectorFromClosure<?,?>)other).body);
- }
-
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/MethodEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/MethodEffector.java b/core/src/main/java/org/apache/brooklyn/effector/core/MethodEffector.java
deleted file mode 100644
index 7dd0828..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/MethodEffector.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.codehaus.groovy.runtime.MethodClosure;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-
-/** concrete class for providing an Effector implementation that gets its information from annotations on a method;
- * see Effector*Test for usage example.
- * <p>
- * note that the method must be on an interface in order for it to be remoted, with the current implementation.
- * see comments in {@link #call(Entity, Map)} for more details.
- */
-public class MethodEffector<T> extends AbstractEffector<T> {
-
- private static final long serialVersionUID = 6989688364011965968L;
- private static final Logger log = LoggerFactory.getLogger(MethodEffector.class);
-
- @SuppressWarnings("rawtypes")
- public static Effector<?> create(Method m) {
- return new MethodEffector(m);
- }
-
- protected static class AnnotationsOnMethod {
- final Class<?> clazz;
- final String name;
- final String description;
- final Class<?> returnType;
- final List<ParameterType<?>> parameters;
-
- public AnnotationsOnMethod(Class<?> clazz, String methodName) {
- this(clazz, inferBestMethod(clazz, methodName));
- }
-
- public AnnotationsOnMethod(Class<?> clazz, Method method) {
- this.clazz = clazz;
- this.name = method.getName();
- this.returnType = method.getReturnType();
-
- // Get the description
- org.apache.brooklyn.core.annotation.Effector effectorAnnotation = method.getAnnotation(org.apache.brooklyn.core.annotation.Effector.class);
- description = (effectorAnnotation != null) ? effectorAnnotation.description() : null;
-
- // Get the parameters
- parameters = Lists.newArrayList();
- int numParameters = method.getParameterTypes().length;
- for (int i = 0; i < numParameters; i++) {
- parameters.add(toParameterType(method, i));
- }
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- protected static ParameterType<?> toParameterType(Method method, int paramIndex) {
- Annotation[] anns = method.getParameterAnnotations()[paramIndex];
- Class<?> type = method.getParameterTypes()[paramIndex];
- EffectorParam paramAnnotation = findAnnotation(anns, EffectorParam.class);
-
- // TODO if blank, could do "param"+(i+1); would that be better?
- // TODO this will now give "" if name is blank, rather than previously null. Is that ok?!
- String name = (paramAnnotation != null) ? paramAnnotation.name() : null;
-
- String paramDescription = (paramAnnotation == null || EffectorParam.MAGIC_STRING_MEANING_NULL.equals(paramAnnotation.description())) ? null : paramAnnotation.description();
- String description = (paramDescription != null) ? paramDescription : null;
-
- String paramDefaultValue = (paramAnnotation == null || EffectorParam.MAGIC_STRING_MEANING_NULL.equals(paramAnnotation.defaultValue())) ? null : paramAnnotation.defaultValue();
- Object defaultValue = (paramDefaultValue != null) ? TypeCoercions.coerce(paramDefaultValue, type) : null;
-
- return new BasicParameterType(name, type, description, defaultValue);
- }
-
- @SuppressWarnings("unchecked")
- protected static <T extends Annotation> T findAnnotation(Annotation[] anns, Class<T> type) {
- for (Annotation ann : anns) {
- if (type.isInstance(ann)) return (T) ann;
- }
- return null;
- }
-
- protected static Method inferBestMethod(Class<?> clazz, String methodName) {
- Method best = null;
- for (Method it : clazz.getMethods()) {
- if (it.getName().equals(methodName)) {
- if (best==null || best.getParameterTypes().length < it.getParameterTypes().length) best=it;
- }
- }
- if (best==null) {
- throw new IllegalStateException("Cannot find method "+methodName+" on "+clazz.getCanonicalName());
- }
- return best;
- }
- }
-
- /** Defines a new effector whose details are supplied as annotations on the given type and method name */
- public MethodEffector(Class<?> whereEffectorDefined, String methodName) {
- this(new AnnotationsOnMethod(whereEffectorDefined, methodName), null);
- }
-
- public MethodEffector(Method method) {
- this(new AnnotationsOnMethod(method.getDeclaringClass(), method), null);
- }
-
- public MethodEffector(MethodClosure mc) {
- this(new AnnotationsOnMethod((Class<?>)mc.getDelegate(), mc.getMethod()), null);
- }
-
- @SuppressWarnings("unchecked")
- protected MethodEffector(AnnotationsOnMethod anns, String description) {
- super(anns.name, (Class<T>)anns.returnType, anns.parameters, GroovyJavaMethods.<String>elvis(description, anns.description));
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public T call(Entity entity, Map parameters) {
- Object[] parametersArray = EffectorUtils.prepareArgsForEffector(this, parameters);
- if (entity instanceof AbstractEntity) {
- return EffectorUtils.invokeMethodEffector(entity, this, parametersArray);
- } else {
- // we are dealing with a proxy here
- // this implementation invokes the method on the proxy
- // (requiring it to be on the interface)
- // and letting the proxy deal with the remoting / runAtEntity;
- // alternatively we could create the task here and pass it to runAtEntity;
- // the latter may allow us to simplify/remove a lot of the stuff from
- // EffectorUtils and possibly Effectors and Entities
-
- // TODO Should really find method with right signature, rather than just the right args.
- // TODO prepareArgs can miss things out that have "default values"! Code below will probably fail if that happens.
- Method[] methods = entity.getClass().getMethods();
- for (Method method : methods) {
- if (method.getName().equals(getName())) {
- if (parametersArray.length == method.getParameterTypes().length) {
- try {
- return (T) method.invoke(entity, parametersArray);
- } catch (Exception e) {
- // exception handled by the proxy invocation (which leads to EffectorUtils.invokeEffectorMethod...)
- throw Exceptions.propagate(e);
- }
- }
- }
- }
- String msg = "Could not find method for effector "+getName()+" with "+parametersArray.length+" parameters on "+entity;
- log.warn(msg+" (throwing); available methods are: "+Arrays.toString(methods));
- throw new IllegalStateException(msg);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
deleted file mode 100644
index b904ba7..0000000
--- a/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core.ssh;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.config.ConfigUtils;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.location.internal.LocationInternal;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshTasks;
-import org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.ssh.BashCommands;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-
-/**
- * Conveniences for generating {@link Task} instances to perform SSH activities.
- * <p>
- * If the {@link SshMachineLocation machine} is not specified directly it
- * will be inferred from the {@link Entity} context of either the {@link Effector}
- * or the current {@link Task}.
- *
- * @see SshTasks
- * @since 0.6.0
- */
-@Beta
-public class SshEffectorTasks {
-
- private static final Logger log = LoggerFactory.getLogger(SshEffectorTasks.class);
-
- public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
- "Whether to ignore any ssh flags (behaviour constraints) set on the entity or location " +
- "where this is running, using only flags explicitly specified", false);
-
- /**
- * Like {@link EffectorBody} but providing conveniences when in an entity with a single machine location.
- */
- public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
-
- /** convenience for accessing the machine */
- public SshMachineLocation machine() {
- return EffectorTasks.getSshMachine(entity());
- }
-
- /** convenience for generating an {@link PlainSshExecTaskFactory} which can be further customised if desired, and then (it must be explicitly) queued */
- public ProcessTaskFactory<Integer> ssh(String ...commands) {
- return new SshEffectorTaskFactory<Integer>(commands).machine(machine());
- }
- }
-
- /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link EffectorTaskFactory} signature so can be used directly as an impl for an effector,
- * also injects the machine automatically; can also be used outwith effector contexts, and machine is still injected if it is
- * run from inside a task at an entity with a single SshMachineLocation */
- public static class SshEffectorTaskFactory<RET> extends AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements EffectorTaskFactory<RET> {
-
- public SshEffectorTaskFactory(String ...commands) {
- super(commands);
- }
- public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
- super(machine, commands);
- }
- @Override
- public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> effector, ConfigBag parameters) {
- markDirty();
- if (summary==null) summary(effector.getName()+" (ssh)");
- machine(EffectorTasks.getSshMachine(entity));
- return newTask();
- }
- @Override
- public synchronized ProcessTaskWrapper<RET> newTask() {
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- if (machine==null) {
- if (log.isDebugEnabled())
- log.debug("Using an ssh task not in an effector without any machine; will attempt to infer the machine: "+this);
- if (entity!=null)
- machine(EffectorTasks.getSshMachine(entity));
- }
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
-
- @Override
- public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType type) {
- return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
- }
-
- @Override
- public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
- return (SshEffectorTaskFactory<Boolean>) super.returningIsExitCodeZero();
- }
-
- public SshEffectorTaskFactory<String> requiringZeroAndReturningStdout() {
- return (SshEffectorTaskFactory<String>) super.requiringZeroAndReturningStdout();
- }
-
- public <RET2> SshEffectorTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
- return (SshEffectorTaskFactory<RET2>) super.returning(resultTransformation);
- }
- }
-
- public static class SshPutEffectorTaskFactory extends SshPutTaskFactory implements EffectorTaskFactory<Void> {
- public SshPutEffectorTaskFactory(String remoteFile) {
- super(remoteFile);
- }
- public SshPutEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
- super(machine, remoteFile);
- }
- @Override
- public SshPutTaskWrapper newTask(Entity entity, Effector<Void> effector, ConfigBag parameters) {
- machine(EffectorTasks.getSshMachine(entity));
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- @Override
- public SshPutTaskWrapper newTask() {
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- if (machine==null) {
- if (log.isDebugEnabled())
- log.debug("Using an ssh put task not in an effector without any machine; will attempt to infer the machine: "+this);
- if (entity!=null) {
- machine(EffectorTasks.getSshMachine(entity));
- }
-
- }
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- }
-
- public static class SshFetchEffectorTaskFactory extends SshFetchTaskFactory implements EffectorTaskFactory<String> {
- public SshFetchEffectorTaskFactory(String remoteFile) {
- super(remoteFile);
- }
- public SshFetchEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
- super(machine, remoteFile);
- }
- @Override
- public SshFetchTaskWrapper newTask(Entity entity, Effector<String> effector, ConfigBag parameters) {
- machine(EffectorTasks.getSshMachine(entity));
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- @Override
- public SshFetchTaskWrapper newTask() {
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- if (machine==null) {
- if (log.isDebugEnabled())
- log.debug("Using an ssh fetch task not in an effector without any machine; will attempt to infer the machine: "+this);
- if (entity!=null)
- machine(EffectorTasks.getSshMachine(entity));
- }
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- }
-
- public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
- return new SshEffectorTaskFactory<Integer>(commands);
- }
-
- public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
- return ssh(commands.toArray(new String[commands.size()]));
- }
-
- public static SshPutTaskFactory put(String remoteFile) {
- return new SshPutEffectorTaskFactory(remoteFile);
- }
-
- public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
- return new SshFetchEffectorTaskFactory(remoteFile);
- }
-
- /** task which returns 0 if pid is running */
- public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
- return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit code)").allowingNonZeroExitCode();
- }
-
- /** task which fails if the given PID is not running */
- public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
- return codePidRunning(pid).summary("PID "+pid+" is-running check (required)").requiringExitCodeZero("Process with PID "+pid+" is required to be running");
- }
-
- /** as {@link #codePidRunning(Integer)} but returning boolean */
- public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
- return codePidRunning(pid).summary("PID "+pid+" is-running check (boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
- public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return Integer.valueOf(0).equals(input.getExitCode()); }
- });
- }
-
-
- /** task which returns 0 if pid in the given file is running;
- * method accepts wildcards so long as they match a single file on the remote end
- * <p>
- * returns 1 if no matching file,
- * 1 if matching file but no matching process,
- * and 2 if 2+ matching files */
- public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final String pidFile) {
- return ssh(BashCommands.chain(
- // this fails, but isn't an error
- BashCommands.requireTest("-f "+pidFile, "The PID file "+pidFile+" does not exist."),
- // this fails and logs an error picked up later
- BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", "ERROR: there are multiple matching PID files"),
- // this fails and logs an error picked up later
- BashCommands.require("cat "+pidFile, "ERROR: the PID file "+pidFile+" cannot be read (permissions?)."),
- // finally check the process
- "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" is-running check (exit code)")
- .allowingNonZeroExitCode()
- .addCompletionListener(new Function<ProcessTaskWrapper<?>,Void>() {
- public Void apply(ProcessTaskWrapper<?> input) {
- if (input.getStderr().contains("ERROR:"))
- throw new IllegalStateException("Invalid or inaccessible PID filespec: "+pidFile);
- return null;
- }
- });
- }
-
- /** task which fails if the pid in the given file is not running (or if there is no such PID file);
- * method accepts wildcards so long as they match a single file on the remote end (fails if 0 or 2+ matching files) */
- public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String pidFile) {
- return codePidFromFileRunning(pidFile)
- .summary("PID file "+pidFile+" is-running check (required)")
- .requiringExitCodeZero("Process with PID from file "+pidFile+" is required to be running");
- }
-
- /** as {@link #codePidFromFileRunning(String)} but returning boolean */
- public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String pidFile) {
- return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" is-running check (boolean)").
- returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
- public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return ((Integer)0).equals(input.getExitCode()); }
- });
- }
-
- /** extracts the values for the main brooklyn.ssh.config.* config keys (i.e. those declared in ConfigKeys)
- * as declared on the entity, and inserts them in a map using the unprefixed state, for ssh.
- * <p>
- * currently this is computed for each call, which may be wasteful, but it is reliable in the face of config changes.
- * we could cache the Map. note that we do _not_ cache (or even own) the SshTool;
- * the SshTool is created or re-used by the SshMachineLocation making use of these properties */
- @Beta
- public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
- ConfigBag allConfig = ConfigBag.newInstance();
-
- StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
- allConfig.putAll(globalConfig.getAllConfig());
-
- if (optionalLocation!=null)
- allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
-
- allConfig.putAll(((EntityInternal)entity).getAllConfig());
-
- Map<String, Object> result = Maps.newLinkedHashMap();
- for (String keyS : allConfig.getAllConfig().keySet()) {
- if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
- ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
-
- Object val = allConfig.getStringKey(keyS);
-
- /*
- * NOV 2013 changing this to rely on config above being inserted in the right order,
- * so entity config will be preferred over location, and location over global.
- * If that is consistent then remove the lines below.
- * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
- */
-
-// // have to use raw config to test whether the config is set
-// Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
-// if (val!=null) {
-// val = entity.getConfig(key);
-// } else {
-// val = globalConfig.getRawConfig(key);
-// if (val!=null) val = globalConfig.getConfig(key);
-// }
-// if (val!=null) {
- result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
-// }
- }
- }
- return result;
- }
-
- private static void applySshFlags(ConfigBag config, Entity entity, Location machine) {
- if (entity!=null) {
- if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
- config.putIfAbsent(getSshFlags(entity, machine));
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
index 1b16369..bf39663 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicCluster.java
@@ -33,11 +33,11 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.factory.EntityFactory;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.MemberReplaceable;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.group.zoneaware.BalancingNodePlacementStrategy;
import org.apache.brooklyn.entity.group.zoneaware.ProportionalZoneFailureDetector;
import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
index 7a0c31b..a8c63ef 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicClusterImpl.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.api.location.MachineProvisioningLocation;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.EntityFactory;
import org.apache.brooklyn.core.entity.factory.EntityFactoryForLocation;
@@ -50,7 +51,6 @@ import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.entity.trait.StartableMethods;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.cloud.AvailabilityZoneExtension;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.stock.DelegateEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
index 7611ba8..daedc39 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicFabricImpl.java
@@ -32,6 +32,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.factory.EntityFactory;
@@ -40,7 +41,6 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Changeable;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
index 36ac0f9..bb43d3b 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicGroup.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabric.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabric.java b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabric.java
index fc11e9b..7c46d14 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabric.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/DynamicRegionsFabric.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.group;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
@ImplementedBy(DynamicRegionsFabricImpl.class)
public interface DynamicRegionsFabric extends DynamicFabric {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/entity/group/QuarantineGroupImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/entity/group/QuarantineGroupImpl.java b/core/src/main/java/org/apache/brooklyn/entity/group/QuarantineGroupImpl.java
index dfddf5f..886862a 100644
--- a/core/src/main/java/org/apache/brooklyn/entity/group/QuarantineGroupImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/entity/group/QuarantineGroupImpl.java
@@ -23,10 +23,10 @@ import java.util.Set;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
index 7a5fecf..6b9c780 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/core/HttpRequestSensor.java
@@ -25,7 +25,7 @@ import net.minidev.json.JSONObject;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.AddSensor;
+import org.apache.brooklyn.core.effector.AddSensor;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
index 7bc10bf..0c3a00f 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.AddSensor;
+import org.apache.brooklyn.core.effector.AddSensor;
import org.apache.brooklyn.sensor.enricher.Propagator;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.Tasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
index 33b284c..95aba9f 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
@@ -40,8 +40,8 @@ import org.apache.brooklyn.api.mgmt.ExecutionContext;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.EffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
index 10eea13..448cd61 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
@@ -32,10 +32,10 @@ import org.apache.brooklyn.api.mgmt.TaskQueueingContext;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.ConfigUtils;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorBasicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorBasicTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorBasicTest.java
new file mode 100644
index 0000000..b05a397
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorBasicTest.java
@@ -0,0 +1,183 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.HasTaskChildren;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.trait.FailingEntity;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.test.TestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class EffectorBasicTest extends BrooklynAppUnitTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(EffectorBasicTest.class);
+
+ // NB: more tests of effectors in EffectorSayHiTest and EffectorConcatenateTest
+ // as well as EntityConfigMapUsageTest and others
+
+ private List<SimulatedLocation> locs;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ locs = ImmutableList.of(new SimulatedLocation());
+ }
+
+ @Test
+ public void testInvokeEffectorStart() {
+ app.start(locs);
+ TestUtils.assertSetsEqual(locs, app.getLocations());
+ // TODO above does not get registered as a task
+ }
+
+ @Test
+ public void testInvokeEffectorStartWithMap() {
+ app.invoke(Startable.START, MutableMap.of("locations", locs)).getUnchecked();
+ TestUtils.assertSetsEqual(locs, app.getLocations());
+ }
+
+ @Test
+ public void testInvokeEffectorStartWithArgs() {
+ Entities.invokeEffectorWithArgs((EntityLocal)app, app, Startable.START, locs).getUnchecked();
+ TestUtils.assertSetsEqual(locs, app.getLocations());
+ }
+
+ @Test
+ public void testInvokeEffectorStartWithTwoEntities() {
+ TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(locs);
+ TestUtils.assertSetsEqual(locs, app.getLocations());
+ TestUtils.assertSetsEqual(locs, entity.getLocations());
+ TestUtils.assertSetsEqual(locs, entity2.getLocations());
+ }
+
+ @Test
+ public void testInvokeEffectorTaskHasTag() {
+ Task<Void> starting = app.invoke(Startable.START, MutableMap.of("locations", locs));
+// log.info("TAGS: "+starting.getTags());
+ Assert.assertTrue(starting.getTags().contains(ManagementContextInternal.EFFECTOR_TAG));
+ }
+
+ // check various failure situations
+
+ private FailingEntity createFailingEntity() {
+ FailingEntity entity = app.createAndManageChild(EntitySpec.create(FailingEntity.class)
+ .configure(FailingEntity.FAIL_ON_START, true));
+ return entity;
+ }
+
+ // uncaught failures are propagates
+
+ @Test
+ public void testInvokeEffectorStartFailing_Method() {
+ FailingEntity entity = createFailingEntity();
+ assertStartMethodFails(entity);
+ }
+
+ @Test
+ public void testInvokeEffectorStartFailing_EntityInvoke() {
+ FailingEntity entity = createFailingEntity();
+ assertTaskFails( entity.invoke(Startable.START, MutableMap.of("locations", locs)) );
+ }
+
+ @Test
+ public void testInvokeEffectorStartFailing_EntitiesInvoke() {
+ FailingEntity entity = createFailingEntity();
+
+ assertTaskFails( Entities.invokeEffectorWithArgs(entity, entity, Startable.START, locs) );
+ }
+
+ // caught failures are NOT propagated!
+
+ @Test
+ public void testInvokeEffectorStartFailing_MethodInDynamicTask() {
+ Task<Void> task = app.getExecutionContext().submit(Tasks.<Void>builder().dynamic(true).body(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ testInvokeEffectorStartFailing_Method();
+ return null;
+ }
+ }).build());
+
+ assertTaskSucceeds(task);
+ assertTaskHasFailedChild(task);
+ }
+
+ @Test
+ public void testInvokeEffectorStartFailing_MethodInTask() {
+ Task<Void> task = app.getExecutionContext().submit(Tasks.<Void>builder().dynamic(false).body(new Callable<Void>() {
+ @Override public Void call() throws Exception {
+ testInvokeEffectorStartFailing_Method();
+ return null;
+ }
+ }).build());
+
+ assertTaskSucceeds(task);
+ }
+
+ private void assertTaskSucceeds(Task<Void> task) {
+ task.getUnchecked();
+ Assert.assertFalse(task.isError());
+ }
+
+ private void assertTaskHasFailedChild(Task<Void> task) {
+ Assert.assertTrue(Tasks.failed( ((HasTaskChildren)task).getChildren() ).iterator().hasNext());
+ }
+
+ private void assertStartMethodFails(FailingEntity entity) {
+ try {
+ entity.start(locs);
+ Assert.fail("Should have failed");
+ } catch (Exception e) {
+ // expected
+ }
+ }
+
+ protected void assertTaskFails(Task<?> t) {
+ try {
+ t.get();
+ Assert.fail("Should have failed");
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ // expected
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorConcatenateTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorConcatenateTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorConcatenateTest.java
new file mode 100644
index 0000000..c909a9d
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorConcatenateTest.java
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ExecutionManager;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.annotation.Effector;
+import org.apache.brooklyn.core.annotation.EffectorParam;
+import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.BasicExecutionContext;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class EffectorConcatenateTest {
+
+
+ private static final Logger log = LoggerFactory.getLogger(EffectorConcatenateTest.class);
+ private static final long TIMEOUT = 10*1000;
+
+ public static class MyEntityImpl extends AbstractEntity {
+
+ public static MethodEffector<String> CONCATENATE = new MethodEffector<String>(MyEntityImpl.class, "concatenate");
+ public static MethodEffector<Void> WAIT_A_BIT = new MethodEffector<Void>(MyEntityImpl.class, "waitabit");
+ public static MethodEffector<Void> SPAWN_CHILD = new MethodEffector<Void>(MyEntityImpl.class, "spawnchild");
+
+ public MyEntityImpl() {
+ super();
+ }
+ public MyEntityImpl(Entity parent) {
+ super(parent);
+ }
+
+ /** The "current task" representing the effector currently executing */
+ AtomicReference<Task<?>> waitingTask = new AtomicReference<Task<?>>();
+
+ /** latch is .countDown'ed by the effector at the beginning of the "waiting" point */
+ CountDownLatch nowWaitingLatch = new CountDownLatch(1);
+
+ /** latch is await'ed on by the effector when it is in the "waiting" point */
+ CountDownLatch continueFromWaitingLatch = new CountDownLatch(1);
+
+ @Effector(description="sample effector concatenating strings")
+ public String concatenate(@EffectorParam(name="first", description="first argument") String first,
+ @EffectorParam(name="second", description="2nd arg") String second) throws Exception {
+ return first+second;
+ }
+
+ @Effector(description="sample effector doing some waiting")
+ public void waitabit() throws Exception {
+ waitingTask.set(Tasks.current());
+
+ Tasks.setExtraStatusDetails("waitabit extra status details");
+
+ Tasks.withBlockingDetails("waitabit.blocking", new Callable<Void>() {
+ public Void call() throws Exception {
+ nowWaitingLatch.countDown();
+ if (!continueFromWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("took too long to be told to continue");
+ }
+ return null;
+ }});
+ }
+
+ @Effector(description="sample effector that spawns a child task that waits a bit")
+ public void spawnchild() throws Exception {
+ // spawn a child, then wait
+ BasicExecutionContext.getCurrentExecutionContext().submit(
+ MutableMap.of("displayName", "SpawnedChildName"),
+ new Callable<Void>() {
+ public Void call() throws Exception {
+ log.info("beginning spawned child response "+Tasks.current()+", with tags "+Tasks.current().getTags());
+ Tasks.setBlockingDetails("spawned child blocking details");
+ nowWaitingLatch.countDown();
+ if (!continueFromWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ fail("took too long to be told to continue");
+ }
+ return null;
+ }});
+ }
+ }
+
+ private TestApplication app;
+ private MyEntityImpl e;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() {
+ app = new TestApplicationImpl();
+ e = new MyEntityImpl(app);
+ Entities.startManagement(app);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() {
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test
+ public void testCanInvokeEffector() throws Exception {
+ // invocation map syntax
+ Task<String> task = e.invoke(MyEntityImpl.CONCATENATE, ImmutableMap.of("first", "a", "second", "b"));
+ assertEquals(task.get(TIMEOUT, TimeUnit.MILLISECONDS), "ab");
+
+ // method syntax
+ assertEquals("xy", e.concatenate("x", "y"));
+ }
+
+ @Test
+ public void testReportsTaskDetails() throws Exception {
+ final AtomicReference<String> result = new AtomicReference<String>();
+
+ Thread bg = new Thread(new Runnable() {
+ public void run() {
+ try {
+ // Expect "wait a bit" to tell us it's blocking
+ if (!e.nowWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ result.set("took too long for waitabit to be waiting");
+ return;
+ }
+
+ // Expect "wait a bit" to have retrieved and set its task
+ try {
+ Task<?> t = e.waitingTask.get();
+ String status = t.getStatusDetail(true);
+ log.info("waitabit task says:\n"+status);
+ if (!status.contains("waitabit extra status details")) {
+ result.set("Status not in expected format: doesn't contain extra status details phrase 'My extra status details'\n"+status);
+ return;
+ }
+ if (!status.startsWith("waitabit.blocking")) {
+ result.set("Status not in expected format: doesn't start with blocking details 'waitabit.blocking'\n"+status);
+ return;
+ }
+ } finally {
+ e.continueFromWaitingLatch.countDown();
+ }
+ } catch (Throwable t) {
+ log.warn("Failure: "+t, t);
+ result.set("Failure: "+t);
+ }
+ }});
+ bg.start();
+
+ e.invoke(MyEntityImpl.WAIT_A_BIT, ImmutableMap.<String,Object>of())
+ .get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+ bg.join(TIMEOUT*2);
+ assertFalse(bg.isAlive());
+
+ String problem = result.get();
+ if (problem!=null) fail(problem);
+ }
+
+ @Test
+ public void testReportsSpawnedTaskDetails() throws Exception {
+ final AtomicReference<String> result = new AtomicReference<String>();
+
+ Thread bg = new Thread(new Runnable() {
+ public void run() {
+ try {
+ // Expect "spawned child" to tell us it's blocking
+ if (!e.nowWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
+ result.set("took too long for spawnchild's sub-task to be waiting");
+ return;
+ }
+
+ // Expect spawned task to be have been tagged with entity
+ ExecutionManager em = e.getManagementContext().getExecutionManager();
+ Task<?> subtask = Iterables.find(BrooklynTaskTags.getTasksInEntityContext(em, e), new Predicate<Task<?>>() {
+ public boolean apply(Task<?> input) {
+ return "SpawnedChildName".equals(input.getDisplayName());
+ }
+ });
+
+ // Expect spawned task to haev correct "blocking details"
+ try {
+ String status = subtask.getStatusDetail(true);
+ log.info("subtask task says:\n"+status);
+ if (!status.contains("spawned child blocking details")) {
+ result.set("Status not in expected format: doesn't contain blocking details phrase 'spawned child blocking details'\n"+status);
+ return;
+ }
+ } finally {
+ e.continueFromWaitingLatch.countDown();
+ }
+ } catch (Throwable t) {
+ log.warn("Failure: "+t, t);
+ result.set("Failure: "+t);
+ }
+ }});
+ bg.start();
+
+ e.invoke(MyEntityImpl.SPAWN_CHILD, ImmutableMap.<String,Object>of())
+ .get(TIMEOUT, TimeUnit.MILLISECONDS);
+
+ bg.join(TIMEOUT*2);
+ assertFalse(bg.isAlive());
+
+ String problem = result.get();
+ if (problem!=null) fail(problem);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorMetadataTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorMetadataTest.java
new file mode 100644
index 0000000..1f1be85
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorMetadataTest.java
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.annotation.EffectorParam;
+import org.apache.brooklyn.core.effector.BasicParameterType;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Test the operation of the {@link Effector} implementations.
+ *
+ * TODO clarify test purpose
+ */
+public class EffectorMetadataTest extends BrooklynAppUnitTestSupport {
+
+ private MyAnnotatedEntity e1;
+ private MyOverridingEntity e2;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ e1 = app.createAndManageChild(EntitySpec.create(MyAnnotatedEntity.class));
+ e2 = app.createAndManageChild(EntitySpec.create(MyOverridingEntity.class));
+ }
+
+ @Test
+ public void testEffectorMetaDataFromAnnotationsWithConstant() {
+ Effector<?> effector = EffectorUtils.findEffectorDeclared(e1, "effWithNewAnnotation").get();
+ Assert.assertTrue(Effectors.sameSignature(effector, MyAnnotatedEntity.EFF_WITH_NEW_ANNOTATION));
+ assertEquals(effector.getName(), "effWithNewAnnotation");
+ assertEquals(effector.getDescription(), "my effector description");
+ assertEquals(effector.getReturnType(), String.class);
+ assertParametersEqual(
+ effector.getParameters(),
+ ImmutableList.<ParameterType<?>>of(
+ new BasicParameterType<String>("param1", String.class, "my param description", "my default val")));
+ }
+
+ @Test
+ public void testEffectorMetaDataFromAnnotationsWithoutConstant() {
+ Effector<?> effector = EffectorUtils.findEffectorDeclared(e1, "effWithAnnotationButNoConstant").get();
+ assertEquals(effector.getName(), "effWithAnnotationButNoConstant");
+ assertEquals(effector.getDescription(), "my effector description");
+ assertEquals(effector.getReturnType(), String.class);
+ assertParametersEqual(
+ effector.getParameters(),
+ ImmutableList.<ParameterType<?>>of(
+ new BasicParameterType<String>("param1", String.class, "my param description", "my default val")));
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Test
+ public void testEffectorMetaDataFromOverriddenMethod() {
+ // Overridden with new annotations
+ Effector<?> startEffector = EffectorUtils.findEffectorDeclared(e2, "start").get();
+ assertEquals(startEffector.getName(), "start");
+ assertEquals(startEffector.getDescription(), "My overridden start description");
+ assertEquals(startEffector.getReturnType(), void.class);
+ assertParametersEqual(
+ startEffector.getParameters(),
+ ImmutableList.<ParameterType<?>>of(
+ new BasicParameterType<Collection>("locations", Collection.class, "my overridden param description", null)));
+ }
+
+ private void assertParametersEqual(List<ParameterType<?>> actuals, List<ParameterType<?>> expecteds) {
+ assertEquals(actuals.size(), expecteds.size(), "actual="+actuals);
+ for (int i = 0; i < actuals.size(); i++) {
+ ParameterType<?> actual = actuals.get(i);
+ ParameterType<?> expected = expecteds.get(i);
+ assertParameterEqual(actual, expected);
+ }
+ }
+
+ private void assertParameterEqual(ParameterType<?> actual, ParameterType<?> expected) {
+ assertEquals(actual.getName(), expected.getName(), "actual="+actual);
+ assertEquals(actual.getDescription(), expected.getDescription(), "actual="+actual);
+ assertEquals(actual.getParameterClass(), expected.getParameterClass(), "actual="+actual);
+ assertEquals(actual.getParameterClassName(), expected.getParameterClassName(), "actual="+actual);
+ }
+
+ @ImplementedBy(MyAnnotatedEntityImpl.class)
+ public interface MyAnnotatedEntity extends Entity {
+ static MethodEffector<String> EFF_WITH_NEW_ANNOTATION = new MethodEffector<String>(MyAnnotatedEntity.class, "effWithNewAnnotation");
+
+ @org.apache.brooklyn.core.annotation.Effector(description="my effector description")
+ public String effWithNewAnnotation(
+ @EffectorParam(name="param1", defaultValue="my default val", description="my param description") String param1);
+
+ @org.apache.brooklyn.core.annotation.Effector(description="my effector description")
+ public String effWithAnnotationButNoConstant(
+ @EffectorParam(name="param1", defaultValue="my default val", description="my param description") String param1);
+ }
+
+ public static class MyAnnotatedEntityImpl extends AbstractEntity implements MyAnnotatedEntity {
+ @Override
+ public String effWithNewAnnotation(String param1) {
+ return param1;
+ }
+
+ @Override
+ public String effWithAnnotationButNoConstant(String param1) {
+ return param1;
+ }
+ }
+
+ @ImplementedBy(MyOverridingEntityImpl.class)
+ public interface MyOverridingEntity extends Entity, Startable {
+ org.apache.brooklyn.api.effector.Effector<Void> START = Effectors.effector(Startable.START)
+ .description("My overridden start description")
+ .parameter(Collection.class, "locations", "my overridden param description")
+ .build();
+ }
+
+ public static class MyOverridingEntityImpl extends AbstractEntity implements MyOverridingEntity {
+
+ @Override
+ public void restart() {
+ }
+
+ @Override
+ public void start(Collection<? extends Location> locations2) {
+ }
+
+ @Override
+ public void stop() {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiGroovyTest.groovy b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiGroovyTest.groovy
new file mode 100644
index 0000000..5dd776e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiGroovyTest.groovy
@@ -0,0 +1,182 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector
+
+import static org.testng.Assert.*
+
+import org.apache.brooklyn.api.effector.Effector
+import org.apache.brooklyn.api.entity.Entity
+import org.apache.brooklyn.api.entity.EntitySpec
+import org.apache.brooklyn.api.entity.ImplementedBy
+import org.apache.brooklyn.api.mgmt.ManagementContext
+import org.apache.brooklyn.api.mgmt.Task
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.mgmt.internal.EffectorUtils
+import org.apache.brooklyn.core.test.entity.TestApplication
+import org.apache.brooklyn.core.annotation.EffectorParam
+import org.apache.brooklyn.core.effector.BasicParameterType;
+import org.apache.brooklyn.core.effector.ExplicitEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.entity.AbstractEntity
+import org.apache.brooklyn.core.entity.Entities
+import org.apache.brooklyn.core.entity.trait.Startable
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.annotations.AfterMethod
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+/**
+ * Test the operation of the {@link Effector} implementations.
+ *
+ * TODO clarify test purpose
+ */
+public class EffectorSayHiGroovyTest {
+ private static final Logger log = LoggerFactory.getLogger(EffectorSayHiTest.class);
+
+ private TestApplication app;
+ private MyEntity e;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() {
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test
+ public void testFindEffectors() {
+ assertEquals("sayHi1", e.SAY_HI_1.getName());
+ assertEquals(["name", "greeting"], e.SAY_HI_1.getParameters()[0..1]*.getName());
+ assertEquals("says hello", e.SAY_HI_1.getDescription());
+
+ assertEquals("sayHi1", e.SAY_HI_1_ALT.getName());
+ assertEquals(["name", "greeting"], e.SAY_HI_1_ALT.getParameters()[0..1]*.getName());
+ assertEquals("says hello", e.SAY_HI_1_ALT.getDescription());
+
+ assertEquals("sayHi2", e.SAY_HI_2.getName());
+ assertEquals(["name", "greeting"], e.SAY_HI_2.getParameters()[0..1]*.getName());
+ assertEquals("says hello", e.SAY_HI_2.getDescription());
+ }
+
+ @Test
+ public void testFindTraitEffectors() {
+ assertEquals("locations", Startable.START.getParameters()[0].getName());
+ }
+
+ @Test
+ public void testInvokeEffectorMethod1BypassInterception() {
+ String name = "sayHi1"
+ def args = ["Bob", "hello"] as Object[]
+
+ //try the alt syntax recommended from web
+ def metaMethod = e.metaClass.getMetaMethod(name, args)
+ if (metaMethod==null)
+ throw new IllegalArgumentException("Invalid arguments (no method found) for method $name: "+args);
+ assertEquals("hello Bob", metaMethod.invoke(e, args))
+ }
+
+ @Test
+ public void testInvokeEffectorMethod2BypassInterception() {
+ String name = "sayHi2"
+ def args = ["Bob", "hello"] as Object[]
+ assertEquals("hello Bob", e.metaClass.invokeMethod(e, name, args))
+ }
+
+ @Test
+ public void testInvokeEffectors1() {
+ assertEquals("hi Bob", e.sayHi1("Bob", "hi"))
+
+ assertEquals("hello Bob", e.SAY_HI_1.call(e, [name:"Bob"]) )
+ assertEquals("hello Bob", e.invoke(e.SAY_HI_1, [name:"Bob"]).get() );
+
+ assertEquals("hello Bob", e.SAY_HI_1_ALT.call(e, [name:"Bob"]) )
+ }
+
+ @Test
+ public void testInvokeEffectors2() {
+ assertEquals("hi Bob", e.sayHi2("Bob", "hi"))
+
+ assertEquals("hello Bob", e.SAY_HI_2.call(e, [name:"Bob"]) )
+ assertEquals("hello Bob", e.invoke(e.SAY_HI_2, [name:"Bob"]).get() );
+
+ }
+
+ @Test
+ public void testCanRetrieveTaskForEffector() {
+ e.sayHi2("Bob", "hi")
+
+ ManagementContext managementContext = e.getManagementContext()
+
+ Set<Task> tasks = managementContext.getExecutionManager().getTasksWithAllTags([
+ BrooklynTaskTags.tagForContextEntity(e),"EFFECTOR"])
+ assertEquals(tasks.size(), 1)
+ assertTrue(tasks.iterator().next().getDescription().contains("sayHi2"))
+ }
+}
+public interface CanSayHi {
+ //prefer following simple groovy syntax
+ static Effector<String> SAY_HI_1 = new MethodEffector<String>(CanSayHi.&sayHi1);
+ //slightly longer-winded pojo also supported
+ static Effector<String> SAY_HI_1_ALT = new MethodEffector<String>(CanSayHi.class, "sayHi1");
+
+ @org.apache.brooklyn.core.annotation.Effector(description="says hello")
+ public String sayHi1(
+ @EffectorParam(name="name") String name,
+ @EffectorParam(name="greeting", defaultValue="hello", description="what to say") String greeting);
+
+ //finally there is a way to provide a class/closure if needed or preferred for some odd reason
+ static Effector<String> SAY_HI_2 =
+
+ //groovy 1.8.2 balks at runtime during getCallSiteArray (bug 5122) if we use anonymous inner class
+// new ExplicitEffector<CanSayHi,String>(
+// "sayHi2", String.class, [
+// [ "name", String.class, "person to say hi to" ] as BasicParameterType<String>,
+// [ "greeting", String.class, "what to say as greeting", "hello" ] as BasicParameterType<String>
+// ],
+// "says hello to a person") {
+// public String invokeEffector(CanSayHi e, Map m) {
+// e.sayHi2(m)
+// }
+// };
+ //following is a workaround, not greatly enamoured of it... but MethodEffector is generally preferred anyway
+ ExplicitEffector.create("sayHi2", String.class, [
+ new BasicParameterType<String>("name", String.class, "person to say hi to"),
+ new BasicParameterType<String>("greeting", String.class, "what to say as greeting", "hello")
+ ],
+ "says hello", { e, m ->
+ def args = EffectorUtils.prepareArgsForEffector(SAY_HI_2, m);
+ e.sayHi2(args[0], args[1]) })
+
+ public String sayHi2(String name, String greeting);
+
+}
+
+@ImplementedBy(MyEntityImpl.class)
+public interface MyEntity extends Entity, CanSayHi {
+}
+
+public class MyEntityImpl extends AbstractEntity implements MyEntity {
+ public String sayHi1(String name, String greeting) { "$greeting $name" }
+ public String sayHi2(String name, String greeting) { "$greeting $name" }
+}
[36/36] incubator-brooklyn git commit: This closes #854
Posted by he...@apache.org.
This closes #854
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/147f9ec4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/147f9ec4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/147f9ec4
Branch: refs/heads/master
Commit: 147f9ec446a6bb59c8550e62eacc5c0970b73227
Parents: 9e80f33 6f15e8a
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Wed Aug 19 23:52:04 2015 +0100
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Wed Aug 19 23:52:04 2015 +0100
----------------------------------------------------------------------
.../apache/brooklyn/api/entity/Application.java | 2 +-
.../org/apache/brooklyn/api/entity/Entity.java | 8 +-
.../brooklyn/api/entity/EntityInitializer.java | 2 -
.../apache/brooklyn/api/entity/EntityLocal.java | 176 ++
.../api/entity/drivers/EntityDriver.java | 2 +-
.../brooklyn/api/internal/EntityLocal.java | 178 --
.../BrooklynClassLoadingContext.java | 50 -
.../api/mgmt/rebind/RebindExceptionHandler.java | 2 +-
.../core/BrooklynFeatureEnablement.java | 209 +++
.../apache/brooklyn/core/BrooklynLogging.java | 2 +-
.../brooklyn/core/annotation/Effector.java | 33 +
.../brooklyn/core/annotation/EffectorParam.java | 42 +
.../catalog/internal/BasicBrooklynCatalog.java | 10 +-
.../catalog/internal/CatalogClasspathDo.java | 2 +-
.../core/catalog/internal/CatalogUtils.java | 4 +-
.../brooklyn/core/config/BasicConfigKey.java | 2 +-
.../apache/brooklyn/core/config/ConfigKeys.java | 8 +-
.../config/internal/AbstractConfigMapImpl.java | 2 +-
.../core/config/render/RendererHints.java | 2 +-
.../core/effector/AbstractEffector.java | 90 +
.../core/effector/AddChildrenEffector.java | 117 ++
.../brooklyn/core/effector/AddEffector.java | 116 ++
.../brooklyn/core/effector/AddSensor.java | 126 ++
.../core/effector/BasicParameterType.java | 116 ++
.../brooklyn/core/effector/EffectorAndBody.java | 60 +
.../brooklyn/core/effector/EffectorBase.java | 106 ++
.../brooklyn/core/effector/EffectorBody.java | 100 +
.../brooklyn/core/effector/EffectorTasks.java | 229 +++
.../core/effector/EffectorWithBody.java | 32 +
.../brooklyn/core/effector/Effectors.java | 202 ++
.../core/effector/ExplicitEffector.java | 74 +
.../brooklyn/core/effector/MethodEffector.java | 180 ++
.../core/effector/ssh/SshEffectorTasks.java | 335 ++++
.../core/enricher/AbstractEnricher.java | 115 ++
.../core/enricher/EnricherDynamicType.java | 43 +
.../core/enricher/EnricherTypeSnapshot.java | 39 +
.../core/entity/AbstractApplication.java | 264 +++
.../brooklyn/core/entity/AbstractEntity.java | 1739 ++++++++++++++++++
.../apache/brooklyn/core/entity/Attributes.java | 169 ++
.../core/entity/BrooklynConfigKeys.java | 188 ++
.../apache/brooklyn/core/entity/Entities.java | 1108 +++++++++++
.../brooklyn/core/entity/EntityAdjuncts.java | 70 +
.../core/entity/EntityAndAttribute.java | 107 ++
.../brooklyn/core/entity/EntityDynamicType.java | 339 ++++
.../brooklyn/core/entity/EntityFunctions.java | 153 ++
.../core/entity/EntityInitializers.java | 49 +
.../brooklyn/core/entity/EntityInternal.java | 201 ++
.../brooklyn/core/entity/EntityPredicates.java | 451 +++++
.../brooklyn/core/entity/EntitySuppliers.java | 47 +
.../brooklyn/core/entity/EntityTasks.java | 81 +
.../core/entity/EntityTypeSnapshot.java | 126 ++
.../brooklyn/core/entity/EntityTypes.java | 28 +
.../core/entity/StartableApplication.java | 25 +
.../drivers/BasicEntityDriverManager.java | 56 +
.../drivers/ReflectiveEntityDriverFactory.java | 277 +++
.../drivers/RegistryEntityDriverFactory.java | 127 ++
.../downloads/BasicDownloadRequirement.java | 85 +
.../downloads/BasicDownloadResolver.java | 66 +
.../drivers/downloads/BasicDownloadTargets.java | 121 ++
.../downloads/BasicDownloadsManager.java | 161 ++
.../DownloadProducerFromCloudsoftRepo.java | 83 +
.../DownloadProducerFromLocalRepo.java | 84 +
.../DownloadProducerFromProperties.java | 344 ++++
.../DownloadProducerFromUrlAttribute.java | 63 +
.../drivers/downloads/DownloadSubstituters.java | 172 ++
.../drivers/downloads/FilenameProducers.java | 64 +
.../AbstractConfigurableEntityFactory.java | 82 +
.../core/entity/factory/ApplicationBuilder.java | 247 +++
.../factory/BasicConfigurableEntityFactory.java | 75 +
.../entity/factory/ClosureEntityFactory.java | 53 +
.../factory/ConfigurableEntityFactory.java | 33 +
...figurableEntityFactoryFromEntityFactory.java | 45 +
.../core/entity/factory/EntityFactory.java | 32 +
.../factory/EntityFactoryForLocation.java | 30 +
.../internal/ConfigMapViewWithStringKeys.java | 130 ++
.../core/entity/internal/EntityConfigMap.java | 306 +++
.../internal/EntityTransientCopyInternal.java | 121 ++
.../core/entity/lifecycle/Lifecycle.java | 185 ++
.../core/entity/lifecycle/PolicyDescriptor.java | 68 +
.../core/entity/lifecycle/QuorumCheck.java | 108 ++
.../entity/lifecycle/ServiceStateLogic.java | 639 +++++++
.../brooklyn/core/entity/trait/Changeable.java | 35 +
.../core/entity/trait/MemberReplaceable.java | 45 +
.../brooklyn/core/entity/trait/Resizable.java | 50 +
.../brooklyn/core/entity/trait/Startable.java | 123 ++
.../core/entity/trait/StartableMethods.java | 125 ++
.../apache/brooklyn/core/feed/AbstractFeed.java | 240 +++
.../core/feed/AttributePollHandler.java | 248 +++
.../brooklyn/core/feed/ConfigToAttributes.java | 59 +
.../core/feed/DelegatingPollHandler.java | 96 +
.../apache/brooklyn/core/feed/FeedConfig.java | 297 +++
.../apache/brooklyn/core/feed/PollConfig.java | 85 +
.../apache/brooklyn/core/feed/PollHandler.java | 38 +
.../org/apache/brooklyn/core/feed/Poller.java | 205 +++
.../internal/BrooklynFeatureEnablement.java | 208 ---
.../core/internal/BrooklynInitialization.java | 2 +-
.../core/location/AbstractLocation.java | 709 +++++++
.../core/location/AbstractLocationResolver.java | 188 ++
.../AggregatingMachineProvisioningLocation.java | 141 ++
.../core/location/BasicHardwareDetails.java | 56 +
.../core/location/BasicLocationDefinition.java | 85 +
.../core/location/BasicLocationRegistry.java | 489 +++++
.../core/location/BasicMachineDetails.java | 183 ++
.../core/location/BasicMachineMetadata.java | 84 +
.../brooklyn/core/location/BasicOsDetails.java | 123 ++
.../core/location/CatalogLocationResolver.java | 79 +
.../location/DefinedLocationByIdResolver.java | 74 +
.../location/DeprecatedKeysMappingBuilder.java | 66 +
.../core/location/HasSubnetHostname.java | 32 +
.../core/location/LocationConfigKeys.java | 79 +
.../core/location/LocationConfigUtils.java | 559 ++++++
.../core/location/LocationPredicates.java | 108 ++
...ocationPropertiesFromBrooklynProperties.java | 223 +++
.../brooklyn/core/location/Locations.java | 160 ++
.../apache/brooklyn/core/location/Machines.java | 191 ++
.../core/location/NamedLocationResolver.java | 97 +
.../brooklyn/core/location/PortRanges.java | 257 +++
.../core/location/RegistryLocationResolver.java | 42 +
.../core/location/SupportsPortForwarding.java | 39 +
.../location/access/BrooklynAccessUtils.java | 154 ++
.../location/access/PortForwardManager.java | 328 ++++
.../access/PortForwardManagerAuthority.java | 46 +
.../access/PortForwardManagerClient.java | 405 ++++
.../location/access/PortForwardManagerImpl.java | 505 +++++
.../PortForwardManagerLocationResolver.java | 89 +
.../core/location/access/PortMapping.java | 101 +
.../AbstractAvailabilityZoneExtension.java | 82 +
...bstractCloudMachineProvisioningLocation.java | 97 +
.../cloud/AvailabilityZoneExtension.java | 54 +
.../location/cloud/CloudLocationConfig.java | 116 ++
.../cloud/names/AbstractCloudMachineNamer.java | 150 ++
.../cloud/names/BasicCloudMachineNamer.java | 91 +
.../location/cloud/names/CloudMachineNamer.java | 61 +
.../cloud/names/CustomMachineNamer.java | 72 +
.../core/location/dynamic/DynamicLocation.java | 50 +
.../core/location/dynamic/LocationOwner.java | 85 +
.../location/geo/GeoBytesHostGeoLookup.java | 104 ++
.../core/location/geo/HasHostGeoInfo.java | 25 +
.../brooklyn/core/location/geo/HostGeoInfo.java | 205 +++
.../core/location/geo/HostGeoLookup.java | 27 +
.../location/geo/LocalhostExternalIpLoader.java | 177 ++
.../location/geo/MaxMind2HostGeoLookup.java | 114 ++
.../core/location/geo/UtraceHostGeoLookup.java | 209 +++
.../location/internal/LocationDynamicType.java | 40 +
.../location/internal/LocationInternal.java | 93 +
.../location/internal/LocationTypeSnapshot.java | 40 +
.../core/mgmt/EntityManagementUtils.java | 10 +-
.../AbstractBrooklynClassLoadingContext.java | 1 -
.../BrooklynClassLoadingContext.java | 50 +
.../BrooklynClassLoadingContextSequential.java | 1 -
...ssLoaderFromBrooklynClassLoadingContext.java | 2 -
.../core/mgmt/entitlement/Entitlements.java | 2 +-
.../mgmt/ha/HighAvailabilityManagerImpl.java | 4 +-
.../internal/AbstractManagementContext.java | 14 +-
.../mgmt/internal/BrooklynGarbageCollector.java | 2 +-
.../mgmt/internal/BrooklynShutdownHooks.java | 6 +-
.../core/mgmt/internal/EffectorUtils.java | 6 +-
.../mgmt/internal/EntityManagementSupport.java | 6 +-
.../core/mgmt/internal/LocalEntityManager.java | 10 +-
.../mgmt/internal/LocalLocationManager.java | 6 +-
.../mgmt/internal/LocalManagementContext.java | 6 +-
.../mgmt/internal/LocalSubscriptionManager.java | 2 +-
.../core/mgmt/internal/LocalUsageManager.java | 65 +-
.../internal/ManagementContextInternal.java | 1 +
.../NonDeploymentManagementContext.java | 3 +-
.../internal/NonDeploymentUsageManager.java | 15 +-
.../core/mgmt/internal/UsageListener.java | 103 --
.../core/mgmt/internal/UsageManager.java | 165 --
.../mgmt/persist/BrooklynPersistenceUtils.java | 4 +-
.../core/mgmt/persist/XmlMementoSerializer.java | 12 +-
.../rebind/ActivePartialRebindIteration.java | 2 +-
.../mgmt/rebind/BasicEnricherRebindSupport.java | 2 +-
.../mgmt/rebind/BasicEntityRebindSupport.java | 12 +-
.../mgmt/rebind/BasicFeedRebindSupport.java | 2 +-
.../mgmt/rebind/BasicLocationRebindSupport.java | 2 +-
.../mgmt/rebind/BasicPolicyRebindSupport.java | 2 +-
.../rebind/ImmediateDeltaChangeListener.java | 2 +-
.../mgmt/rebind/InitialFullRebindIteration.java | 2 +-
.../rebind/PeriodicDeltaChangeListener.java | 4 +-
.../mgmt/rebind/RebindExceptionHandlerImpl.java | 2 +-
.../core/mgmt/rebind/RebindIteration.java | 20 +-
.../core/mgmt/rebind/RebindManagerImpl.java | 6 +-
.../core/mgmt/rebind/dto/AbstractMemento.java | 2 +-
.../mgmt/rebind/dto/BasicEnricherMemento.java | 2 +-
.../mgmt/rebind/dto/BasicEntityMemento.java | 4 +-
.../core/mgmt/rebind/dto/BasicFeedMemento.java | 2 +-
.../mgmt/rebind/dto/BasicLocationMemento.java | 2 +-
.../mgmt/rebind/dto/BasicPolicyMemento.java | 2 +-
.../mgmt/rebind/dto/MementosGenerators.java | 12 +-
.../core/mgmt/usage/ApplicationUsage.java | 2 +-
.../brooklyn/core/mgmt/usage/LocationUsage.java | 2 +-
.../brooklyn/core/mgmt/usage/UsageListener.java | 103 ++
.../brooklyn/core/mgmt/usage/UsageManager.java | 165 ++
.../core/objs/AbstractBrooklynObject.java | 2 +-
.../core/objs/AbstractEntityAdjunct.java | 10 +-
.../brooklyn/core/objs/AdjunctConfigMap.java | 6 +-
.../brooklyn/core/objs/BrooklynTypes.java | 6 +-
.../core/objs/proxy/EntityProxyImpl.java | 12 +-
.../core/objs/proxy/InternalEntityFactory.java | 12 +-
.../objs/proxy/InternalLocationFactory.java | 4 +-
.../core/objs/proxy/InternalPolicyFactory.java | 6 +-
.../brooklyn/core/policy/AbstractPolicy.java | 119 ++
.../apache/brooklyn/core/policy/Policies.java | 73 +
.../brooklyn/core/policy/PolicyDynamicType.java | 43 +
.../core/policy/PolicyTypeSnapshot.java | 39 +
.../brooklyn/core/sensor/AttributeMap.java | 202 ++
.../sensor/AttributeSensorAndConfigKey.java | 147 ++
.../core/sensor/BasicAttributeSensor.java | 62 +
.../BasicAttributeSensorAndConfigKey.java | 114 ++
.../core/sensor/BasicNotificationSensor.java | 36 +
.../brooklyn/core/sensor/BasicSensor.java | 114 ++
.../brooklyn/core/sensor/BasicSensorEvent.java | 112 ++
.../core/sensor/DependentConfiguration.java | 823 +++++++++
.../brooklyn/core/sensor/HttpRequestSensor.java | 96 +
.../sensor/PortAttributeSensorAndConfigKey.java | 141 ++
.../apache/brooklyn/core/sensor/Sensors.java | 164 ++
.../brooklyn/core/sensor/StaticSensor.java | 72 +
...platedStringAttributeSensorAndConfigKey.java | 66 +
.../core/server/entity/BrooklynMetrics.java | 4 +-
.../core/server/entity/BrooklynMetricsImpl.java | 2 +-
.../effector/core/AbstractEffector.java | 90 -
.../effector/core/AddChildrenEffector.java | 117 --
.../brooklyn/effector/core/AddEffector.java | 116 --
.../brooklyn/effector/core/AddSensor.java | 126 --
.../effector/core/BasicParameterType.java | 116 --
.../brooklyn/effector/core/EffectorAndBody.java | 60 -
.../brooklyn/effector/core/EffectorBase.java | 106 --
.../brooklyn/effector/core/EffectorBody.java | 100 -
.../brooklyn/effector/core/EffectorTasks.java | 229 ---
.../effector/core/EffectorWithBody.java | 32 -
.../brooklyn/effector/core/Effectors.java | 202 --
.../effector/core/ExplicitEffector.java | 74 -
.../brooklyn/effector/core/MethodEffector.java | 180 --
.../stock/AbstractAggregatingEnricher.java | 174 ++
.../enricher/stock/AbstractAggregator.java | 238 +++
.../stock/AbstractMultipleSensorAggregator.java | 169 ++
.../enricher/stock/AbstractTransformer.java | 101 +
.../stock/AbstractTransformingEnricher.java | 38 +
.../stock/AbstractTypeTransformingEnricher.java | 68 +
.../brooklyn/enricher/stock/AddingEnricher.java | 107 ++
.../brooklyn/enricher/stock/Aggregator.java | 222 +++
.../brooklyn/enricher/stock/Combiner.java | 138 ++
.../stock/CustomAggregatingEnricher.java | 320 ++++
.../brooklyn/enricher/stock/Enrichers.java | 825 +++++++++
.../apache/brooklyn/enricher/stock/Joiner.java | 127 ++
.../brooklyn/enricher/stock/Propagator.java | 201 ++
.../stock/SensorPropagatingEnricher.java | 181 ++
.../stock/SensorTransformingEnricher.java | 106 ++
.../brooklyn/enricher/stock/Transformer.java | 103 ++
.../brooklyn/enricher/stock/UpdatingMap.java | 159 ++
.../YamlRollingTimeWindowMeanEnricher.java | 178 ++
.../stock/YamlTimeWeightedDeltaEnricher.java | 83 +
.../brooklyn/entity/annotation/Effector.java | 33 -
.../entity/annotation/EffectorParam.java | 42 -
.../entity/core/AbstractApplication.java | 264 ---
.../brooklyn/entity/core/AbstractEntity.java | 1739 ------------------
.../apache/brooklyn/entity/core/Attributes.java | 169 --
.../entity/core/BrooklynConfigKeys.java | 188 --
.../apache/brooklyn/entity/core/Entities.java | 1108 -----------
.../brooklyn/entity/core/EntityAdjuncts.java | 70 -
.../entity/core/EntityAndAttribute.java | 107 --
.../brooklyn/entity/core/EntityDynamicType.java | 339 ----
.../brooklyn/entity/core/EntityFunctions.java | 153 --
.../entity/core/EntityInitializers.java | 49 -
.../brooklyn/entity/core/EntityInternal.java | 201 --
.../brooklyn/entity/core/EntityPredicates.java | 451 -----
.../brooklyn/entity/core/EntitySuppliers.java | 47 -
.../brooklyn/entity/core/EntityTasks.java | 81 -
.../entity/core/EntityTypeSnapshot.java | 126 --
.../brooklyn/entity/core/EntityTypes.java | 28 -
.../entity/core/StartableApplication.java | 25 -
.../internal/ConfigMapViewWithStringKeys.java | 130 --
.../entity/core/internal/EntityConfigMap.java | 306 ---
.../internal/EntityTransientCopyInternal.java | 121 --
.../drivers/BasicEntityDriverManager.java | 56 -
.../drivers/ReflectiveEntityDriverFactory.java | 277 ---
.../drivers/RegistryEntityDriverFactory.java | 127 --
.../downloads/BasicDownloadRequirement.java | 85 -
.../downloads/BasicDownloadResolver.java | 66 -
.../drivers/downloads/BasicDownloadTargets.java | 121 --
.../downloads/BasicDownloadsManager.java | 161 --
.../DownloadProducerFromCloudsoftRepo.java | 83 -
.../DownloadProducerFromLocalRepo.java | 84 -
.../DownloadProducerFromProperties.java | 344 ----
.../DownloadProducerFromUrlAttribute.java | 63 -
.../drivers/downloads/DownloadSubstituters.java | 172 --
.../drivers/downloads/FilenameProducers.java | 64 -
.../AbstractConfigurableEntityFactory.java | 82 -
.../entity/factory/ApplicationBuilder.java | 247 ---
.../factory/BasicConfigurableEntityFactory.java | 75 -
.../entity/factory/ClosureEntityFactory.java | 53 -
.../factory/ConfigurableEntityFactory.java | 33 -
...figurableEntityFactoryFromEntityFactory.java | 45 -
.../brooklyn/entity/factory/EntityFactory.java | 32 -
.../factory/EntityFactoryForLocation.java | 30 -
.../brooklyn/entity/group/AbstractGroup.java | 6 +-
.../entity/group/AbstractGroupImpl.java | 10 +-
.../group/AbstractMembershipTrackingPolicy.java | 6 +-
.../apache/brooklyn/entity/group/Cluster.java | 4 +-
.../brooklyn/entity/group/DynamicCluster.java | 20 +-
.../entity/group/DynamicClusterImpl.java | 26 +-
.../brooklyn/entity/group/DynamicFabric.java | 10 +-
.../entity/group/DynamicFabricImpl.java | 28 +-
.../brooklyn/entity/group/DynamicGroup.java | 8 +-
.../brooklyn/entity/group/DynamicGroupImpl.java | 2 +-
.../entity/group/DynamicMultiGroup.java | 2 +-
.../entity/group/DynamicMultiGroupImpl.java | 6 +-
.../entity/group/DynamicRegionsFabric.java | 6 +-
.../entity/group/DynamicRegionsFabricImpl.java | 6 +-
.../brooklyn/entity/group/QuarantineGroup.java | 4 +-
.../entity/group/QuarantineGroupImpl.java | 8 +-
.../BalancingNodePlacementStrategy.java | 2 +-
.../brooklyn/entity/lifecycle/Lifecycle.java | 185 --
.../entity/lifecycle/PolicyDescriptor.java | 68 -
.../brooklyn/entity/lifecycle/QuorumCheck.java | 108 --
.../entity/lifecycle/ServiceStateLogic.java | 639 -------
.../brooklyn/entity/stock/BasicApplication.java | 2 +-
.../entity/stock/BasicApplicationImpl.java | 2 +-
.../brooklyn/entity/stock/BasicEntityImpl.java | 2 +-
.../brooklyn/entity/stock/BasicStartable.java | 4 +-
.../entity/stock/BasicStartableImpl.java | 18 +-
.../brooklyn/entity/stock/DataEntity.java | 2 +-
.../brooklyn/entity/stock/DataEntityImpl.java | 6 +-
.../brooklyn/entity/stock/DelegateEntity.java | 4 +-
.../entity/stock/DelegateEntityImpl.java | 4 +-
.../entity/stock/EffectorStartableImpl.java | 8 +-
.../brooklyn/entity/trait/Changeable.java | 35 -
.../entity/trait/MemberReplaceable.java | 45 -
.../apache/brooklyn/entity/trait/Resizable.java | 50 -
.../apache/brooklyn/entity/trait/Startable.java | 123 --
.../brooklyn/entity/trait/StartableMethods.java | 125 --
.../brooklyn/feed/function/FunctionFeed.java | 208 +++
.../feed/function/FunctionPollConfig.java | 111 ++
.../org/apache/brooklyn/feed/http/HttpFeed.java | 382 ++++
.../brooklyn/feed/http/HttpPollConfig.java | 160 ++
.../brooklyn/feed/http/HttpPollValue.java | 40 +
.../apache/brooklyn/feed/http/HttpPolls.java | 39 +
.../brooklyn/feed/http/HttpValueFunctions.java | 154 ++
.../brooklyn/feed/http/JsonFunctions.java | 235 +++
.../apache/brooklyn/feed/shell/ShellFeed.java | 273 +++
.../brooklyn/feed/shell/ShellPollConfig.java | 125 ++
.../org/apache/brooklyn/feed/ssh/SshFeed.java | 290 +++
.../apache/brooklyn/feed/ssh/SshPollConfig.java | 142 ++
.../apache/brooklyn/feed/ssh/SshPollValue.java | 60 +
.../brooklyn/feed/ssh/SshValueFunctions.java | 73 +
.../windows/WindowsPerformanceCounterFeed.java | 412 +++++
.../WindowsPerformanceCounterPollConfig.java | 53 +
.../location/access/BrooklynAccessUtils.java | 154 --
.../location/access/PortForwardManager.java | 328 ----
.../access/PortForwardManagerAuthority.java | 46 -
.../access/PortForwardManagerClient.java | 405 ----
.../location/access/PortForwardManagerImpl.java | 505 -----
.../PortForwardManagerLocationResolver.java | 89 -
.../brooklyn/location/access/PortMapping.java | 101 -
.../location/byon/ByonLocationResolver.java | 2 +-
.../FixedListMachineProvisioningLocation.java | 6 +-
.../location/byon/HostLocationResolver.java | 8 +-
.../byon/SingleMachineLocationResolver.java | 8 +-
.../AbstractAvailabilityZoneExtension.java | 82 -
...bstractCloudMachineProvisioningLocation.java | 97 -
.../cloud/AvailabilityZoneExtension.java | 54 -
.../location/cloud/CloudLocationConfig.java | 116 --
.../cloud/names/AbstractCloudMachineNamer.java | 150 --
.../cloud/names/BasicCloudMachineNamer.java | 91 -
.../location/cloud/names/CloudMachineNamer.java | 61 -
.../cloud/names/CustomMachineNamer.java | 72 -
.../location/core/AbstractLocation.java | 709 -------
.../location/core/AbstractLocationResolver.java | 188 --
.../AggregatingMachineProvisioningLocation.java | 141 --
.../location/core/BasicHardwareDetails.java | 56 -
.../location/core/BasicLocationDefinition.java | 85 -
.../location/core/BasicLocationRegistry.java | 489 -----
.../location/core/BasicMachineDetails.java | 183 --
.../location/core/BasicMachineMetadata.java | 84 -
.../brooklyn/location/core/BasicOsDetails.java | 123 --
.../location/core/CatalogLocationResolver.java | 79 -
.../core/DefinedLocationByIdResolver.java | 74 -
.../core/DeprecatedKeysMappingBuilder.java | 66 -
.../location/core/HasSubnetHostname.java | 32 -
.../location/core/LocationConfigKeys.java | 79 -
.../location/core/LocationConfigUtils.java | 559 ------
.../location/core/LocationPredicates.java | 108 --
...ocationPropertiesFromBrooklynProperties.java | 223 ---
.../brooklyn/location/core/Locations.java | 160 --
.../apache/brooklyn/location/core/Machines.java | 191 --
.../brooklyn/location/core/MultiLocation.java | 166 --
.../location/core/MultiLocationResolver.java | 145 --
.../location/core/NamedLocationResolver.java | 97 -
.../brooklyn/location/core/PortRanges.java | 257 ---
.../location/core/RegistryLocationResolver.java | 42 -
.../location/core/SupportsPortForwarding.java | 39 -
.../core/internal/LocationDynamicType.java | 40 -
.../core/internal/LocationInternal.java | 93 -
.../core/internal/LocationTypeSnapshot.java | 40 -
.../location/dynamic/DynamicLocation.java | 50 -
.../location/dynamic/LocationOwner.java | 85 -
.../location/geo/GeoBytesHostGeoLookup.java | 104 --
.../brooklyn/location/geo/HasHostGeoInfo.java | 25 -
.../brooklyn/location/geo/HostGeoInfo.java | 205 ---
.../brooklyn/location/geo/HostGeoLookup.java | 27 -
.../location/geo/LocalhostExternalIpLoader.java | 177 --
.../location/geo/MaxMind2HostGeoLookup.java | 114 --
.../location/geo/UtraceHostGeoLookup.java | 209 ---
.../localhost/LocalhostLocationResolver.java | 4 +-
.../LocalhostMachineProvisioningLocation.java | 12 +-
...calhostPropertiesFromBrooklynProperties.java | 2 +-
.../brooklyn/location/multi/MultiLocation.java | 167 ++
.../location/multi/MultiLocationResolver.java | 149 ++
.../location/ssh/SshMachineLocation.java | 16 +-
.../winrm/AdvertiseWinrmLoginPolicy.java | 8 +-
.../location/winrm/WinRmMachineLocation.java | 4 +-
.../brooklyn/policy/core/AbstractPolicy.java | 119 --
.../policy/core/GeneralPurposePolicy.java | 36 -
.../apache/brooklyn/policy/core/Policies.java | 73 -
.../brooklyn/policy/core/PolicyDynamicType.java | 43 -
.../policy/core/PolicyTypeSnapshot.java | 39 -
.../brooklyn/sensor/core/AttributeMap.java | 202 --
.../core/AttributeSensorAndConfigKey.java | 147 --
.../sensor/core/BasicAttributeSensor.java | 62 -
.../core/BasicAttributeSensorAndConfigKey.java | 114 --
.../sensor/core/BasicNotificationSensor.java | 36 -
.../brooklyn/sensor/core/BasicSensor.java | 114 --
.../brooklyn/sensor/core/BasicSensorEvent.java | 112 --
.../sensor/core/DependentConfiguration.java | 823 ---------
.../brooklyn/sensor/core/HttpRequestSensor.java | 96 -
.../core/PortAttributeSensorAndConfigKey.java | 141 --
.../apache/brooklyn/sensor/core/Sensors.java | 164 --
.../brooklyn/sensor/core/StaticSensor.java | 72 -
...platedStringAttributeSensorAndConfigKey.java | 66 -
.../enricher/AbstractAggregatingEnricher.java | 173 --
.../sensor/enricher/AbstractAggregator.java | 237 ---
.../sensor/enricher/AbstractEnricher.java | 115 --
.../AbstractMultipleSensorAggregator.java | 169 --
.../sensor/enricher/AbstractTransformer.java | 100 -
.../enricher/AbstractTransformingEnricher.java | 38 -
.../AbstractTypeTransformingEnricher.java | 67 -
.../sensor/enricher/AddingEnricher.java | 106 --
.../brooklyn/sensor/enricher/Aggregator.java | 221 ---
.../brooklyn/sensor/enricher/Combiner.java | 137 --
.../enricher/CustomAggregatingEnricher.java | 320 ----
.../sensor/enricher/EnricherDynamicType.java | 43 -
.../sensor/enricher/EnricherTypeSnapshot.java | 39 -
.../brooklyn/sensor/enricher/Enrichers.java | 824 ---------
.../apache/brooklyn/sensor/enricher/Joiner.java | 126 --
.../brooklyn/sensor/enricher/Propagator.java | 200 --
.../enricher/SensorPropagatingEnricher.java | 180 --
.../enricher/SensorTransformingEnricher.java | 106 --
.../brooklyn/sensor/enricher/Transformer.java | 103 --
.../brooklyn/sensor/enricher/UpdatingMap.java | 158 --
.../YamlRollingTimeWindowMeanEnricher.java | 178 --
.../enricher/YamlTimeWeightedDeltaEnricher.java | 83 -
.../brooklyn/sensor/feed/AbstractFeed.java | 240 ---
.../sensor/feed/AttributePollHandler.java | 248 ---
.../sensor/feed/ConfigToAttributes.java | 59 -
.../sensor/feed/DelegatingPollHandler.java | 96 -
.../apache/brooklyn/sensor/feed/FeedConfig.java | 297 ---
.../apache/brooklyn/sensor/feed/PollConfig.java | 85 -
.../brooklyn/sensor/feed/PollHandler.java | 38 -
.../org/apache/brooklyn/sensor/feed/Poller.java | 205 ---
.../sensor/feed/function/FunctionFeed.java | 208 ---
.../feed/function/FunctionPollConfig.java | 111 --
.../brooklyn/sensor/feed/http/HttpFeed.java | 382 ----
.../sensor/feed/http/HttpPollConfig.java | 160 --
.../sensor/feed/http/HttpPollValue.java | 40 -
.../brooklyn/sensor/feed/http/HttpPolls.java | 39 -
.../sensor/feed/http/HttpValueFunctions.java | 154 --
.../sensor/feed/http/JsonFunctions.java | 235 ---
.../brooklyn/sensor/feed/shell/ShellFeed.java | 273 ---
.../sensor/feed/shell/ShellPollConfig.java | 125 --
.../brooklyn/sensor/feed/ssh/SshFeed.java | 290 ---
.../brooklyn/sensor/feed/ssh/SshPollConfig.java | 142 --
.../brooklyn/sensor/feed/ssh/SshPollValue.java | 60 -
.../sensor/feed/ssh/SshValueFunctions.java | 73 -
.../windows/WindowsPerformanceCounterFeed.java | 412 -----
.../WindowsPerformanceCounterPollConfig.java | 53 -
.../util/core/BrooklynLanguageExtensions.java | 2 +-
.../util/core/BrooklynNetworkUtils.java | 2 +-
.../brooklyn/util/core/ResourceUtils.java | 2 +-
.../brooklyn/util/core/flags/FlagUtils.java | 7 +-
.../brooklyn/util/core/flags/TypeCoercions.java | 16 +-
.../util/core/http/HttpToolResponse.java | 2 +-
.../brooklyn/util/core/internal/Repeater.java | 2 +-
.../internal/ssh/sshj/SshjClientConnection.java | 2 +-
.../util/core/internal/ssh/sshj/SshjTool.java | 2 +-
.../util/core/task/BasicExecutionContext.java | 2 +-
.../util/core/task/BasicExecutionManager.java | 2 +-
.../brooklyn/util/core/task/BasicTask.java | 2 +-
.../brooklyn/util/core/task/DynamicTasks.java | 2 +-
.../brooklyn/util/core/task/ScheduledTask.java | 4 +-
.../brooklyn/util/core/task/ValueResolver.java | 2 +-
.../brooklyn/util/core/task/ssh/SshTasks.java | 5 +-
.../util/core/text/TemplateProcessor.java | 8 +-
...pache.brooklyn.api.location.LocationResolver | 12 +-
.../core/BrooklynFeatureEnablementTest.java | 118 ++
.../brooklyn/core/BrooklynVersionTest.java | 2 +-
.../core/catalog/internal/CatalogDtoTest.java | 2 +-
.../core/catalog/internal/CatalogScanTest.java | 2 +-
.../core/catalog/internal/CatalogTestUtils.java | 2 +-
.../catalog/internal/CatalogVersioningTest.java | 2 +-
.../core/catalog/internal/MyCatalogItems.java | 4 +-
...apListAndOtherStructuredConfigKeyTest.groovy | 6 +-
.../core/effector/EffectorBasicTest.java | 183 ++
.../core/effector/EffectorConcatenateTest.java | 241 +++
.../core/effector/EffectorMetadataTest.java | 166 ++
.../effector/EffectorSayHiGroovyTest.groovy | 182 ++
.../core/effector/EffectorSayHiTest.java | 173 ++
.../core/effector/EffectorTaskTest.java | 437 +++++
.../core/effector/ssh/SshEffectorTasksTest.java | 265 +++
.../core/enricher/BasicEnricherTest.java | 119 ++
.../core/enricher/EnricherConfigTest.java | 147 ++
.../entity/AbstractApplicationLegacyTest.java | 155 ++
.../core/entity/AbstractEntityLegacyTest.java | 131 ++
.../brooklyn/core/entity/AttributeMapTest.java | 226 +++
.../brooklyn/core/entity/AttributeTest.java | 66 +
.../entity/ConfigEntityInheritanceTest.java | 190 ++
.../core/entity/DependentConfigurationTest.java | 413 +++++
.../brooklyn/core/entity/DynamicEntityTest.java | 60 +
.../brooklyn/core/entity/EntitiesTest.java | 134 ++
.../brooklyn/core/entity/EntityConfigTest.java | 178 ++
.../core/entity/EntityFunctionsTest.java | 77 +
.../core/entity/EntityLocationsTest.java | 126 ++
.../core/entity/EntityPreManagementTest.java | 146 ++
.../core/entity/EntityPredicatesTest.java | 129 ++
.../core/entity/EntityRegistrationTest.java | 102 +
.../core/entity/EntitySetFromFlagTest.java | 213 +++
.../brooklyn/core/entity/EntitySpecTest.java | 214 +++
.../core/entity/EntitySubscriptionTest.java | 242 +++
.../core/entity/EntitySuppliersTest.java | 70 +
.../brooklyn/core/entity/EntityTypeTest.java | 284 +++
.../brooklyn/core/entity/OwnedChildrenTest.java | 213 +++
.../core/entity/PolicyRegistrationTest.java | 152 ++
.../entity/RecordingSensorEventListener.java | 115 ++
.../brooklyn/core/entity/SanitizerTest.java | 38 +
.../drivers/BasicEntityDriverManagerTest.java | 74 +
.../drivers/EntityDriverRegistryTest.java | 59 +
.../ReflectiveEntityDriverFactoryTest.java | 169 ++
.../RegistryEntityDriverFactoryTest.java | 86 +
.../downloads/BasicDownloadsRegistryTest.java | 155 ++
.../DownloadProducerFromLocalRepoTest.java | 130 ++
.../DownloadProducerFromPropertiesTest.java | 162 ++
.../downloads/DownloadSubstitutersTest.java | 131 ++
.../downloads/FilenameProducersTest.java | 34 +
.../drivers/downloads/MyEntityDriver.java | 44 +
.../brooklyn/core/entity/hello/HelloEntity.java | 53 +
.../core/entity/hello/HelloEntityImpl.java | 31 +
.../core/entity/hello/LocalEntitiesTest.java | 282 +++
.../entity/internal/ConfigMapGroovyTest.groovy | 61 +
.../core/entity/internal/ConfigMapTest.java | 298 +++
.../EntityConfigMapUsageLegacyTest.java | 292 +++
.../internal/EntityConfigMapUsageTest.java | 318 ++++
.../lifecycle/LifecycleTransitionTest.java | 51 +
.../entity/lifecycle/ServiceStateLogicTest.java | 314 ++++
.../ApplicationBuilderOverridingTest.java | 221 +++
.../proxying/BasicEntityTypeRegistryTest.java | 135 ++
.../core/entity/proxying/EntityManagerTest.java | 83 +
.../core/entity/proxying/EntityProxyTest.java | 171 ++
.../proxying/InternalEntityFactoryTest.java | 109 ++
.../core/entity/trait/FailingEntity.java | 84 +
.../core/entity/trait/FailingEntityImpl.java | 87 +
.../core/entity/trait/StartableMethodsTest.java | 127 ++
.../core/feed/ConfigToAttributesTest.java | 70 +
.../apache/brooklyn/core/feed/PollerTest.java | 108 ++
.../internal/BrooklynFeatureEnablementTest.java | 117 --
.../core/location/AbstractLocationTest.java | 185 ++
...regatingMachineProvisioningLocationTest.java | 117 ++
.../location/LegacyAbstractLocationTest.java | 151 ++
.../core/location/LocationConfigTest.java | 204 ++
.../core/location/LocationConfigUtilsTest.java | 156 ++
.../core/location/LocationExtensionsTest.java | 187 ++
.../core/location/LocationManagementTest.java | 82 +
.../core/location/LocationPredicatesTest.java | 102 +
...ionPropertiesFromBrooklynPropertiesTest.java | 122 ++
.../core/location/LocationRegistryTest.java | 161 ++
.../core/location/MachineDetailsTest.java | 83 +
.../brooklyn/core/location/PortRangesTest.java | 130 ++
.../RecordingMachineLocationCustomizer.java | 71 +
.../core/location/SimulatedLocation.java | 141 ++
.../core/location/TestPortSupplierLocation.java | 90 +
.../access/BrooklynAccessUtilsTest.java | 139 ++
.../PortForwardManagerLocationResolverTest.java | 83 +
.../access/PortForwardManagerRebindTest.java | 195 ++
.../location/access/PortForwardManagerTest.java | 193 ++
.../location/cloud/CloudMachineNamerTest.java | 161 ++
.../location/cloud/CustomMachineNamerTest.java | 79 +
.../core/location/geo/HostGeoInfoTest.java | 52 +
.../geo/HostGeoLookupIntegrationTest.java | 87 +
...ocalhostExternalIpLoaderIntegrationTest.java | 54 +
.../AcmeEntitlementManagerTestFixture.java | 4 +-
.../core/mgmt/entitlement/EntitlementsTest.java | 4 +-
.../mgmt/entitlement/EntityEntitlementTest.java | 4 +-
.../ha/HighAvailabilityManagerInMemoryTest.java | 2 +-
.../HighAvailabilityManagerSplitBrainTest.java | 6 +-
.../ha/HighAvailabilityManagerTestFixture.java | 2 +-
.../brooklyn/core/mgmt/ha/HotStandbyTest.java | 2 +-
.../core/mgmt/ha/MasterChooserTest.java | 2 +-
.../brooklyn/core/mgmt/ha/WarmStandbyTest.java | 2 +-
.../core/mgmt/internal/AccessManagerTest.java | 6 +-
.../internal/EntityExecutionManagerTest.java | 8 +-
.../internal/LocalSubscriptionManagerTest.java | 2 +-
.../brooklyn/core/mgmt/osgi/OsgiPathTest.java | 2 +-
.../core/mgmt/osgi/OsgiStandaloneTest.java | 2 +-
.../mgmt/osgi/OsgiVersionMoreEntityTest.java | 8 +-
...ntoPersisterInMemorySizeIntegrationTest.java | 2 +-
.../BrooklynMementoPersisterTestFixture.java | 6 +-
.../mgmt/persist/FileBasedObjectStoreTest.java | 2 +-
.../mgmt/persist/XmlMementoSerializerTest.java | 6 +-
.../mgmt/rebind/ActivePartialRebindTest.java | 6 +-
.../core/mgmt/rebind/CheckpointEntityTest.java | 4 +-
.../mgmt/rebind/RebindCatalogEntityTest.java | 14 +-
.../core/mgmt/rebind/RebindCatalogItemTest.java | 4 +-
...talogWhenCatalogPersistenceDisabledTest.java | 2 +-
.../mgmt/rebind/RebindDynamicGroupTest.java | 2 +-
.../core/mgmt/rebind/RebindEnricherTest.java | 14 +-
.../rebind/RebindEntityDynamicTypeInfoTest.java | 4 +-
.../core/mgmt/rebind/RebindEntityTest.java | 22 +-
.../core/mgmt/rebind/RebindFailuresTest.java | 8 +-
.../core/mgmt/rebind/RebindFeedTest.java | 20 +-
.../core/mgmt/rebind/RebindGroupTest.java | 2 +-
.../core/mgmt/rebind/RebindLocationTest.java | 2 +-
.../mgmt/rebind/RebindManagerSorterTest.java | 2 +-
.../core/mgmt/rebind/RebindPolicyTest.java | 10 +-
.../core/mgmt/rebind/RebindTestFixture.java | 8 +-
.../mgmt/rebind/RebindTestFixtureWithApp.java | 2 +-
.../core/policy/basic/BasicPolicyTest.java | 2 +-
.../core/policy/basic/EnricherTypeTest.java | 2 +-
.../core/policy/basic/PolicyConfigTest.java | 2 +-
.../policy/basic/PolicySubscriptionTest.java | 8 +-
.../core/policy/basic/PolicyTypeTest.java | 2 +-
.../core/sensor/HttpRequestSensorTest.java | 85 +
.../brooklyn/core/sensor/StaticSensorTest.java | 55 +
.../core/server/entity/BrooklynMetricsTest.java | 6 +-
.../core/test/BrooklynAppLiveTestSupport.java | 4 +-
.../core/test/BrooklynAppUnitTestSupport.java | 6 +-
.../apache/brooklyn/core/test/HttpService.java | 2 +-
.../core/test/entity/NoopStartable.java | 2 +-
.../core/test/entity/TestApplication.java | 10 +-
.../core/test/entity/TestApplicationImpl.java | 4 +-
.../brooklyn/core/test/entity/TestCluster.java | 2 +-
.../core/test/entity/TestClusterImpl.java | 4 +-
.../brooklyn/core/test/entity/TestEntity.java | 20 +-
.../core/test/entity/TestEntityImpl.java | 6 +-
.../entity/TestEntityTransientCopyImpl.java | 2 +-
.../core/test/location/TestPaasLocation.java | 32 -
.../brooklyn/core/test/policy/TestEnricher.java | 2 +-
.../brooklyn/core/test/policy/TestPolicy.java | 2 +-
.../longevity/EntityCleanupLongevityTest.java | 2 +-
.../EntityCleanupLongevityTestFixture.java | 6 +-
.../test/qa/longevity/EntityCleanupTest.java | 2 +-
.../qa/performance/AbstractPerformanceTest.java | 6 +-
.../qa/performance/EntityPerformanceTest.java | 2 +-
.../EntityPersistencePerformanceTest.java | 2 +-
.../effector/core/EffectorBasicTest.java | 183 --
.../effector/core/EffectorConcatenateTest.java | 241 ---
.../effector/core/EffectorMetadataTest.java | 166 --
.../core/EffectorSayHiGroovyTest.groovy | 179 --
.../effector/core/EffectorSayHiTest.java | 173 --
.../effector/core/EffectorTaskTest.java | 437 -----
...stomAggregatingEnricherDeprecatedTest.groovy | 368 ++++
.../stock/CustomAggregatingEnricherTest.java | 556 ++++++
.../brooklyn/enricher/stock/EnrichersTest.java | 501 +++++
...SensorPropagatingEnricherDeprecatedTest.java | 108 ++
.../stock/SensorPropagatingEnricherTest.java | 218 +++
.../TransformingEnricherDeprecatedTest.groovy | 83 +
.../stock/TransformingEnricherTest.java | 71 +
.../YamlRollingTimeWindowMeanEnricherTest.java | 179 ++
.../YamlTimeWeightedDeltaEnricherTest.java | 107 ++
.../core/AbstractApplicationLegacyTest.java | 156 --
.../entity/core/AbstractEntityLegacyTest.java | 131 --
.../brooklyn/entity/core/AttributeMapTest.java | 226 ---
.../brooklyn/entity/core/AttributeTest.java | 66 -
.../core/ConfigEntityInheritanceTest.java | 188 --
.../entity/core/DependentConfigurationTest.java | 413 -----
.../brooklyn/entity/core/DynamicEntityTest.java | 60 -
.../brooklyn/entity/core/EntitiesTest.java | 134 --
.../brooklyn/entity/core/EntityConfigTest.java | 178 --
.../entity/core/EntityFunctionsTest.java | 77 -
.../entity/core/EntityLocationsTest.java | 126 --
.../entity/core/EntityPreManagementTest.java | 146 --
.../entity/core/EntityPredicatesTest.java | 129 --
.../entity/core/EntityRegistrationTest.java | 102 -
.../entity/core/EntitySetFromFlagTest.java | 213 ---
.../brooklyn/entity/core/EntitySpecTest.java | 214 ---
.../entity/core/EntitySubscriptionTest.java | 242 ---
.../entity/core/EntitySuppliersTest.java | 70 -
.../brooklyn/entity/core/EntityTypeTest.java | 284 ---
.../brooklyn/entity/core/OwnedChildrenTest.java | 213 ---
.../entity/core/PolicyRegistrationTest.java | 152 --
.../core/RecordingSensorEventListener.java | 115 --
.../brooklyn/entity/core/SanitizerTest.java | 38 -
.../core/internal/ConfigMapGroovyTest.groovy | 61 -
.../entity/core/internal/ConfigMapTest.java | 298 ---
.../EntityConfigMapUsageLegacyTest.java | 292 ---
.../core/internal/EntityConfigMapUsageTest.java | 318 ----
.../drivers/BasicEntityDriverManagerTest.java | 74 -
.../drivers/EntityDriverRegistryTest.java | 59 -
.../ReflectiveEntityDriverFactoryTest.java | 169 --
.../RegistryEntityDriverFactoryTest.java | 86 -
.../downloads/BasicDownloadsRegistryTest.java | 155 --
.../DownloadProducerFromLocalRepoTest.java | 130 --
.../DownloadProducerFromPropertiesTest.java | 162 --
.../downloads/DownloadSubstitutersTest.java | 131 --
.../downloads/FilenameProducersTest.java | 34 -
.../drivers/downloads/MyEntityDriver.java | 44 -
.../entity/group/DynamicClusterTest.java | 18 +-
...DynamicClusterWithAvailabilityZonesTest.java | 14 +-
.../entity/group/DynamicFabricTest.java | 12 +-
.../brooklyn/entity/group/DynamicGroupTest.java | 10 +-
.../entity/group/DynamicMultiGroupTest.java | 10 +-
.../entity/group/DynamicRegionsFabricTest.java | 2 +-
.../entity/group/GroupPickUpEntitiesTest.java | 10 +-
.../apache/brooklyn/entity/group/GroupTest.java | 9 +-
.../group/MembershipTrackingPolicyTest.java | 6 +-
.../entity/group/QuarantineGroupTest.java | 4 +-
.../BalancingNodePlacementStrategyTest.java | 2 +-
.../ProportionalZoneFailureDetectorTest.java | 2 +-
.../brooklyn/entity/hello/HelloEntity.java | 53 -
.../brooklyn/entity/hello/HelloEntityImpl.java | 31 -
.../entity/hello/LocalEntitiesTest.java | 282 ---
.../lifecycle/LifecycleTransitionTest.java | 51 -
.../entity/lifecycle/ServiceStateLogicTest.java | 314 ----
.../ApplicationBuilderOverridingTest.java | 221 ---
.../proxying/BasicEntityTypeRegistryTest.java | 135 --
.../entity/proxying/EntityManagerTest.java | 83 -
.../entity/proxying/EntityProxyTest.java | 171 --
.../proxying/InternalEntityFactoryTest.java | 109 --
.../entity/stock/BasicStartableTest.java | 15 +-
.../brooklyn/entity/stock/DataEntityTest.java | 8 +-
.../brooklyn/entity/trait/FailingEntity.java | 84 -
.../entity/trait/FailingEntityImpl.java | 87 -
.../entity/trait/StartableMethodsTest.java | 127 --
.../feed/function/FunctionFeedTest.java | 315 ++++
.../feed/http/HttpFeedIntegrationTest.java | 160 ++
.../apache/brooklyn/feed/http/HttpFeedTest.java | 392 ++++
.../feed/http/HttpValueFunctionsTest.java | 94 +
.../brooklyn/feed/http/JsonFunctionsTest.java | 130 ++
.../feed/shell/ShellFeedIntegrationTest.java | 226 +++
.../feed/ssh/SshFeedIntegrationTest.java | 264 +++
.../WindowsPerformanceCounterFeedLiveTest.java | 104 ++
.../WindowsPerformanceCounterFeedTest.java | 132 ++
.../access/BrooklynAccessUtilsTest.java | 137 --
.../PortForwardManagerLocationResolverTest.java | 82 -
.../access/PortForwardManagerRebindTest.java | 194 --
.../location/access/PortForwardManagerTest.java | 192 --
.../location/byon/ByonLocationResolverTest.java | 10 +-
...stMachineProvisioningLocationRebindTest.java | 6 +-
...ixedListMachineProvisioningLocationTest.java | 6 +-
.../location/byon/HostLocationResolverTest.java | 2 +-
.../byon/SingleMachineLocationResolverTest.java | 2 +-
.../location/cloud/CloudMachineNamerTest.java | 160 --
.../location/cloud/CustomMachineNamerTest.java | 78 -
.../location/core/AbstractLocationTest.java | 185 --
...regatingMachineProvisioningLocationTest.java | 117 --
.../core/LegacyAbstractLocationTest.java | 151 --
.../location/core/LocationConfigTest.java | 204 --
.../location/core/LocationConfigUtilsTest.java | 156 --
.../location/core/LocationExtensionsTest.java | 187 --
.../location/core/LocationManagementTest.java | 82 -
.../location/core/LocationPredicatesTest.java | 102 -
...ionPropertiesFromBrooklynPropertiesTest.java | 122 --
.../location/core/LocationRegistryTest.java | 161 --
.../location/core/MachineDetailsTest.java | 83 -
.../location/core/MultiLocationRebindTest.java | 122 --
.../core/MultiLocationResolverTest.java | 203 --
.../location/core/MultiLocationTest.java | 121 --
.../location/core/PaasLocationTest.java | 35 -
.../brooklyn/location/core/PortRangesTest.java | 130 --
.../RecordingMachineLocationCustomizer.java | 71 -
.../location/core/SimulatedLocation.java | 141 --
.../location/core/TestPortSupplierLocation.java | 90 -
.../LocalhostLocationResolverTest.java | 269 ---
...ocalhostMachineProvisioningLocationTest.java | 215 ---
.../LocalhostProvisioningAndAccessTest.java | 59 -
.../brooklyn/location/geo/HostGeoInfoTest.java | 51 -
.../geo/HostGeoLookupIntegrationTest.java | 83 -
...ocalhostExternalIpLoaderIntegrationTest.java | 53 -
.../LocalhostLocationResolverTest.java | 269 +++
...ocalhostMachineProvisioningLocationTest.java | 215 +++
.../LocalhostProvisioningAndAccessTest.java | 59 +
.../location/multi/MultiLocationRebindTest.java | 122 ++
.../multi/MultiLocationResolverTest.java | 203 ++
.../location/multi/MultiLocationTest.java | 121 ++
.../location/paas/PaasLocationTest.java | 34 +
.../location/paas/TestPaasLocation.java | 32 +
.../ssh/SshMachineLocationIntegrationTest.java | 2 +-
.../SshMachineLocationReuseIntegrationTest.java | 2 +-
.../location/ssh/SshMachineLocationTest.java | 26 +-
.../winrm/WinRmMachineLocationTest.java | 2 +-
.../sensor/core/HttpRequestSensorTest.java | 85 -
.../brooklyn/sensor/core/StaticSensorTest.java | 55 -
.../sensor/enricher/BasicEnricherTest.java | 119 --
...stomAggregatingEnricherDeprecatedTest.groovy | 367 ----
.../enricher/CustomAggregatingEnricherTest.java | 556 ------
.../sensor/enricher/EnricherConfigTest.java | 147 --
.../brooklyn/sensor/enricher/EnrichersTest.java | 501 -----
...SensorPropagatingEnricherDeprecatedTest.java | 108 --
.../enricher/SensorPropagatingEnricherTest.java | 218 ---
.../TransformingEnricherDeprecatedTest.groovy | 82 -
.../enricher/TransformingEnricherTest.java | 71 -
.../YamlRollingTimeWindowMeanEnricherTest.java | 179 --
.../YamlTimeWeightedDeltaEnricherTest.java | 107 --
.../sensor/feed/ConfigToAttributesTest.java | 70 -
.../apache/brooklyn/sensor/feed/PollerTest.java | 108 --
.../sensor/feed/function/FunctionFeedTest.java | 315 ----
.../feed/http/HttpFeedIntegrationTest.java | 160 --
.../brooklyn/sensor/feed/http/HttpFeedTest.java | 392 ----
.../feed/http/HttpValueFunctionsTest.java | 94 -
.../sensor/feed/http/JsonFunctionsTest.java | 130 --
.../feed/shell/ShellFeedIntegrationTest.java | 226 ---
.../sensor/feed/ssh/SshFeedIntegrationTest.java | 264 ---
.../WindowsPerformanceCounterFeedLiveTest.java | 104 --
.../WindowsPerformanceCounterFeedTest.java | 132 --
.../util/core/http/HttpToolIntegrationTest.java | 2 +-
.../util/core/internal/RepeaterTest.groovy | 4 +-
.../util/core/internal/TypeCoercionsTest.java | 2 +-
.../sshj/SshjToolAsyncStubIntegrationTest.java | 2 +-
.../ssh/sshj/SshjToolIntegrationTest.java | 2 +-
.../core/ssh/BashCommandsIntegrationTest.java | 2 +-
.../brooklyn/util/core/task/TasksTest.java | 4 +-
.../util/core/task/ssh/SshTasksTest.java | 5 +-
.../util/core/task/system/SystemTasksTest.java | 2 +-
.../util/core/text/TemplateProcessorTest.java | 2 +-
.../big_examples/global-web-fabric/index.md | 16 +-
...est-app-with-enrichers-slightly-simpler.yaml | 4 +-
.../brooklyn/demo/GlobalWebFabricExample.java | 10 +-
.../brooklyn/demo/KafkaClusterExample.java | 4 +-
.../demo/StandaloneQpidBrokerExample.java | 6 +-
.../brooklyn/demo/CumulusRDFApplication.java | 24 +-
.../demo/HighAvailabilityCassandraCluster.java | 6 +-
.../brooklyn/demo/ResilientMongoDbApp.java | 8 +-
.../brooklyn/demo/RiakClusterExample.java | 6 +-
.../brooklyn/demo/SimpleCassandraCluster.java | 6 +-
.../brooklyn/demo/SimpleCouchDBCluster.java | 2 +-
.../brooklyn/demo/SimpleMongoDBReplicaSet.java | 2 +-
.../brooklyn/demo/SimpleRedisCluster.java | 2 +-
.../apache/brooklyn/demo/StormSampleApp.java | 6 +-
.../brooklyn/demo/WideAreaCassandraCluster.java | 6 +-
.../brooklyn/demo/NodeJsTodoApplication.java | 12 +-
.../brooklyn/demo/SingleWebServerExample.java | 10 +-
.../demo/WebClusterDatabaseExample.java | 16 +-
.../demo/WebClusterDatabaseExampleApp.java | 16 +-
.../demo/WebClusterDatabaseExampleGroovy.groovy | 8 +-
.../apache/brooklyn/demo/WebClusterExample.java | 4 +-
...lusterDatabaseExampleAppIntegrationTest.java | 6 +-
.../JcloudsBlobStoreBasedObjectStore.java | 4 +-
...AbstractJcloudsSubnetSshMachineLocation.java | 2 +-
.../location/jclouds/BrooklynMachinePool.java | 2 +-
.../jclouds/ComputeServiceRegistryImpl.java | 2 +-
.../jclouds/JcloudsByonLocationResolver.java | 10 +-
.../location/jclouds/JcloudsLocation.java | 22 +-
.../location/jclouds/JcloudsLocationConfig.java | 8 +-
.../jclouds/JcloudsLocationResolver.java | 8 +-
.../jclouds/JcloudsMachineLocation.java | 2 +-
.../location/jclouds/JcloudsMachineNamer.java | 2 +-
...JcloudsPropertiesFromBrooklynProperties.java | 6 +-
.../jclouds/JcloudsSshMachineLocation.java | 6 +-
.../JcloudsLocationSecurityGroupCustomizer.java | 2 +-
.../JcloudsPortForwarderExtension.java | 4 +-
.../zone/AwsAvailabilityZoneExtension.java | 4 +-
.../policy/jclouds/os/CreateUserPolicy.java | 10 +-
.../mgmt/persist/jclouds/BlobStoreCleaner.java | 4 +-
.../persist/jclouds/BlobStoreExpiryTest.java | 6 +-
.../mgmt/persist/jclouds/BlobStoreTest.java | 6 +-
.../JcloudsBlobStoreBasedObjectStoreTest.java | 2 +-
.../jclouds/JcloudsExpect100ContinueTest.java | 2 +-
.../JcloudsObjectStoreAccessorWriterTest.java | 2 +-
.../jclouds/AbstractJcloudsLiveTest.java | 2 +-
.../jclouds/JcloudsAddressesLiveTest.java | 2 +-
.../JcloudsByonLocationResolverTest.java | 2 +-
.../jclouds/JcloudsLocationMetadataTest.java | 4 +-
.../jclouds/JcloudsLocationResolverTest.java | 4 +-
.../location/jclouds/JcloudsLocationTest.java | 8 +-
.../location/jclouds/LiveTestEntity.java | 4 +-
.../jclouds/RebindJcloudsLocationLiveTest.java | 4 +-
.../JcloudsPortForwardingStubbedLiveTest.java | 4 +-
.../provider/AbstractJcloudsLocationTest.java | 2 +-
.../AwsEc2LocationWindowsLiveTest.groovy | 2 +-
.../zone/AwsAvailabilityZoneExtensionTest.java | 2 +-
parent/pom.xml | 2 +-
.../policy/autoscaling/AutoScalerPolicy.java | 12 +-
.../brooklyn/policy/enricher/DeltaEnricher.java | 2 +-
.../policy/enricher/HttpLatencyDetector.java | 14 +-
.../policy/enricher/RollingMeanEnricher.java | 2 +-
.../enricher/RollingTimeWindowMeanEnricher.java | 4 +-
.../enricher/TimeFractionDeltaEnricher.java | 2 +-
.../enricher/TimeWeightedDeltaEnricher.java | 6 +-
.../followthesun/DefaultFollowTheSunModel.java | 2 +-
.../policy/followthesun/FollowTheSunPolicy.java | 6 +-
.../policy/followthesun/FollowTheSunPool.java | 4 +-
.../followthesun/FollowTheSunPoolImpl.java | 6 +-
.../policy/ha/AbstractFailureDetector.java | 6 +-
.../policy/ha/ConditionalSuspendPolicy.java | 4 +-
.../policy/ha/ConnectionFailureDetector.java | 2 +-
.../apache/brooklyn/policy/ha/HASensors.java | 2 +-
.../policy/ha/ServiceFailureDetector.java | 12 +-
.../brooklyn/policy/ha/ServiceReplacer.java | 14 +-
.../brooklyn/policy/ha/ServiceRestarter.java | 16 +-
.../policy/ha/SshMachineFailureDetector.java | 4 +-
.../loadbalancing/BalanceableContainer.java | 2 +-
.../loadbalancing/BalanceableWorkerPool.java | 4 +-
.../BalanceableWorkerPoolImpl.java | 6 +-
.../loadbalancing/LoadBalancingPolicy.java | 6 +-
.../brooklyn/policy/loadbalancing/Movable.java | 8 +-
.../autoscaling/AutoScalerPolicyMetricTest.java | 6 +-
.../autoscaling/AutoScalerPolicyRebindTest.java | 8 +-
.../AutoScalerPolicyReconfigurationTest.java | 4 +-
.../autoscaling/AutoScalerPolicyTest.java | 6 +-
.../autoscaling/LocallyResizableEntity.java | 6 +-
.../policy/enricher/DeltaEnrichersTests.groovy | 12 +-
.../enricher/HttpLatencyDetectorTest.java | 4 +-
.../policy/enricher/RebindEnricherTest.java | 4 +-
.../enricher/RollingMeanEnricherTest.groovy | 12 +-
.../RollingTimeWindowMeanEnricherTest.groovy | 12 +-
.../enricher/TimeFractionDeltaEnricherTest.java | 10 +-
.../AbstractFollowTheSunPolicyTest.java | 8 +-
.../followthesun/FollowTheSunModelTest.java | 2 +-
.../FollowTheSunPolicySoakTest.java | 6 +-
.../followthesun/FollowTheSunPolicyTest.java | 6 +-
.../ha/ConnectionFailureDetectorTest.java | 4 +-
.../brooklyn/policy/ha/HaPolicyRebindTest.java | 8 +-
...ServiceFailureDetectorStabilizationTest.java | 10 +-
.../policy/ha/ServiceFailureDetectorTest.java | 12 +-
.../brooklyn/policy/ha/ServiceReplacerTest.java | 18 +-
.../policy/ha/ServiceRestarterTest.java | 10 +-
.../AbstractLoadBalancingPolicyTest.java | 8 +-
.../BalanceableWorkerPoolTest.java | 8 +-
.../ItemsInContainersGroupTest.java | 6 +-
.../LoadBalancingPolicyConcurrencyTest.java | 4 +-
.../LoadBalancingPolicySoakTest.java | 4 +-
.../loadbalancing/LoadBalancingPolicyTest.java | 4 +-
.../loadbalancing/MockContainerEntity.java | 6 +-
.../loadbalancing/MockContainerEntityImpl.java | 2 +-
.../policy/loadbalancing/MockItemEntity.java | 2 +-
.../loadbalancing/MockItemEntityImpl.java | 2 +-
.../brooklyn/entity/database/Database.groovy | 2 +-
.../entity/database/derby/DerbyDatabase.java | 18 +-
.../database/derby/DerbyDatabaseDriver.java | 2 +-
.../database/derby/DerbyDatabaseSshDriver.java | 8 +-
.../entity/database/derby/DerbySchema.java | 22 +-
.../postgresql/PostgreSqlNodeSaltImpl.java | 28 +-
.../brooklyn/entity/salt/SaltBashCommands.java | 9 +-
.../apache/brooklyn/entity/salt/SaltConfig.java | 18 +-
.../brooklyn/entity/salt/SaltConfigs.java | 10 +-
.../entity/salt/SaltLifecycleEffectorTasks.java | 22 +-
.../brooklyn/entity/salt/SaltStackMaster.java | 15 +-
.../entity/salt/SaltStackMasterImpl.java | 3 +-
.../entity/salt/SaltStackMasterSshDriver.java | 10 +-
.../apache/brooklyn/entity/salt/SaltTasks.java | 33 +-
.../postgresql/PostgreSqlSaltLiveTest.java | 17 +-
.../brooklyn/entity/salt/SaltConfigsTest.java | 7 +-
.../entity/salt/SaltLiveTestSupport.java | 6 +-
.../entity/monitoring/zabbix/ZabbixFeed.java | 20 +-
.../monitoring/zabbix/ZabbixMonitored.java | 4 +-
.../monitoring/zabbix/ZabbixPollConfig.java | 6 +-
.../entity/monitoring/zabbix/ZabbixServer.java | 2 +-
.../monitoring/zabbix/ZabbixServerImpl.java | 10 +-
.../nosql/hazelcast/HazelcastCluster.java | 14 +-
.../nosql/hazelcast/HazelcastClusterImpl.java | 13 +-
.../entity/nosql/hazelcast/HazelcastNode.java | 21 +-
.../nosql/hazelcast/HazelcastNodeImpl.java | 13 +-
.../nosql/hazelcast/HazelcastNodeSshDriver.java | 15 +-
.../nosql/infinispan/Infinispan5Server.java | 12 +-
.../nosql/infinispan/Infinispan5SshDriver.java | 10 +-
.../hazelcast/HazelcastClusterEc2LiveTest.java | 7 +-
.../HazelcastClusterSoftlayerLiveTest.java | 7 +-
.../Infinispan5ServerIntegrationTest.groovy | 12 +-
.../entity/brooklynnode/BrooklynCluster.java | 4 +-
.../brooklynnode/BrooklynClusterImpl.java | 14 +-
.../brooklynnode/BrooklynEntityMirror.java | 2 +-
.../brooklynnode/BrooklynEntityMirrorImpl.java | 20 +-
.../entity/brooklynnode/BrooklynNode.java | 14 +-
.../entity/brooklynnode/BrooklynNodeImpl.java | 32 +-
.../brooklynnode/BrooklynNodeSshDriver.java | 6 +-
.../brooklynnode/RemoteEffectorBuilder.java | 4 +-
.../BrooklynClusterUpgradeEffectorBody.java | 12 +-
.../BrooklynNodeUpgradeEffectorBody.java | 12 +-
.../effector/SelectMasterEffectorBody.java | 6 +-
.../SetHighAvailabilityModeEffectorBody.java | 8 +-
...SetHighAvailabilityPriorityEffectorBody.java | 4 +-
.../brooklyn/entity/chef/ChefAttributeFeed.java | 12 +-
.../entity/chef/ChefAttributePollConfig.java | 2 +-
.../brooklyn/entity/chef/ChefConfigs.java | 2 +-
.../entity/chef/ChefLifecycleEffectorTasks.java | 8 +-
.../brooklyn/entity/chef/ChefSoloDriver.java | 2 +-
.../brooklyn/entity/chef/ChefSoloTasks.java | 2 +-
.../apache/brooklyn/entity/chef/ChefTasks.java | 4 +-
.../entity/chef/KnifeConvergeTaskFactory.java | 2 +-
.../brooklyn/entity/java/JavaAppUtils.java | 8 +-
.../java/JavaSoftwareProcessSshDriver.java | 12 +-
.../entity/java/JmxAttributeSensor.java | 14 +-
.../apache/brooklyn/entity/java/JmxSupport.java | 10 +-
.../brooklyn/entity/java/UsesJavaMXBeans.java | 4 +-
.../apache/brooklyn/entity/java/UsesJmx.java | 8 +-
.../brooklyn/entity/java/VanillaJavaApp.java | 2 +-
.../entity/java/VanillaJavaAppImpl.java | 2 +-
.../entity/machine/MachineAttributes.java | 2 +-
.../brooklyn/entity/machine/MachineEntity.java | 6 +-
.../entity/machine/MachineEntityImpl.java | 10 +-
.../entity/machine/MachineInitTasks.java | 2 +-
.../entity/machine/pool/ServerPool.java | 12 +-
.../entity/machine/pool/ServerPoolImpl.java | 18 +-
.../entity/machine/pool/ServerPoolLocation.java | 4 +-
.../pool/ServerPoolLocationResolver.java | 8 +-
.../base/AbstractSoftwareProcessDriver.java | 8 +-
.../base/AbstractSoftwareProcessSshDriver.java | 14 +-
.../AbstractSoftwareProcessWinRmDriver.java | 4 +-
.../software/base/AbstractVanillaProcess.java | 2 +-
.../SameServerDriverLifecycleEffectorTasks.java | 6 +-
.../entity/software/base/SameServerEntity.java | 10 +-
.../software/base/SameServerEntityImpl.java | 8 +-
.../entity/software/base/SoftwareProcess.java | 16 +-
.../software/base/SoftwareProcessDriver.java | 4 +-
...wareProcessDriverLifecycleEffectorTasks.java | 10 +-
.../software/base/SoftwareProcessImpl.java | 30 +-
.../base/VanillaSoftwareProcessSshDriver.java | 4 +-
.../software/base/VanillaWindowsProcess.java | 2 +-
.../base/VanillaWindowsProcessWinRmDriver.java | 4 +-
.../MachineLifecycleEffectorTasks.java | 32 +-
.../software/base/lifecycle/ScriptHelper.java | 2 +-
.../system_service/EntityLaunchListener.java | 2 +-
.../system_service/InitdServiceInstaller.java | 8 +-
.../system_service/SystemServiceEnricher.java | 10 +-
.../feed/jmx/JmxAttributePollConfig.java | 74 +
.../org/apache/brooklyn/feed/jmx/JmxFeed.java | 423 +++++
.../org/apache/brooklyn/feed/jmx/JmxHelper.java | 724 ++++++++
.../feed/jmx/JmxNotificationFilters.java | 64 +
.../jmx/JmxNotificationSubscriptionConfig.java | 95 +
.../feed/jmx/JmxOperationPollConfig.java | 121 ++
.../brooklyn/feed/jmx/JmxValueFunctions.java | 95 +
.../sensor/feed/jmx/JmxAttributePollConfig.java | 74 -
.../brooklyn/sensor/feed/jmx/JmxFeed.java | 423 -----
.../brooklyn/sensor/feed/jmx/JmxHelper.java | 724 --------
.../sensor/feed/jmx/JmxNotificationFilters.java | 64 -
.../jmx/JmxNotificationSubscriptionConfig.java | 95 -
.../sensor/feed/jmx/JmxOperationPollConfig.java | 121 --
.../sensor/feed/jmx/JmxValueFunctions.java | 95 -
.../brooklyn/sensor/ssh/SshCommandEffector.java | 11 +-
.../brooklyn/sensor/ssh/SshCommandSensor.java | 12 +-
.../brooklyn/sensor/ssh/SshEffectorTasks.java | 334 ----
.../winrm/WindowsPerformanceCounterSensors.java | 8 +-
.../entity/AbstractGoogleComputeLiveTest.java | 4 +-
.../entity/AbstractSoftlayerLiveTest.java | 4 +-
.../BrooklynNodeIntegrationTest.java | 12 +-
.../entity/brooklynnode/BrooklynNodeTest.java | 8 +-
.../entity/brooklynnode/MockBrooklynNode.java | 4 +-
.../brooklynnode/SameBrooklynNodeImpl.java | 8 +-
.../brooklynnode/SelectMasterEffectorTest.java | 12 +-
.../brooklyn/entity/chef/ChefConfigsTest.java | 4 +-
.../entity/chef/ChefLiveTestSupport.java | 2 +-
.../chef/ChefServerTasksIntegrationTest.java | 4 +-
.../ChefSoloDriverMySqlEntityLiveTest.java | 4 +-
.../mysql/ChefSoloDriverToyMySqlEntity.java | 6 +-
.../brooklyn/entity/java/EntityPollingTest.java | 8 +-
...SoftwareProcessSshDriverIntegrationTest.java | 4 +-
.../brooklyn/entity/java/JmxSupportTest.java | 2 +-
.../entity/java/VanillaJavaAppRebindTest.java | 4 +-
.../entity/java/VanillaJavaAppTest.java | 10 +-
.../entity/machine/MachineEntityRebindTest.java | 4 +-
.../machine/pool/AbstractServerPoolTest.java | 8 +-
.../entity/machine/pool/ServerPoolLiveTest.java | 2 +-
.../pool/ServerPoolLocationResolverTest.java | 6 +-
.../machine/pool/ServerPoolRebindTest.java | 2 +-
.../entity/machine/pool/ServerPoolTest.java | 4 +-
.../software/base/AbstractDockerLiveTest.java | 4 +-
...ctSoftwareProcessRestartIntegrationTest.java | 6 +-
.../software/base/DoNothingSoftwareProcess.java | 2 +-
.../base/DoNothingSoftwareProcessDriver.java | 2 +-
.../base/DoNothingSoftwareProcessImpl.java | 2 +-
.../software/base/SameServerEntityTest.java | 2 +-
.../software/base/SoftwareEffectorTest.java | 8 +-
.../base/SoftwareProcessEntityLatchTest.java | 8 +-
.../base/SoftwareProcessEntityRebindTest.java | 14 +-
.../base/SoftwareProcessEntityTest.java | 28 +-
...SoftwareProcessSshDriverIntegrationTest.java | 10 +-
.../base/SoftwareProcessSubclassTest.java | 4 +-
...ftwareProcessAndChildrenIntegrationTest.java | 4 +-
.../MachineLifecycleEffectorTasksTest.java | 14 +-
.../base/lifecycle/ScriptHelperTest.java | 8 +-
.../base/lifecycle/StartStopSshDriverTest.java | 6 +-
.../usage/ApplicationUsageTrackingTest.java | 6 +-
.../mgmt/usage/LocationUsageTrackingTest.java | 4 +-
.../usage/RecordingLegacyUsageListener.java | 2 +-
.../core/mgmt/usage/RecordingUsageListener.java | 2 +-
.../test/core/mgmt/usage/UsageListenerTest.java | 8 +-
.../base/test/driver/MockSshDriver.java | 2 +-
...rWithAvailabilityZonesMultiLocationTest.java | 6 +-
.../software/base/test/jmx/JmxService.java | 4 +-
.../location/MachineDetailsEc2LiveTest.java | 6 +-
.../MachineDetailsGoogleComputeLiveTest.java | 6 +-
.../location/WinRmMachineLocationLiveTest.java | 2 +-
.../test/mysql/AbstractToyMySqlEntityTest.java | 8 +-
.../mysql/DynamicToyMySqlEntityBuilder.java | 8 +-
.../PortAttributeSensorAndConfigKeyTest.java | 4 +-
.../test/ssh/SshCommandIntegrationTest.java | 10 +-
.../SystemServiceEnricherTest.java | 10 +-
.../apache/brooklyn/feed/jmx/JmxFeedTest.java | 422 +++++
.../apache/brooklyn/feed/jmx/JmxHelperTest.java | 311 ++++
.../brooklyn/feed/jmx/RebindJmxFeedTest.java | 148 ++
.../brooklyn/sensor/feed/jmx/JmxFeedTest.java | 422 -----
.../brooklyn/sensor/feed/jmx/JmxHelperTest.java | 311 ----
.../sensor/feed/jmx/RebindJmxFeedTest.java | 148 --
.../sensor/ssh/SshEffectorTasksTest.java | 264 ---
.../entity/database/DatastoreMixins.java | 4 +-
.../entity/database/crate/CrateNode.java | 12 +-
.../entity/database/crate/CrateNodeImpl.java | 12 +-
.../database/crate/CrateNodeSshDriver.java | 4 +-
.../entity/database/mariadb/MariaDbNode.java | 12 +-
.../database/mariadb/MariaDbNodeImpl.java | 10 +-
.../database/mariadb/MariaDbSshDriver.java | 6 +-
.../entity/database/mysql/MySqlCluster.java | 4 +-
.../entity/database/mysql/MySqlClusterImpl.java | 20 +-
.../entity/database/mysql/MySqlNode.java | 18 +-
.../entity/database/mysql/MySqlNodeImpl.java | 10 +-
.../entity/database/mysql/MySqlSshDriver.java | 8 +-
.../database/postgresql/PostgreSqlNode.java | 8 +-
.../PostgreSqlNodeChefImplFromScratch.java | 14 +-
.../database/postgresql/PostgreSqlNodeImpl.java | 2 +-
.../postgresql/PostgreSqlSshDriver.java | 6 +-
.../entity/database/rubyrep/RubyRepNode.java | 8 +-
.../database/rubyrep/RubyRepNodeImpl.java | 4 +-
.../database/rubyrep/RubyRepSshDriver.java | 6 +-
.../crate/CrateNodeIntegrationTest.java | 6 +-
.../mariadb/MariaDbIntegrationTest.java | 4 +-
.../database/postgresql/PostgreSqlChefTest.java | 8 +-
.../postgresql/PostgreSqlIntegrationTest.java | 4 +-
.../postgresql/PostgreSqlRackspaceLiveTest.java | 2 +-
.../database/rubyrep/RubyRepEc2LiveTest.java | 2 +-
.../rubyrep/RubyRepIntegrationTest.java | 6 +-
.../rubyrep/RubyRepRackspaceLiveTest.java | 2 +-
.../entity/messaging/MessageBroker.java | 2 +-
.../apache/brooklyn/entity/messaging/Queue.java | 4 +-
.../apache/brooklyn/entity/messaging/Topic.java | 2 +-
.../messaging/activemq/ActiveMQBroker.java | 10 +-
.../messaging/activemq/ActiveMQBrokerImpl.java | 6 +-
.../activemq/ActiveMQDestinationImpl.java | 6 +-
.../messaging/activemq/ActiveMQQueueImpl.java | 4 +-
.../messaging/activemq/ActiveMQSshDriver.java | 2 +-
.../entity/messaging/amqp/AmqpExchange.java | 2 +-
.../entity/messaging/amqp/AmqpServer.java | 6 +-
.../entity/messaging/jms/JMSBrokerImpl.java | 2 +-
.../messaging/jms/JMSDestinationImpl.java | 2 +-
.../kafka/AbstractfKafkaSshDriver.java | 4 +-
.../brooklyn/entity/messaging/kafka/Kafka.java | 4 +-
.../entity/messaging/kafka/KafkaBroker.java | 6 +-
.../entity/messaging/kafka/KafkaBrokerImpl.java | 8 +-
.../entity/messaging/kafka/KafkaCluster.java | 10 +-
.../messaging/kafka/KafkaClusterImpl.java | 10 +-
.../entity/messaging/kafka/KafkaZooKeeper.java | 6 +-
.../messaging/kafka/KafkaZooKeeperImpl.java | 2 +-
.../kafka/KafkaZooKeeperSshDriver.java | 2 +-
.../entity/messaging/qpid/QpidBroker.java | 6 +-
.../entity/messaging/qpid/QpidBrokerImpl.java | 8 +-
.../messaging/qpid/QpidDestinationImpl.java | 6 +-
.../entity/messaging/qpid/QpidQueueImpl.java | 4 +-
.../entity/messaging/qpid/QpidSshDriver.java | 2 +-
.../entity/messaging/rabbit/RabbitBroker.java | 6 +-
.../messaging/rabbit/RabbitBrokerImpl.java | 2 +-
.../messaging/rabbit/RabbitDestination.java | 2 +-
.../entity/messaging/rabbit/RabbitQueue.java | 6 +-
.../messaging/rabbit/RabbitSshDriver.java | 2 +-
.../brooklyn/entity/messaging/storm/Storm.java | 6 +-
.../entity/messaging/storm/StormDeployment.java | 2 +-
.../messaging/storm/StormDeploymentImpl.java | 4 +-
.../entity/messaging/storm/StormImpl.java | 6 +-
.../entity/messaging/storm/StormSshDriver.java | 10 +-
.../entity/zookeeper/AbstractZooKeeperImpl.java | 6 +-
.../entity/zookeeper/ZooKeeperEnsemble.java | 4 +-
.../entity/zookeeper/ZooKeeperEnsembleImpl.java | 4 +-
.../entity/zookeeper/ZooKeeperNode.java | 6 +-
.../entity/zookeeper/ZooKeeperSshDriver.java | 2 +-
.../messaging/activemq/ActiveMQEc2LiveTest.java | 2 +-
.../activemq/ActiveMQGoogleComputeLiveTest.java | 2 +-
.../activemq/ActiveMQIntegrationTest.java | 6 +-
.../messaging/kafka/KafkaIntegrationTest.java | 6 +-
.../entity/messaging/kafka/KafkaLiveTest.java | 4 +-
.../entity/messaging/kafka/KafkaSupport.java | 2 +-
.../messaging/qpid/QpidIntegrationTest.java | 8 +-
.../messaging/rabbit/RabbitIntegrationTest.java | 6 +-
.../storm/StormAbstractCloudLiveTest.java | 8 +-
.../messaging/storm/StormEc2LiveTest.java | 4 +-
.../zookeeper/ZooKeeperEc2LiveTest.java | 4 +-
.../zookeeper/ZooKeeperEnsembleLiveTest.java | 8 +-
.../entity/monitoring/monit/MonitNode.java | 8 +-
.../entity/monitoring/monit/MonitNodeImpl.java | 6 +-
.../entity/monitoring/monit/MonitSshDriver.java | 2 +-
.../monitoring/monit/MonitIntegrationTest.java | 4 +-
.../entity/network/bind/BindDnsServer.java | 8 +-
.../entity/network/bind/BindDnsServerImpl.java | 6 +-
.../bind/BindDnsServerIntegrationTest.java | 12 +-
.../network/bind/BindDnsServerLiveTest.java | 4 +-
.../bind/DoNothingSoftwareProcessDriver.java | 2 +-
.../network/bind/PrefixAndIdEnricher.java | 6 +-
.../network/bind/TestBindDnsServerImpl.java | 2 +-
.../nosql/cassandra/CassandraDatacenter.java | 10 +-
.../cassandra/CassandraDatacenterImpl.java | 16 +-
.../entity/nosql/cassandra/CassandraFabric.java | 4 +-
.../nosql/cassandra/CassandraFabricImpl.java | 10 +-
.../entity/nosql/cassandra/CassandraNode.java | 10 +-
.../nosql/cassandra/CassandraNodeImpl.java | 26 +-
.../nosql/cassandra/CassandraNodeSshDriver.java | 14 +-
.../nosql/couchbase/CouchbaseCluster.java | 2 +-
.../nosql/couchbase/CouchbaseClusterImpl.java | 26 +-
.../entity/nosql/couchbase/CouchbaseNode.java | 16 +-
.../nosql/couchbase/CouchbaseNodeImpl.java | 16 +-
.../nosql/couchbase/CouchbaseNodeSshDriver.java | 18 +-
.../nosql/couchbase/CouchbaseSyncGateway.java | 6 +-
.../couchbase/CouchbaseSyncGatewayImpl.java | 8 +-
.../CouchbaseSyncGatewaySshDriver.java | 8 +-
.../entity/nosql/couchdb/CouchDBCluster.java | 4 +-
.../entity/nosql/couchdb/CouchDBNode.java | 2 +-
.../entity/nosql/couchdb/CouchDBNodeImpl.java | 6 +-
.../nosql/couchdb/CouchDBNodeSshDriver.java | 2 +-
.../elasticsearch/ElasticSearchCluster.java | 2 +-
.../nosql/elasticsearch/ElasticSearchNode.java | 10 +-
.../elasticsearch/ElasticSearchNodeImpl.java | 10 +-
.../ElasticSearchNodeSshDriver.java | 4 +-
.../nosql/mongodb/AbstractMongoDBServer.java | 6 +-
.../nosql/mongodb/AbstractMongoDBSshDriver.java | 4 +-
.../entity/nosql/mongodb/MongoDBClient.java | 6 +-
.../entity/nosql/mongodb/MongoDBClientImpl.java | 2 +-
.../nosql/mongodb/MongoDBClientSshDriver.java | 6 +-
.../nosql/mongodb/MongoDBClientSupport.java | 3 +-
.../entity/nosql/mongodb/MongoDBReplicaSet.java | 2 +-
.../nosql/mongodb/MongoDBReplicaSetImpl.java | 8 +-
.../entity/nosql/mongodb/MongoDBServer.java | 4 +-
.../entity/nosql/mongodb/MongoDBServerImpl.java | 6 +-
.../entity/nosql/mongodb/ReplicaSetConfig.java | 3 +-
.../sharding/CoLocatedMongoDBRouter.java | 2 +-
.../sharding/CoLocatedMongoDBRouterImpl.java | 8 +-
.../sharding/MongoDBConfigServerCluster.java | 2 +-
.../nosql/mongodb/sharding/MongoDBRouter.java | 2 +-
.../mongodb/sharding/MongoDBRouterCluster.java | 2 +-
.../sharding/MongoDBRouterClusterImpl.java | 4 +-
.../mongodb/sharding/MongoDBRouterImpl.java | 4 +-
.../sharding/MongoDBShardClusterImpl.java | 2 +-
.../sharding/MongoDBShardedDeployment.java | 4 +-
.../sharding/MongoDBShardedDeploymentImpl.java | 18 +-
.../entity/nosql/redis/RedisCluster.java | 2 +-
.../entity/nosql/redis/RedisClusterImpl.java | 14 +-
.../entity/nosql/redis/RedisShardImpl.java | 2 +-
.../brooklyn/entity/nosql/redis/RedisStore.java | 6 +-
.../entity/nosql/redis/RedisStoreImpl.java | 8 +-
.../entity/nosql/redis/RedisStoreSshDriver.java | 2 +-
.../brooklyn/entity/nosql/riak/RiakCluster.java | 4 +-
.../entity/nosql/riak/RiakClusterImpl.java | 20 +-
.../brooklyn/entity/nosql/riak/RiakNode.java | 14 +-
.../entity/nosql/riak/RiakNodeImpl.java | 16 +-
.../entity/nosql/riak/RiakNodeSshDriver.java | 6 +-
.../brooklyn/entity/nosql/solr/SolrServer.java | 8 +-
.../entity/nosql/solr/SolrServerImpl.java | 10 +-
.../entity/nosql/solr/SolrServerSshDriver.java | 2 +-
.../entity/nosql/cassandra/AstyanaxSupport.java | 2 +-
.../CassandraDatacenterIntegrationTest.java | 4 +-
.../cassandra/CassandraDatacenterLiveTest.java | 6 +-
...assandraDatacenterRebindIntegrationTest.java | 2 +-
.../cassandra/CassandraDatacenterTest.java | 4 +-
.../nosql/cassandra/CassandraFabricTest.java | 14 +-
.../cassandra/CassandraNodeIntegrationTest.java | 6 +-
.../nosql/couchbase/CouchbaseOfflineTest.java | 6 +-
.../CouchbaseSyncGatewayEc2LiveTest.java | 2 +-
.../nosql/couchdb/AbstractCouchDBNodeTest.java | 6 +-
.../nosql/couchdb/CouchDBClusterLiveTest.java | 6 +-
.../nosql/couchdb/CouchDBNodeEc2LiveTest.java | 2 +-
.../couchdb/CouchDBNodeIntegrationTest.java | 2 +-
.../nosql/couchdb/CouchDBNodeLiveTest.java | 2 +-
.../entity/nosql/couchdb/JcouchdbSupport.java | 2 +-
.../ElasticSearchClusterIntegrationTest.java | 6 +-
.../ElasticSearchNodeIntegrationTest.java | 10 +-
.../nosql/mongodb/MongoDBIntegrationTest.java | 6 +-
.../mongodb/MongoDBReplicaSetEc2LiveTest.java | 2 +-
.../MongoDBReplicaSetIntegrationTest.java | 2 +-
.../entity/nosql/mongodb/MongoDBTestHelper.java | 3 +-
.../MongoDBConfigServerIntegrationTest.java | 6 +-
.../MongoDBShardedDeploymentEc2LiveTest.java | 2 +-
...MongoDBShardedDeploymentIntegrationTest.java | 2 +-
.../redis/RedisClusterIntegrationTest.java | 6 +-
.../nosql/redis/RedisIntegrationTest.java | 6 +-
.../nosql/riak/RiakClusterEc2LiveTest.java | 2 +-
.../nosql/riak/RiakNodeIntegrationTest.java | 4 +-
.../entity/nosql/solr/SolrJSupport.java | 2 +-
.../nosql/solr/SolrServerEc2LiveTest.java | 2 +-
.../nosql/solr/SolrServerIntegrationTest.java | 4 +-
.../entity/nosql/solr/SolrServerLiveTest.java | 2 +-
.../entity/osgi/karaf/KarafContainer.java | 12 +-
.../entity/osgi/karaf/KarafContainerImpl.java | 14 +-
.../entity/osgi/karaf/KarafSshDriver.java | 2 +-
.../entity/osgi/karaf/KarafContainerTest.java | 8 +-
.../entity/dns/AbstractGeoDnsService.java | 10 +-
.../entity/dns/AbstractGeoDnsServiceImpl.java | 12 +-
.../dns/geoscaling/GeoscalingDnsService.java | 4 +-
.../geoscaling/GeoscalingDnsServiceImpl.java | 6 +-
.../geoscaling/GeoscalingScriptGenerator.java | 2 +-
.../entity/proxy/AbstractController.java | 2 +-
.../entity/proxy/AbstractControllerImpl.java | 16 +-
.../AbstractNonProvisionedControllerImpl.java | 6 +-
.../brooklyn/entity/proxy/LoadBalancer.java | 14 +-
.../entity/proxy/nginx/NginxController.java | 10 +-
.../entity/proxy/nginx/NginxControllerImpl.java | 18 +-
.../entity/proxy/nginx/NginxSshDriver.java | 8 +-
.../brooklyn/entity/proxy/nginx/UrlMapping.java | 6 +-
.../entity/proxy/nginx/UrlMappingImpl.java | 10 +-
.../webapp/ControlledDynamicWebAppCluster.java | 16 +-
.../ControlledDynamicWebAppClusterImpl.java | 20 +-
.../entity/webapp/DynamicWebAppCluster.java | 2 +-
.../entity/webapp/DynamicWebAppClusterImpl.java | 10 +-
.../entity/webapp/DynamicWebAppFabric.java | 2 +-
.../entity/webapp/DynamicWebAppFabricImpl.java | 2 +-
.../entity/webapp/ElasticJavaWebAppService.java | 8 +-
.../entity/webapp/JavaWebAppService.java | 8 +-
.../webapp/JavaWebAppSoftwareProcessImpl.java | 4 +-
.../entity/webapp/JavaWebAppSshDriver.java | 2 +-
.../entity/webapp/WebAppServiceConstants.java | 8 +-
.../entity/webapp/WebAppServiceMethods.java | 4 +-
.../entity/webapp/WebAppServiceMetrics.java | 8 +-
.../entity/webapp/jboss/JBoss6Server.java | 2 +-
.../entity/webapp/jboss/JBoss6ServerImpl.java | 8 +-
.../entity/webapp/jboss/JBoss6SshDriver.java | 4 +-
.../entity/webapp/jboss/JBoss7Server.java | 8 +-
.../entity/webapp/jboss/JBoss7ServerImpl.java | 12 +-
.../entity/webapp/jboss/JBoss7SshDriver.java | 2 +-
.../entity/webapp/jetty/Jetty6Server.java | 4 +-
.../entity/webapp/jetty/Jetty6ServerImpl.java | 8 +-
.../entity/webapp/jetty/Jetty6SshDriver.java | 2 +-
.../webapp/nodejs/NodeJsWebAppService.java | 4 +-
.../webapp/nodejs/NodeJsWebAppServiceImpl.java | 12 +-
.../webapp/nodejs/NodeJsWebAppSshDriver.java | 2 +-
.../entity/webapp/tomcat/Tomcat8Server.java | 2 +-
.../entity/webapp/tomcat/TomcatServer.java | 8 +-
.../entity/webapp/tomcat/TomcatServerImpl.java | 4 +-
.../entity/webapp/tomcat/TomcatSshDriver.java | 2 +-
.../entity/dns/AbstractGeoDnsServiceTest.java | 20 +-
.../geoscaling/GeoscalingIntegrationTest.java | 14 +-
.../GeoscalingScriptGeneratorTest.java | 2 +-
.../entity/proxy/AbstractControllerTest.java | 10 +-
.../brooklyn/entity/proxy/StubAppServer.java | 8 +-
.../brooklyn/entity/proxy/UrlMappingTest.java | 12 +-
.../nginx/NginxClusterIntegrationTest.java | 8 +-
.../nginx/NginxHttpsSslIntegrationTest.java | 8 +-
.../proxy/nginx/NginxIntegrationTest.java | 4 +-
.../proxy/nginx/NginxLightIntegrationTest.java | 6 +-
.../proxy/nginx/NginxRebindIntegrationTest.java | 6 +-
.../nginx/NginxRebindWithHaIntegrationTest.java | 12 +-
.../nginx/NginxUrlMappingIntegrationTest.java | 8 +-
.../proxy/nginx/NginxWebClusterEc2LiveTest.java | 8 +-
.../AbstractWebAppFixtureIntegrationTest.java | 12 +-
...lledDynamicWebAppClusterIntegrationTest.java | 8 +-
.../ControlledDynamicWebAppClusterTest.java | 8 +-
.../entity/webapp/DynamicWebAppClusterTest.java | 10 +-
.../entity/webapp/DynamicWebAppFabricTest.java | 10 +-
.../webapp/ElasticCustomLocationTest.java | 10 +-
...ElasticJavaWebAppServiceIntegrationTest.java | 4 +-
.../webapp/TomcatAutoScalerPolicyTest.java | 2 +-
.../webapp/WebAppConcurrentDeployTest.java | 6 +-
.../webapp/WebAppLiveIntegrationTest.groovy | 8 +-
...namicWebAppClusterRebindIntegrationTest.java | 8 +-
...namicWebAppClusterRebindIntegrationTest.java | 6 +-
.../jboss/JBoss6ServerAwsEc2LiveTest.java | 2 +-
...Boss6ServerNonInheritingIntegrationTest.java | 2 +-
.../jboss/JBoss7ServerAwsEc2LiveTest.java | 2 +-
.../jboss/JBoss7ServerDockerLiveTest.java | 2 +-
...Boss7ServerNonInheritingIntegrationTest.java | 4 +-
.../JBoss7ServerRebindingIntegrationTest.java | 2 +-
...ultiVersionWebAppFixtureIntegrationTest.java | 2 +-
.../Jboss7ServerGoogleComputeLiveTest.java | 2 +-
.../JettyWebAppFixtureIntegrationTest.java | 2 +-
.../NodeJsWebAppFixtureIntegrationTest.java | 7 +-
.../NodeJsWebAppSimpleIntegrationTest.java | 2 +-
.../webapp/tomcat/Tomcat8ServerEc2LiveTest.java | 2 +-
.../tomcat/Tomcat8ServerSoftlayerLiveTest.java | 2 +-
...mcat8ServerWebAppFixtureIntegrationTest.java | 4 +-
.../webapp/tomcat/TomcatServerEc2LiveTest.java | 2 +-
.../tomcat/TomcatServerSoftlayerLiveTest.java | 2 +-
...omcatServerWebAppFixtureIntegrationTest.java | 4 +-
.../test/entity/TestJavaWebAppEntity.java | 8 +-
.../app/ClusterWebServerDatabaseSample.java | 16 +-
.../sample/app/SingleWebServerSample.java | 6 +-
.../app/SampleLocalhostIntegrationTest.java | 4 +-
.../brooklyn/sample/app/SampleUnitTest.java | 4 +-
.../camp/brooklyn/YamlLauncherAbstract.java | 2 +-
.../api/AssemblyTemplateSpecInstantiator.java | 2 +-
.../BrooklynAssemblyTemplateInstantiator.java | 4 +-
.../BrooklynComponentTemplateResolver.java | 4 +-
.../spi/creation/BrooklynEntityMatcher.java | 2 +-
.../creation/BrooklynYamlTypeInstantiator.java | 2 +-
.../brooklyn/spi/creation/CampCatalogUtils.java | 2 +-
.../spi/creation/CampToSpecTransformer.java | 2 +-
.../spi/dsl/BrooklynDslDeferredSupplier.java | 6 +-
.../spi/dsl/methods/BrooklynDslCommon.java | 4 +-
.../brooklyn/spi/dsl/methods/DslComponent.java | 10 +-
.../camp/brooklyn/AbstractYamlRebindTest.java | 4 +-
.../camp/brooklyn/AbstractYamlTest.java | 2 +-
.../BrooklynYamlTypeInstantiatorTest.java | 2 +-
.../camp/brooklyn/ByonLocationsYamlTest.java | 10 +-
.../camp/brooklyn/DslAndRebindYamlTest.java | 8 +-
.../brooklyn/EmptySoftwareProcessYamlTest.java | 2 +-
.../EnrichersSlightlySimplerYamlTest.java | 8 +-
.../camp/brooklyn/EnrichersYamlTest.java | 8 +-
.../camp/brooklyn/EntitiesYamlTest.java | 16 +-
...aWebAppWithDslYamlRebindIntegrationTest.java | 2 +-
.../brooklyn/JavaWebAppsIntegrationTest.java | 6 +-
.../camp/brooklyn/JavaWebAppsMatchingTest.java | 2 +-
.../camp/brooklyn/LocationsYamlTest.java | 2 +-
.../camp/brooklyn/MapReferenceYamlTest.java | 2 +-
.../brooklyn/camp/brooklyn/ObjectsYamlTest.java | 2 +-
.../camp/brooklyn/PoliciesYamlTest.java | 4 +-
.../camp/brooklyn/ReferencedYamlTest.java | 2 +-
.../brooklyn/ReferencingYamlTestEntityImpl.java | 2 +-
.../brooklyn/ReloadBrooklynPropertiesTest.java | 4 +-
.../camp/brooklyn/TestEntityWithInitConfig.java | 6 +-
.../brooklyn/TestEntityWithInitConfigImpl.java | 2 +-
.../camp/brooklyn/TestReferencingEnricher.java | 2 +-
.../camp/brooklyn/TestReferencingPolicy.java | 2 +-
.../TestSensorAndEffectorInitializer.java | 10 +-
.../brooklyn/VanillaBashNetcatYamlTest.java | 12 +-
.../brooklyn/camp/brooklyn/WrapAppTest.java | 2 +-
.../catalog/AbstractCatalogXmlTest.java | 2 +-
.../CatalogOsgiVersionMoreEntityTest.java | 2 +-
.../brooklyn/catalog/CatalogYamlCombiTest.java | 2 +-
.../brooklyn/catalog/CatalogYamlEntityTest.java | 2 +-
.../catalog/CatalogYamlLocationTest.java | 2 +-
.../brooklyn/catalog/CatalogYamlPolicyTest.java | 2 +-
.../brooklyn/catalog/CatalogYamlRebindTest.java | 6 +-
.../catalog/CatalogYamlTemplateTest.java | 2 +-
.../brooklyn/test/lite/CampYamlLiteTest.java | 10 +-
.../test/lite/TestAppAssemblyInstantiator.java | 2 +-
...est-app-with-enrichers-slightly-simpler.yaml | 16 +-
.../test-webapp-with-averaging-enricher.yaml | 4 +-
.../org/apache/brooklyn/cli/CloudExplorer.java | 4 +-
.../main/java/org/apache/brooklyn/cli/Main.java | 12 +-
.../apache/brooklyn/cli/lister/ClassFinder.java | 8 +-
.../brooklyn/cli/lister/ItemDescriptors.java | 2 +-
.../java/org/apache/brooklyn/cli/CliTest.java | 14 +-
.../src/test/resources/ExampleAppInFile.groovy | 2 +-
.../brooklyn/cli/BaseCliIntegrationTest.java | 3 +-
usage/downstream-parent/pom.xml | 4 +-
.../BrooklynJavascriptGuiLauncherTest.java | 2 +-
.../brooklyn/launcher/BrooklynLauncher.java | 10 +-
.../brooklyn/launcher/BrooklynWebServer.java | 2 +-
.../launcher/config/BrooklynGlobalConfig.java | 4 +-
.../entity/basic/VanillaSoftwareYamlTest.java | 2 +-
.../BrooklynEntityMirrorIntegrationTest.java | 6 +-
.../brooklynnode/BrooklynNodeRestTest.java | 8 +-
.../BrooklynLauncherRebindTestFixture.java | 4 +-
.../brooklyn/launcher/BrooklynLauncherTest.java | 2 +-
.../launcher/BrooklynWebServerTest.java | 2 +-
.../brooklyn/launcher/WebAppRunnerTest.java | 4 +-
.../blueprints/AbstractBlueprintTest.java | 6 +-
.../qa/load/SimulatedJBoss7ServerImpl.java | 16 +-
.../qa/load/SimulatedMySqlNodeImpl.java | 6 +-
.../qa/load/SimulatedNginxControllerImpl.java | 10 +-
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 18 +-
.../SoftlayerObtainPrivateLiveTest.java | 8 +-
.../org/apache/brooklyn/qa/load/LoadTest.java | 6 +-
.../webcluster/SinusoidalLoadGenerator.java | 4 +-
.../qa/longevity/webcluster/WebClusterApp.java | 10 +-
.../ApplicationResourceIntegrationTest.java | 6 +-
.../rest/client/BrooklynApiRestClientTest.java | 6 +-
.../resources/AbstractBrooklynRestResource.java | 2 +-
.../rest/resources/ApplicationResource.java | 10 +-
.../rest/resources/EffectorResource.java | 2 +-
.../rest/resources/EntityConfigResource.java | 6 +-
.../brooklyn/rest/resources/EntityResource.java | 2 +-
.../rest/resources/LocationResource.java | 2 +-
.../rest/resources/PolicyConfigResource.java | 2 +-
.../brooklyn/rest/resources/PolicyResource.java | 4 +-
.../brooklyn/rest/resources/SensorResource.java | 6 +-
.../brooklyn/rest/resources/ServerResource.java | 10 +-
.../brooklyn/rest/resources/UsageResource.java | 2 +-
.../rest/transform/ApplicationTransformer.java | 6 +-
.../rest/transform/CatalogTransformer.java | 2 +-
.../rest/transform/EffectorTransformer.java | 2 +-
.../rest/transform/EntityTransformer.java | 2 +-
.../rest/transform/LocationTransformer.java | 6 +-
.../rest/transform/PolicyTransformer.java | 4 +-
.../rest/util/BrooklynRestResourceUtils.java | 18 +-
.../brooklyn/rest/util/EntityLocationUtils.java | 2 +-
.../BrooklynRestApiLauncherTestFixture.java | 2 +-
.../brooklyn/rest/HaMasterCheckFilterTest.java | 2 +-
.../brooklyn/rest/domain/ApplicationTest.java | 2 +-
.../brooklyn/rest/domain/SensorSummaryTest.java | 4 +-
.../ApplicationResourceIntegrationTest.java | 2 +-
.../rest/resources/ApplicationResourceTest.java | 20 +-
.../rest/resources/CatalogResourceTest.java | 2 +-
.../rest/resources/DescendantsTest.java | 4 +-
.../resources/EntityConfigResourceTest.java | 4 +-
.../rest/resources/EntityResourceTest.java | 4 +-
.../rest/resources/LocationResourceTest.java | 2 +-
.../rest/resources/ScriptResourceTest.java | 2 +-
.../SensorResourceIntegrationTest.java | 4 +-
.../rest/resources/SensorResourceTest.java | 6 +-
.../rest/resources/ServerShutdownTest.java | 10 +-
.../rest/resources/UsageResourceTest.java | 2 +-
.../brooklynnode/DeployBlueprintTest.java | 4 +-
.../rest/testing/BrooklynRestApiTest.java | 4 +-
.../rest/testing/BrooklynRestResourceTest.java | 2 +-
.../rest/testing/mocks/CapitalizePolicy.java | 4 +-
.../testing/mocks/NameMatcherGroupImpl.java | 2 +-
.../rest/testing/mocks/RestMockApp.java | 2 +-
.../rest/testing/mocks/RestMockAppBuilder.java | 4 +-
.../testing/mocks/RestMockSimpleEntity.java | 10 +-
.../testing/mocks/RestMockSimplePolicy.java | 2 +-
.../util/BrooklynRestResourceUtilsTest.java | 8 +-
.../rest/util/EntityLocationUtilsTest.java | 8 +-
.../json/BrooklynJacksonSerializerTest.java | 4 +-
.../apache/brooklyn/test/EntityTestUtils.java | 2 +-
.../brooklyn/util/GroovyJavaMethods.groovy | 146 --
.../util/groovy/GroovyJavaMethods.groovy | 146 ++
.../brooklyn/util/groovy/JavadocDummy.java | 30 +
.../brooklyn/util/groovy/LanguageUtils.groovy | 383 ++++
.../brooklyn/util/groovy/TimeExtras.groovy | 83 +
.../brooklyn/util/internal/JavadocDummy.java | 30 -
.../brooklyn/util/internal/LanguageUtils.groovy | 383 ----
.../brooklyn/util/internal/TimeExtras.groovy | 83 -
.../util/groovy/LanguageUtilsTest.groovy | 152 ++
.../brooklyn/util/groovy/PojoTestingFields.java | 28 +
.../brooklyn/util/groovy/TimeExtrasTest.groovy | 49 +
.../util/internal/LanguageUtilsTest.groovy | 154 --
.../util/internal/PojoTestingFields.java | 28 -
.../util/internal/TimeExtrasTest.groovy | 49 -
.../test/osgi/entities/SimpleApplication.java | 2 +-
.../osgi/entities/SimpleApplicationImpl.java | 4 +-
.../test/osgi/entities/SimpleEntityImpl.java | 2 +-
.../test/osgi/entities/SimpleLocation.java | 2 +-
.../test/osgi/entities/SimplePolicy.java | 2 +-
.../test/osgi/entities/more/MoreEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntityImpl.java | 4 +-
.../test/osgi/entities/more/MoreLocation.java | 2 +-
.../test/osgi/entities/more/MorePolicy.java | 2 +-
.../test/osgi/entities/more/MoreTemplate.java | 2 +-
.../test/osgi/entities/more/MoreEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntityImpl.java | 4 +-
.../test/osgi/entities/more/MoreEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntityImpl.java | 4 +-
.../test/osgi/entities/more/MoreLocation.java | 2 +-
.../test/osgi/entities/more/MorePolicy.java | 2 +-
.../test/osgi/entities/more/MoreTemplate.java | 2 +-
.../brooklyn/test/BrooklynLeakListener.java | 89 -
.../brooklyn/test/LoggingVerboseReporter.java | 36 -
.../test/PlatformTestSelectorListener.java | 57 -
.../apache/brooklyn/test/StatusListener.java | 100 -
.../test/TestResourceUnavailableException.java | 140 --
.../apache/brooklyn/test/VerboseReporter.java | 343 ----
.../test/support/BrooklynLeakListener.java | 89 +
.../test/support/LoggingVerboseReporter.java | 36 +
.../support/PlatformTestSelectorListener.java | 57 +
.../brooklyn/test/support/StatusListener.java | 100 +
.../TestResourceUnavailableException.java | 140 ++
.../brooklyn/test/support/VerboseReporter.java | 343 ++++
1547 files changed, 54899 insertions(+), 54913 deletions(-)
----------------------------------------------------------------------
[19/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeed.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeed.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeed.java
deleted file mode 100644
index 3b6324c..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeed.java
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectName;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;
-import org.apache.brooklyn.sensor.feed.PollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-
-/**
- * Provides a feed of attribute values, by polling or subscribing over jmx.
- *
- * Example usage (e.g. in an entity that extends {@link SoftwareProcessImpl}):
- * <pre>
- * {@code
- * private JmxFeed feed;
- *
- * //@Override
- * protected void connectSensors() {
- * super.connectSensors();
- *
- * feed = JmxFeed.builder()
- * .entity(this)
- * .period(500, TimeUnit.MILLISECONDS)
- * .pollAttribute(new JmxAttributePollConfig<Integer>(ERROR_COUNT)
- * .objectName(requestProcessorMbeanName)
- * .attributeName("errorCount"))
- * .pollAttribute(new JmxAttributePollConfig<Boolean>(SERVICE_UP)
- * .objectName(serverMbeanName)
- * .attributeName("Started")
- * .onError(Functions.constant(false)))
- * .build();
- * }
- *
- * {@literal @}Override
- * protected void disconnectSensors() {
- * super.disconnectSensors();
- * if (feed != null) feed.stop();
- * }
- * }
- * </pre>
- *
- * @author aled
- */
-public class JmxFeed extends AbstractFeed {
-
- public static final Logger log = LoggerFactory.getLogger(JmxFeed.class);
-
- public static final long JMX_CONNECTION_TIMEOUT_MS = 120*1000;
-
- public static final ConfigKey<JmxHelper> HELPER = ConfigKeys.newConfigKey(JmxHelper.class, "helper");
- public static final ConfigKey<Boolean> OWN_HELPER = ConfigKeys.newBooleanConfigKey("ownHelper");
- public static final ConfigKey<String> JMX_URI = ConfigKeys.newStringConfigKey("jmxUri");
- public static final ConfigKey<Long> JMX_CONNECTION_TIMEOUT = ConfigKeys.newLongConfigKey("jmxConnectionTimeout");
-
- @SuppressWarnings("serial")
- public static final ConfigKey<SetMultimap<String, JmxAttributePollConfig<?>>> ATTRIBUTE_POLLS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<String, JmxAttributePollConfig<?>>>() {},
- "attributePolls");
-
- @SuppressWarnings("serial")
- public static final ConfigKey<SetMultimap<List<?>, JmxOperationPollConfig<?>>> OPERATION_POLLS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<List<?>, JmxOperationPollConfig<?>>>() {},
- "operationPolls");
-
- @SuppressWarnings("serial")
- public static final ConfigKey<SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>>> NOTIFICATION_SUBSCRIPTIONS = ConfigKeys.newConfigKey(
- new TypeToken<SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>>>() {},
- "notificationPolls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EntityLocal entity;
- private JmxHelper helper;
- private long jmxConnectionTimeout = JMX_CONNECTION_TIMEOUT_MS;
- private long period = 500;
- private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
- private List<JmxAttributePollConfig<?>> attributePolls = Lists.newArrayList();
- private List<JmxOperationPollConfig<?>> operationPolls = Lists.newArrayList();
- private List<JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = Lists.newArrayList();
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = val;
- return this;
- }
- public Builder helper(JmxHelper val) {
- this.helper = val;
- return this;
- }
- public Builder period(Duration duration) {
- return period(duration.toMilliseconds(), TimeUnit.MILLISECONDS);
- }
- public Builder period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public Builder period(long val, TimeUnit units) {
- this.period = val;
- this.periodUnits = units;
- return this;
- }
- public Builder pollAttribute(JmxAttributePollConfig<?> config) {
- attributePolls.add(config);
- return this;
- }
- public Builder pollOperation(JmxOperationPollConfig<?> config) {
- operationPolls.add(config);
- return this;
- }
- public Builder subscribeToNotification(JmxNotificationSubscriptionConfig<?> config) {
- notificationSubscriptions.add(config);
- return this;
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public JmxFeed build() {
- built = true;
- JmxFeed result = new JmxFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("JmxFeed.Builder created, but build() never called");
- }
- }
-
- private final SetMultimap<ObjectName, NotificationListener> notificationListeners = HashMultimap.create();
-
- /**
- * For rebind; do not call directly; use builder
- */
- public JmxFeed() {
- }
-
- protected JmxFeed(Builder builder) {
- super();
- if (builder.helper != null) {
- JmxHelper helper = builder.helper;
- setConfig(HELPER, helper);
- setConfig(OWN_HELPER, false);
- setConfig(JMX_URI, helper.getUrl());
- }
- setConfig(JMX_CONNECTION_TIMEOUT, builder.jmxConnectionTimeout);
-
- SetMultimap<String, JmxAttributePollConfig<?>> attributePolls = HashMultimap.<String,JmxAttributePollConfig<?>>create();
- for (JmxAttributePollConfig<?> config : builder.attributePolls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "rawtypes", "unchecked" })
- JmxAttributePollConfig<?> configCopy = new JmxAttributePollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
- attributePolls.put(configCopy.getObjectName().getCanonicalName() + configCopy.getAttributeName(), configCopy);
- }
- setConfig(ATTRIBUTE_POLLS, attributePolls);
-
- SetMultimap<List<?>, JmxOperationPollConfig<?>> operationPolls = HashMultimap.<List<?>,JmxOperationPollConfig<?>>create();
- for (JmxOperationPollConfig<?> config : builder.operationPolls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "rawtypes", "unchecked" })
- JmxOperationPollConfig<?> configCopy = new JmxOperationPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
- operationPolls.put(configCopy.buildOperationIdentity(), configCopy);
- }
- setConfig(OPERATION_POLLS, operationPolls);
-
- SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = HashMultimap.create();
- for (JmxNotificationSubscriptionConfig<?> config : builder.notificationSubscriptions) {
- if (!config.isEnabled()) continue;
- notificationSubscriptions.put(config.getNotificationFilter(), config);
- }
- setConfig(NOTIFICATION_SUBSCRIPTIONS, notificationSubscriptions);
- initUniqueTag(builder.uniqueTag, attributePolls, operationPolls, notificationSubscriptions);
- }
-
- @Override
- public void setEntity(EntityLocal entity) {
- if (getConfig(HELPER) == null) {
- JmxHelper helper = new JmxHelper(entity);
- setConfig(HELPER, helper);
- setConfig(OWN_HELPER, true);
- setConfig(JMX_URI, helper.getUrl());
- }
- super.setEntity(entity);
- }
-
- public String getJmxUri() {
- return getConfig(JMX_URI);
- }
-
- protected JmxHelper getHelper() {
- return getConfig(HELPER);
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<Object> getPoller() {
- return (Poller<Object>) super.getPoller();
- }
-
- @Override
- protected boolean isConnected() {
- return super.isConnected() && getHelper().isConnected();
- }
-
- @Override
- protected void preStart() {
- /*
- * All actions on the JmxHelper are done async (through the poller's threading) so we don't
- * block on start/rebind if the entity is unreachable
- * (without this we get a 120s pause in JmxHelper.connect restarting)
- */
- final SetMultimap<NotificationFilter, JmxNotificationSubscriptionConfig<?>> notificationSubscriptions = getConfig(NOTIFICATION_SUBSCRIPTIONS);
- final SetMultimap<List<?>, JmxOperationPollConfig<?>> operationPolls = getConfig(OPERATION_POLLS);
- final SetMultimap<String, JmxAttributePollConfig<?>> attributePolls = getConfig(ATTRIBUTE_POLLS);
-
- getPoller().submit(new Callable<Void>() {
- public Void call() {
- getHelper().connect(getConfig(JMX_CONNECTION_TIMEOUT));
- return null;
- }
- @Override public String toString() { return "Connect JMX "+getHelper().getUrl(); }
- });
-
- for (final NotificationFilter filter : notificationSubscriptions.keySet()) {
- getPoller().submit(new Callable<Void>() {
- public Void call() {
- // TODO Could config.getObjectName have wildcards? Is this code safe?
- Set<JmxNotificationSubscriptionConfig<?>> configs = notificationSubscriptions.get(filter);
- NotificationListener listener = registerNotificationListener(configs);
- ObjectName objectName = Iterables.get(configs, 0).getObjectName();
- notificationListeners.put(objectName, listener);
- return null;
- }
- @Override public String toString() { return "Register JMX notifications: "+notificationSubscriptions.get(filter); }
- });
- }
-
- // Setup polling of sensors
- for (final String jmxAttributeName : attributePolls.keys()) {
- registerAttributePoller(attributePolls.get(jmxAttributeName));
- }
-
- // Setup polling of operations
- for (final List<?> operationIdentifier : operationPolls.keys()) {
- registerOperationPoller(operationPolls.get(operationIdentifier));
- }
- }
-
- @Override
- protected void preStop() {
- super.preStop();
-
- for (Map.Entry<ObjectName, NotificationListener> entry : notificationListeners.entries()) {
- unregisterNotificationListener(entry.getKey(), entry.getValue());
- }
- notificationListeners.clear();
- }
-
- @Override
- protected void postStop() {
- super.postStop();
- JmxHelper helper = getHelper();
- Boolean ownHelper = getConfig(OWN_HELPER);
- if (helper != null && ownHelper) helper.terminate();
- }
-
- /**
- * Registers to poll a jmx-operation for an ObjectName, where all the given configs are for the same ObjectName + operation + parameters.
- */
- private void registerOperationPoller(Set<JmxOperationPollConfig<?>> configs) {
- Set<AttributePollHandler<? super Object>> handlers = Sets.newLinkedHashSet();
- long minPeriod = Integer.MAX_VALUE;
-
- final ObjectName objectName = Iterables.get(configs, 0).getObjectName();
- final String operationName = Iterables.get(configs, 0).getOperationName();
- final List<String> signature = Iterables.get(configs, 0).getSignature();
- final List<?> params = Iterables.get(configs, 0).getParams();
-
- for (JmxOperationPollConfig<?> config : configs) {
- handlers.add(new AttributePollHandler<Object>(config, getEntity(), this));
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- }
-
- getPoller().scheduleAtFixedRate(
- new Callable<Object>() {
- public Object call() throws Exception {
- if (log.isDebugEnabled()) log.debug("jmx operation polling for {} sensors at {} -> {}", new Object[] {getEntity(), getJmxUri(), operationName});
- if (signature.size() == params.size()) {
- return getHelper().operation(objectName, operationName, signature, params);
- } else {
- return getHelper().operation(objectName, operationName, params.toArray());
- }
- }
- },
- new DelegatingPollHandler<Object>(handlers), minPeriod);
- }
-
- /**
- * Registers to poll a jmx-attribute for an ObjectName, where all the given configs are for that same ObjectName + attribute.
- */
- private void registerAttributePoller(Set<JmxAttributePollConfig<?>> configs) {
- Set<AttributePollHandler<? super Object>> handlers = Sets.newLinkedHashSet();
- long minPeriod = Integer.MAX_VALUE;
-
- final ObjectName objectName = Iterables.get(configs, 0).getObjectName();
- final String jmxAttributeName = Iterables.get(configs, 0).getAttributeName();
-
- for (JmxAttributePollConfig<?> config : configs) {
- handlers.add(new AttributePollHandler<Object>(config, getEntity(), this));
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- }
-
- // TODO Not good calling this holding the synchronization lock
- getPoller().scheduleAtFixedRate(
- new Callable<Object>() {
- public Object call() throws Exception {
- if (log.isTraceEnabled()) log.trace("jmx attribute polling for {} sensors at {} -> {}", new Object[] {getEntity(), getJmxUri(), jmxAttributeName});
- return getHelper().getAttribute(objectName, jmxAttributeName);
- }
- },
- new DelegatingPollHandler<Object>(handlers), minPeriod);
- }
-
- /**
- * Registers to subscribe to notifications for an ObjectName, where all the given configs are for that same ObjectName + filter.
- */
- private NotificationListener registerNotificationListener(Set<JmxNotificationSubscriptionConfig<?>> configs) {
- final List<AttributePollHandler<? super javax.management.Notification>> handlers = Lists.newArrayList();
-
- final ObjectName objectName = Iterables.get(configs, 0).getObjectName();
- final NotificationFilter filter = Iterables.get(configs, 0).getNotificationFilter();
-
- for (final JmxNotificationSubscriptionConfig<?> config : configs) {
- AttributePollHandler<javax.management.Notification> handler = new AttributePollHandler<javax.management.Notification>(config, getEntity(), this) {
- @Override protected Object transformValueOnSuccess(javax.management.Notification val) {
- if (config.getOnNotification() != null) {
- return config.getOnNotification().apply(val);
- } else {
- Object result = super.transformValueOnSuccess(val);
- if (result instanceof javax.management.Notification)
- return ((javax.management.Notification)result).getUserData();
- return result;
- }
- }
- };
- handlers.add(handler);
- }
- final PollHandler<javax.management.Notification> compoundHandler = new DelegatingPollHandler<javax.management.Notification>(handlers);
-
- NotificationListener listener = new NotificationListener() {
- @Override public void handleNotification(Notification notification, Object handback) {
- compoundHandler.onSuccess(notification);
- }
- };
- getHelper().addNotificationListener(objectName, listener, filter);
-
- return listener;
- }
-
- private void unregisterNotificationListener(ObjectName objectName, NotificationListener listener) {
- try {
- getHelper().removeNotificationListener(objectName, listener);
- } catch (RuntimeException e) {
- log.warn("Failed to unregister listener: "+objectName+", "+listener+"; continuing...", e);
- }
- }
-
- @Override
- public String toString() {
- return "JmxFeed["+(getManagementContext()!=null&&getManagementContext().isRunning()?getJmxUri():"mgmt-not-running")+"]";
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelper.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelper.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelper.java
deleted file mode 100644
index 16e4826..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelper.java
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth;
-import groovy.time.TimeDuration;
-
-import java.io.IOException;
-import java.security.KeyStore;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.JMX;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanServerConnection;
-import javax.management.MalformedObjectNameException;
-import javax.management.NotCompliantMBeanException;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.entity.java.JmxSupport;
-import org.apache.brooklyn.entity.java.UsesJmx;
-import org.apache.brooklyn.util.core.crypto.SecureKeys;
-import org.apache.brooklyn.util.crypto.SslTrustUtils;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.exceptions.RuntimeInterruptedException;
-import org.apache.brooklyn.util.jmx.jmxmp.JmxmpAgent;
-import org.apache.brooklyn.util.repeat.Repeater;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-
-public class JmxHelper {
-
- private static final Logger LOG = LoggerFactory.getLogger(JmxHelper.class);
-
- public static final String JMX_URL_FORMAT = "service:jmx:rmi:///jndi/rmi://%s:%d/%s";
- // first host:port may be ignored, so above is sufficient, but not sure
- public static final String RMI_JMX_URL_FORMAT = "service:jmx:rmi://%s:%d/jndi/rmi://%s:%d/%s";
- // jmxmp
- public static final String JMXMP_URL_FORMAT = "service:jmx:jmxmp://%s:%d";
-
- // Tracks the MBeans we have failed to find, with a set keyed off the url
- private static final Map<String, Set<ObjectName>> notFoundMBeansByUrl = Collections.synchronizedMap(new WeakHashMap<String, Set<ObjectName>>());
-
- public static final Map<String, String> CLASSES = ImmutableMap.<String,String>builder()
- .put("Integer", Integer.TYPE.getName())
- .put("Long", Long.TYPE.getName())
- .put("Boolean", Boolean.TYPE.getName())
- .put("Byte", Byte.TYPE.getName())
- .put("Character", Character.TYPE.getName())
- .put("Double", Double.TYPE.getName())
- .put("Float", Float.TYPE.getName())
- .put("GStringImpl", String.class.getName())
- .put("LinkedHashMap", Map.class.getName())
- .put("TreeMap", Map.class.getName())
- .put("HashMap", Map.class.getName())
- .put("ConcurrentHashMap", Map.class.getName())
- .put("TabularDataSupport", TabularData.class.getName())
- .put("CompositeDataSupport", CompositeData.class.getName())
- .build();
-
- /** constructs a JMX URL suitable for connecting to the given entity, being smart about JMX/RMI vs JMXMP */
- public static String toJmxUrl(EntityLocal entity) {
- String url = entity.getAttribute(UsesJmx.JMX_URL);
- if (url != null) {
- return url;
- } else {
- new JmxSupport(entity, null).setJmxUrl();
- url = entity.getAttribute(UsesJmx.JMX_URL);
- return Preconditions.checkNotNull(url, "Could not find URL for "+entity);
- }
- }
-
- /** constructs an RMI/JMX URL with the given inputs
- * (where the RMI Registry Port should be non-null, and at least one must be non-null) */
- public static String toRmiJmxUrl(String host, Integer jmxRmiServerPort, Integer rmiRegistryPort, String context) {
- if (rmiRegistryPort != null && rmiRegistryPort > 0) {
- if (jmxRmiServerPort!=null && jmxRmiServerPort > 0 && jmxRmiServerPort!=rmiRegistryPort) {
- // we have an explicit known JMX RMI server port (e.g. because we are using the agent),
- // distinct from the RMI registry port
- // (if the ports are the same, it is a short-hand, and don't use this syntax!)
- return String.format(RMI_JMX_URL_FORMAT, host, jmxRmiServerPort, host, rmiRegistryPort, context);
- }
- return String.format(JMX_URL_FORMAT, host, rmiRegistryPort, context);
- } else if (jmxRmiServerPort!=null && jmxRmiServerPort > 0) {
- LOG.warn("No RMI registry port set for "+host+"; attempting to use JMX port for RMI lookup");
- return String.format(JMX_URL_FORMAT, host, jmxRmiServerPort, context);
- } else {
- LOG.warn("No RMI/JMX details set for "+host+"; returning null");
- return null;
- }
- }
-
- /** constructs a JMXMP URL for connecting to the given host and port */
- public static String toJmxmpUrl(String host, Integer jmxmpPort) {
- return "service:jmx:jmxmp://"+host+(jmxmpPort!=null ? ":"+jmxmpPort : "");
- }
-
- final EntityLocal entity;
- final String url;
- final String user;
- final String password;
-
- private volatile transient JMXConnector connector;
- private volatile transient MBeanServerConnection connection;
- private transient boolean triedConnecting;
- private transient boolean failedReconnecting;
- private transient long failedReconnectingTime;
- private int minTimeBetweenReconnectAttempts = 1000;
- private final AtomicBoolean terminated = new AtomicBoolean();
-
- // Tracks the MBeans we have failed to find for this JmsHelper's connection URL (so can log just once for each)
- private final Set<ObjectName> notFoundMBeans;
-
- public JmxHelper(EntityLocal entity) {
- this(toJmxUrl(entity), entity, entity.getAttribute(UsesJmx.JMX_USER), entity.getAttribute(UsesJmx.JMX_PASSWORD));
-
- if (entity.getAttribute(UsesJmx.JMX_URL) == null) {
- entity.setAttribute(UsesJmx.JMX_URL, url);
- }
- }
-
- // TODO split this in to two classes, one for entities, and one entity-neutral
- // (simplifying set of constructors below)
-
- public JmxHelper(String url) {
- this(url, null, null);
- }
-
- public JmxHelper(String url, String user, String password) {
- this(url, null, user, password);
- }
-
- public JmxHelper(String url, EntityLocal entity, String user, String password) {
- this.url = url;
- this.entity = entity;
- this.user = user;
- this.password = password;
-
- synchronized (notFoundMBeansByUrl) {
- Set<ObjectName> set = notFoundMBeansByUrl.get(url);
- if (set == null) {
- set = Collections.synchronizedSet(Collections.newSetFromMap(new WeakHashMap<ObjectName, Boolean>()));
- notFoundMBeansByUrl.put(url, set);
- }
- notFoundMBeans = set;
- }
- }
-
- public void setMinTimeBetweenReconnectAttempts(int val) {
- minTimeBetweenReconnectAttempts = val;
- }
-
- public String getUrl(){
- return url;
- }
-
- // ============== connection related calls =======================
-
- //for tesing purposes
- protected MBeanServerConnection getConnection() {
- return connection;
- }
-
- /**
- * Checks if the JmxHelper is connected. Returned value could be stale as soon
- * as it is received.
- *
- * This method is thread safe.
- *
- * @return true if connected, false otherwise.
- */
- public boolean isConnected() {
- return connection!=null;
- }
-
- /**
- * Reconnects. If it already is connected, it disconnects first.
- *
- * @throws IOException
- */
- public synchronized void reconnectWithRetryDampened() throws IOException {
- // If we've already tried reconnecting very recently, don't try again immediately
- if (failedReconnecting) {
- long timeSince = (System.currentTimeMillis() - failedReconnectingTime);
- if (timeSince < minTimeBetweenReconnectAttempts) {
- String msg = "Not reconnecting to JMX at "+url+" because attempt failed "+Time.makeTimeStringRounded(timeSince)+" ago";
- throw new IllegalStateException(msg);
- }
- }
-
- reconnect();
- }
-
- public synchronized void reconnect() throws IOException {
- disconnect();
-
- try {
- connect();
- failedReconnecting = false;
- } catch (Exception e) {
- if (failedReconnecting) {
- if (LOG.isDebugEnabled()) LOG.debug("unable to re-connect to JMX url (repeated failure): {}: {}", url, e);
- } else {
- LOG.debug("unable to re-connect to JMX url {} (rethrowing): {}", url, e);
- failedReconnecting = true;
- }
- failedReconnectingTime = System.currentTimeMillis();
- throw Throwables.propagate(e);
- }
- }
-
- /** attempts to connect immediately */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public synchronized void connect() throws IOException {
- if (terminated.get()) throw new IllegalStateException("JMX Helper "+this+" already terminated");
- if (connection != null) return;
-
- triedConnecting = true;
- if (connector != null) connector.close();
- JMXServiceURL serviceUrl = new JMXServiceURL(url);
- Map env = getConnectionEnvVars();
- try {
- connector = JMXConnectorFactory.connect(serviceUrl, env);
- } catch (NullPointerException npe) {
- //some software -- eg WSO2 -- will throw an NPE exception if the JMX connection can't be created, instead of an IOException.
- //this is a break of contract with the JMXConnectorFactory.connect method, so this code verifies if the NPE is
- //thrown by a known offender (wso2) and if so replaces the bad exception by a new IOException.
- //ideally WSO2 will fix this bug and we can remove this code.
- boolean thrownByWso2 = npe.getStackTrace()[0].toString().contains("org.wso2.carbon.core.security.CarbonJMXAuthenticator.authenticate");
- if (thrownByWso2) {
- throw new IOException("Failed to connect to url "+url+". NullPointerException is thrown, but replaced by an IOException to fix a WSO2 JMX problem", npe);
- } else {
- throw npe;
- }
- } catch (IOException e) {
- Exceptions.propagateIfFatal(e);
- if (terminated.get()) {
- throw new IllegalStateException("JMX Helper "+this+" already terminated", e);
- } else {
- throw e;
- }
- }
- connection = connector.getMBeanServerConnection();
-
- if (terminated.get()) {
- disconnectNow();
- throw new IllegalStateException("JMX Helper "+this+" already terminated");
- }
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public Map getConnectionEnvVars() {
- Map env = new LinkedHashMap();
-
- if (groovyTruth(user) && groovyTruth(password)) {
- String[] creds = new String[] {user, password};
- env.put(JMXConnector.CREDENTIALS, creds);
- }
-
- if (entity!=null && groovyTruth(entity.getConfig(UsesJmx.JMX_SSL_ENABLED))) {
- env.put("jmx.remote.profiles", JmxmpAgent.TLS_JMX_REMOTE_PROFILES);
-
- PrivateKey key = entity.getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
- Certificate cert = entity.getConfig(UsesJmx.JMX_SSL_ACCESS_CERT);
- KeyStore ks = SecureKeys.newKeyStore();
- try {
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- if (key!=null) {
- ks.setKeyEntry("brooklyn-jmx-access", key, "".toCharArray(), new Certificate[] { cert });
- }
- kmf.init(ks, "".toCharArray());
-
- TrustManager tms =
- // TODO use root cert for trusting server
- //trustStore!=null ? SecureKeys.getTrustManager(trustStore) :
- SslTrustUtils.TRUST_ALL;
-
- SSLContext ctx = SSLContext.getInstance("TLSv1");
- ctx.init(kmf.getKeyManagers(), new TrustManager[] { tms }, null);
- SSLSocketFactory ssf = ctx.getSocketFactory();
- env.put(JmxmpAgent.TLS_SOCKET_FACTORY_PROPERTY, ssf);
-
- } catch (Exception e) {
- LOG.warn("Error setting key "+key+" for "+entity+": "+e, e);
- }
- }
-
- return env;
- }
-
- /**
- * Continuously attempts to connect for at least the indicated amount of time; or indefinitely if -1. This method
- * is useful when you are not sure if the system you are trying to connect to already is up and running.
- *
- * This method doesn't throw an Exception, but returns true on success, false otherwise.
- *
- * TODO: What happens if already connected?
- *
- * @param timeoutMs
- * @return
- */
- public boolean connect(long timeoutMs) {
- if (LOG.isDebugEnabled()) LOG.debug("Connecting to JMX URL: {} ({})", url, ((timeoutMs == -1) ? "indefinitely" : timeoutMs+"ms timeout"));
- long startMs = System.currentTimeMillis();
- long endMs = (timeoutMs == -1) ? Long.MAX_VALUE : (startMs + timeoutMs);
- long currentTime = startMs;
- Throwable lastError = null;
- int attempt = 0;
- while (currentTime <= endMs) {
- currentTime = System.currentTimeMillis();
- if (attempt != 0) sleep(100); //sleep 100 to prevent thrashing and facilitate interruption
- if (LOG.isTraceEnabled()) LOG.trace("trying connection to {} at time {}", url, currentTime);
-
- try {
- connect();
- return true;
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (!terminated.get() && shouldRetryOn(e)) {
- if (LOG.isDebugEnabled()) LOG.debug("Attempt {} failed connecting to {} ({})", new Object[] {attempt + 1, url, e.getMessage()});
- lastError = e;
- } else {
- throw Exceptions.propagate(e);
- }
- }
- attempt++;
- }
- LOG.warn("unable to connect to JMX url: "+url, lastError);
- return false;
- }
-
- private boolean shouldRetryOn(Exception e) {
- // Expect SecurityException, IOException, etc.
- // But can also see things like javax.naming.ServiceUnavailableException with WSO2 app-servers.
- // So let's not try to second guess strange behaviours that future entities will exhibit.
- //
- // However, if it was our request that was invalid then not worth retrying.
-
- if (e instanceof AttributeNotFoundException) return false;
- if (e instanceof InstanceAlreadyExistsException) return false;
- if (e instanceof InstanceNotFoundException) return false;
- if (e instanceof InvalidAttributeValueException) return false;
- if (e instanceof ListenerNotFoundException) return false;
- if (e instanceof MalformedObjectNameException) return false;
- if (e instanceof NotCompliantMBeanException) return false;
- if (e instanceof InterruptedException) return false;
- if (e instanceof RuntimeInterruptedException) return false;
-
- return true;
- }
-
- /**
- * A thread-safe version of {@link #disconnectNow()}.
- *
- * This method is threadsafe.
- */
- public synchronized void disconnect() {
- disconnectNow();
- }
-
- /**
- * Disconnects, preventing subsequent connections to be made. Method doesn't throw an exception.
- *
- * Can safely be called if already disconnected.
- *
- * This method is not threadsafe, but will thus not block if
- * another thread is taking a long time for connections to timeout.
- *
- * Any concurrent requests will likely get an IOException - see
- * {@linkplain http://docs.oracle.com/javase/7/docs/api/javax/management/remote/JMXConnector.html#close()}.
- *
- */
- public void terminate() {
- terminated.set(true);
- disconnectNow();
- }
-
- protected void disconnectNow() {
- triedConnecting = false;
- if (connector != null) {
- if (LOG.isDebugEnabled()) LOG.debug("Disconnecting from JMX URL {}", url);
- try {
- connector.close();
- } catch (Exception e) {
- // close attempts to connect to close cleanly; and if it can't, it throws;
- // often we disconnect as part of shutdown, even if the other side has already stopped --
- // so swallow exceptions (no situations known where we need a clean closure on the remote side)
- if (LOG.isDebugEnabled()) LOG.debug("Caught exception disconnecting from JMX at {} ({})", url, e.getMessage());
- if (LOG.isTraceEnabled()) LOG.trace("Details for exception disconnecting JMX", e);
- } finally {
- connector = null;
- connection = null;
- }
- }
- }
-
- /**
- * Gets a usable MBeanServerConnection.
- *
- * Method is threadsafe.
- *
- * @returns the MBeanServerConnection
- * @throws IllegalStateException if not connected.
- */
- private synchronized MBeanServerConnection getConnectionOrFail() {
- if (isConnected())
- return getConnection();
-
- if (triedConnecting) {
- throw new IllegalStateException("Failed to connect to JMX at "+url);
- } else {
- String msg = "Not connected (and not attempted to connect) to JMX at "+url+
- (failedReconnecting ? (" (last reconnect failure at "+ Time.makeDateString(failedReconnectingTime) + ")") : "");
- throw new IllegalStateException(msg);
- }
- }
-
- private <T> T invokeWithReconnect(Callable<T> task) {
- try {
- return task.call();
- } catch (Exception e) {
- if (shouldRetryOn(e)) {
- try {
- reconnectWithRetryDampened();
- return task.call();
- } catch (Exception e2) {
- throw Throwables.propagate(e2);
- }
- } else {
- throw Throwables.propagate(e);
- }
- }
- }
-
- // ====================== query related calls =======================================
-
- /**
- * Converts from an object name pattern to a real object name, by querying with findMBean;
- * if no matching MBean can be found (or if more than one match found) then returns null.
- * If the supplied object name is not a pattern then just returns that. If the
- */
- public ObjectName toLiteralObjectName(ObjectName objectName) {
- if (checkNotNull(objectName, "objectName").isPattern()) {
- ObjectInstance bean = findMBean(objectName);
- return (bean != null) ? bean.getObjectName() : null;
- } else {
- return objectName;
- }
- }
-
- public Set<ObjectInstance> findMBeans(final ObjectName objectName) {
- return invokeWithReconnect(new Callable<Set<ObjectInstance>>() {
- public Set<ObjectInstance> call() throws Exception {
- return getConnectionOrFail().queryMBeans(objectName, null);
- }});
- }
-
- public ObjectInstance findMBean(ObjectName objectName) {
- Set<ObjectInstance> beans = findMBeans(objectName);
- if (beans.size() == 1) {
- notFoundMBeans.remove(objectName);
- return Iterables.getOnlyElement(beans);
- } else {
- boolean changed = notFoundMBeans.add(objectName);
-
- if (beans.size() > 1) {
- if (changed) {
- LOG.warn("JMX object name query returned {} values for {} at {}; ignoring all",
- new Object[] {beans.size(), objectName.getCanonicalName(), url});
- } else {
- if (LOG.isDebugEnabled()) LOG.debug("JMX object name query returned {} values for {} at {} (repeating); ignoring all",
- new Object[] {beans.size(), objectName.getCanonicalName(), url});
- }
- } else {
- if (changed) {
- LOG.warn("JMX object {} not found at {}", objectName.getCanonicalName(), url);
- } else {
- if (LOG.isDebugEnabled()) LOG.debug("JMX object {} not found at {} (repeating)", objectName.getCanonicalName(), url);
- }
- }
- return null;
- }
- }
-
- public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, Duration timeout) {
- return doesMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
- }
- public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, TimeDuration timeout) {
- return doesMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
- }
-
- public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, long timeoutMillis) {
- return doesMBeanExistsEventually(objectName, timeoutMillis, TimeUnit.MILLISECONDS);
- }
-
- public Set<ObjectInstance> doesMBeanExistsEventually(String objectName, Duration timeout) {
- return doesMBeanExistsEventually(createObjectName(objectName), timeout);
- }
- public Set<ObjectInstance> doesMBeanExistsEventually(String objectName, TimeDuration timeout) {
- return doesMBeanExistsEventually(createObjectName(objectName), timeout);
- }
-
- public Set<ObjectInstance> doesMBeanExistsEventually(String objectName, long timeout, TimeUnit timeUnit) {
- return doesMBeanExistsEventually(createObjectName(objectName), timeout, timeUnit);
- }
-
- /** returns set of beans found, with retry, empty set if none after timeout */
- public Set<ObjectInstance> doesMBeanExistsEventually(final ObjectName objectName, long timeout, TimeUnit timeUnit) {
- final long timeoutMillis = timeUnit.toMillis(timeout);
- final AtomicReference<Set<ObjectInstance>> beans = new AtomicReference<Set<ObjectInstance>>(ImmutableSet.<ObjectInstance>of());
- try {
- Repeater.create("Wait for "+objectName)
- .limitTimeTo(timeout, timeUnit)
- .every(500, TimeUnit.MILLISECONDS)
- .until(new Callable<Boolean>() {
- public Boolean call() {
- connect(timeoutMillis);
- beans.set(findMBeans(objectName));
- return !beans.get().isEmpty();
- }})
- .rethrowException()
- .run();
- return beans.get();
- } catch (Exception e) {
- throw Exceptions.propagate(e);
- }
- }
-
- public void assertMBeanExistsEventually(ObjectName objectName, Duration timeout) {
- assertMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
- }
- public void assertMBeanExistsEventually(ObjectName objectName, TimeDuration timeout) {
- assertMBeanExistsEventually(objectName, timeout.toMilliseconds(), TimeUnit.MILLISECONDS);
- }
-
- public void assertMBeanExistsEventually(ObjectName objectName, long timeoutMillis) {
- assertMBeanExistsEventually(objectName, timeoutMillis, TimeUnit.MILLISECONDS);
- }
-
- public void assertMBeanExistsEventually(ObjectName objectName, long timeout, TimeUnit timeUnit) {
- Set<ObjectInstance> beans = doesMBeanExistsEventually(objectName, timeout, timeUnit);
- if (beans.size() != 1) {
- throw new IllegalStateException("MBean "+objectName+" not found within "+timeout+
- (beans.size() > 1 ? "; found multiple matches: "+beans : ""));
- }
- }
-
- /**
- * Returns a specific attribute for a JMX {@link ObjectName}.
- */
- public Object getAttribute(ObjectName objectName, final String attribute) {
- final ObjectName realObjectName = toLiteralObjectName(objectName);
-
- if (realObjectName != null) {
- Object result = invokeWithReconnect(new Callable<Object>() {
- public Object call() throws Exception {
- return getConnectionOrFail().getAttribute(realObjectName, attribute);
- }});
-
- if (LOG.isTraceEnabled()) LOG.trace("From {}, for jmx attribute {}.{}, got value {}", new Object[] {url, objectName.getCanonicalName(), attribute, result});
- return result;
- } else {
- return null;
- }
- }
-
- public void setAttribute(String objectName, String attribute, Object val) {
- setAttribute(createObjectName(objectName), attribute, val);
- }
-
- public void setAttribute(ObjectName objectName, final String attribute, final Object val) {
- final ObjectName realObjectName = toLiteralObjectName(objectName);
-
- if (realObjectName != null) {
- invokeWithReconnect(new Callable<Void>() {
- public Void call() throws Exception {
- getConnectionOrFail().setAttribute(realObjectName, new javax.management.Attribute(attribute, val));
- return null;
- }});
- if (LOG.isTraceEnabled()) LOG.trace("From {}, for jmx attribute {}.{}, set value {}", new Object[] {url, objectName.getCanonicalName(), attribute, val});
- } else {
- if (LOG.isDebugEnabled()) LOG.debug("From {}, cannot set attribute {}.{}, because mbean not found", new Object[] {url, objectName.getCanonicalName(), attribute});
- }
- }
-
- /** @see #operation(ObjectName, String, Object ...) */
- public Object operation(String objectName, String method, Object... arguments) {
- return operation(createObjectName(objectName), method, arguments);
- }
-
- /**
- * Executes an operation on a JMX {@link ObjectName}.
- */
- public Object operation(ObjectName objectName, final String method, final Object... arguments) {
- final ObjectName realObjectName = toLiteralObjectName(objectName);
- final String[] signature = new String[arguments.length];
- for (int i = 0; i < arguments.length; i++) {
- Class<?> clazz = arguments[i].getClass();
- signature[i] = (CLASSES.containsKey(clazz.getSimpleName()) ? CLASSES.get(clazz.getSimpleName()) : clazz.getName());
- }
-
- Object result = invokeWithReconnect(new Callable<Object>() {
- public Object call() throws Exception {
- return getConnectionOrFail().invoke(realObjectName, method, arguments, signature);
- }});
-
- if (LOG.isTraceEnabled()) LOG.trace("From {}, for jmx operation {}.{}({}), got value {}", new Object[] {url, realObjectName.getCanonicalName(), method, Arrays.asList(arguments),
- result});
- return result;
- }
-
- public void addNotificationListener(String objectName, NotificationListener listener) {
- addNotificationListener(createObjectName(objectName), listener, null);
- }
-
- public void addNotificationListener(String objectName, NotificationListener listener, NotificationFilter filter) {
- addNotificationListener(createObjectName(objectName), listener, filter);
- }
-
- public void addNotificationListener(ObjectName objectName, NotificationListener listener) {
- addNotificationListener(objectName, listener, null);
- }
-
- public void addNotificationListener(final ObjectName objectName, final NotificationListener listener, final NotificationFilter filter) {
- invokeWithReconnect(new Callable<Void>() {
- public Void call() throws Exception {
- getConnectionOrFail().addNotificationListener(objectName, listener, filter, null);
- return null;
- }});
- }
-
- public void removeNotificationListener(String objectName, NotificationListener listener) {
- removeNotificationListener(createObjectName(objectName), listener);
- }
-
- public void removeNotificationListener(final ObjectName objectName, final NotificationListener listener) {
- removeNotificationListener(objectName, listener, null);
- }
-
- public void removeNotificationListener(final ObjectName objectName, final NotificationListener listener, final NotificationFilter filter) {
- if (isConnected()) invokeWithReconnect(new Callable<Void>() {
- public Void call() throws Exception {
- getConnectionOrFail().removeNotificationListener(objectName, listener, filter, null);
- return null;
- }});
- }
-
- public <M> M getProxyObject(String objectName, Class<M> mbeanInterface) {
- return getProxyObject(createObjectName(objectName), mbeanInterface);
- }
-
- public <M> M getProxyObject(ObjectName objectName, Class<M> mbeanInterface) {
- MBeanServerConnection connection = getConnectionOrFail();
- return JMX.newMBeanProxy(connection, objectName, mbeanInterface, false);
- }
-
- public static ObjectName createObjectName(String name) {
- try {
- return new ObjectName(name);
- } catch (MalformedObjectNameException e) {
- throw Throwables.propagate(e);
- }
- }
-
- private static void sleep(long sleepTimeMillis) {
- try {
- Thread.sleep(sleepTimeMillis);
- } catch (InterruptedException e) {
- throw new RuntimeInterruptedException(e);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationFilters.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationFilters.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationFilters.java
deleted file mode 100644
index 182866a..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationFilters.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationFilterSupport;
-
-public class JmxNotificationFilters {
-
- private JmxNotificationFilters() {} // instead use static utility methods
-
- /**
- * Matches the given notification type.
- * @see {@link NotificationFilterSupport#enableType(String)}
- */
- public static NotificationFilter matchesType(String type) {
- return matchesTypes(type);
- }
-
- /**
- * Matches any of the given notification types.
- * @see {@link NotificationFilterSupport#enableType(String)}
- */
- public static NotificationFilter matchesTypes(String... types) {
- NotificationFilterSupport result = new NotificationFilterSupport();
- for (String type : types) {
- result.enableType(type);
- }
- return result;
- }
-
- /**
- * @deprecated since 0.6.0;
- * only works if this brooklyn class is on the classpath of the JVM that your
- * subscribing to notifications on (because it tries to push the filter instance
- * to that JVM). So of very limited use in real-world java processes to be managed.
- * Therefore this will be deleted to avoid people hitting this surprising behaviour.
- */
- @SuppressWarnings("serial")
- public static NotificationFilter matchesTypeRegex(final String typeRegex) {
- return new NotificationFilter() {
- @Override public boolean isNotificationEnabled(Notification notif) {
- return notif.getType().matches(typeRegex);
- }
- };
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationSubscriptionConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationSubscriptionConfig.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationSubscriptionConfig.java
deleted file mode 100644
index 2a99c62..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxNotificationSubscriptionConfig.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import javax.management.MalformedObjectNameException;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.ObjectName;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.FeedConfig;
-import org.apache.brooklyn.util.collections.MutableList;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-
-public class JmxNotificationSubscriptionConfig<T> extends FeedConfig<javax.management.Notification, T, JmxNotificationSubscriptionConfig<T>>{
-
- private ObjectName objectName;
- private NotificationFilter notificationFilter;
- private Function<Notification, T> onNotification;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public JmxNotificationSubscriptionConfig(AttributeSensor<T> sensor) {
- super(sensor);
- onSuccess((Function)Functions.identity());
- }
-
- public JmxNotificationSubscriptionConfig(JmxNotificationSubscriptionConfig<T> other) {
- super(other);
- this.objectName = other.objectName;
- this.notificationFilter = other.notificationFilter;
- this.onNotification = other.onNotification;
- }
-
- public ObjectName getObjectName() {
- return objectName;
- }
-
- public NotificationFilter getNotificationFilter() {
- return notificationFilter;
- }
-
- public Function<Notification, T> getOnNotification() {
- return onNotification;
- }
-
- public JmxNotificationSubscriptionConfig<T> objectName(ObjectName val) {
- this.objectName = val; return this;
- }
-
- public JmxNotificationSubscriptionConfig<T> objectName(String val) {
- try {
- return objectName(new ObjectName(val));
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException("Invalid object name ("+val+")", e);
- }
- }
-
- public JmxNotificationSubscriptionConfig<T> notificationFilter(NotificationFilter val) {
- this.notificationFilter = val; return this;
- }
-
- public JmxNotificationSubscriptionConfig<T> onNotification(Function<Notification,T> val) {
- this.onNotification = val; return this;
- }
-
- @Override
- protected Object toStringPollSource() {
- return objectName;
- }
-
- @Override
- protected MutableList<Object> equalsFields() {
- return super.equalsFields()
- .appendIfNotNull(notificationFilter).appendIfNotNull(onNotification);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxOperationPollConfig.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxOperationPollConfig.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxOperationPollConfig.java
deleted file mode 100644
index b72a4ee..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxOperationPollConfig.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import java.util.Collections;
-import java.util.List;
-
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
-public class JmxOperationPollConfig<T> extends PollConfig<Object, T, JmxOperationPollConfig<T>>{
-
- private ObjectName objectName;
- private String operationName;
- private List<String> signature = Collections.emptyList();
- private List<?> params = Collections.emptyList();
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public JmxOperationPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- onSuccess((Function)Functions.identity());
- }
-
- public JmxOperationPollConfig(JmxOperationPollConfig<T> other) {
- super(other);
- this.objectName = other.objectName;
- this.operationName = other.operationName;
- this.signature = other.signature != null ? ImmutableList.copyOf(other.signature) : null;
- this.params = other.params != null ? ImmutableList.copyOf(other.params) : null;
- }
-
- public ObjectName getObjectName() {
- return objectName;
- }
-
- public String getOperationName() {
- return operationName;
- }
-
- public List<String> getSignature() {
- return signature;
- }
-
- public List<?> getParams() {
- return params;
- }
-
- public JmxOperationPollConfig<T> objectName(ObjectName val) {
- this.objectName = val; return this;
- }
-
- public JmxOperationPollConfig<T> objectName(String val) {
- try {
- return objectName(new ObjectName(val));
- } catch (MalformedObjectNameException e) {
- throw new IllegalArgumentException("Invalid object name ("+val+")", e);
- }
- }
-
- public JmxOperationPollConfig<T> operationName(String val) {
- this.operationName = val; return this;
- }
-
- public JmxOperationPollConfig<T> operationSignature(List<String> val) {
- this.signature = val; return this;
- }
-
- public JmxOperationPollConfig<T> operationParams(List<?> val) {
- this.params = val; return this;
- }
-
- public List<?> buildOperationIdentity() {
- // FIXME Have a build() method for ensuring signature is set, and making class subsequently immutable?
- return ImmutableList.of(operationName, buildSignature(), params);
- }
-
- private List<String> buildSignature() {
- if (signature != null && signature.size() == params.size()) {
- return signature;
- } else {
- List<String> derivedSignature = Lists.newLinkedList();
- for (Object param : params) {
- Class<?> clazz = (param != null) ? param.getClass() : null;
- String clazzName = (clazz != null) ?
- (JmxHelper.CLASSES.containsKey(clazz.getSimpleName()) ?
- JmxHelper.CLASSES.get(clazz.getSimpleName()) : clazz.getName()) :
- Object.class.getName();
- derivedSignature.add(clazzName);
- }
- return derivedSignature;
- }
- }
-
- @Override protected String toStringBaseName() { return "jmx"; }
- @Override protected String toStringPollSource() { return objectName+":"+operationName+(params!=null ? params : "[]"); }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxValueFunctions.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxValueFunctions.java b/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxValueFunctions.java
deleted file mode 100644
index d0b5e21..0000000
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/feed/jmx/JmxValueFunctions.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.jmx;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.TabularData;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-
-public class JmxValueFunctions {
-
- private static final Logger log = LoggerFactory.getLogger(JmxValueFunctions.class);
-
- /**
- * @return a closure that converts a TabularDataSupport to a map.
- */
- public static Function<TabularData, Map> tabularDataToMap() {
- return new Function<TabularData, Map>() {
- @Override public Map apply(TabularData input) {
- return tabularDataToMap(input);
- }};
- }
-
- public static Function<TabularData, Map> tabularDataToMapOfMaps() {
- return new Function<TabularData, Map>() {
- @Override public Map apply(TabularData input) {
- return tabularDataToMapOfMaps(input);
- }};
- }
-
- public static Function<CompositeData,Map> compositeDataToMap() {
- return new Function<CompositeData, Map>() {
- @Override public Map apply(CompositeData input) {
- return compositeDataToMap(input);
- }};
- }
-
- public static Map tabularDataToMap(TabularData table) {
- Map<String, Object> result = Maps.newLinkedHashMap();
- for (Object entry : table.values()) {
- CompositeData data = (CompositeData) entry; //.getValue()
- for (String key : data.getCompositeType().keySet()) {
- Object old = result.put(key, data.get(key));
- if (old != null) {
- log.warn("tablularDataToMap has overwritten key {}", key);
- }
- }
- }
- return result;
- }
-
- public static Map<List<?>, Map<String, Object>> tabularDataToMapOfMaps(TabularData table) {
- Map<List<?>, Map<String, Object>> result = Maps.newLinkedHashMap();
- for (Object k : table.keySet()) {
- final Object[] kValues = ((List<?>)k).toArray();
- CompositeData v = (CompositeData) table.get(kValues);
- result.put((List<?>)k, compositeDataToMap(v));
- }
- return result;
- }
-
- public static Map<String, Object> compositeDataToMap(CompositeData data) {
- Map<String, Object> result = Maps.newLinkedHashMap();
- for (String key : data.getCompositeType().keySet()) {
- Object old = result.put(key, data.get(key));
- if (old != null) {
- log.warn("compositeDataToMap has overwritten key {}", key);
- }
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
index 59dc3c2..31c116f 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
@@ -28,9 +28,9 @@ import org.apache.brooklyn.core.effector.AddSensor;
import org.apache.brooklyn.core.sensor.HttpRequestSensor;
import org.apache.brooklyn.entity.java.JmxAttributeSensor;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java b/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
index ad02ce9..3e0e4c6 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/winrm/WindowsPerformanceCounterSensors.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.sensor.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.text.Strings;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
index 0cfa8f4..1c54ba1 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
@@ -52,7 +52,7 @@ import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.StopNodeAndKillAppsE
import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwareParameters.StopMode;
import org.apache.brooklyn.entity.stock.BasicApplication;
import org.apache.brooklyn.entity.stock.BasicApplicationImpl;
-import org.apache.brooklyn.sensor.feed.http.JsonFunctions;
+import org.apache.brooklyn.feed.http.JsonFunctions;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.test.HttpTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
index 75ca2ff..6c777cf 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
@@ -29,11 +29,11 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeImpl;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeSshDriver;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
index e117651..9fd2e5c 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.EntityHttpClient;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeImpl.DeployBlueprintEffectorBody;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
/** Implementation of BrooklynNode which just presents the node where this is running, for convenience;
*
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
index ff8884b..9669e02 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
@@ -34,6 +34,9 @@ import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.feed.AttributePollHandler;
+import org.apache.brooklyn.core.feed.DelegatingPollHandler;
+import org.apache.brooklyn.core.feed.Poller;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
import org.apache.brooklyn.entity.brooklynnode.BrooklynClusterImpl;
@@ -41,9 +44,6 @@ import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster.SelectMasterEffector;
import org.apache.brooklyn.entity.brooklynnode.CallbackEntityHttpClient.Request;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.feed.AttributePollHandler;
-import org.apache.brooklyn.sensor.feed.DelegatingPollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
index 7d3c895..70b20ad 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
@@ -27,8 +27,8 @@ import org.apache.brooklyn.entity.chef.ChefConfig;
import org.apache.brooklyn.entity.chef.ChefConfigs;
import org.apache.brooklyn.entity.chef.ChefSoloDriver;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
index 17b7f15..eae757a 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
@@ -32,8 +32,8 @@ import org.apache.brooklyn.entity.java.VanillaJavaAppSshDriver;
import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
-import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.feed.jmx.JmxFeed;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppTest.java
index e56243c..20e3e63 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppTest.java
@@ -51,7 +51,7 @@ import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.java.VanillaJavaApp;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/ScriptHelperTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/ScriptHelperTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/ScriptHelperTest.java
index 8c4d37a..080b5c0 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/ScriptHelperTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/ScriptHelperTest.java
@@ -31,8 +31,8 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest;
import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest.MyService;
import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest.MyServiceImpl;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
index ab88f2c..2e23789 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/jmx/JmxService.java
@@ -46,7 +46,7 @@ import mx4j.tools.naming.NamingServiceMBean;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.entity.java.UsesJmx;
-import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.feed.jmx.JmxHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
[10/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterCluster.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterCluster.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterCluster.java
index 9093ac4..a313c1c 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterCluster.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouterCluster.java
@@ -22,8 +22,8 @@ import java.util.Collection;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
@ImplementedBy(MongoDBRouterClusterImpl.class)
public interface MongoDBRouterCluster extends DynamicCluster {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java
index 2752fbe..d48313c 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeployment.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.nosql.mongodb.MongoDBReplicaSet;
import org.apache.brooklyn.entity.nosql.mongodb.MongoDBServer;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
index 5ec9723..cbebbec 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBShardedDeploymentImpl.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.entity.nosql.mongodb.sharding;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
import java.util.Collection;
import java.util.List;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
index 4f13e44..838def8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisClusterImpl.java
@@ -29,8 +29,8 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceProblemsLogic;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
import org.apache.brooklyn.util.exceptions.CompoundRuntimeException;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStore.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStore.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStore.java
index 9f27f5f..6b98b3b 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStore.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/redis/RedisStore.java
@@ -23,10 +23,10 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakCluster.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakCluster.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakCluster.java
index 8ba0658..e6de705 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakCluster.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakCluster.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
index df60e48..d3a9b70 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakClusterImpl.java
@@ -38,9 +38,9 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
index 4b43757..358e8cb 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
@@ -30,11 +30,11 @@ import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
index 9ddabe4..090f36d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeImpl.java
@@ -32,9 +32,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.entity.webapp.WebAppServiceMethods;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
index 1045762..702d595 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/solr/SolrServer.java
@@ -26,12 +26,12 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJavaMXBeans;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeIntegrationTest.java b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeIntegrationTest.java
index ce1553b..831b9a7 100644
--- a/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeIntegrationTest.java
+++ b/software/nosql/src/test/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeIntegrationTest.java
@@ -28,9 +28,9 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.nosql.cassandra.CassandraNode;
import org.apache.brooklyn.entity.nosql.cassandra.AstyanaxSupport.AstyanaxSample;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.test.NetworkingTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
index 7bb7890..e605c08 100644
--- a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
+++ b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
@@ -29,12 +29,12 @@ import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
index bfa91a0..2896b48 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsService.java
@@ -29,7 +29,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.geo.HostGeoInfo;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
index 983fda3..f421df7 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/dns/geoscaling/GeoscalingDnsService.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.entity.dns.AbstractGeoDnsService;
import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@ImplementedBy(GeoscalingDnsServiceImpl.class)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractController.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractController.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractController.java
index 1e8cc84..ec3d7a8 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractController.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/AbstractController.java
@@ -24,9 +24,9 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.group.Cluster;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
index e4d6262..2a81d0d 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
@@ -30,10 +30,10 @@ import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.webapp.WebAppService;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
index 35e28ba..649973d 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
@@ -29,11 +29,11 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.proxy.AbstractController;
import org.apache.brooklyn.entity.proxy.ProxySslConfig;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
index 8ccb4a2..a564121 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
@@ -27,10 +27,10 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.AbstractGroup;
import org.apache.brooklyn.entity.proxy.AbstractController;
import org.apache.brooklyn.entity.proxy.ProxySslConfig;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
index 85a7e97..47d2ee8 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/ControlledDynamicWebAppCluster.java
@@ -32,12 +32,12 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.MemberReplaceable;
import org.apache.brooklyn.core.entity.trait.Resizable;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.group.Cluster;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.group.DynamicGroup;
import org.apache.brooklyn.entity.proxy.LoadBalancer;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppCluster.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppCluster.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppCluster.java
index 8daad8d..c1466d3 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppCluster.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppCluster.java
@@ -22,8 +22,8 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.time.Duration;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabric.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabric.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabric.java
index 2f5fdf5..2feeed7 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabric.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppFabric.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.webapp;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.entity.group.DynamicFabric;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
/**
* DynamicWebAppFabric provide a fabric of clusters, aggregating the entity attributes. Currently totals and averages:
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
index 650b1e9..4f3ca03 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
@@ -29,8 +29,8 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.entity.java.UsesJava;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
public interface JavaWebAppService extends WebAppService, UsesJava {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceConstants.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceConstants.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceConstants.java
index 09be36f..df9b92e 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceConstants.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceConstants.java
@@ -23,9 +23,9 @@ import java.util.Set;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.collect.ImmutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMetrics.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMetrics.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMetrics.java
index 6319089..7264698 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMetrics.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/WebAppServiceMetrics.java
@@ -20,16 +20,16 @@ package org.apache.brooklyn.entity.webapp;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.render.RendererHints;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.math.MathFunctions;
import org.apache.brooklyn.util.text.ByteSizeStrings;
import org.apache.brooklyn.util.time.Duration;
public interface WebAppServiceMetrics {
- public static final org.apache.brooklyn.sensor.core.BasicAttributeSensor<Integer> ERROR_COUNT =
- new org.apache.brooklyn.sensor.core.BasicAttributeSensor<Integer>(Integer.class, "webapp.reqs.errors", "Request errors");
+ public static final org.apache.brooklyn.core.sensor.BasicAttributeSensor<Integer> ERROR_COUNT =
+ new org.apache.brooklyn.core.sensor.BasicAttributeSensor<Integer>(Integer.class, "webapp.reqs.errors", "Request errors");
public static final AttributeSensor<Integer> TOTAL_PROCESSING_TIME = Sensors.newIntegerSensor(
"webapp.reqs.processingTime.total", "Total processing time, reported by webserver (millis)");
public static final AttributeSensor<Integer> MAX_PROCESSING_TIME =
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6Server.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6Server.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6Server.java
index 3e3419d..4b2da35 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6Server.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss6Server.java
@@ -22,10 +22,10 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@Catalog(name="JBoss Application Server 6", description="AS6: an open source Java application server from JBoss", iconUrl="classpath:///jboss-logo.png")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7Server.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7Server.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7Server.java
index 5fc7a23..6a67e45 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7Server.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jboss/JBoss7Server.java
@@ -24,12 +24,12 @@ import org.apache.brooklyn.api.objs.HasShortName;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.JavaClassNames;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6Server.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6Server.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6Server.java
index 1bce7e7..c0fdf2c 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6Server.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/jetty/Jetty6Server.java
@@ -24,11 +24,11 @@ import org.apache.brooklyn.api.objs.HasShortName;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8Server.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8Server.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8Server.java
index d9e2f7f..19a70c9 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8Server.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/Tomcat8Server.java
@@ -22,8 +22,8 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.JavaClassNames;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
index 332c277..72ff1eb 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/tomcat/TomcatServer.java
@@ -25,12 +25,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.javalang.JavaClassNames;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
index 3e8b604..2d75f98 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/StubAppServer.java
@@ -31,7 +31,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableMap;
import com.google.common.base.Throwables;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
index b8e5516..abaa2d6 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/proxy/nginx/NginxHttpsSslIntegrationTest.java
@@ -28,6 +28,7 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.proxy.LoadBalancer;
@@ -36,7 +37,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.JavaWebAppService;
import org.apache.brooklyn.entity.webapp.WebAppService;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.HttpTestUtils;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
----------------------------------------------------------------------
diff --git a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
index 6f2907b..bc53541 100644
--- a/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
+++ b/usage/archetypes/quickstart/src/brooklyn-sample/src/main/java/com/acme/sample/brooklyn/sample/app/ClusterWebServerDatabaseSample.java
@@ -11,6 +11,7 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.group.DynamicCluster;
@@ -22,7 +23,6 @@ import org.apache.brooklyn.entity.webapp.WebAppService;
import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
import org.apache.brooklyn.policy.enricher.HttpLatencyDetector;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.SensorPropagatingEnricher;
import org.apache.brooklyn.sensor.enricher.SensorTransformingEnricher;
import org.apache.brooklyn.util.maven.MavenArtifact;
@@ -32,8 +32,8 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Functions;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.formatString;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.formatString;
/** This sample builds a 3-tier application with an elastic app-server cluster,
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
index 906cbca..52122bf 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/BrooklynDslCommon.java
@@ -35,7 +35,7 @@ import org.apache.brooklyn.camp.brooklyn.spi.dsl.BrooklynDslDeferredSupplier;
import org.apache.brooklyn.camp.brooklyn.spi.dsl.DslUtils;
import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
import org.apache.brooklyn.core.entity.EntityDynamicType;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.ClassCoercionException;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
index c5dd80c..eebc628 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/methods/DslComponent.java
@@ -34,8 +34,8 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.core.mgmt.internal.EntityManagerInternal;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.task.TaskBuilder;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
index 026eeee..79addd4 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/DslAndRebindYamlTest.java
@@ -33,8 +33,8 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.task.Tasks;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
index 2a2fe6b..6816ce2 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EnrichersSlightlySimplerYamlTest.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.webapp.JavaWebAppSoftwareProcess;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.collections.MutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
index f9fe108..6dd636d 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -49,12 +49,12 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.mgmt.internal.EntityManagerInternal;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.software.base.SameServerEntity;
import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
index 85b67af..67f7369 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.testng.Assert;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
index f3f0e50..52dd4cc 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Networking;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
index 9e3e1cd..3c191a1 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedTheeTierApp.java
@@ -18,8 +18,8 @@
*/
package org.apache.brooklyn.qa.load;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.formatString;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.formatString;
import java.util.Collection;
import java.util.List;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
index 136bbf5..f43cdcb 100644
--- a/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
+++ b/usage/qa/src/test/java/org/apache/brooklyn/qa/longevity/webcluster/WebClusterApp.java
@@ -27,12 +27,12 @@ import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.proxy.nginx.NginxController;
import org.apache.brooklyn.entity.webapp.ControlledDynamicWebAppCluster;
import org.apache.brooklyn.entity.webapp.jboss.JBoss7Server;
import org.apache.brooklyn.launcher.BrooklynLauncher;
import org.apache.brooklyn.policy.autoscaling.AutoScalerPolicy;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.util.CommandLineUtil;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index b084505..5bc8df9 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -55,6 +55,7 @@ import org.apache.brooklyn.core.mgmt.entitlement.EntitlementPredicates;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.EntityAndItem;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.StringAndArgument;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.AbstractGroup;
import org.apache.brooklyn.rest.api.ApplicationApi;
import org.apache.brooklyn.rest.domain.ApplicationSpec;
@@ -67,7 +68,6 @@ import org.apache.brooklyn.rest.transform.EntityTransformer;
import org.apache.brooklyn.rest.transform.TaskTransformer;
import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
import org.apache.brooklyn.rest.util.WebResourceUtils;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
index c645874..1976d6f 100644
--- a/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
+++ b/usage/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
@@ -31,12 +31,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.rest.api.SensorApi;
import org.apache.brooklyn.rest.domain.SensorSummary;
import org.apache.brooklyn.rest.filter.HaHotStateRequired;
import org.apache.brooklyn.rest.transform.SensorTransformer;
import org.apache.brooklyn.rest.util.WebResourceUtils;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.task.ValueResolver;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/rest-server/src/test/java/org/apache/brooklyn/rest/domain/SensorSummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/domain/SensorSummaryTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/domain/SensorSummaryTest.java
index c144117..0355def 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/domain/SensorSummaryTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/domain/SensorSummaryTest.java
@@ -35,10 +35,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.rest.transform.SensorTransformer;
-import org.apache.brooklyn.sensor.core.Sensors;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/DescendantsTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/DescendantsTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/DescendantsTest.java
index 3a6eb32..8e11d82 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/DescendantsTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/DescendantsTest.java
@@ -35,12 +35,12 @@ import org.testng.annotations.Test;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.rest.domain.ApplicationSpec;
import org.apache.brooklyn.rest.domain.EntitySpec;
import org.apache.brooklyn.rest.domain.EntitySummary;
import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
import org.apache.brooklyn.rest.testing.mocks.RestMockSimpleEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.text.StringEscapes;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceTest.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceTest.java
index 8d02369..ad606c7 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceTest.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/resources/SensorResourceTest.java
@@ -29,13 +29,13 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.rest.api.SensorApi;
import org.apache.brooklyn.rest.domain.ApplicationSpec;
import org.apache.brooklyn.rest.domain.EntitySpec;
import org.apache.brooklyn.rest.test.config.render.TestRendererHints;
import org.apache.brooklyn.rest.testing.BrooklynRestResourceTest;
import org.apache.brooklyn.rest.testing.mocks.RestMockSimpleEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.HttpTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.stream.Streams;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
index e680bc1..2983f4e 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
@@ -28,12 +28,12 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
public class RestMockSimpleEntity extends SoftwareProcessImpl {
[03/36] incubator-brooklyn git commit: Move SshEffectorTasks into core’s effector.ssh package
Posted by he...@apache.org.
Move SshEffectorTasks into core’s effector.ssh package
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/4820fa46
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/4820fa46
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/4820fa46
Branch: refs/heads/master
Commit: 4820fa46722e980f3b90b55849977c3b115492e0
Parents: 0eab0fa
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 22:35:40 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 19 22:35:40 2015 +0100
----------------------------------------------------------------------
.../effector/core/ssh/SshEffectorTasks.java | 334 +++++++++++++++++++
.../util/core/task/ssh/SshEffectorTasks.java | 329 ------------------
.../brooklyn/util/core/task/ssh/SshTasks.java | 1 +
.../effector/core/ssh/SshEffectorTasksTest.java | 264 +++++++++++++++
.../core/task/ssh/SshEffectorTasksTest.java | 264 ---------------
.../util/core/task/ssh/SshTasksTest.java | 1 +
.../brooklyn/demo/CumulusRDFApplication.java | 2 +-
.../postgresql/PostgreSqlNodeSaltImpl.java | 2 +-
.../entity/salt/SaltLifecycleEffectorTasks.java | 2 +-
.../apache/brooklyn/entity/salt/SaltTasks.java | 2 +-
.../postgresql/PostgreSqlSaltLiveTest.java | 2 +-
.../brooklynnode/BrooklynNodeSshDriver.java | 2 +-
.../BrooklynNodeUpgradeEffectorBody.java | 2 +-
.../entity/chef/ChefLifecycleEffectorTasks.java | 2 +-
.../brooklyn/entity/chef/ChefSoloTasks.java | 2 +-
.../apache/brooklyn/entity/chef/ChefTasks.java | 2 +-
.../java/JavaSoftwareProcessSshDriver.java | 2 +-
.../entity/machine/MachineEntityImpl.java | 2 +-
.../base/AbstractSoftwareProcessSshDriver.java | 2 +-
.../MachineLifecycleEffectorTasks.java | 2 +-
.../brooklyn/sensor/ssh/SshCommandEffector.java | 4 +-
.../ChefSoloDriverMySqlEntityLiveTest.java | 2 +-
.../mysql/ChefSoloDriverToyMySqlEntity.java | 2 +-
.../software/base/SoftwareEffectorTest.java | 4 +-
.../test/mysql/AbstractToyMySqlEntityTest.java | 2 +-
.../mysql/DynamicToyMySqlEntityBuilder.java | 2 +-
.../database/mariadb/MariaDbSshDriver.java | 2 +-
.../entity/database/mysql/MySqlSshDriver.java | 2 +-
.../PostgreSqlNodeChefImplFromScratch.java | 2 +-
.../postgresql/PostgreSqlSshDriver.java | 2 +-
.../database/postgresql/PostgreSqlChefTest.java | 2 +-
.../nosql/cassandra/CassandraNodeSshDriver.java | 2 +-
.../nosql/couchbase/CouchbaseNodeSshDriver.java | 2 +-
.../entity/nosql/riak/RiakNodeSshDriver.java | 2 +-
.../entity/osgi/karaf/KarafContainerTest.java | 2 +-
.../qa/load/SimulatedMySqlNodeImpl.java | 2 +-
36 files changed, 632 insertions(+), 625 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
new file mode 100644
index 0000000..b904ba7
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasks.java
@@ -0,0 +1,334 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.effector.core.ssh;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.StringConfigMap;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigUtils;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.location.internal.LocationInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshTasks;
+import org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.ssh.BashCommands;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Function;
+import com.google.common.collect.Maps;
+
+/**
+ * Conveniences for generating {@link Task} instances to perform SSH activities.
+ * <p>
+ * If the {@link SshMachineLocation machine} is not specified directly it
+ * will be inferred from the {@link Entity} context of either the {@link Effector}
+ * or the current {@link Task}.
+ *
+ * @see SshTasks
+ * @since 0.6.0
+ */
+@Beta
+public class SshEffectorTasks {
+
+ private static final Logger log = LoggerFactory.getLogger(SshEffectorTasks.class);
+
+ public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
+ "Whether to ignore any ssh flags (behaviour constraints) set on the entity or location " +
+ "where this is running, using only flags explicitly specified", false);
+
+ /**
+ * Like {@link EffectorBody} but providing conveniences when in an entity with a single machine location.
+ */
+ public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
+
+ /** convenience for accessing the machine */
+ public SshMachineLocation machine() {
+ return EffectorTasks.getSshMachine(entity());
+ }
+
+ /** convenience for generating an {@link PlainSshExecTaskFactory} which can be further customised if desired, and then (it must be explicitly) queued */
+ public ProcessTaskFactory<Integer> ssh(String ...commands) {
+ return new SshEffectorTaskFactory<Integer>(commands).machine(machine());
+ }
+ }
+
+ /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link EffectorTaskFactory} signature so can be used directly as an impl for an effector,
+ * also injects the machine automatically; can also be used outwith effector contexts, and machine is still injected if it is
+ * run from inside a task at an entity with a single SshMachineLocation */
+ public static class SshEffectorTaskFactory<RET> extends AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements EffectorTaskFactory<RET> {
+
+ public SshEffectorTaskFactory(String ...commands) {
+ super(commands);
+ }
+ public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
+ super(machine, commands);
+ }
+ @Override
+ public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> effector, ConfigBag parameters) {
+ markDirty();
+ if (summary==null) summary(effector.getName()+" (ssh)");
+ machine(EffectorTasks.getSshMachine(entity));
+ return newTask();
+ }
+ @Override
+ public synchronized ProcessTaskWrapper<RET> newTask() {
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ if (machine==null) {
+ if (log.isDebugEnabled())
+ log.debug("Using an ssh task not in an effector without any machine; will attempt to infer the machine: "+this);
+ if (entity!=null)
+ machine(EffectorTasks.getSshMachine(entity));
+ }
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+
+ @Override
+ public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType type) {
+ return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
+ }
+
+ @Override
+ public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
+ return (SshEffectorTaskFactory<Boolean>) super.returningIsExitCodeZero();
+ }
+
+ public SshEffectorTaskFactory<String> requiringZeroAndReturningStdout() {
+ return (SshEffectorTaskFactory<String>) super.requiringZeroAndReturningStdout();
+ }
+
+ public <RET2> SshEffectorTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
+ return (SshEffectorTaskFactory<RET2>) super.returning(resultTransformation);
+ }
+ }
+
+ public static class SshPutEffectorTaskFactory extends SshPutTaskFactory implements EffectorTaskFactory<Void> {
+ public SshPutEffectorTaskFactory(String remoteFile) {
+ super(remoteFile);
+ }
+ public SshPutEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
+ super(machine, remoteFile);
+ }
+ @Override
+ public SshPutTaskWrapper newTask(Entity entity, Effector<Void> effector, ConfigBag parameters) {
+ machine(EffectorTasks.getSshMachine(entity));
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ @Override
+ public SshPutTaskWrapper newTask() {
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ if (machine==null) {
+ if (log.isDebugEnabled())
+ log.debug("Using an ssh put task not in an effector without any machine; will attempt to infer the machine: "+this);
+ if (entity!=null) {
+ machine(EffectorTasks.getSshMachine(entity));
+ }
+
+ }
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ }
+
+ public static class SshFetchEffectorTaskFactory extends SshFetchTaskFactory implements EffectorTaskFactory<String> {
+ public SshFetchEffectorTaskFactory(String remoteFile) {
+ super(remoteFile);
+ }
+ public SshFetchEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
+ super(machine, remoteFile);
+ }
+ @Override
+ public SshFetchTaskWrapper newTask(Entity entity, Effector<String> effector, ConfigBag parameters) {
+ machine(EffectorTasks.getSshMachine(entity));
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ @Override
+ public SshFetchTaskWrapper newTask() {
+ Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ if (machine==null) {
+ if (log.isDebugEnabled())
+ log.debug("Using an ssh fetch task not in an effector without any machine; will attempt to infer the machine: "+this);
+ if (entity!=null)
+ machine(EffectorTasks.getSshMachine(entity));
+ }
+ applySshFlags(getConfig(), entity, getMachine());
+ return super.newTask();
+ }
+ }
+
+ public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
+ return new SshEffectorTaskFactory<Integer>(commands);
+ }
+
+ public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
+ return ssh(commands.toArray(new String[commands.size()]));
+ }
+
+ public static SshPutTaskFactory put(String remoteFile) {
+ return new SshPutEffectorTaskFactory(remoteFile);
+ }
+
+ public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
+ return new SshFetchEffectorTaskFactory(remoteFile);
+ }
+
+ /** task which returns 0 if pid is running */
+ public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
+ return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit code)").allowingNonZeroExitCode();
+ }
+
+ /** task which fails if the given PID is not running */
+ public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
+ return codePidRunning(pid).summary("PID "+pid+" is-running check (required)").requiringExitCodeZero("Process with PID "+pid+" is required to be running");
+ }
+
+ /** as {@link #codePidRunning(Integer)} but returning boolean */
+ public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
+ return codePidRunning(pid).summary("PID "+pid+" is-running check (boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+ public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return Integer.valueOf(0).equals(input.getExitCode()); }
+ });
+ }
+
+
+ /** task which returns 0 if pid in the given file is running;
+ * method accepts wildcards so long as they match a single file on the remote end
+ * <p>
+ * returns 1 if no matching file,
+ * 1 if matching file but no matching process,
+ * and 2 if 2+ matching files */
+ public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final String pidFile) {
+ return ssh(BashCommands.chain(
+ // this fails, but isn't an error
+ BashCommands.requireTest("-f "+pidFile, "The PID file "+pidFile+" does not exist."),
+ // this fails and logs an error picked up later
+ BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", "ERROR: there are multiple matching PID files"),
+ // this fails and logs an error picked up later
+ BashCommands.require("cat "+pidFile, "ERROR: the PID file "+pidFile+" cannot be read (permissions?)."),
+ // finally check the process
+ "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" is-running check (exit code)")
+ .allowingNonZeroExitCode()
+ .addCompletionListener(new Function<ProcessTaskWrapper<?>,Void>() {
+ public Void apply(ProcessTaskWrapper<?> input) {
+ if (input.getStderr().contains("ERROR:"))
+ throw new IllegalStateException("Invalid or inaccessible PID filespec: "+pidFile);
+ return null;
+ }
+ });
+ }
+
+ /** task which fails if the pid in the given file is not running (or if there is no such PID file);
+ * method accepts wildcards so long as they match a single file on the remote end (fails if 0 or 2+ matching files) */
+ public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String pidFile) {
+ return codePidFromFileRunning(pidFile)
+ .summary("PID file "+pidFile+" is-running check (required)")
+ .requiringExitCodeZero("Process with PID from file "+pidFile+" is required to be running");
+ }
+
+ /** as {@link #codePidFromFileRunning(String)} but returning boolean */
+ public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String pidFile) {
+ return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" is-running check (boolean)").
+ returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
+ public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return ((Integer)0).equals(input.getExitCode()); }
+ });
+ }
+
+ /** extracts the values for the main brooklyn.ssh.config.* config keys (i.e. those declared in ConfigKeys)
+ * as declared on the entity, and inserts them in a map using the unprefixed state, for ssh.
+ * <p>
+ * currently this is computed for each call, which may be wasteful, but it is reliable in the face of config changes.
+ * we could cache the Map. note that we do _not_ cache (or even own) the SshTool;
+ * the SshTool is created or re-used by the SshMachineLocation making use of these properties */
+ @Beta
+ public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
+ ConfigBag allConfig = ConfigBag.newInstance();
+
+ StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
+ allConfig.putAll(globalConfig.getAllConfig());
+
+ if (optionalLocation!=null)
+ allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
+
+ allConfig.putAll(((EntityInternal)entity).getAllConfig());
+
+ Map<String, Object> result = Maps.newLinkedHashMap();
+ for (String keyS : allConfig.getAllConfig().keySet()) {
+ if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
+ ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
+
+ Object val = allConfig.getStringKey(keyS);
+
+ /*
+ * NOV 2013 changing this to rely on config above being inserted in the right order,
+ * so entity config will be preferred over location, and location over global.
+ * If that is consistent then remove the lines below.
+ * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
+ */
+
+// // have to use raw config to test whether the config is set
+// Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
+// if (val!=null) {
+// val = entity.getConfig(key);
+// } else {
+// val = globalConfig.getRawConfig(key);
+// if (val!=null) val = globalConfig.getConfig(key);
+// }
+// if (val!=null) {
+ result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
+// }
+ }
+ }
+ return result;
+ }
+
+ private static void applySshFlags(ConfigBag config, Entity entity, Location machine) {
+ if (entity!=null) {
+ if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
+ config.putIfAbsent(getSshFlags(entity, machine));
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
deleted file mode 100644
index 849cd25..0000000
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasks.java
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.core.task.ssh;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.config.ConfigUtils;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.location.internal.LocationInternal;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.EffectorTasks.EffectorTaskFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.internal.AbstractSshExecTaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.internal.PlainSshExecTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.ssh.BashCommands;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-
-/**
- * Conveniences for generating {@link Task} instances to perform SSH activities.
- * <p>
- * If the {@link SshMachineLocation machine} is not specified directly it
- * will be inferred from the {@link Entity} context of either the {@link Effector}
- * or the current {@link Task}.
- *
- * @see SshTasks
- * @since 0.6.0
- */
-@Beta
-public class SshEffectorTasks {
-
- private static final Logger log = LoggerFactory.getLogger(SshEffectorTasks.class);
-
- public static final ConfigKey<Boolean> IGNORE_ENTITY_SSH_FLAGS = ConfigKeys.newBooleanConfigKey("ignoreEntitySshFlags",
- "Whether to ignore any ssh flags (behaviour constraints) set on the entity or location " +
- "where this is running, using only flags explicitly specified", false);
-
- /**
- * Like {@link EffectorBody} but providing conveniences when in an entity with a single machine location.
- */
- public abstract static class SshEffectorBody<T> extends EffectorBody<T> {
-
- /** convenience for accessing the machine */
- public SshMachineLocation machine() {
- return EffectorTasks.getSshMachine(entity());
- }
-
- /** convenience for generating an {@link PlainSshExecTaskFactory} which can be further customised if desired, and then (it must be explicitly) queued */
- public ProcessTaskFactory<Integer> ssh(String ...commands) {
- return new SshEffectorTaskFactory<Integer>(commands).machine(machine());
- }
- }
-
- /** variant of {@link PlainSshExecTaskFactory} which fulfills the {@link EffectorTaskFactory} signature so can be used directly as an impl for an effector,
- * also injects the machine automatically; can also be used outwith effector contexts, and machine is still injected if it is
- * run from inside a task at an entity with a single SshMachineLocation */
- public static class SshEffectorTaskFactory<RET> extends AbstractSshExecTaskFactory<SshEffectorTaskFactory<RET>,RET> implements EffectorTaskFactory<RET> {
-
- public SshEffectorTaskFactory(String ...commands) {
- super(commands);
- }
- public SshEffectorTaskFactory(SshMachineLocation machine, String ...commands) {
- super(machine, commands);
- }
- @Override
- public ProcessTaskWrapper<RET> newTask(Entity entity, Effector<RET> effector, ConfigBag parameters) {
- markDirty();
- if (summary==null) summary(effector.getName()+" (ssh)");
- machine(EffectorTasks.getSshMachine(entity));
- return newTask();
- }
- @Override
- public synchronized ProcessTaskWrapper<RET> newTask() {
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- if (machine==null) {
- if (log.isDebugEnabled())
- log.debug("Using an ssh task not in an effector without any machine; will attempt to infer the machine: "+this);
- if (entity!=null)
- machine(EffectorTasks.getSshMachine(entity));
- }
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
-
- @Override
- public <T2> SshEffectorTaskFactory<T2> returning(ScriptReturnType type) {
- return (SshEffectorTaskFactory<T2>) super.<T2>returning(type);
- }
-
- @Override
- public SshEffectorTaskFactory<Boolean> returningIsExitCodeZero() {
- return (SshEffectorTaskFactory<Boolean>) super.returningIsExitCodeZero();
- }
-
- public SshEffectorTaskFactory<String> requiringZeroAndReturningStdout() {
- return (SshEffectorTaskFactory<String>) super.requiringZeroAndReturningStdout();
- }
-
- public <RET2> SshEffectorTaskFactory<RET2> returning(Function<ProcessTaskWrapper<?>, RET2> resultTransformation) {
- return (SshEffectorTaskFactory<RET2>) super.returning(resultTransformation);
- }
- }
-
- public static class SshPutEffectorTaskFactory extends SshPutTaskFactory implements EffectorTaskFactory<Void> {
- public SshPutEffectorTaskFactory(String remoteFile) {
- super(remoteFile);
- }
- public SshPutEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
- super(machine, remoteFile);
- }
- @Override
- public SshPutTaskWrapper newTask(Entity entity, Effector<Void> effector, ConfigBag parameters) {
- machine(EffectorTasks.getSshMachine(entity));
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- @Override
- public SshPutTaskWrapper newTask() {
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- if (machine==null) {
- if (log.isDebugEnabled())
- log.debug("Using an ssh put task not in an effector without any machine; will attempt to infer the machine: "+this);
- if (entity!=null) {
- machine(EffectorTasks.getSshMachine(entity));
- }
-
- }
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- }
-
- public static class SshFetchEffectorTaskFactory extends SshFetchTaskFactory implements EffectorTaskFactory<String> {
- public SshFetchEffectorTaskFactory(String remoteFile) {
- super(remoteFile);
- }
- public SshFetchEffectorTaskFactory(SshMachineLocation machine, String remoteFile) {
- super(machine, remoteFile);
- }
- @Override
- public SshFetchTaskWrapper newTask(Entity entity, Effector<String> effector, ConfigBag parameters) {
- machine(EffectorTasks.getSshMachine(entity));
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- @Override
- public SshFetchTaskWrapper newTask() {
- Entity entity = BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
- if (machine==null) {
- if (log.isDebugEnabled())
- log.debug("Using an ssh fetch task not in an effector without any machine; will attempt to infer the machine: "+this);
- if (entity!=null)
- machine(EffectorTasks.getSshMachine(entity));
- }
- applySshFlags(getConfig(), entity, getMachine());
- return super.newTask();
- }
- }
-
- public static SshEffectorTaskFactory<Integer> ssh(String ...commands) {
- return new SshEffectorTaskFactory<Integer>(commands);
- }
-
- public static SshEffectorTaskFactory<Integer> ssh(List<String> commands) {
- return ssh(commands.toArray(new String[commands.size()]));
- }
-
- public static SshPutTaskFactory put(String remoteFile) {
- return new SshPutEffectorTaskFactory(remoteFile);
- }
-
- public static SshFetchEffectorTaskFactory fetch(String remoteFile) {
- return new SshFetchEffectorTaskFactory(remoteFile);
- }
-
- /** task which returns 0 if pid is running */
- public static SshEffectorTaskFactory<Integer> codePidRunning(Integer pid) {
- return ssh("ps -p "+pid).summary("PID "+pid+" is-running check (exit code)").allowingNonZeroExitCode();
- }
-
- /** task which fails if the given PID is not running */
- public static SshEffectorTaskFactory<?> requirePidRunning(Integer pid) {
- return codePidRunning(pid).summary("PID "+pid+" is-running check (required)").requiringExitCodeZero("Process with PID "+pid+" is required to be running");
- }
-
- /** as {@link #codePidRunning(Integer)} but returning boolean */
- public static SshEffectorTaskFactory<Boolean> isPidRunning(Integer pid) {
- return codePidRunning(pid).summary("PID "+pid+" is-running check (boolean)").returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
- public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return Integer.valueOf(0).equals(input.getExitCode()); }
- });
- }
-
-
- /** task which returns 0 if pid in the given file is running;
- * method accepts wildcards so long as they match a single file on the remote end
- * <p>
- * returns 1 if no matching file,
- * 1 if matching file but no matching process,
- * and 2 if 2+ matching files */
- public static SshEffectorTaskFactory<Integer> codePidFromFileRunning(final String pidFile) {
- return ssh(BashCommands.chain(
- // this fails, but isn't an error
- BashCommands.requireTest("-f "+pidFile, "The PID file "+pidFile+" does not exist."),
- // this fails and logs an error picked up later
- BashCommands.requireTest("`ls "+pidFile+" | wc -w` -eq 1", "ERROR: there are multiple matching PID files"),
- // this fails and logs an error picked up later
- BashCommands.require("cat "+pidFile, "ERROR: the PID file "+pidFile+" cannot be read (permissions?)."),
- // finally check the process
- "ps -p `cat "+pidFile+"`")).summary("PID file "+pidFile+" is-running check (exit code)")
- .allowingNonZeroExitCode()
- .addCompletionListener(new Function<ProcessTaskWrapper<?>,Void>() {
- public Void apply(ProcessTaskWrapper<?> input) {
- if (input.getStderr().contains("ERROR:"))
- throw new IllegalStateException("Invalid or inaccessible PID filespec: "+pidFile);
- return null;
- }
- });
- }
-
- /** task which fails if the pid in the given file is not running (or if there is no such PID file);
- * method accepts wildcards so long as they match a single file on the remote end (fails if 0 or 2+ matching files) */
- public static SshEffectorTaskFactory<?> requirePidFromFileRunning(String pidFile) {
- return codePidFromFileRunning(pidFile)
- .summary("PID file "+pidFile+" is-running check (required)")
- .requiringExitCodeZero("Process with PID from file "+pidFile+" is required to be running");
- }
-
- /** as {@link #codePidFromFileRunning(String)} but returning boolean */
- public static SshEffectorTaskFactory<Boolean> isPidFromFileRunning(String pidFile) {
- return codePidFromFileRunning(pidFile).summary("PID file "+pidFile+" is-running check (boolean)").
- returning(new Function<ProcessTaskWrapper<?>, Boolean>() {
- public Boolean apply(@Nullable ProcessTaskWrapper<?> input) { return ((Integer)0).equals(input.getExitCode()); }
- });
- }
-
- /** extracts the values for the main brooklyn.ssh.config.* config keys (i.e. those declared in ConfigKeys)
- * as declared on the entity, and inserts them in a map using the unprefixed state, for ssh.
- * <p>
- * currently this is computed for each call, which may be wasteful, but it is reliable in the face of config changes.
- * we could cache the Map. note that we do _not_ cache (or even own) the SshTool;
- * the SshTool is created or re-used by the SshMachineLocation making use of these properties */
- @Beta
- public static Map<String, Object> getSshFlags(Entity entity, Location optionalLocation) {
- ConfigBag allConfig = ConfigBag.newInstance();
-
- StringConfigMap globalConfig = ((EntityInternal)entity).getManagementContext().getConfig();
- allConfig.putAll(globalConfig.getAllConfig());
-
- if (optionalLocation!=null)
- allConfig.putAll(((LocationInternal)optionalLocation).config().getBag());
-
- allConfig.putAll(((EntityInternal)entity).getAllConfig());
-
- Map<String, Object> result = Maps.newLinkedHashMap();
- for (String keyS : allConfig.getAllConfig().keySet()) {
- if (keyS.startsWith(SshTool.BROOKLYN_CONFIG_KEY_PREFIX)) {
- ConfigKey<?> key = ConfigKeys.newConfigKey(Object.class, keyS);
-
- Object val = allConfig.getStringKey(keyS);
-
- /*
- * NOV 2013 changing this to rely on config above being inserted in the right order,
- * so entity config will be preferred over location, and location over global.
- * If that is consistent then remove the lines below.
- * (We can also accept null entity and so combine with SshTasks.getSshFlags.)
- */
-
-// // have to use raw config to test whether the config is set
-// Object val = ((EntityInternal)entity).getConfigMap().getRawConfig(key);
-// if (val!=null) {
-// val = entity.getConfig(key);
-// } else {
-// val = globalConfig.getRawConfig(key);
-// if (val!=null) val = globalConfig.getConfig(key);
-// }
-// if (val!=null) {
- result.put(ConfigUtils.unprefixedKey(SshTool.BROOKLYN_CONFIG_KEY_PREFIX, key).getName(), val);
-// }
- }
- }
- return result;
- }
-
- private static void applySshFlags(ConfigBag config, Entity entity, Location machine) {
- if (entity!=null) {
- if (!config.get(IGNORE_ENTITY_SSH_FLAGS)) {
- config.putIfAbsent(getSshFlags(entity, machine));
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
index 022b52b..10eea13 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/task/ssh/SshTasks.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.config.ConfigUtils;
import org.apache.brooklyn.core.location.AbstractLocation;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
new file mode 100644
index 0000000..597d267
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/effector/core/ssh/SshEffectorTasksTest.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.effector.core.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.io.Files;
+
+public class SshEffectorTasksTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
+
+ TestApplication app;
+ ManagementContext mgmt;
+ SshMachineLocation host;
+ File tempDir;
+
+ boolean failureExpected;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setup() throws Exception {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ mgmt = app.getManagementContext();
+
+ LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+ host = lhc.obtain();
+ app.start(Arrays.asList(host));
+ clearExpectedFailure();
+ tempDir = Files.createTempDir();
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (mgmt != null) Entities.destroyAll(mgmt);
+ mgmt = null;
+ FileUtils.deleteDirectory(tempDir);
+ checkExpectedFailure();
+ }
+
+ protected void checkExpectedFailure() {
+ if (failureExpected) {
+ clearExpectedFailure();
+ Assert.fail("Test should have thrown an exception but it did not.");
+ }
+ }
+
+ protected void clearExpectedFailure() {
+ failureExpected = false;
+ }
+
+ protected void setExpectingFailure() {
+ failureExpected = true;
+ }
+
+ public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
+ return Entities.submit(app, taskFactory);
+ }
+
+ // ------------------- basic ssh
+
+ @Test(groups="Integration")
+ public void testSshEchoHello() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
+ Assert.assertFalse(t.isDone());
+ Assert.assertEquals(t.get(), (Integer)0);
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ Assert.assertEquals(t.getStdout().trim(), "hello world");
+ }
+
+ @Test(groups="Integration")
+ public void testSshPut() throws IOException {
+ String fn = Urls.mergePaths(tempDir.getPath(), "f1");
+ SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
+ t.block();
+ Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
+ // and make sure this doesn't throw
+ Assert.assertTrue(t.isDone());
+ Assert.assertTrue(t.isSuccessful());
+ Assert.assertEquals(t.get(), null);
+ Assert.assertEquals(t.getExitCode(), (Integer)0);
+ }
+
+ @Test(groups="Integration")
+ public void testSshFetch() throws IOException {
+ String fn = Urls.mergePaths(tempDir.getPath(), "f2");
+ FileUtils.write(new File(fn), "hello fetched world");
+
+ SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
+ t.block();
+
+ Assert.assertTrue(t.isDone());
+ Assert.assertEquals(t.get(), "hello fetched world");
+ }
+
+ // ----------------- pid stuff
+
+ @Test(groups="Integration")
+ public void testNonRunningPid() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
+ Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
+ Assert.assertNotEquals(t.getExitCode(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
+ Assert.assertFalse(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testNonRunningPidRequired() {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ }
+ checkExpectedFailure();
+ }
+
+ public static Integer getMyPid() {
+ try {
+ java.lang.management.RuntimeMXBean runtime =
+ java.lang.management.ManagementFactory.getRuntimeMXBean();
+ java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
+ jvm.setAccessible(true);
+// sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+ Object mgmt = jvm.get(runtime);
+ java.lang.reflect.Method pid_method =
+ mgmt.getClass().getDeclaredMethod("getProcessId");
+ pid_method.setAccessible(true);
+
+ return (Integer) pid_method.invoke(mgmt);
+ } catch (Exception e) {
+ throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
+ }
+ }
+
+ @Test(groups="Integration")
+ public void testRunningPid() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
+ Assert.assertTrue(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testRunningPidFromFile() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
+ Assert.assertTrue(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailure() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( "99999".getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)1);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)1);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)2);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnSuccess() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+
+ t.getTask().getUnchecked();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
+
+ t.getTask().getUnchecked();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
deleted file mode 100644
index 92f45d7..0000000
--- a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshEffectorTasksTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.util.core.task.ssh;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.TaskAdaptable;
-import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
-import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
-import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
-import org.apache.brooklyn.util.net.Urls;
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-
-import com.google.common.io.Files;
-
-public class SshEffectorTasksTest {
-
- private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
-
- TestApplication app;
- ManagementContext mgmt;
- SshMachineLocation host;
- File tempDir;
-
- boolean failureExpected;
-
- @BeforeMethod(alwaysRun=true)
- public void setup() throws Exception {
- app = TestApplication.Factory.newManagedInstanceForTests();
- mgmt = app.getManagementContext();
-
- LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
- host = lhc.obtain();
- app.start(Arrays.asList(host));
- clearExpectedFailure();
- tempDir = Files.createTempDir();
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (mgmt != null) Entities.destroyAll(mgmt);
- mgmt = null;
- FileUtils.deleteDirectory(tempDir);
- checkExpectedFailure();
- }
-
- protected void checkExpectedFailure() {
- if (failureExpected) {
- clearExpectedFailure();
- Assert.fail("Test should have thrown an exception but it did not.");
- }
- }
-
- protected void clearExpectedFailure() {
- failureExpected = false;
- }
-
- protected void setExpectingFailure() {
- failureExpected = true;
- }
-
- public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
- return Entities.submit(app, taskFactory);
- }
-
- // ------------------- basic ssh
-
- @Test(groups="Integration")
- public void testSshEchoHello() {
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
- Assert.assertFalse(t.isDone());
- Assert.assertEquals(t.get(), (Integer)0);
- Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
- Assert.assertEquals(t.getStdout().trim(), "hello world");
- }
-
- @Test(groups="Integration")
- public void testSshPut() throws IOException {
- String fn = Urls.mergePaths(tempDir.getPath(), "f1");
- SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
- t.block();
- Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
- // and make sure this doesn't throw
- Assert.assertTrue(t.isDone());
- Assert.assertTrue(t.isSuccessful());
- Assert.assertEquals(t.get(), null);
- Assert.assertEquals(t.getExitCode(), (Integer)0);
- }
-
- @Test(groups="Integration")
- public void testSshFetch() throws IOException {
- String fn = Urls.mergePaths(tempDir.getPath(), "f2");
- FileUtils.write(new File(fn), "hello fetched world");
-
- SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
- t.block();
-
- Assert.assertTrue(t.isDone());
- Assert.assertEquals(t.get(), "hello fetched world");
- }
-
- // ----------------- pid stuff
-
- @Test(groups="Integration")
- public void testNonRunningPid() {
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
- Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
- Assert.assertNotEquals(t.getExitCode(), (Integer)0);
- ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
- Assert.assertFalse(t2.getTask().getUnchecked());
- }
-
- @Test(groups="Integration")
- public void testNonRunningPidRequired() {
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- }
- checkExpectedFailure();
- }
-
- public static Integer getMyPid() {
- try {
- java.lang.management.RuntimeMXBean runtime =
- java.lang.management.ManagementFactory.getRuntimeMXBean();
- java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
- jvm.setAccessible(true);
-// sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
- Object mgmt = jvm.get(runtime);
- java.lang.reflect.Method pid_method =
- mgmt.getClass().getDeclaredMethod("getProcessId");
- pid_method.setAccessible(true);
-
- return (Integer) pid_method.invoke(mgmt);
- } catch (Exception e) {
- throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
- }
- }
-
- @Test(groups="Integration")
- public void testRunningPid() {
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
- Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
- ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
- Assert.assertTrue(t2.getTask().getUnchecked());
- }
-
- @Test(groups="Integration")
- public void testRunningPidFromFile() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( (""+getMyPid()).getBytes(), f );
- ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
- Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
- ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
- Assert.assertTrue(t2.getTask().getUnchecked());
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnFailure() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( "99999".getBytes(), f );
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- Assert.assertEquals(t.getExitCode(), (Integer)1);
- }
- checkExpectedFailure();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
-
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- Assert.assertEquals(t.getExitCode(), (Integer)1);
- }
- checkExpectedFailure();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
-
- setExpectingFailure();
- try {
- t.getTask().getUnchecked();
- } catch (Exception e) {
- log.info("The error if required PID is not found is: "+e);
- clearExpectedFailure();
- Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
- Assert.assertEquals(t.getExitCode(), (Integer)2);
- }
- checkExpectedFailure();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnSuccess() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( (""+getMyPid()).getBytes(), f );
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
-
- t.getTask().getUnchecked();
- }
-
- @Test(groups="Integration")
- public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
- File f = File.createTempFile("testBrooklynPid", ".pid");
- Files.write( (""+getMyPid()).getBytes(), f );
- ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
-
- t.getTask().getUnchecked();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
index 3ef139e..6b6c0b1 100644
--- a/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
+++ b/core/src/test/java/org/apache/brooklyn/util/core/task/ssh/SshTasksTest.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasksTest;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
----------------------------------------------------------------------
diff --git a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
index ef925c6..e7e1df9 100644
--- a/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
+++ b/examples/simple-nosql-cluster/src/main/java/org/apache/brooklyn/demo/CumulusRDFApplication.java
@@ -46,6 +46,7 @@ import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.nosql.cassandra.CassandraDatacenter;
@@ -64,7 +65,6 @@ import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
index 70747b5..58ec93f 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeSaltImpl.java
@@ -22,7 +22,6 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.salt.SaltConfig;
import org.apache.brooklyn.entity.salt.SaltConfigs;
import org.apache.brooklyn.entity.salt.SaltLifecycleEffectorTasks;
@@ -40,6 +39,7 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
index 4fa3d96..198d139 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltLifecycleEffectorTasks.java
@@ -23,10 +23,10 @@ import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
index 87096a6..c00e48b 100644
--- a/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
+++ b/sandbox/extra/src/main/java/org/apache/brooklyn/entity/salt/SaltTasks.java
@@ -32,10 +32,10 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.ssh.BashCommands;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
index 1a42cbb..b25c92f 100644
--- a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
+++ b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
@@ -24,7 +24,6 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.PortRange;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNodeSaltImpl;
import org.apache.brooklyn.entity.salt.SaltConfig;
@@ -40,6 +39,7 @@ import org.apache.brooklyn.entity.database.VogellaExampleAccess;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNode;
import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.time.Duration;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
index f27a6dc..6962767 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/BrooklynNodeSshDriver.java
@@ -31,6 +31,7 @@ import java.util.Map;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.drivers.downloads.DownloadSubstituters;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -39,7 +40,6 @@ import org.apache.brooklyn.util.core.file.ArchiveBuilder;
import org.apache.brooklyn.util.core.file.ArchiveUtils;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
index 0b1c089..b1cb9be 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityTasks;
import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNodeDriver;
@@ -43,7 +44,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwarePara
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.text.Identifiers;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index 45c639c..03b7518 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -26,6 +26,7 @@ import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.slf4j.Logger;
@@ -37,7 +38,6 @@ import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskTags;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.net.Urls;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
index c543779..327b70b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefSoloTasks.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.entity.chef;
import java.util.Map;
import org.apache.brooklyn.api.mgmt.TaskFactory;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.ssh.BashCommands;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
index a7b79a3..c8a8b39 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefTasks.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.mgmt.TaskFactory;
import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.file.ArchiveTasks;
import org.apache.brooklyn.util.core.file.ArchiveUtils.ArchiveType;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskBuilder;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.ssh.BashCommands;
import org.apache.brooklyn.util.text.Identifiers;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
index 6e4b7c7..ce5f82d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java
@@ -32,6 +32,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -54,7 +55,6 @@ import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.ssh.SshTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
index 144894b..1bb994d 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
@@ -32,7 +33,6 @@ import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
import org.apache.brooklyn.sensor.feed.ssh.SshPollValue;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
index 2be96b6..a303f85 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.lifecycle.NaiveScriptRunner;
import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
import org.slf4j.Logger;
@@ -53,7 +54,6 @@ import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.core.internal.ssh.sshj.SshjTool;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
index c2e4cc8..0515166 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasks.java
@@ -55,6 +55,7 @@ import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.machine.MachineInitTasks;
import org.apache.brooklyn.entity.machine.ProvidesProvisioningFlags;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
@@ -80,7 +81,6 @@ import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
index f91be61..da4a9ce 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
@@ -28,11 +28,11 @@ import org.apache.brooklyn.effector.core.AddEffector;
import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks.SshEffectorTaskFactory;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks.SshEffectorTaskFactory;
import org.apache.brooklyn.util.text.Strings;
import com.google.common.base.Preconditions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
index 0166d94..8de4bb0 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.chef.mysql;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
index 468b95e..21d1d2f 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
@@ -22,6 +22,7 @@ import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.mgmt.TaskFactory;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefConfig;
import org.apache.brooklyn.entity.chef.ChefConfigs;
import org.apache.brooklyn.entity.chef.ChefSoloDriver;
@@ -29,7 +30,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.time.Duration;
@Deprecated /** @deprecated since 0.7.0 use see examples {Dynamic,Typed}ToyMySqlEntityChef */
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
index 1057ef9..244adf8 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks.SshEffectorBody;
import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks.SshEffectorBody;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
[23/36] incubator-brooklyn git commit: Rename o.a.b.sensor.feed to
o.a.b.feed and o.a.b.core.feed
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
deleted file mode 100644
index e9767d9..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.windows;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ExecutionContext;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.effector.EffectorTasks;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-import org.apache.brooklyn.sensor.feed.AbstractFeed;
-import org.apache.brooklyn.sensor.feed.PollHandler;
-import org.apache.brooklyn.sensor.feed.Poller;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * A sensor feed that retrieves performance counters from a Windows host and posts the values to sensors.
- *
- * <p>To use this feed, you must provide the entity, and a collection of mappings between Windows performance counter
- * names and Brooklyn attribute sensors.</p>
- *
- * <p>This feed uses SSH to invoke the windows utility <tt>typeperf</tt> to query for a specific set of performance
- * counters, by name. The values are extracted from the response, and published to the entity's sensors.</p>
- *
- * <p>Example:</p>
- *
- * {@code
- * @Override
- * protected void connectSensors() {
- * WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
- * .entity(entity)
- * .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
- * .addSensor("\\Memory\\Available MBytes", AVAILABLE_MEMORY)
- * .build();
- * }
- * }
- *
- * @since 0.6.0
- * @author richardcloudsoft
- */
-public class WindowsPerformanceCounterFeed extends AbstractFeed {
-
- private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeed.class);
-
- // This pattern matches CSV line(s) with the date in the first field, and at least one further field.
- protected static final Pattern lineWithPerfData = Pattern.compile("^\"[\\d:/\\-. ]+\",\".*\"$", Pattern.MULTILINE);
- private static final Joiner JOINER_ON_SPACE = Joiner.on(' ');
- private static final Joiner JOINER_ON_COMMA = Joiner.on(',');
- private static final int OUTPUT_COLUMN_WIDTH = 100;
-
- @SuppressWarnings("serial")
- public static final ConfigKey<Collection<WindowsPerformanceCounterPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<Collection<WindowsPerformanceCounterPollConfig<?>>>() {},
- "polls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EntityLocal entity;
- private Set<WindowsPerformanceCounterPollConfig<?>> polls = Sets.newLinkedHashSet();
- private Duration period = Duration.of(30, TimeUnit.SECONDS);
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = checkNotNull(val, "entity");
- return this;
- }
- public Builder addSensor(WindowsPerformanceCounterPollConfig<?> config) {
- polls.add(config);
- return this;
- }
- public Builder addSensor(String performanceCounterName, AttributeSensor<?> sensor) {
- return addSensor(new WindowsPerformanceCounterPollConfig(sensor).performanceCounterName(checkNotNull(performanceCounterName, "performanceCounterName")));
- }
- public Builder addSensors(Map<String, AttributeSensor> sensors) {
- for (Map.Entry<String, AttributeSensor> entry : sensors.entrySet()) {
- addSensor(entry.getKey(), entry.getValue());
- }
- return this;
- }
- public Builder period(Duration period) {
- this.period = checkNotNull(period, "period");
- return this;
- }
- public Builder period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public Builder period(long val, TimeUnit units) {
- return period(Duration.of(val, units));
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public WindowsPerformanceCounterFeed build() {
- built = true;
- WindowsPerformanceCounterFeed result = new WindowsPerformanceCounterFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("WindowsPerformanceCounterFeed.Builder created, but build() never called");
- }
- }
-
- /**
- * For rebind; do not call directly; use builder
- */
- public WindowsPerformanceCounterFeed() {
- }
-
- protected WindowsPerformanceCounterFeed(Builder builder) {
- List<WindowsPerformanceCounterPollConfig<?>> polls = Lists.newArrayList();
- for (WindowsPerformanceCounterPollConfig<?> config : builder.polls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "unchecked", "rawtypes" })
- WindowsPerformanceCounterPollConfig<?> configCopy = new WindowsPerformanceCounterPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
- polls.add(configCopy);
- }
- config().set(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls);
- }
-
- @Override
- protected void preStart() {
- Collection<WindowsPerformanceCounterPollConfig<?>> polls = getConfig(POLLS);
-
- long minPeriod = Integer.MAX_VALUE;
- List<String> performanceCounterNames = Lists.newArrayList();
- for (WindowsPerformanceCounterPollConfig<?> config : polls) {
- minPeriod = Math.min(minPeriod, config.getPeriod());
- performanceCounterNames.add(config.getPerformanceCounterName());
- }
-
- Iterable<String> allParams = ImmutableList.<String>builder()
- .add("(Get-Counter")
- .add("-Counter")
- .add(JOINER_ON_COMMA.join(Iterables.transform(performanceCounterNames, QuoteStringFunction.INSTANCE)))
- .add("-SampleInterval")
- .add("2") // TODO: extract SampleInterval as a config key
- .add(").CounterSamples")
- .add("|")
- .add("Format-Table")
- .add(String.format("@{Expression={$_.Path};width=%d},@{Expression={$_.CookedValue};width=%<d}", OUTPUT_COLUMN_WIDTH))
- .add("-HideTableHeaders")
- .add("|")
- .add("Out-String")
- .add("-Width")
- .add(String.valueOf(OUTPUT_COLUMN_WIDTH * 2))
- .build();
- String command = JOINER_ON_SPACE.join(allParams);
- log.debug("Windows performance counter poll command for {} will be: {}", entity, command);
-
- GetPerformanceCountersJob<WinRmToolResponse> job = new GetPerformanceCountersJob(getEntity(), command);
- getPoller().scheduleAtFixedRate(
- new CallInEntityExecutionContext(entity, job),
- new SendPerfCountersToSensors(getEntity(), polls),
- minPeriod);
- }
-
- private static class GetPerformanceCountersJob<T> implements Callable<T> {
-
- private final Entity entity;
- private final String command;
-
- GetPerformanceCountersJob(Entity entity, String command) {
- this.entity = entity;
- this.command = command;
- }
-
- @Override
- public T call() throws Exception {
- WinRmMachineLocation machine = EffectorTasks.getWinRmMachine(entity);
- WinRmToolResponse response = machine.executePsScript(command);
- return (T)response;
- }
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<WinRmToolResponse> getPoller() {
- return (Poller<WinRmToolResponse>) super.getPoller();
- }
-
- /**
- * A {@link java.util.concurrent.Callable} that wraps another {@link java.util.concurrent.Callable}, where the
- * inner {@link java.util.concurrent.Callable} is executed in the context of a
- * specific entity.
- *
- * @param <T> The type of the {@link java.util.concurrent.Callable}.
- */
- private static class CallInEntityExecutionContext<T> implements Callable<T> {
- private final Callable<T> job;
- private EntityLocal entity;
-
- private CallInEntityExecutionContext(EntityLocal entity, Callable<T> job) {
- this.job = job;
- this.entity = entity;
- }
-
- @Override
- public T call() throws Exception {
- ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext();
- return executionContext.submit(Maps.newHashMap(), job).get();
- }
- }
-
- @VisibleForTesting
- static class SendPerfCountersToSensors implements PollHandler<WinRmToolResponse> {
- private final EntityLocal entity;
- private final List<WindowsPerformanceCounterPollConfig<?>> polls;
- private final Set<AttributeSensor<?>> failedAttributes = Sets.newLinkedHashSet();
- private static final Pattern MACHINE_NAME_LOOKBACK_PATTERN = Pattern.compile(String.format("(?<=\\\\\\\\.{0,%d})\\\\.*", OUTPUT_COLUMN_WIDTH));
-
- public SendPerfCountersToSensors(EntityLocal entity, Collection<WindowsPerformanceCounterPollConfig<?>> polls) {
- this.entity = entity;
- this.polls = ImmutableList.copyOf(polls);
- }
-
- @Override
- public boolean checkSuccess(WinRmToolResponse val) {
- // TODO not just using statusCode; also looking at absence of stderr.
- // Status code is (empirically) unreliable: it returns 0 sometimes even when failed
- // (but never returns non-zero on success).
- if (val.getStatusCode() != 0) return false;
- String stderr = val.getStdErr();
- if (stderr == null || stderr.length() != 0) return false;
- String out = val.getStdOut();
- if (out == null || out.length() == 0) return false;
- return true;
- }
-
- @Override
- public void onSuccess(WinRmToolResponse val) {
- for (String pollResponse : val.getStdOut().split("\r\n")) {
- if (Strings.isNullOrEmpty(pollResponse)) {
- continue;
- }
- String path = pollResponse.substring(0, OUTPUT_COLUMN_WIDTH - 1);
- // The performance counter output prepends the sensor name with "\\<machinename>" so we need to remove it
- Matcher machineNameLookbackMatcher = MACHINE_NAME_LOOKBACK_PATTERN.matcher(path);
- if (!machineNameLookbackMatcher.find()) {
- continue;
- }
- String name = machineNameLookbackMatcher.group(0).trim();
- String rawValue = pollResponse.substring(OUTPUT_COLUMN_WIDTH).replaceAll("^\\s+", "");
- WindowsPerformanceCounterPollConfig<?> config = getPollConfig(name);
- Class<?> clazz = config.getSensor().getType();
- AttributeSensor<Object> attribute = (AttributeSensor<Object>) Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
- try {
- Object value = TypeCoercions.coerce(rawValue, TypeToken.of(clazz));
- entity.setAttribute(attribute, value);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (failedAttributes.add(attribute)) {
- log.warn("Failed to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
- } else {
- if (log.isTraceEnabled()) log.trace("Failed (repeatedly) to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
- }
- }
- }
- }
-
- @Override
- public void onFailure(WinRmToolResponse val) {
- log.error("Windows Performance Counter query did not respond as expected. exitcode={} stdout={} stderr={}",
- new Object[]{val.getStatusCode(), val.getStdOut(), val.getStdErr()});
- for (WindowsPerformanceCounterPollConfig<?> config : polls) {
- Class<?> clazz = config.getSensor().getType();
- AttributeSensor<?> attribute = Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
- entity.setAttribute(attribute, null);
- }
- }
-
- @Override
- public void onException(Exception exception) {
- log.error("Detected exception while retrieving Windows Performance Counters from entity " +
- entity.getDisplayName(), exception);
- for (WindowsPerformanceCounterPollConfig<?> config : polls) {
- entity.setAttribute(Sensors.newSensor(config.getSensor().getClass(), config.getPerformanceCounterName(), config.getDescription()), null);
- }
- }
-
- @Override
- public String getDescription() {
- return "" + polls;
- }
-
- @Override
- public String toString() {
- return super.toString()+"["+getDescription()+"]";
- }
-
- private WindowsPerformanceCounterPollConfig<?> getPollConfig(String sensorName) {
- for (WindowsPerformanceCounterPollConfig<?> poll : polls) {
- if (poll.getPerformanceCounterName().equalsIgnoreCase(sensorName)) {
- return poll;
- }
- }
- throw new IllegalStateException(String.format("%s not found in configured polls: %s", sensorName, polls));
- }
- }
-
- static class PerfCounterValueIterator implements Iterator<String> {
-
- // This pattern matches the contents of the first field, and optionally matches the rest of the line as
- // further fields. Feed the second match back into the pattern again to get the next field, and repeat until
- // all fields are discovered.
- protected static final Pattern splitPerfData = Pattern.compile("^\"([^\\\"]*)\"((,\"[^\\\"]*\")*)$");
-
- private Matcher matcher;
-
- public PerfCounterValueIterator(String input) {
- matcher = splitPerfData.matcher(input);
- // Throw away the first element (the timestamp) (and also confirm that we have a pattern match)
- checkArgument(hasNext(), "input "+input+" does not match expected pattern "+splitPerfData.pattern());
- next();
- }
-
- @Override
- public boolean hasNext() {
- return matcher != null && matcher.find();
- }
-
- @Override
- public String next() {
- String next = matcher.group(1);
-
- String remainder = matcher.group(2);
- if (!Strings.isNullOrEmpty(remainder)) {
- assert remainder.startsWith(",");
- remainder = remainder.substring(1);
- matcher = splitPerfData.matcher(remainder);
- } else {
- matcher = null;
- }
-
- return next;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- private static enum QuoteStringFunction implements Function<String, String> {
- INSTANCE;
-
- @Nullable
- @Override
- public String apply(@Nullable String input) {
- return input != null ? "\"" + input + "\"" : null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterPollConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterPollConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterPollConfig.java
deleted file mode 100644
index 34bc08c..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterPollConfig.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.feed.windows;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.feed.PollConfig;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-
-public class WindowsPerformanceCounterPollConfig<T> extends PollConfig<Object, T, WindowsPerformanceCounterPollConfig<T>>{
-
- private String performanceCounterName;
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public WindowsPerformanceCounterPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- description(sensor.getDescription());
- onSuccess((Function)Functions.identity());
- }
-
- public WindowsPerformanceCounterPollConfig(WindowsPerformanceCounterPollConfig<T> other) {
- super(other);
- this.performanceCounterName = other.performanceCounterName;
- }
-
- public String getPerformanceCounterName() {
- return performanceCounterName;
- }
-
- public WindowsPerformanceCounterPollConfig<T> performanceCounterName(String val) {
- this.performanceCounterName = val; return this;
- }
-
- @Override protected String toStringPollSource() { return performanceCounterName; }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
index 9e8e061..ad768f7 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/http/HttpToolResponse.java
@@ -26,7 +26,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import org.apache.brooklyn.sensor.feed.http.HttpPollValue;
+import org.apache.brooklyn.feed.http.HttpPollValue;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.stream.Streams;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/core/feed/ConfigToAttributesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/feed/ConfigToAttributesTest.java b/core/src/test/java/org/apache/brooklyn/core/feed/ConfigToAttributesTest.java
new file mode 100644
index 0000000..1cc48df
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/feed/ConfigToAttributesTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ConfigToAttributesTest {
+
+ private ManagementContextInternal managementContext;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ managementContext = new LocalManagementContext();
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (managementContext != null) Entities.destroyAll(managementContext);
+ }
+
+ @Test
+ public void testApplyTemplatedConfigWithEntity() {
+ TestApplication app = managementContext.getEntityManager().createEntity(EntitySpec.create(TestApplication.class)
+ .configure(TestEntity.CONF_NAME, "myval"));
+ Entities.startManagement(app, managementContext);
+
+ BasicAttributeSensorAndConfigKey<String> key = new TemplatedStringAttributeSensorAndConfigKey("mykey", "my descr", "${config['test.confName']!'notfound'}");
+ String val = ConfigToAttributes.apply(app, key);
+ assertEquals(app.getAttribute(key), val);
+ assertEquals(val, "myval");
+
+ }
+
+ @Test
+ public void testApplyTemplatedConfigWithManagementContext() {
+ managementContext.getBrooklynProperties().put(TestEntity.CONF_NAME, "myglobalval");
+ BasicAttributeSensorAndConfigKey<String> key = new TemplatedStringAttributeSensorAndConfigKey("mykey", "my descr", "${config['test.confName']!'notfound'}");
+ String val = ConfigToAttributes.transform(managementContext, key);
+ assertEquals(val, "myglobalval");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/core/feed/PollerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/feed/PollerTest.java b/core/src/test/java/org/apache/brooklyn/core/feed/PollerTest.java
new file mode 100644
index 0000000..0f2c1ce
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/feed/PollerTest.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.feed;
+
+import static org.testng.Assert.assertTrue;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.feed.PollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class PollerTest extends BrooklynAppUnitTestSupport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PollerTest.class);
+
+ private TestEntity entity;
+ private Poller<Integer> poller;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ poller = new Poller<Integer>(entity, false);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (poller != null) poller.stop();
+ super.tearDown();
+ }
+
+ @Test(groups={"Integration", "WIP"}) // because takes > 1 second
+ public void testPollingSubTaskFailsOnceKeepsGoing() throws Exception {
+ final AtomicInteger counter = new AtomicInteger();
+ poller.scheduleAtFixedRate(
+ new Callable<Integer>() {
+ @Override public Integer call() throws Exception {
+ int result = counter.incrementAndGet();
+ if (result % 2 == 0) {
+ DynamicTasks.queue("in-poll", new Runnable() {
+ public void run() {
+ throw new IllegalStateException("Simulating error in sub-task for poll");
+ }});
+ }
+ return result;
+ }
+ },
+ new PollHandler<Integer>() {
+ @Override public boolean checkSuccess(Integer val) {
+ return true;
+ }
+ @Override public void onSuccess(Integer val) {
+
+ }
+ @Override public void onFailure(Integer val) {
+ }
+ @Override
+ public void onException(Exception exception) {
+ LOG.info("Exception in test poller", exception);
+ }
+ @Override public String getDescription() {
+ return "mypollhandler";
+ }
+ },
+ new Duration(10, TimeUnit.MILLISECONDS));
+ poller.start();
+
+ Asserts.succeedsContinually(MutableMap.of("timeout", 2*1000, "period", 500), new Runnable() {
+ int oldCounter = -1;
+ @Override public void run() {
+ assertTrue(counter.get() > oldCounter);
+ oldCounter = counter.get();
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java b/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
index a5b4294..b8d8c35 100644
--- a/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
+++ b/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
@@ -21,11 +21,11 @@ package org.apache.brooklyn.core.location;
import static org.testng.Assert.assertEquals;
import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.feed.ConfigToAttributes;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
index f0c6551..4a724e4 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
@@ -35,14 +35,14 @@ import org.apache.brooklyn.core.mgmt.internal.BrooklynGarbageCollector;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
-import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
-import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpFeed;
-import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
-import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
-import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
-import org.apache.brooklyn.sensor.feed.ssh.SshPollConfig;
-import org.apache.brooklyn.sensor.feed.ssh.SshValueFunctions;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.feed.ssh.SshFeed;
+import org.apache.brooklyn.feed.ssh.SshPollConfig;
+import org.apache.brooklyn.feed.ssh.SshValueFunctions;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/function/FunctionFeedTest.java b/core/src/test/java/org/apache/brooklyn/feed/function/FunctionFeedTest.java
new file mode 100644
index 0000000..c362e4e6
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/function/FunctionFeedTest.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.function;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Feed;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionFeedTest;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicates;
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.util.concurrent.Callables;
+
+public class FunctionFeedTest extends BrooklynAppUnitTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(FunctionFeedTest.class);
+
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
+
+ private Location loc;
+ private EntityLocal entity;
+ private FunctionFeed feed;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = new LocalhostMachineProvisioningLocation();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ super.tearDown();
+ }
+
+ @Test
+ public void testPollsFunctionRepeatedlyToSetAttribute() throws Exception {
+ feed = FunctionFeed.builder()
+ .entity(entity)
+ .poll(new FunctionPollConfig<Integer,Integer>(SENSOR_INT)
+ .period(1)
+ .callable(new IncrementingCallable())
+ //.onSuccess((Function<Object,Integer>)(Function)Functions.identity()))
+ )
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ @Override
+ public void run() {
+ Integer val = entity.getAttribute(SENSOR_INT);
+ assertTrue(val != null && val > 2, "val=" + val);
+ }
+ });
+ }
+
+ @Test
+ public void testFeedDeDupe() throws Exception {
+ testPollsFunctionRepeatedlyToSetAttribute();
+ entity.addFeed(feed);
+ log.info("Feed 0 is: "+feed);
+ Feed feed0 = feed;
+
+ testPollsFunctionRepeatedlyToSetAttribute();
+ entity.addFeed(feed);
+ log.info("Feed 1 is: "+feed);
+ Feed feed1 = feed;
+ Assert.assertFalse(feed1==feed0);
+
+ FeedSupport feeds = ((EntityInternal)entity).feeds();
+ Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
+
+ // a couple extra checks, compared to the de-dupe test in other *FeedTest classes
+ Feed feedAdded = Iterables.getOnlyElement(feeds.getFeeds());
+ Assert.assertTrue(feedAdded==feed1);
+ Assert.assertFalse(feedAdded==feed0);
+ }
+
+ @Test
+ public void testFeedDeDupeIgnoresSameObject() throws Exception {
+ testPollsFunctionRepeatedlyToSetAttribute();
+ entity.addFeed(feed);
+ assertFeedIsPolling();
+ entity.addFeed(feed);
+ assertFeedIsPollingContinuously();
+ }
+
+ @Test
+ public void testCallsOnSuccessWithResultOfCallable() throws Exception {
+ feed = FunctionFeed.builder()
+ .entity(entity)
+ .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+ .period(1)
+ .callable(Callables.returning(123))
+ .onSuccess(new AddOneFunction()))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 124);
+ }
+
+ @Test
+ public void testCallsOnExceptionWithExceptionFromCallable() throws Exception {
+ final String errMsg = "my err msg";
+
+ feed = FunctionFeed.builder()
+ .entity(entity)
+ .poll(new FunctionPollConfig<Object, String>(SENSOR_STRING)
+ .period(1)
+ .callable(new ExceptionCallable(errMsg))
+ .onException(new ToStringFunction()))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ @Override
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains(errMsg), "val=" + val);
+ }
+ });
+ }
+
+ @Test
+ public void testCallsOnFailureWithResultOfCallable() throws Exception {
+ feed = FunctionFeed.builder()
+ .entity(entity)
+ .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+ .period(1)
+ .callable(Callables.returning(1))
+ .checkSuccess(Predicates.alwaysFalse())
+ .onSuccess(new AddOneFunction())
+ .onFailure(Functions.constant(-1)))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, -1);
+ }
+
+ @Test
+ public void testCallsOnExceptionWhenCheckSuccessIsFalseButNoFailureHandler() throws Exception {
+ feed = FunctionFeed.builder()
+ .entity(entity)
+ .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+ .period(1)
+ .callable(Callables.returning(1))
+ .checkSuccess(Predicates.alwaysFalse())
+ .onSuccess(new AddOneFunction())
+ .onException(Functions.constant(-1)))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, -1);
+ }
+
+ @Test
+ public void testSharesFunctionWhenMultiplePostProcessors() throws Exception {
+ final IncrementingCallable incrementingCallable = new IncrementingCallable();
+ final List<Integer> ints = new CopyOnWriteArrayList<Integer>();
+ final List<String> strings = new CopyOnWriteArrayList<String>();
+
+ entity.subscribe(entity, SENSOR_INT, new SensorEventListener<Integer>() {
+ @Override public void onEvent(SensorEvent<Integer> event) {
+ ints.add(event.getValue());
+ }});
+ entity.subscribe(entity, SENSOR_STRING, new SensorEventListener<String>() {
+ @Override public void onEvent(SensorEvent<String> event) {
+ strings.add(event.getValue());
+ }});
+
+ feed = FunctionFeed.builder()
+ .entity(entity)
+ .poll(new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+ .period(10)
+ .callable(incrementingCallable))
+ .poll(new FunctionPollConfig<Integer, String>(SENSOR_STRING)
+ .period(10)
+ .callable(incrementingCallable)
+ .onSuccess(new ToStringFunction()))
+ .build();
+
+ Asserts.succeedsEventually(new Runnable() {
+ @Override
+ public void run() {
+ assertEquals(ints.subList(0, 2), ImmutableList.of(0, 1));
+ assertTrue(strings.size()>=2, "wrong strings list: "+strings);
+ assertEquals(strings.subList(0, 2), ImmutableList.of("0", "1"), "wrong strings list: "+strings);
+ }});
+ }
+
+ @Test
+ @SuppressWarnings("unused")
+ public void testFunctionPollConfigBuilding() throws Exception {
+ FunctionPollConfig<Integer, Integer> typeFromCallable = FunctionPollConfig.forSensor(SENSOR_INT)
+ .period(1)
+ .callable(Callables.returning(1))
+ .onSuccess(Functions.constant(-1));
+
+ FunctionPollConfig<Integer, Integer> typeFromSupplier = FunctionPollConfig.forSensor(SENSOR_INT)
+ .period(1)
+ .supplier(Suppliers.ofInstance(1))
+ .onSuccess(Functions.constant(-1));
+
+ FunctionPollConfig<Integer, Integer> usingConstructor = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+ .period(1)
+ .supplier(Suppliers.ofInstance(1))
+ .onSuccess(Functions.constant(-1));
+
+ FunctionPollConfig<Integer, Integer> usingConstructorWithFailureOrException = new FunctionPollConfig<Integer, Integer>(SENSOR_INT)
+ .period(1)
+ .supplier(Suppliers.ofInstance(1))
+ .onFailureOrException(Functions.<Integer>constant(null));
+ }
+
+
+ private void assertFeedIsPolling() {
+ final Integer val = entity.getAttribute(SENSOR_INT);
+ Asserts.succeedsEventually(new Runnable() {
+ @Override
+ public void run() {
+ assertNotEquals(val, entity.getAttribute(SENSOR_INT));
+ }
+ });
+ }
+
+ private void assertFeedIsPollingContinuously() {
+ Asserts.succeedsContinually(new Runnable() {
+ @Override
+ public void run() {
+ assertFeedIsPolling();
+ }
+ });
+ }
+
+ private static class IncrementingCallable implements Callable<Integer> {
+ private final AtomicInteger next = new AtomicInteger(0);
+
+ @Override public Integer call() {
+ return next.getAndIncrement();
+ }
+ }
+
+ private static class AddOneFunction implements Function<Integer, Integer> {
+ @Override public Integer apply(@Nullable Integer input) {
+ return (input != null) ? (input + 1) : null;
+ }
+ }
+
+ private static class ExceptionCallable implements Callable<Void> {
+ private final String msg;
+ ExceptionCallable(String msg) {
+ this.msg = msg;
+ }
+ @Override public Void call() {
+ throw new RuntimeException(msg);
+ }
+ }
+
+ public static class ToStringFunction implements Function<Object, String> {
+ @Override public String apply(@Nullable Object input) {
+ return (input != null) ? (input.toString()) : null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedIntegrationTest.java b/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedIntegrationTest.java
new file mode 100644
index 0000000..ee7e226
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedIntegrationTest.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.HttpService;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+
+public class HttpFeedIntegrationTest extends BrooklynAppUnitTestSupport {
+
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor("aLong", "");
+
+ private HttpService httpService;
+
+ private Location loc;
+ private EntityLocal entity;
+ private HttpFeed feed;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = new LocalhostMachineProvisioningLocation();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ if (httpService != null) httpService.shutdown();
+ super.tearDown();
+ }
+
+ @Test(groups = {"Integration"})
+ public void testPollsAndParsesHttpGetResponseWithSsl() throws Exception {
+ httpService = new HttpService(PortRanges.fromString("9000+"), true).start();
+ URI baseUrl = new URI(httpService.getUrl());
+
+ assertEquals(baseUrl.getScheme(), "https", "baseUrl="+baseUrl);
+
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUri(baseUrl)
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction()))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 200);
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains("Hello, World"), "val="+val);
+ }});
+ }
+
+ @Test(groups = {"Integration"})
+ public void testPollsAndParsesHttpGetResponseWithBasicAuthentication() throws Exception {
+ final String username = "brooklyn";
+ final String password = "hunter2";
+ httpService = new HttpService(PortRanges.fromString("9000+"))
+ .basicAuthentication(username, password)
+ .start();
+ URI baseUrl = new URI(httpService.getUrl());
+ assertEquals(baseUrl.getScheme(), "http", "baseUrl="+baseUrl);
+
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUri(baseUrl)
+ .credentials(username, password)
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction()))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 200);
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.contains("Hello, World"), "val="+val);
+ }});
+ }
+
+ @Test(groups = {"Integration"})
+ public void testPollWithInvalidCredentialsFails() throws Exception {
+ httpService = new HttpService(PortRanges.fromString("9000+"))
+ .basicAuthentication("brooklyn", "hunter2")
+ .start();
+
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUri(httpService.getUrl())
+ .credentials("brooklyn", "9876543210")
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode())
+ .onFailure(HttpValueFunctions.responseCode()))
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction())
+ .onException(Functions.constant("Failed!")))
+ .build();
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_INT, 401);
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String val = entity.getAttribute(SENSOR_STRING);
+ assertTrue(val != null && val.equals("Failed!"), "val=" + val);
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java b/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
new file mode 100644
index 0000000..d8ac492
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/http/HttpFeedTest.java
@@ -0,0 +1,392 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URL;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityFunctions;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.feed.FeedConfig;
+import org.apache.brooklyn.core.feed.PollConfig;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.feed.http.HttpFeed;
+import org.apache.brooklyn.feed.http.HttpPollConfig;
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.http.BetterMockWebServer;
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.net.Networking;
+import org.apache.brooklyn.util.time.Duration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.SocketPolicy;
+
+public class HttpFeedTest extends BrooklynAppUnitTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(HttpFeedTest.class);
+
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ final static AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor( "aLong", "");
+
+ private static final long TIMEOUT_MS = 10*1000;
+
+ private BetterMockWebServer server;
+ private URL baseUrl;
+
+ private Location loc;
+ private EntityLocal entity;
+ private HttpFeed feed;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ server = BetterMockWebServer.newInstanceLocalhost();
+ for (int i = 0; i < 100; i++) {
+ server.enqueue(new MockResponse().setResponseCode(200).addHeader("content-type: application/json").setBody("{\"foo\":\"myfoo\"}"));
+ }
+ server.play();
+ baseUrl = server.getUrl("/");
+
+ loc = app.newLocalhostProvisioningLocation();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ if (server != null) server.shutdown();
+ feed = null;
+ super.tearDown();
+ }
+
+ @Test
+ public void testPollsAndParsesHttpGetResponse() throws Exception {
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+ .poll(HttpPollConfig.forSensor(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .poll(HttpPollConfig.forSensor(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction()))
+ .build();
+
+ assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
+ assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
+ }
+
+ @Test
+ public void testFeedDeDupe() throws Exception {
+ testPollsAndParsesHttpGetResponse();
+ entity.addFeed(feed);
+ log.info("Feed 0 is: "+feed);
+
+ testPollsAndParsesHttpGetResponse();
+ log.info("Feed 1 is: "+feed);
+ entity.addFeed(feed);
+
+ FeedSupport feeds = ((EntityInternal)entity).feeds();
+ Assert.assertEquals(feeds.getFeeds().size(), 1, "Wrong feed count: "+feeds.getFeeds());
+ }
+
+ @Test
+ public void testSetsConnectionTimeout() throws Exception {
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .connectionTimeout(Duration.TEN_SECONDS)
+ .socketTimeout(Duration.TEN_SECONDS)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .build();
+
+ assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
+ }
+
+ // TODO How to cause the other end to just freeze (similar to aws-ec2 when securityGroup port is not open)?
+ @Test
+ public void testSetsConnectionTimeoutWhenServerDisconnects() throws Exception {
+ if (server != null) server.shutdown();
+ server = BetterMockWebServer.newInstanceLocalhost();
+ for (int i = 0; i < 100; i++) {
+ server.enqueue(new MockResponse().setSocketPolicy(SocketPolicy.DISCONNECT_AT_START));
+ }
+ server.play();
+ baseUrl = server.getUrl("/");
+
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .connectionTimeout(Duration.TEN_SECONDS)
+ .socketTimeout(Duration.TEN_SECONDS)
+ .onSuccess(HttpValueFunctions.responseCode())
+ .onException(Functions.constant(-1)))
+ .build();
+
+ assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
+ }
+
+
+ @Test
+ public void testPollsAndParsesHttpPostResponse() throws Exception {
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .method("post")
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .method("post")
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction()))
+ .build();
+
+ assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
+ assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
+ }
+
+ @Test
+ public void testUsesFailureHandlerOn4xx() throws Exception {
+ server = BetterMockWebServer.newInstanceLocalhost();
+ for (int i = 0; i < 100; i++) {
+ server.enqueue(new MockResponse()
+ .setResponseCode(401)
+ .setBody("Unauthorised"));
+ }
+ server.play();
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(server.getUrl("/"))
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode())
+ .onFailure(HttpValueFunctions.responseCode()))
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction())
+ .onFailure(Functions.constant("Failed")))
+ .build();
+
+ assertSensorEventually(SENSOR_INT, 401, TIMEOUT_MS);
+ assertSensorEventually(SENSOR_STRING, "Failed", TIMEOUT_MS);
+
+ server.shutdown();
+ }
+
+ @Test
+ public void testUsesExceptionHandlerOn4xxAndNoFailureHandler() throws Exception {
+ server = BetterMockWebServer.newInstanceLocalhost();
+ for (int i = 0; i < 100; i++) {
+ server.enqueue(new MockResponse()
+ .setResponseCode(401)
+ .setBody("Unauthorised"));
+ }
+ server.play();
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(server.getUrl("/"))
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode())
+ .onException(Functions.constant(-1)))
+ .build();
+
+ assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
+
+ server.shutdown();
+ }
+
+ @Test(groups="Integration")
+ // marked integration as it takes a wee while
+ public void testSuspendResume() throws Exception {
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+ .poll(new HttpPollConfig<Integer>(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction()))
+ .build();
+ assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
+ feed.suspend();
+ final int countWhenSuspended = server.getRequestCount();
+
+ Thread.sleep(500);
+ if (server.getRequestCount() > countWhenSuspended+1)
+ Assert.fail("Request count continued to increment while feed was suspended, from "+countWhenSuspended+" to "+server.getRequestCount());
+
+ feed.resume();
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ assertTrue(server.getRequestCount() > countWhenSuspended + 1,
+ "Request count failed to increment when feed was resumed, from " + countWhenSuspended + ", still at " + server.getRequestCount());
+ }
+ });
+ }
+
+ @Test(groups="Integration")
+ // marked integration as it takes a wee while
+ public void testStartSuspended() throws Exception {
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+ .poll(HttpPollConfig.forSensor(SENSOR_INT)
+ .period(100)
+ .onSuccess(HttpValueFunctions.responseCode()))
+ .poll(HttpPollConfig.forSensor(SENSOR_STRING)
+ .period(100)
+ .onSuccess(HttpValueFunctions.stringContentsFunction()))
+ .suspended()
+ .build();
+ Asserts.continually(MutableMap.of("timeout", 500),
+ Entities.attributeSupplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(null));
+ int countWhenSuspended = server.getRequestCount();
+ feed.resume();
+ Asserts.eventually(Entities.attributeSupplier(entity, SENSOR_INT), Predicates.<Integer>equalTo(200));
+ if (server.getRequestCount() <= countWhenSuspended)
+ Assert.fail("Request count failed to increment when feed was resumed, from "+countWhenSuspended+", still at "+server.getRequestCount());
+ log.info("RUN: "+countWhenSuspended+" - "+server.getRequestCount());
+ }
+
+
+ @Test
+ public void testPollsAndParsesHttpErrorResponseLocal() throws Exception {
+ int unboundPort = Networking.nextAvailablePort(10000);
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUri("http://localhost:" + unboundPort + "/path/should/not/exist")
+ .poll(new HttpPollConfig<String>(SENSOR_STRING)
+ .onSuccess(Functions.constant("success"))
+ .onFailure(Functions.constant("failure"))
+ .onException(Functions.constant("error")))
+ .build();
+
+ assertSensorEventually(SENSOR_STRING, "error", TIMEOUT_MS);
+ }
+
+ @Test
+ public void testPollsMulti() throws Exception {
+ newMultiFeed(baseUrl);
+ assertSensorEventually(SENSOR_INT, (Integer)200, TIMEOUT_MS);
+ assertSensorEventually(SENSOR_STRING, "{\"foo\":\"myfoo\"}", TIMEOUT_MS);
+ }
+
+ // because takes a wee while
+ @SuppressWarnings("rawtypes")
+ @Test(groups="Integration")
+ public void testPollsMultiClearsOnSubsequentFailure() throws Exception {
+ server = BetterMockWebServer.newInstanceLocalhost();
+ for (int i = 0; i < 10; i++) {
+ server.enqueue(new MockResponse()
+ .setResponseCode(200)
+ .setBody("Hello World"));
+ }
+ for (int i = 0; i < 10; i++) {
+ server.enqueue(new MockResponse()
+ .setResponseCode(401)
+ .setBody("Unauthorised"));
+ }
+ server.play();
+
+ newMultiFeed(server.getUrl("/"));
+
+ assertSensorEventually(SENSOR_INT, 200, TIMEOUT_MS);
+ assertSensorEventually(SENSOR_STRING, "Hello World", TIMEOUT_MS);
+
+ assertSensorEventually(SENSOR_INT, -1, TIMEOUT_MS);
+ assertSensorEventually(SENSOR_STRING, null, TIMEOUT_MS);
+
+ List<String> attrs = Lists.transform(MutableList.copyOf( ((EntityInternal)entity).getAllAttributes().keySet() ),
+ new Function<AttributeSensor,String>() {
+ @Override public String apply(AttributeSensor input) { return input.getName(); } });
+ Assert.assertTrue(!attrs.contains(SENSOR_STRING.getName()), "attrs contained "+SENSOR_STRING);
+ Assert.assertTrue(!attrs.contains(FeedConfig.NO_SENSOR.getName()), "attrs contained "+FeedConfig.NO_SENSOR);
+
+ server.shutdown();
+ }
+
+ private void newMultiFeed(URL baseUrl) {
+ feed = HttpFeed.builder()
+ .entity(entity)
+ .baseUrl(baseUrl)
+
+ .poll(HttpPollConfig.forMultiple()
+ .onSuccess(new Function<HttpToolResponse,Void>() {
+ public Void apply(HttpToolResponse response) {
+ entity.setAttribute(SENSOR_INT, response.getResponseCode());
+ if (response.getResponseCode()==200)
+ entity.setAttribute(SENSOR_STRING, response.getContentAsString());
+ return null;
+ }
+ })
+ .onFailureOrException(Functionals.function(EntityFunctions.settingSensorsConstant(entity, MutableMap.<AttributeSensor<?>,Object>of(
+ SENSOR_INT, -1,
+ SENSOR_STRING, PollConfig.REMOVE))))
+ .period(100))
+ .build();
+ }
+
+
+ private <T> void assertSensorEventually(final AttributeSensor<T> sensor, final T expectedVal, long timeout) {
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", timeout), new Callable<Void>() {
+ public Void call() {
+ assertEquals(entity.getAttribute(sensor), expectedVal);
+ return null;
+ }
+ });
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
new file mode 100644
index 0000000..23ffae3
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/http/HttpValueFunctionsTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.util.core.http.HttpToolResponse;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class HttpValueFunctionsTest {
+
+ private int responseCode = 200;
+ private long fullLatency = 1000;
+ private String headerName = "my_header";
+ private String headerVal = "my_header_val";
+ private String bodyKey = "mykey";
+ private String bodyVal = "myvalue";
+ private String body = "{"+bodyKey+":"+bodyVal+"}";
+ private long now;
+ private HttpToolResponse response;
+
+ @BeforeMethod
+ public void setUp() throws Exception {
+ now = System.currentTimeMillis();
+ response = new HttpToolResponse(responseCode, ImmutableMap.of(headerName, ImmutableList.of(headerVal)),
+ body.getBytes(), now-fullLatency, fullLatency / 2, fullLatency);
+ }
+
+ @Test
+ public void testResponseCode() throws Exception {
+ assertEquals(HttpValueFunctions.responseCode().apply(response), Integer.valueOf(responseCode));
+ }
+
+ @Test
+ public void testContainsHeader() throws Exception {
+ assertTrue(HttpValueFunctions.containsHeader(headerName).apply(response));
+ assertFalse(HttpValueFunctions.containsHeader("wrong_header").apply(response));
+ }
+
+ @Test
+ public void testStringContents() throws Exception {
+ assertEquals(HttpValueFunctions.stringContentsFunction().apply(response), body);
+ }
+
+ @Test
+ public void testJsonContents() throws Exception {
+ JsonElement json = HttpValueFunctions.jsonContents().apply(response);
+ assertTrue(json.isJsonObject());
+ assertEquals(json.getAsJsonObject().entrySet(), ImmutableMap.of(bodyKey, new JsonPrimitive(bodyVal)).entrySet());
+ }
+
+ @Test
+ public void testJsonContentsGettingElement() throws Exception {
+ assertEquals(HttpValueFunctions.jsonContents(bodyKey, String.class).apply(response), bodyVal);
+ }
+
+ @Test(expectedExceptions=NoSuchElementException.class)
+ public void testJsonContentsGettingMissingElement() throws Exception {
+ assertNull(HttpValueFunctions.jsonContents("wrongkey", String.class).apply(response));
+ }
+
+ @Test
+ public void testLatency() throws Exception {
+ assertEquals(HttpValueFunctions.latency().apply(response), Long.valueOf(fullLatency));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/daf40919/core/src/test/java/org/apache/brooklyn/feed/http/JsonFunctionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/http/JsonFunctionsTest.java b/core/src/test/java/org/apache/brooklyn/feed/http/JsonFunctionsTest.java
new file mode 100644
index 0000000..928035e
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/feed/http/JsonFunctionsTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.feed.http;
+
+import java.util.NoSuchElementException;
+
+import org.apache.brooklyn.feed.http.JsonFunctions;
+import org.apache.brooklyn.util.collections.Jsonya;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.collections.Jsonya.Navigator;
+import org.apache.brooklyn.util.guava.Functionals;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import com.jayway.jsonpath.PathNotFoundException;
+
+public class JsonFunctionsTest {
+
+ public static JsonElement europeMap() {
+ Navigator<MutableMap<Object, Object>> europe = Jsonya.newInstance().at("europe", "uk", "edinburgh")
+ .put("population", 500*1000)
+ .put("weather", "wet", "lighting", "dark")
+ .root().at("europe").at("france").put("population", 80*1000*1000)
+ .root();
+ return new JsonParser().parse( europe.toString() );
+ }
+
+ @Test
+ public void testWalk1() {
+ JsonElement pop = JsonFunctions.walk("europe", "france", "population").apply(europeMap());
+ Assert.assertEquals( (int)JsonFunctions.cast(Integer.class).apply(pop), 80*1000*1000 );
+ }
+
+ @Test
+ public void testWalk2() {
+ String weather = Functionals.chain(
+ JsonFunctions.walk("europe.uk.edinburgh.weather"),
+ JsonFunctions.cast(String.class) ).apply(europeMap());
+ Assert.assertEquals(weather, "wet");
+ }
+
+ @Test(expectedExceptions=NoSuchElementException.class)
+ public void testWalkWrong() {
+ Functionals.chain(
+ JsonFunctions.walk("europe", "spain", "barcelona"),
+ JsonFunctions.cast(String.class) ).apply(europeMap());
+ }
+
+
+ @Test
+ public void testWalkM() {
+ Maybe<JsonElement> pop = JsonFunctions.walkM("europe", "france", "population").apply( Maybe.of(europeMap()) );
+ Assert.assertEquals( (int)JsonFunctions.castM(Integer.class).apply(pop), 80*1000*1000 );
+ }
+
+ @Test
+ public void testWalkMWrong1() {
+ Maybe<JsonElement> m = JsonFunctions.walkM("europe", "spain", "barcelona").apply( Maybe.of( europeMap()) );
+ Assert.assertTrue(m.isAbsent());
+ }
+
+ @Test(expectedExceptions=Exception.class)
+ public void testWalkMWrong2() {
+ Maybe<JsonElement> m = JsonFunctions.walkM("europe", "spain", "barcelona").apply( Maybe.of( europeMap()) );
+ JsonFunctions.castM(String.class).apply(m);
+ }
+
+
+ @Test
+ public void testWalkN() {
+ JsonElement pop = JsonFunctions.walkN("europe", "france", "population").apply( europeMap() );
+ Assert.assertEquals( (int)JsonFunctions.cast(Integer.class).apply(pop), 80*1000*1000 );
+ }
+
+ @Test
+ public void testWalkNWrong1() {
+ JsonElement m = JsonFunctions.walkN("europe", "spain", "barcelona").apply( europeMap() );
+ Assert.assertNull(m);
+ }
+
+ public void testWalkNWrong2() {
+ JsonElement m = JsonFunctions.walkN("europe", "spain", "barcelona").apply( europeMap() );
+ String n = JsonFunctions.cast(String.class).apply(m);
+ Assert.assertNull(n);
+ }
+
+ @Test
+ public void testGetPath1(){
+ Integer obj = (Integer) JsonFunctions.getPath("$.europe.uk.edinburgh.population").apply(europeMap());
+ Assert.assertEquals((int) obj, 500*1000);
+ }
+
+ @Test
+ public void testGetPath2(){
+ String obj = (String) JsonFunctions.getPath("$.europe.uk.edinburgh.lighting").apply(europeMap());
+ Assert.assertEquals(obj, "dark");
+ }
+
+ @Test
+ public void testGetMissingPathIsNullOrThrows(){
+ try {
+ // TODO is there a way to force this to return null if not found?
+ // for me (Alex) it throws but for others it seems to return null
+ Object obj = JsonFunctions.getPath("$.europe.spain.malaga").apply(europeMap());
+ Assert.assertNull(obj);
+ } catch (PathNotFoundException e) {
+ // not unexpected
+ }
+ }
+
+}
[06/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to
o.a.b.core.effector
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java
new file mode 100644
index 0000000..76dcdba
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorSayHiTest.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.annotation.EffectorParam;
+import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.task.BasicTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+/**
+ * Test the operation of the {@link Effector} implementations.
+ *
+ * TODO clarify test purpose
+ */
+public class EffectorSayHiTest extends BrooklynAppUnitTestSupport {
+
+ //TODO test edge/error conditions
+ //(missing parameters, wrong number of params, etc)
+
+ private static final Logger log = LoggerFactory.getLogger(EffectorSayHiTest.class);
+
+ private MyEntity e;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
+ }
+
+ @Test
+ public void testFindEffectorMetaData() {
+ assertEquals("sayHi1", e.SAY_HI_1.getName());
+ assertEquals("says hello", e.SAY_HI_1.getDescription());
+
+ assertEquals(ImmutableList.of("name", "greeting"), getParameterNames(e.SAY_HI_1));
+ assertEquals(MutableMap.of("name", null, "greeting", "what to say"), getParameterDescriptions(e.SAY_HI_1));
+ }
+
+ @Test
+ public void testFindTraitEffectors() {
+ assertEquals(ImmutableList.of("locations"), getParameterNames(Startable.START));
+ }
+
+ @Test
+ public void testInvokeEffectors1() throws Exception {
+ assertEquals("hi Bob", e.sayHi1("Bob", "hi"));
+
+ assertEquals("hi Bob", e.SAY_HI_1.call(e, ImmutableMap.of("name", "Bob", "greeting", "hi")) );
+ assertEquals("hi Bob", e.invoke(e.SAY_HI_1, ImmutableMap.of("name", "Bob", "greeting", "hi")).get() );
+
+ // and with default greeting param value
+ assertEquals("hi Bob", e.SAY_HI_1.call(e, ImmutableMap.of("name", "Bob", "greeting", "hi")) );
+ assertEquals("hello Bob", e.invoke(e.SAY_HI_1, ImmutableMap.of("name", "Bob")).get() );
+ }
+
+ @Test
+ public void testCanRetrieveTaskForEffector() {
+ e.sayHi1("Bob", "hi");
+
+ Set<Task<?>> tasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+ BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
+ assertEquals(tasks.size(), 1);
+ assertTrue(tasks.iterator().next().getDescription().contains("sayHi1"));
+ }
+
+ @Test
+ public void testDelegatedNestedEffectorNotRepresentedAsTask() {
+ e.delegateSayHi1("Bob", "hi");
+
+ Set<Task<?>> tasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+ BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
+ assertEquals(tasks.size(), 1);
+ assertTrue(tasks.iterator().next().getDescription().contains("delegateSayHi1"));
+ assertFalse(tasks.iterator().next().getDescription().contains("sayHi1"));
+ }
+
+ @Test
+ public void testCanExcludeNonEffectorTasks() throws Exception {
+ ExecutionContext executionContext = mgmt.getExecutionContext(e);
+ executionContext.submit(new BasicTask<Void>(new Runnable() { public void run() {} }));
+
+ Set<Task<?>> effectTasks = mgmt.getExecutionManager().getTasksWithAllTags(ImmutableList.of(
+ BrooklynTaskTags.tagForContextEntity(e),ManagementContextInternal.EFFECTOR_TAG));
+ assertEquals(effectTasks.size(), 0);
+ }
+
+ public interface CanSayHi {
+ static MethodEffector<String> SAY_HI_1 = new MethodEffector<String>(CanSayHi.class, "sayHi1");
+ static MethodEffector<String> DELEGATE_SAY_HI_1 = new MethodEffector<String>(CanSayHi.class, "delegateSayHi1");
+
+ @org.apache.brooklyn.core.annotation.Effector(description="says hello")
+ public String sayHi1(
+ @EffectorParam(name="name") String name,
+ @EffectorParam(name="greeting", defaultValue="hello", description="what to say") String greeting);
+
+ @org.apache.brooklyn.core.annotation.Effector(description="delegate says hello")
+ public String delegateSayHi1(
+ @EffectorParam(name="name") String name,
+ @EffectorParam(name="greeting") String greeting);
+ }
+
+ @ImplementedBy(MyEntityImpl.class)
+ public interface MyEntity extends Entity, CanSayHi {
+ }
+
+ public static class MyEntityImpl extends AbstractEntity implements MyEntity {
+ @Override
+ public String sayHi1(String name, String greeting) {
+ return greeting+" "+name;
+ }
+ @Override
+ public String delegateSayHi1(String name, String greeting) {
+ return sayHi1(name, greeting);
+ }
+ }
+
+ private List<String> getParameterNames(Effector<?> effector) {
+ return ImmutableList.copyOf(getParameterDescriptions(effector).keySet());
+ }
+
+ private Map<String, String> getParameterDescriptions(Effector<?> effector) {
+ Map<String,String> result = Maps.newLinkedHashMap();
+ for (ParameterType<?> parameter : effector.getParameters()) {
+ result.put(parameter.getName(), parameter.getDescription());
+ }
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java
new file mode 100644
index 0000000..3e79aa9
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/EffectorTaskTest.java
@@ -0,0 +1,437 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.mgmt.HasTaskChildren;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.EffectorWithBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.TaskBuilder;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+public class EffectorTaskTest extends BrooklynAppUnitTestSupport {
+
+ // ----------- syntax 1 -- effector with body in a class
+
+ public static final Effector<Integer> DOUBLE_1 = Effectors.effector(Integer.class, "double")
+ .description("doubles the given number")
+ .parameter(Integer.class, "numberToDouble")
+ .impl(new EffectorBody<Integer>() {
+ @Override
+ public Integer call(ConfigBag parameters) {
+ // do a sanity check
+ Assert.assertNotNull(entity());
+
+ // finally double the input
+ return 2*(Integer)parameters.getStringKey("numberToDouble");
+ }
+ })
+ .build();
+
+ public static class DoublingEntity extends AbstractEntity {
+ public static final Effector<Integer> DOUBLE = EffectorTaskTest.DOUBLE_1;
+ }
+
+ @Test
+ public void testSyntaxOneDouble1() throws Exception {
+ // just use "dynamic" support of effector
+ Assert.assertEquals(app.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+ @Test
+ public void testSyntaxOneTaggedCorrectly() throws Exception {
+ Task<Integer> t = app.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3));
+ t.get();
+ checkTags(t, app, DOUBLE_1, false);
+ }
+
+ @Test
+ // also assert it works when the effector is defined on an entity
+ public void testSimpleEffectorOnEntity() throws Exception {
+ Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
+
+ Assert.assertEquals(doubler.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+ @Test
+ // also assert it works when an abstract effector name is passed in to the entity
+ public void testSimpleEffectorNameMatching() throws Exception {
+ Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
+
+ Assert.assertEquals(doubler.invoke(Effectors.effector(Integer.class, "double").buildAbstract(), MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+
+ // ----------- syntax 2 -- effector with body built with fluent API
+
+ public static EffectorTaskFactory<Integer> times(final EffectorTaskFactory<Integer> x, final int y) {
+ return new EffectorTaskFactory<Integer>() {
+ @Override
+ public Task<Integer> newTask(final Entity entity, final Effector<Integer> effector, final ConfigBag parameters) {
+ return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() {
+ return DynamicTasks.get( x.newTask(entity, effector, parameters) )*y;
+ } }).build();
+ }
+ };
+ }
+
+ public static final Effector<Integer> DOUBLE_2 = Effectors.effector(Integer.class, "double")
+ .description("doubles the given number")
+ .parameter(Integer.class, "numberToDouble")
+ .impl(times(EffectorTasks.parameter(Integer.class, "numberToDouble"), 2))
+ .build();
+
+ @Test
+ public void testSyntaxTwoDouble2() throws Exception {
+ Assert.assertEquals(app.invoke(DOUBLE_2, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+ @Test
+ public void testEffectorImplTaggedCorrectly() throws Exception {
+ Task<Integer> t = app.invoke(DOUBLE_2, MutableMap.of("numberToDouble", 3));
+ t.get();
+ checkTags(t, app, DOUBLE_2, true);
+ }
+
+ public static final Effector<Integer> DOUBLE_CALL_ABSTRACT = Effectors.effector(Integer.class, "double_call")
+ .description("doubles the given number")
+ .parameter(Integer.class, "numberToDouble")
+ .buildAbstract();
+ public static final Effector<Integer> DOUBLE_CALL = Effectors.effector(DOUBLE_CALL_ABSTRACT)
+ .impl(new EffectorBody<Integer>() {
+ @Override
+ public Integer call(ConfigBag parameters) {
+ final Entity parent = entity();
+ final Entity child = Iterables.getOnlyElement(entity().getChildren());
+
+ final Effector<Integer> DOUBLE_CHECK_ABSTRACT = Effectors.effector(Integer.class, "double_check")
+ .description("doubles the given number and checks tags, assuming double exists as an effector here")
+ .parameter(Integer.class, "numberToDouble")
+ .buildAbstract();
+ Effector<Integer> DOUBLE_CHECK = Effectors.effector(DOUBLE_CHECK_ABSTRACT)
+ .impl(new EffectorBody<Integer>() {
+ @Override
+ public Integer call(ConfigBag parameters) {
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, null, false));
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_CHECK_ABSTRACT, false));
+ Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), child, DOUBLE_1, false));
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, true));
+ Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, null, false));
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_CALL_ABSTRACT, true));
+ Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(Tasks.current(), parent, DOUBLE_1, true));
+
+ return entity().invoke(DOUBLE_1, parameters.getAllConfig()).getUnchecked();
+ }
+ }).build();
+
+ return child.invoke(DOUBLE_CHECK, parameters.getAllConfig()).getUnchecked();
+ }
+ }).build();
+
+
+ @Test
+ // also assert it works when the effector is defined on an entity
+ public void testNestedEffectorTag() throws Exception {
+ app.createAndManageChild(EntitySpec.create(Entity.class, DoublingEntity.class));
+ Assert.assertEquals(app.invoke(DOUBLE_CALL, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+
+ private void checkTags(Task<Integer> t, Entity entity, Effector<?> eff, boolean shouldHaveChild) {
+ Assert.assertEquals(BrooklynTaskTags.getContextEntity(t), app);
+ Assert.assertTrue(t.getTags().contains(BrooklynTaskTags.EFFECTOR_TAG), "missing effector tag; had: "+t.getTags());
+ Assert.assertTrue(t.getDescription().contains(eff.getName()), "description missing effector name: "+t.getDescription());
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(t, entity, eff, false));
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(t, null, null, false));
+ Assert.assertFalse(BrooklynTaskTags.isInEffectorTask(t, entity, Startable.START, false));
+
+ if (shouldHaveChild) {
+ Task<?> subtask = ((HasTaskChildren)t).getChildren().iterator().next();
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(subtask, entity, eff, false));
+ Assert.assertTrue(BrooklynTaskTags.isInEffectorTask(subtask, null, null, false));
+ }
+ }
+
+ // TEST parameter task missing
+
+ // ----------------- syntax for more complex -- an effector using subtasks
+
+ public static Task<Integer> add(final int x, final int y) {
+ return TaskBuilder.<Integer>builder().name("add").body(new Callable<Integer>() { public Integer call() { return x+y; } }).build();
+ }
+
+ public static Task<Integer> add(final Task<Integer> x, final int y) {
+ return TaskBuilder.<Integer>builder().name("add").body(new Callable<Integer>() { public Integer call() { return DynamicTasks.get(x)+y; } }).build();
+ }
+
+ public static Task<Integer> addBasic(final Task<Integer> x, final int y) {
+ return TaskBuilder.<Integer>builder().name("add (not dynamic)").dynamic(false).body(new Callable<Integer>() { public Integer call() {
+ Preconditions.checkState(x.isSubmitted());
+ return x.getUnchecked()+y;
+ } }).build();
+ }
+
+ public static Task<Integer> times(final int x, final int y) {
+ return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { return x*y; } }).build();
+ }
+
+ public static Task<Integer> times(final Task<Integer> x, final int y) {
+ return TaskBuilder.<Integer>builder().name("times").body(new Callable<Integer>() { public Integer call() { return DynamicTasks.get(x)*y; } }).build();
+ }
+
+ public static final Effector<Integer> TWO_X_PLUS_ONE = Effectors.effector(Integer.class, "twoXPlusOne")
+ .description("doubles the given number and adds one")
+ .parameter(Integer.class, "numberToStartWith")
+ .impl(new EffectorBody<Integer>() {
+ public Integer call(ConfigBag parameters) {
+ int input = (Integer)parameters.getStringKey("numberToStartWith");
+ queue( add(times(input, 2), 1) );
+ return last(Integer.class);
+ }
+ })
+ .build();
+
+ public static final Effector<Integer> TWO_X_PLUS_ONE_BASIC = Effectors.effector(Integer.class, "twoXPlusOne_Basic")
+ .description("doubles the given number and adds one, as a basic task")
+ .parameter(Integer.class, "numberToStartWith")
+ .impl(new EffectorBody<Integer>() {
+ public Integer call(ConfigBag parameters) {
+ int input = (Integer)parameters.getStringKey("numberToStartWith");
+ // note the subtasks must be queued explicitly with a basic task
+ // (but with the DynamicSequentialTask they can be resolved by the task itself; see above)
+ Task<Integer> product = queue(times(input, 2));
+ queue( addBasic(product, 1) );
+ return last(Integer.class);
+ }
+ })
+ .build();
+
+ // TODO a chaining style approach
+
+ public static class Txp1Entity extends AbstractEntity {
+ public static final Effector<Integer> TWO_X_P_1 = EffectorTaskTest.TWO_X_PLUS_ONE;
+ }
+
+ /** the composed effector should allow us to inspect its children */
+ @Test
+ public void testComposedEffector() throws Exception {
+ Entity txp1 = app.createAndManageChild(EntitySpec.create(Entity.class, Txp1Entity.class));
+
+ Task<Integer> e = txp1.invoke(TWO_X_PLUS_ONE, MutableMap.of("numberToStartWith", 3));
+ Assert.assertTrue(e instanceof DynamicSequentialTask);
+ Assert.assertEquals(e.get(), (Integer)7);
+ Assert.assertEquals( Iterables.size( ((HasTaskChildren)e).getChildren() ), 1);
+ Task<?> child = ((HasTaskChildren)e).getChildren().iterator().next();
+ Assert.assertEquals( Iterables.size( ((HasTaskChildren)child).getChildren() ), 1);
+ }
+
+ /** the composed effector should allow us to inspect its children */
+ @Test
+ public void testComposedEffectorBasic() throws Exception {
+ Entity txp1 = app.createAndManageChild(EntitySpec.create(Entity.class, Txp1Entity.class));
+
+ Task<Integer> e = txp1.invoke(TWO_X_PLUS_ONE_BASIC, MutableMap.of("numberToStartWith", 3));
+ Assert.assertTrue(e instanceof DynamicSequentialTask);
+ Assert.assertEquals(e.get(), (Integer)7);
+ Assert.assertEquals( Iterables.size( ((HasTaskChildren)e).getChildren() ), 2);
+ }
+
+ // --------- defining
+
+ @Test
+ public void testEffectorWithBodyWorksEvenIfNotOnEntity() throws Exception {
+ Entity doubler = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ Assert.assertEquals(doubler.invoke(DOUBLE_1, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+ public static final Effector<Integer> DOUBLE_BODYLESS = Effectors.effector(Integer.class, "double")
+ .description("doubles the given number")
+ .parameter(Integer.class, "numberToDouble")
+ .buildAbstract();
+
+ @Test
+ public void testEffectorWithoutBodyFails() throws Exception {
+ Entity doubler = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ boolean failed = false;
+ try {
+ doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3));
+ } catch (Exception e) {
+ failed = true;
+ }
+ if (!failed) Assert.fail("doubling should have failed because it had no body");
+ }
+
+ @Test
+ public void testEffectorBodyAdded() throws Exception {
+ EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ // not yet present
+ Assert.assertNull( doubler.getEffector("double") );
+
+ // add it
+ doubler.getMutableEntityType().addEffector(DOUBLE_BODYLESS, new EffectorBody<Integer>() {
+ @Override
+ public Integer call(ConfigBag parameters) {
+ int input = (Integer)parameters.getStringKey("numberToDouble");
+ return queue(times(input, 2)).getUnchecked();
+ }
+ });
+ // now it is present
+ Assert.assertNotNull( doubler.getEffector("double") );
+
+ Assert.assertEquals(doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+ @Test
+ public void testEffectorBodyAddedImplicitlyButBodylessSignatureInvoked() throws Exception {
+ EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ // add it
+ doubler.getMutableEntityType().addEffector(DOUBLE_1);
+
+ // invoke it, but using something with equivalent name (and signature -- though only name is used currently)
+ // ensures that the call picks up the body by looking in the actual entity
+ Assert.assertEquals(doubler.invoke(DOUBLE_BODYLESS, MutableMap.of("numberToDouble", 3)).get(), (Integer)6);
+ }
+
+ @Test(dependsOnMethods={"testEffectorBodyAdded"})
+ public void testEntityNotPermanentlyChanged() throws Exception {
+ EntityInternal doubler = (EntityInternal) app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ // ensures that independent creations of the class previously modified do not have this effector
+ Assert.assertNull( doubler.getEffector("double") );
+ }
+
+ // --- overriding by using statics ---------
+
+ public static class BadDoublingEntity extends DoublingEntity {
+ public static final Effector<Integer> DOUBLE = Effectors.effector(DoublingEntity.DOUBLE).
+ impl( ((EffectorWithBody<Integer>)TWO_X_PLUS_ONE).getBody() ).build();
+ }
+
+ @Test
+ // also assert it works when the entity is defined on an entity
+ public void testOverriddenEffectorOnEntity() throws Exception {
+ Entity doubler = app.createAndManageChild(EntitySpec.create(Entity.class, BadDoublingEntity.class));
+
+ Assert.assertEquals(doubler.invoke(DoublingEntity.DOUBLE, MutableMap.of("numberToDouble", 3, "numberToStartWith", 3)).get(), (Integer)7);
+ }
+
+ public static final Effector<Void> DUMMY = Effectors.effector(Void.class, "dummy")
+ .impl(new EffectorBody<Void>() {
+ @Override
+ public Void call(ConfigBag parameters) {
+ return null;
+ }
+ })
+ .build();
+
+ public static final Effector<Void> STALL = Effectors.effector(Void.class, "stall")
+ .parameter(AtomicBoolean.class, "lock")
+ .impl(new EffectorBody<Void>() {
+ @Override
+ public Void call(ConfigBag parameters) {
+ AtomicBoolean lock = (AtomicBoolean)parameters.getStringKey("lock");
+ synchronized(lock) {
+ if (!lock.get()) {
+ try {
+ lock.wait();
+ } catch (InterruptedException e) {
+ Exceptions.propagate(e);
+ }
+ }
+ }
+ return null;
+ }
+ })
+ .build();
+
+ public static final Effector<Void> CONTEXT = Effectors.effector(Void.class, "stall_caller")
+ .parameter(AtomicBoolean.class, "lock")
+ .impl(new EffectorBody<Void>() {
+ @Override
+ public Void call(ConfigBag parameters) {
+ Entity child = Iterables.getOnlyElement(entity().getChildren());
+ AtomicBoolean lock = new AtomicBoolean();
+ Task<Void> dummyTask = null;
+
+ try {
+ // Queue a (DST secondary) task which waits until notified, so that tasks queued later will get blocked
+ queue(Effectors.invocation(entity(), STALL, ImmutableMap.of("lock", lock)));
+
+ // Start a new task - submitted directly to child's ExecutionContext, as well as added as a
+ // DST secondary of the current effector.
+ dummyTask = child.invoke(DUMMY, ImmutableMap.<String, Object>of());
+ dummyTask.getUnchecked();
+
+ // Execution completed in the child's ExecutionContext, but still queued as a secondary.
+ // Destroy the child entity so that no subsequent tasks can be executed in its context.
+ Entities.destroy(child);
+ } finally {
+ // Let STALL complete
+ synchronized(lock) {
+ lock.set(true);
+ lock.notifyAll();
+ }
+ // At this point DUMMY will be unblocked and the DST will try to execute it as a secondary.
+ // Submission will be ignored because DUMMY already executed.
+ // If it's not ignored then submission will fail because entity is already unmanaged.
+ }
+ return null;
+ }
+ })
+ .build();
+
+
+ @Test
+ public void testNestedEffectorExecutedAsSecondaryTask() throws Exception {
+ app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ Task<Void> effTask = app.invoke(CONTEXT, ImmutableMap.<String, Object>of());
+ effTask.get();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java b/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java
new file mode 100644
index 0000000..fce676a
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/effector/ssh/SshEffectorTasksTest.java
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasksTest;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+import com.google.common.io.Files;
+
+public class SshEffectorTasksTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
+
+ TestApplication app;
+ ManagementContext mgmt;
+ SshMachineLocation host;
+ File tempDir;
+
+ boolean failureExpected;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setup() throws Exception {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ mgmt = app.getManagementContext();
+
+ LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+ host = lhc.obtain();
+ app.start(Arrays.asList(host));
+ clearExpectedFailure();
+ tempDir = Files.createTempDir();
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (mgmt != null) Entities.destroyAll(mgmt);
+ mgmt = null;
+ FileUtils.deleteDirectory(tempDir);
+ checkExpectedFailure();
+ }
+
+ protected void checkExpectedFailure() {
+ if (failureExpected) {
+ clearExpectedFailure();
+ Assert.fail("Test should have thrown an exception but it did not.");
+ }
+ }
+
+ protected void clearExpectedFailure() {
+ failureExpected = false;
+ }
+
+ protected void setExpectingFailure() {
+ failureExpected = true;
+ }
+
+ public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
+ return Entities.submit(app, taskFactory);
+ }
+
+ // ------------------- basic ssh
+
+ @Test(groups="Integration")
+ public void testSshEchoHello() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
+ Assert.assertFalse(t.isDone());
+ Assert.assertEquals(t.get(), (Integer)0);
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ Assert.assertEquals(t.getStdout().trim(), "hello world");
+ }
+
+ @Test(groups="Integration")
+ public void testSshPut() throws IOException {
+ String fn = Urls.mergePaths(tempDir.getPath(), "f1");
+ SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
+ t.block();
+ Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
+ // and make sure this doesn't throw
+ Assert.assertTrue(t.isDone());
+ Assert.assertTrue(t.isSuccessful());
+ Assert.assertEquals(t.get(), null);
+ Assert.assertEquals(t.getExitCode(), (Integer)0);
+ }
+
+ @Test(groups="Integration")
+ public void testSshFetch() throws IOException {
+ String fn = Urls.mergePaths(tempDir.getPath(), "f2");
+ FileUtils.write(new File(fn), "hello fetched world");
+
+ SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
+ t.block();
+
+ Assert.assertTrue(t.isDone());
+ Assert.assertEquals(t.get(), "hello fetched world");
+ }
+
+ // ----------------- pid stuff
+
+ @Test(groups="Integration")
+ public void testNonRunningPid() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
+ Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
+ Assert.assertNotEquals(t.getExitCode(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
+ Assert.assertFalse(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testNonRunningPidRequired() {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ }
+ checkExpectedFailure();
+ }
+
+ public static Integer getMyPid() {
+ try {
+ java.lang.management.RuntimeMXBean runtime =
+ java.lang.management.ManagementFactory.getRuntimeMXBean();
+ java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
+ jvm.setAccessible(true);
+// sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+ Object mgmt = jvm.get(runtime);
+ java.lang.reflect.Method pid_method =
+ mgmt.getClass().getDeclaredMethod("getProcessId");
+ pid_method.setAccessible(true);
+
+ return (Integer) pid_method.invoke(mgmt);
+ } catch (Exception e) {
+ throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
+ }
+ }
+
+ @Test(groups="Integration")
+ public void testRunningPid() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
+ Assert.assertTrue(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testRunningPidFromFile() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
+ Assert.assertTrue(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailure() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( "99999".getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)1);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)1);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)2);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnSuccess() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+
+ t.getTask().getUnchecked();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
+
+ t.getTask().getUnchecked();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
index 885eb45..fb9276c 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/DynamicEntityTest.java
@@ -24,10 +24,10 @@ import static org.testng.Assert.assertFalse;
import org.apache.brooklyn.api.entity.EntityInitializer;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.effector.EffectorTaskTest;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.EffectorTaskTest;
import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.util.collections.MutableMap;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
index c01c5c9..cead05a 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
@@ -47,13 +47,13 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.sensor.core.BasicSensorEvent;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
index 9d14868..a217514 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
@@ -25,7 +25,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.group.AbstractGroup;
import org.apache.brooklyn.sensor.core.BasicSensor;
import org.apache.brooklyn.sensor.core.Sensors;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
index f648419..1d50609 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/osgi/OsgiVersionMoreEntityTest.java
@@ -42,6 +42,7 @@ import org.apache.brooklyn.core.catalog.internal.CatalogItemBuilder;
import org.apache.brooklyn.core.catalog.internal.CatalogItemDtoAbstract;
import org.apache.brooklyn.core.catalog.internal.CatalogTestUtils;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.classloading.BrooklynClassLoadingContext;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
@@ -50,7 +51,6 @@ import org.apache.brooklyn.core.objs.proxy.InternalEntityFactory;
import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
import org.apache.brooklyn.util.core.osgi.Osgis;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
index c25dd0e..3b9bbfb 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityDynamicTypeInfoTest.java
@@ -29,10 +29,10 @@ import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.stream.Streams;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
index 2106f18..8c185a0 100644
--- a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
@@ -36,11 +36,11 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.ListConfigKey;
import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.config.SetConfigKey;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java
deleted file mode 100644
index 786fe69..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorBasicTest.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import java.util.List;
-import java.util.concurrent.Callable;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.mgmt.HasTaskChildren;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.trait.FailingEntity;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.location.SimulatedLocation;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.test.TestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-
-public class EffectorBasicTest extends BrooklynAppUnitTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(EffectorBasicTest.class);
-
- // NB: more tests of effectors in EffectorSayHiTest and EffectorConcatenateTest
- // as well as EntityConfigMapUsageTest and others
-
- private List<SimulatedLocation> locs;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- locs = ImmutableList.of(new SimulatedLocation());
- }
-
- @Test
- public void testInvokeEffectorStart() {
- app.start(locs);
- TestUtils.assertSetsEqual(locs, app.getLocations());
- // TODO above does not get registered as a task
- }
-
- @Test
- public void testInvokeEffectorStartWithMap() {
- app.invoke(Startable.START, MutableMap.of("locations", locs)).getUnchecked();
- TestUtils.assertSetsEqual(locs, app.getLocations());
- }
-
- @Test
- public void testInvokeEffectorStartWithArgs() {
- Entities.invokeEffectorWithArgs((EntityLocal)app, app, Startable.START, locs).getUnchecked();
- TestUtils.assertSetsEqual(locs, app.getLocations());
- }
-
- @Test
- public void testInvokeEffectorStartWithTwoEntities() {
- TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- TestEntity entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(locs);
- TestUtils.assertSetsEqual(locs, app.getLocations());
- TestUtils.assertSetsEqual(locs, entity.getLocations());
- TestUtils.assertSetsEqual(locs, entity2.getLocations());
- }
-
- @Test
- public void testInvokeEffectorTaskHasTag() {
- Task<Void> starting = app.invoke(Startable.START, MutableMap.of("locations", locs));
-// log.info("TAGS: "+starting.getTags());
- Assert.assertTrue(starting.getTags().contains(ManagementContextInternal.EFFECTOR_TAG));
- }
-
- // check various failure situations
-
- private FailingEntity createFailingEntity() {
- FailingEntity entity = app.createAndManageChild(EntitySpec.create(FailingEntity.class)
- .configure(FailingEntity.FAIL_ON_START, true));
- return entity;
- }
-
- // uncaught failures are propagates
-
- @Test
- public void testInvokeEffectorStartFailing_Method() {
- FailingEntity entity = createFailingEntity();
- assertStartMethodFails(entity);
- }
-
- @Test
- public void testInvokeEffectorStartFailing_EntityInvoke() {
- FailingEntity entity = createFailingEntity();
- assertTaskFails( entity.invoke(Startable.START, MutableMap.of("locations", locs)) );
- }
-
- @Test
- public void testInvokeEffectorStartFailing_EntitiesInvoke() {
- FailingEntity entity = createFailingEntity();
-
- assertTaskFails( Entities.invokeEffectorWithArgs(entity, entity, Startable.START, locs) );
- }
-
- // caught failures are NOT propagated!
-
- @Test
- public void testInvokeEffectorStartFailing_MethodInDynamicTask() {
- Task<Void> task = app.getExecutionContext().submit(Tasks.<Void>builder().dynamic(true).body(new Callable<Void>() {
- @Override public Void call() throws Exception {
- testInvokeEffectorStartFailing_Method();
- return null;
- }
- }).build());
-
- assertTaskSucceeds(task);
- assertTaskHasFailedChild(task);
- }
-
- @Test
- public void testInvokeEffectorStartFailing_MethodInTask() {
- Task<Void> task = app.getExecutionContext().submit(Tasks.<Void>builder().dynamic(false).body(new Callable<Void>() {
- @Override public Void call() throws Exception {
- testInvokeEffectorStartFailing_Method();
- return null;
- }
- }).build());
-
- assertTaskSucceeds(task);
- }
-
- private void assertTaskSucceeds(Task<Void> task) {
- task.getUnchecked();
- Assert.assertFalse(task.isError());
- }
-
- private void assertTaskHasFailedChild(Task<Void> task) {
- Assert.assertTrue(Tasks.failed( ((HasTaskChildren)task).getChildren() ).iterator().hasNext());
- }
-
- private void assertStartMethodFails(FailingEntity entity) {
- try {
- entity.start(locs);
- Assert.fail("Should have failed");
- } catch (Exception e) {
- // expected
- }
- }
-
- protected void assertTaskFails(Task<?> t) {
- try {
- t.get();
- Assert.fail("Should have failed");
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- // expected
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java
deleted file mode 100644
index 9372e41..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorConcatenateTest.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.fail;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ExecutionManager;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.core.annotation.Effector;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
-import org.apache.brooklyn.effector.core.MethodEffector;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.BasicExecutionContext;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
-public class EffectorConcatenateTest {
-
-
- private static final Logger log = LoggerFactory.getLogger(EffectorConcatenateTest.class);
- private static final long TIMEOUT = 10*1000;
-
- public static class MyEntityImpl extends AbstractEntity {
-
- public static MethodEffector<String> CONCATENATE = new MethodEffector<String>(MyEntityImpl.class, "concatenate");
- public static MethodEffector<Void> WAIT_A_BIT = new MethodEffector<Void>(MyEntityImpl.class, "waitabit");
- public static MethodEffector<Void> SPAWN_CHILD = new MethodEffector<Void>(MyEntityImpl.class, "spawnchild");
-
- public MyEntityImpl() {
- super();
- }
- public MyEntityImpl(Entity parent) {
- super(parent);
- }
-
- /** The "current task" representing the effector currently executing */
- AtomicReference<Task<?>> waitingTask = new AtomicReference<Task<?>>();
-
- /** latch is .countDown'ed by the effector at the beginning of the "waiting" point */
- CountDownLatch nowWaitingLatch = new CountDownLatch(1);
-
- /** latch is await'ed on by the effector when it is in the "waiting" point */
- CountDownLatch continueFromWaitingLatch = new CountDownLatch(1);
-
- @Effector(description="sample effector concatenating strings")
- public String concatenate(@EffectorParam(name="first", description="first argument") String first,
- @EffectorParam(name="second", description="2nd arg") String second) throws Exception {
- return first+second;
- }
-
- @Effector(description="sample effector doing some waiting")
- public void waitabit() throws Exception {
- waitingTask.set(Tasks.current());
-
- Tasks.setExtraStatusDetails("waitabit extra status details");
-
- Tasks.withBlockingDetails("waitabit.blocking", new Callable<Void>() {
- public Void call() throws Exception {
- nowWaitingLatch.countDown();
- if (!continueFromWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
- fail("took too long to be told to continue");
- }
- return null;
- }});
- }
-
- @Effector(description="sample effector that spawns a child task that waits a bit")
- public void spawnchild() throws Exception {
- // spawn a child, then wait
- BasicExecutionContext.getCurrentExecutionContext().submit(
- MutableMap.of("displayName", "SpawnedChildName"),
- new Callable<Void>() {
- public Void call() throws Exception {
- log.info("beginning spawned child response "+Tasks.current()+", with tags "+Tasks.current().getTags());
- Tasks.setBlockingDetails("spawned child blocking details");
- nowWaitingLatch.countDown();
- if (!continueFromWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
- fail("took too long to be told to continue");
- }
- return null;
- }});
- }
- }
-
- private TestApplication app;
- private MyEntityImpl e;
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() {
- app = new TestApplicationImpl();
- e = new MyEntityImpl(app);
- Entities.startManagement(app);
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() {
- if (app != null) Entities.destroyAll(app.getManagementContext());
- }
-
- @Test
- public void testCanInvokeEffector() throws Exception {
- // invocation map syntax
- Task<String> task = e.invoke(MyEntityImpl.CONCATENATE, ImmutableMap.of("first", "a", "second", "b"));
- assertEquals(task.get(TIMEOUT, TimeUnit.MILLISECONDS), "ab");
-
- // method syntax
- assertEquals("xy", e.concatenate("x", "y"));
- }
-
- @Test
- public void testReportsTaskDetails() throws Exception {
- final AtomicReference<String> result = new AtomicReference<String>();
-
- Thread bg = new Thread(new Runnable() {
- public void run() {
- try {
- // Expect "wait a bit" to tell us it's blocking
- if (!e.nowWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
- result.set("took too long for waitabit to be waiting");
- return;
- }
-
- // Expect "wait a bit" to have retrieved and set its task
- try {
- Task<?> t = e.waitingTask.get();
- String status = t.getStatusDetail(true);
- log.info("waitabit task says:\n"+status);
- if (!status.contains("waitabit extra status details")) {
- result.set("Status not in expected format: doesn't contain extra status details phrase 'My extra status details'\n"+status);
- return;
- }
- if (!status.startsWith("waitabit.blocking")) {
- result.set("Status not in expected format: doesn't start with blocking details 'waitabit.blocking'\n"+status);
- return;
- }
- } finally {
- e.continueFromWaitingLatch.countDown();
- }
- } catch (Throwable t) {
- log.warn("Failure: "+t, t);
- result.set("Failure: "+t);
- }
- }});
- bg.start();
-
- e.invoke(MyEntityImpl.WAIT_A_BIT, ImmutableMap.<String,Object>of())
- .get(TIMEOUT, TimeUnit.MILLISECONDS);
-
- bg.join(TIMEOUT*2);
- assertFalse(bg.isAlive());
-
- String problem = result.get();
- if (problem!=null) fail(problem);
- }
-
- @Test
- public void testReportsSpawnedTaskDetails() throws Exception {
- final AtomicReference<String> result = new AtomicReference<String>();
-
- Thread bg = new Thread(new Runnable() {
- public void run() {
- try {
- // Expect "spawned child" to tell us it's blocking
- if (!e.nowWaitingLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) {
- result.set("took too long for spawnchild's sub-task to be waiting");
- return;
- }
-
- // Expect spawned task to be have been tagged with entity
- ExecutionManager em = e.getManagementContext().getExecutionManager();
- Task<?> subtask = Iterables.find(BrooklynTaskTags.getTasksInEntityContext(em, e), new Predicate<Task<?>>() {
- public boolean apply(Task<?> input) {
- return "SpawnedChildName".equals(input.getDisplayName());
- }
- });
-
- // Expect spawned task to haev correct "blocking details"
- try {
- String status = subtask.getStatusDetail(true);
- log.info("subtask task says:\n"+status);
- if (!status.contains("spawned child blocking details")) {
- result.set("Status not in expected format: doesn't contain blocking details phrase 'spawned child blocking details'\n"+status);
- return;
- }
- } finally {
- e.continueFromWaitingLatch.countDown();
- }
- } catch (Throwable t) {
- log.warn("Failure: "+t, t);
- result.set("Failure: "+t);
- }
- }});
- bg.start();
-
- e.invoke(MyEntityImpl.SPAWN_CHILD, ImmutableMap.<String,Object>of())
- .get(TIMEOUT, TimeUnit.MILLISECONDS);
-
- bg.join(TIMEOUT*2);
- assertFalse(bg.isAlive());
-
- String problem = result.get();
- if (problem!=null) fail(problem);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java
deleted file mode 100644
index b8b6bf4..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorMetadataTest.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core;
-
-import static org.testng.Assert.assertEquals;
-
-import java.util.Collection;
-import java.util.List;
-
-import org.apache.brooklyn.api.effector.Effector;
-import org.apache.brooklyn.api.effector.ParameterType;
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.core.annotation.EffectorParam;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.effector.core.BasicParameterType;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.MethodEffector;
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Test the operation of the {@link Effector} implementations.
- *
- * TODO clarify test purpose
- */
-public class EffectorMetadataTest extends BrooklynAppUnitTestSupport {
-
- private MyAnnotatedEntity e1;
- private MyOverridingEntity e2;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- e1 = app.createAndManageChild(EntitySpec.create(MyAnnotatedEntity.class));
- e2 = app.createAndManageChild(EntitySpec.create(MyOverridingEntity.class));
- }
-
- @Test
- public void testEffectorMetaDataFromAnnotationsWithConstant() {
- Effector<?> effector = EffectorUtils.findEffectorDeclared(e1, "effWithNewAnnotation").get();
- Assert.assertTrue(Effectors.sameSignature(effector, MyAnnotatedEntity.EFF_WITH_NEW_ANNOTATION));
- assertEquals(effector.getName(), "effWithNewAnnotation");
- assertEquals(effector.getDescription(), "my effector description");
- assertEquals(effector.getReturnType(), String.class);
- assertParametersEqual(
- effector.getParameters(),
- ImmutableList.<ParameterType<?>>of(
- new BasicParameterType<String>("param1", String.class, "my param description", "my default val")));
- }
-
- @Test
- public void testEffectorMetaDataFromAnnotationsWithoutConstant() {
- Effector<?> effector = EffectorUtils.findEffectorDeclared(e1, "effWithAnnotationButNoConstant").get();
- assertEquals(effector.getName(), "effWithAnnotationButNoConstant");
- assertEquals(effector.getDescription(), "my effector description");
- assertEquals(effector.getReturnType(), String.class);
- assertParametersEqual(
- effector.getParameters(),
- ImmutableList.<ParameterType<?>>of(
- new BasicParameterType<String>("param1", String.class, "my param description", "my default val")));
- }
-
- @SuppressWarnings("rawtypes")
- @Test
- public void testEffectorMetaDataFromOverriddenMethod() {
- // Overridden with new annotations
- Effector<?> startEffector = EffectorUtils.findEffectorDeclared(e2, "start").get();
- assertEquals(startEffector.getName(), "start");
- assertEquals(startEffector.getDescription(), "My overridden start description");
- assertEquals(startEffector.getReturnType(), void.class);
- assertParametersEqual(
- startEffector.getParameters(),
- ImmutableList.<ParameterType<?>>of(
- new BasicParameterType<Collection>("locations", Collection.class, "my overridden param description", null)));
- }
-
- private void assertParametersEqual(List<ParameterType<?>> actuals, List<ParameterType<?>> expecteds) {
- assertEquals(actuals.size(), expecteds.size(), "actual="+actuals);
- for (int i = 0; i < actuals.size(); i++) {
- ParameterType<?> actual = actuals.get(i);
- ParameterType<?> expected = expecteds.get(i);
- assertParameterEqual(actual, expected);
- }
- }
-
- private void assertParameterEqual(ParameterType<?> actual, ParameterType<?> expected) {
- assertEquals(actual.getName(), expected.getName(), "actual="+actual);
- assertEquals(actual.getDescription(), expected.getDescription(), "actual="+actual);
- assertEquals(actual.getParameterClass(), expected.getParameterClass(), "actual="+actual);
- assertEquals(actual.getParameterClassName(), expected.getParameterClassName(), "actual="+actual);
- }
-
- @ImplementedBy(MyAnnotatedEntityImpl.class)
- public interface MyAnnotatedEntity extends Entity {
- static MethodEffector<String> EFF_WITH_NEW_ANNOTATION = new MethodEffector<String>(MyAnnotatedEntity.class, "effWithNewAnnotation");
-
- @org.apache.brooklyn.core.annotation.Effector(description="my effector description")
- public String effWithNewAnnotation(
- @EffectorParam(name="param1", defaultValue="my default val", description="my param description") String param1);
-
- @org.apache.brooklyn.core.annotation.Effector(description="my effector description")
- public String effWithAnnotationButNoConstant(
- @EffectorParam(name="param1", defaultValue="my default val", description="my param description") String param1);
- }
-
- public static class MyAnnotatedEntityImpl extends AbstractEntity implements MyAnnotatedEntity {
- @Override
- public String effWithNewAnnotation(String param1) {
- return param1;
- }
-
- @Override
- public String effWithAnnotationButNoConstant(String param1) {
- return param1;
- }
- }
-
- @ImplementedBy(MyOverridingEntityImpl.class)
- public interface MyOverridingEntity extends Entity, Startable {
- org.apache.brooklyn.api.effector.Effector<Void> START = Effectors.effector(Startable.START)
- .description("My overridden start description")
- .parameter(Collection.class, "locations", "my overridden param description")
- .build();
- }
-
- public static class MyOverridingEntityImpl extends AbstractEntity implements MyOverridingEntity {
-
- @Override
- public void restart() {
- }
-
- @Override
- public void start(Collection<? extends Location> locations2) {
- }
-
- @Override
- public void stop() {
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy b/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy
deleted file mode 100644
index ec5c442..0000000
--- a/core/src/test/java/org/apache/brooklyn/effector/core/EffectorSayHiGroovyTest.groovy
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.effector.core
-
-import static org.testng.Assert.*
-
-import org.apache.brooklyn.api.effector.Effector
-import org.apache.brooklyn.api.entity.Entity
-import org.apache.brooklyn.api.entity.EntitySpec
-import org.apache.brooklyn.api.entity.ImplementedBy
-import org.apache.brooklyn.api.mgmt.ManagementContext
-import org.apache.brooklyn.api.mgmt.Task
-import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.core.mgmt.internal.EffectorUtils
-import org.apache.brooklyn.core.test.entity.TestApplication
-import org.apache.brooklyn.core.annotation.EffectorParam
-import org.apache.brooklyn.core.entity.AbstractEntity
-import org.apache.brooklyn.core.entity.Entities
-import org.apache.brooklyn.core.entity.trait.Startable
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-/**
- * Test the operation of the {@link Effector} implementations.
- *
- * TODO clarify test purpose
- */
-public class EffectorSayHiGroovyTest {
- private static final Logger log = LoggerFactory.getLogger(EffectorSayHiTest.class);
-
- private TestApplication app;
- private MyEntity e;
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() {
- app = TestApplication.Factory.newManagedInstanceForTests();
- e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() {
- if (app != null) Entities.destroyAll(app.getManagementContext());
- }
-
- @Test
- public void testFindEffectors() {
- assertEquals("sayHi1", e.SAY_HI_1.getName());
- assertEquals(["name", "greeting"], e.SAY_HI_1.getParameters()[0..1]*.getName());
- assertEquals("says hello", e.SAY_HI_1.getDescription());
-
- assertEquals("sayHi1", e.SAY_HI_1_ALT.getName());
- assertEquals(["name", "greeting"], e.SAY_HI_1_ALT.getParameters()[0..1]*.getName());
- assertEquals("says hello", e.SAY_HI_1_ALT.getDescription());
-
- assertEquals("sayHi2", e.SAY_HI_2.getName());
- assertEquals(["name", "greeting"], e.SAY_HI_2.getParameters()[0..1]*.getName());
- assertEquals("says hello", e.SAY_HI_2.getDescription());
- }
-
- @Test
- public void testFindTraitEffectors() {
- assertEquals("locations", Startable.START.getParameters()[0].getName());
- }
-
- @Test
- public void testInvokeEffectorMethod1BypassInterception() {
- String name = "sayHi1"
- def args = ["Bob", "hello"] as Object[]
-
- //try the alt syntax recommended from web
- def metaMethod = e.metaClass.getMetaMethod(name, args)
- if (metaMethod==null)
- throw new IllegalArgumentException("Invalid arguments (no method found) for method $name: "+args);
- assertEquals("hello Bob", metaMethod.invoke(e, args))
- }
-
- @Test
- public void testInvokeEffectorMethod2BypassInterception() {
- String name = "sayHi2"
- def args = ["Bob", "hello"] as Object[]
- assertEquals("hello Bob", e.metaClass.invokeMethod(e, name, args))
- }
-
- @Test
- public void testInvokeEffectors1() {
- assertEquals("hi Bob", e.sayHi1("Bob", "hi"))
-
- assertEquals("hello Bob", e.SAY_HI_1.call(e, [name:"Bob"]) )
- assertEquals("hello Bob", e.invoke(e.SAY_HI_1, [name:"Bob"]).get() );
-
- assertEquals("hello Bob", e.SAY_HI_1_ALT.call(e, [name:"Bob"]) )
- }
-
- @Test
- public void testInvokeEffectors2() {
- assertEquals("hi Bob", e.sayHi2("Bob", "hi"))
-
- assertEquals("hello Bob", e.SAY_HI_2.call(e, [name:"Bob"]) )
- assertEquals("hello Bob", e.invoke(e.SAY_HI_2, [name:"Bob"]).get() );
-
- }
-
- @Test
- public void testCanRetrieveTaskForEffector() {
- e.sayHi2("Bob", "hi")
-
- ManagementContext managementContext = e.getManagementContext()
-
- Set<Task> tasks = managementContext.getExecutionManager().getTasksWithAllTags([
- BrooklynTaskTags.tagForContextEntity(e),"EFFECTOR"])
- assertEquals(tasks.size(), 1)
- assertTrue(tasks.iterator().next().getDescription().contains("sayHi2"))
- }
-}
-public interface CanSayHi {
- //prefer following simple groovy syntax
- static Effector<String> SAY_HI_1 = new MethodEffector<String>(CanSayHi.&sayHi1);
- //slightly longer-winded pojo also supported
- static Effector<String> SAY_HI_1_ALT = new MethodEffector<String>(CanSayHi.class, "sayHi1");
-
- @org.apache.brooklyn.core.annotation.Effector(description="says hello")
- public String sayHi1(
- @EffectorParam(name="name") String name,
- @EffectorParam(name="greeting", defaultValue="hello", description="what to say") String greeting);
-
- //finally there is a way to provide a class/closure if needed or preferred for some odd reason
- static Effector<String> SAY_HI_2 =
-
- //groovy 1.8.2 balks at runtime during getCallSiteArray (bug 5122) if we use anonymous inner class
-// new ExplicitEffector<CanSayHi,String>(
-// "sayHi2", String.class, [
-// [ "name", String.class, "person to say hi to" ] as BasicParameterType<String>,
-// [ "greeting", String.class, "what to say as greeting", "hello" ] as BasicParameterType<String>
-// ],
-// "says hello to a person") {
-// public String invokeEffector(CanSayHi e, Map m) {
-// e.sayHi2(m)
-// }
-// };
- //following is a workaround, not greatly enamoured of it... but MethodEffector is generally preferred anyway
- ExplicitEffector.create("sayHi2", String.class, [
- new BasicParameterType<String>("name", String.class, "person to say hi to"),
- new BasicParameterType<String>("greeting", String.class, "what to say as greeting", "hello")
- ],
- "says hello", { e, m ->
- def args = EffectorUtils.prepareArgsForEffector(SAY_HI_2, m);
- e.sayHi2(args[0], args[1]) })
-
- public String sayHi2(String name, String greeting);
-
-}
-
-@ImplementedBy(MyEntityImpl.class)
-public interface MyEntity extends Entity, CanSayHi {
-}
-
-public class MyEntityImpl extends AbstractEntity implements MyEntity {
- public String sayHi1(String name, String greeting) { "$greeting $name" }
- public String sayHi2(String name, String greeting) { "$greeting $name" }
-}
[02/36] incubator-brooklyn git commit: Move SshEffectorTasks into core’s effector.ssh package
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
index f2ab43c..82fd74f 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
@@ -25,10 +25,10 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.time.Duration;
import org.apache.brooklyn.util.time.Time;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
index 2e304e6..22a8d8d 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.BasicOsDetails.OsVersions;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.apache.brooklyn.entity.stock.BasicStartable;
import org.slf4j.Logger;
@@ -37,7 +38,6 @@ import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocati
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.ssh.SshTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.ssh.BashCommands;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
index 226ba20..81b4834 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
@@ -38,10 +38,10 @@ import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
index c824cc7..95f497d 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
@@ -41,10 +41,10 @@ import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.BasicOsDetails.OsVersions;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.io.FileUtil;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
index 205670a..e557090 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
@@ -25,6 +25,7 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefConfig;
import org.apache.brooklyn.entity.chef.ChefLifecycleEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefServerTasks;
@@ -38,7 +39,6 @@ import org.apache.brooklyn.util.collections.Jsonya;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.ssh.BashCommands;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
index 0d19989..cbb289b 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
@@ -40,12 +40,12 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.ssh.SshTasks;
import org.apache.brooklyn.util.core.task.ssh.SshTasks.OnFailingTask;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
index fe45f78..bd9ec6b 100644
--- a/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
+++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
@@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
import org.apache.brooklyn.effector.core.EffectorTasks;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefLiveTestSupport;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.database.VogellaExampleAccess;
@@ -32,7 +33,6 @@ import org.apache.brooklyn.api.location.PortRange;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
index ad65cce..832a886 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,7 +52,6 @@ import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.core.text.TemplateProcessor;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index 6a3a89d..7a8ae35 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -39,6 +39,7 @@ import org.apache.brooklyn.core.entity.drivers.downloads.BasicDownloadRequiremen
import org.apache.brooklyn.core.entity.drivers.downloads.DownloadProducerFromUrlAttribute;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
@@ -51,7 +52,6 @@ import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.TaskBuilder;
import org.apache.brooklyn.util.core.task.TaskTags;
import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.repeat.Repeater;
import org.apache.brooklyn.util.ssh.BashCommands;
import org.apache.brooklyn.util.text.NaturalOrderComparator;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
index 802d2da..943a193 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
@@ -41,12 +41,12 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.ssh.SshTasks;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
index 2d2058a..ae525cd 100644
--- a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
+++ b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
@@ -29,10 +29,10 @@ import org.apache.brooklyn.api.location.NoMachinesAvailableException;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Identifiers;
import org.testng.Assert;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4820fa46/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
index 65ddf3b..fc0aa4c 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
@@ -23,6 +23,7 @@ import static java.lang.String.format;
import java.util.concurrent.Callable;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.database.mysql.MySqlNodeImpl;
import org.apache.brooklyn.entity.database.mysql.MySqlSshDriver;
@@ -32,7 +33,6 @@ import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
-import org.apache.brooklyn.util.core.task.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.time.CountdownTimer;
import org.apache.brooklyn.util.time.Duration;
[09/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to
o.a.b.core.effector
Posted by he...@apache.org.
Rename o.a.b.effector.core to o.a.b.core.effector
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/8dbb0e4b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/8dbb0e4b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/8dbb0e4b
Branch: refs/heads/master
Commit: 8dbb0e4b2de44840f23f6cce2862dc41ae9ff307
Parents: 4820fa4
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 22:39:55 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 19 22:39:55 2015 +0100
----------------------------------------------------------------------
.../core/effector/AbstractEffector.java | 90 ++++
.../core/effector/AddChildrenEffector.java | 117 +++++
.../brooklyn/core/effector/AddEffector.java | 116 +++++
.../brooklyn/core/effector/AddSensor.java | 126 ++++++
.../core/effector/BasicParameterType.java | 116 +++++
.../brooklyn/core/effector/EffectorAndBody.java | 60 +++
.../brooklyn/core/effector/EffectorBase.java | 106 +++++
.../brooklyn/core/effector/EffectorBody.java | 100 +++++
.../brooklyn/core/effector/EffectorTasks.java | 229 ++++++++++
.../core/effector/EffectorWithBody.java | 32 ++
.../brooklyn/core/effector/Effectors.java | 202 +++++++++
.../core/effector/ExplicitEffector.java | 74 ++++
.../brooklyn/core/effector/MethodEffector.java | 180 ++++++++
.../core/effector/ssh/SshEffectorTasks.java | 335 ++++++++++++++
.../apache/brooklyn/core/entity/Entities.java | 2 +-
.../brooklyn/core/entity/EntityDynamicType.java | 14 +-
.../core/entity/trait/MemberReplaceable.java | 2 +-
.../brooklyn/core/entity/trait/Resizable.java | 2 +-
.../brooklyn/core/entity/trait/Startable.java | 6 +-
.../core/entity/trait/StartableMethods.java | 2 +-
.../core/mgmt/EntityManagementUtils.java | 2 +-
.../core/mgmt/internal/EffectorUtils.java | 2 +-
.../mgmt/internal/LocalManagementContext.java | 2 +-
.../core/mgmt/persist/XmlMementoSerializer.java | 8 +-
.../core/objs/proxy/EntityProxyImpl.java | 2 +-
.../effector/core/AbstractEffector.java | 90 ----
.../effector/core/AddChildrenEffector.java | 117 -----
.../brooklyn/effector/core/AddEffector.java | 116 -----
.../brooklyn/effector/core/AddSensor.java | 126 ------
.../effector/core/BasicParameterType.java | 116 -----
.../brooklyn/effector/core/EffectorAndBody.java | 60 ---
.../brooklyn/effector/core/EffectorBase.java | 106 -----
.../brooklyn/effector/core/EffectorBody.java | 100 -----
.../brooklyn/effector/core/EffectorTasks.java | 229 ----------
.../effector/core/EffectorWithBody.java | 32 --
.../brooklyn/effector/core/Effectors.java | 202 ---------
.../effector/core/ExplicitEffector.java | 74 ----
.../brooklyn/effector/core/MethodEffector.java | 180 --------
.../effector/core/ssh/SshEffectorTasks.java | 334 --------------
.../brooklyn/entity/group/DynamicCluster.java | 2 +-
.../entity/group/DynamicClusterImpl.java | 2 +-
.../entity/group/DynamicFabricImpl.java | 2 +-
.../brooklyn/entity/group/DynamicGroup.java | 2 +-
.../entity/group/DynamicRegionsFabric.java | 2 +-
.../entity/group/QuarantineGroupImpl.java | 2 +-
.../brooklyn/sensor/core/HttpRequestSensor.java | 2 +-
.../brooklyn/sensor/core/StaticSensor.java | 2 +-
.../windows/WindowsPerformanceCounterFeed.java | 2 +-
.../brooklyn/util/core/task/ssh/SshTasks.java | 2 +-
.../core/effector/EffectorBasicTest.java | 183 ++++++++
.../core/effector/EffectorConcatenateTest.java | 241 ++++++++++
.../core/effector/EffectorMetadataTest.java | 166 +++++++
.../effector/EffectorSayHiGroovyTest.groovy | 182 ++++++++
.../core/effector/EffectorSayHiTest.java | 173 ++++++++
.../core/effector/EffectorTaskTest.java | 437 +++++++++++++++++++
.../core/effector/ssh/SshEffectorTasksTest.java | 265 +++++++++++
.../brooklyn/core/entity/DynamicEntityTest.java | 2 +-
.../brooklyn/core/entity/EntityTypeTest.java | 2 +-
.../brooklyn/core/entity/hello/HelloEntity.java | 2 +-
.../mgmt/osgi/OsgiVersionMoreEntityTest.java | 2 +-
.../rebind/RebindEntityDynamicTypeInfoTest.java | 4 +-
.../brooklyn/core/test/entity/TestEntity.java | 2 +-
.../effector/core/EffectorBasicTest.java | 183 --------
.../effector/core/EffectorConcatenateTest.java | 241 ----------
.../effector/core/EffectorMetadataTest.java | 166 -------
.../core/EffectorSayHiGroovyTest.groovy | 179 --------
.../effector/core/EffectorSayHiTest.java | 173 --------
.../effector/core/EffectorTaskTest.java | 437 -------------------
.../effector/core/ssh/SshEffectorTasksTest.java | 264 -----------
.../location/ssh/SshMachineLocationTest.java | 6 +-
.../util/core/task/ssh/SshTasksTest.java | 2 +-
.../brooklyn/demo/CumulusRDFApplication.java | 6 +-
.../brooklyn/policy/loadbalancing/Movable.java | 2 +-
.../loadbalancing/MockContainerEntity.java | 2 +-
.../postgresql/PostgreSqlNodeSaltImpl.java | 6 +-
.../entity/salt/SaltLifecycleEffectorTasks.java | 2 +-
.../apache/brooklyn/entity/salt/SaltTasks.java | 5 +-
.../postgresql/PostgreSqlSaltLiveTest.java | 4 +-
.../entity/brooklynnode/BrooklynCluster.java | 2 +-
.../brooklynnode/BrooklynEntityMirrorImpl.java | 2 +-
.../entity/brooklynnode/BrooklynNode.java | 2 +-
.../entity/brooklynnode/BrooklynNodeImpl.java | 4 +-
.../brooklynnode/BrooklynNodeSshDriver.java | 2 +-
.../brooklynnode/RemoteEffectorBuilder.java | 4 +-
.../BrooklynClusterUpgradeEffectorBody.java | 4 +-
.../BrooklynNodeUpgradeEffectorBody.java | 6 +-
.../effector/SelectMasterEffectorBody.java | 4 +-
.../SetHighAvailabilityModeEffectorBody.java | 4 +-
...SetHighAvailabilityPriorityEffectorBody.java | 4 +-
.../entity/chef/ChefLifecycleEffectorTasks.java | 2 +-
.../brooklyn/entity/chef/ChefSoloTasks.java | 2 +-
.../apache/brooklyn/entity/chef/ChefTasks.java | 4 +-
.../entity/chef/KnifeConvergeTaskFactory.java | 2 +-
.../java/JavaSoftwareProcessSshDriver.java | 4 +-
.../entity/java/JmxAttributeSensor.java | 2 +-
.../brooklyn/entity/machine/MachineEntity.java | 2 +-
.../entity/machine/MachineEntityImpl.java | 2 +-
.../entity/machine/pool/ServerPool.java | 2 +-
.../entity/machine/pool/ServerPoolImpl.java | 2 +-
.../base/AbstractSoftwareProcessSshDriver.java | 4 +-
.../MachineLifecycleEffectorTasks.java | 6 +-
.../system_service/InitdServiceInstaller.java | 2 +-
.../system_service/SystemServiceEnricher.java | 2 +-
.../brooklyn/sensor/ssh/SshCommandEffector.java | 12 +-
.../brooklyn/sensor/ssh/SshCommandSensor.java | 2 +-
.../brooklynnode/SelectMasterEffectorTest.java | 2 +-
.../ChefSoloDriverMySqlEntityLiveTest.java | 2 +-
.../mysql/ChefSoloDriverToyMySqlEntity.java | 2 +-
.../software/base/SoftwareEffectorTest.java | 6 +-
.../base/SoftwareProcessEntityTest.java | 2 +-
.../base/SoftwareProcessSubclassTest.java | 4 +-
.../test/mysql/AbstractToyMySqlEntityTest.java | 2 +-
.../mysql/DynamicToyMySqlEntityBuilder.java | 2 +-
.../test/ssh/SshCommandIntegrationTest.java | 2 +-
.../SystemServiceEnricherTest.java | 2 +-
.../entity/database/DatastoreMixins.java | 2 +-
.../database/mariadb/MariaDbNodeImpl.java | 2 +-
.../database/mariadb/MariaDbSshDriver.java | 2 +-
.../entity/database/mysql/MySqlNode.java | 2 +-
.../entity/database/mysql/MySqlNodeImpl.java | 2 +-
.../entity/database/mysql/MySqlSshDriver.java | 2 +-
.../database/postgresql/PostgreSqlNode.java | 2 +-
.../PostgreSqlNodeChefImplFromScratch.java | 6 +-
.../database/postgresql/PostgreSqlNodeImpl.java | 2 +-
.../postgresql/PostgreSqlSshDriver.java | 2 +-
.../database/postgresql/PostgreSqlChefTest.java | 4 +-
.../nosql/cassandra/CassandraDatacenter.java | 4 +-
.../cassandra/CassandraDatacenterImpl.java | 2 +-
.../entity/nosql/cassandra/CassandraFabric.java | 2 +-
.../nosql/cassandra/CassandraNodeImpl.java | 2 +-
.../nosql/cassandra/CassandraNodeSshDriver.java | 2 +-
.../nosql/couchbase/CouchbaseClusterImpl.java | 2 +-
.../entity/nosql/couchbase/CouchbaseNode.java | 4 +-
.../nosql/couchbase/CouchbaseNodeImpl.java | 2 +-
.../nosql/couchbase/CouchbaseNodeSshDriver.java | 2 +-
.../entity/nosql/mongodb/MongoDBClient.java | 2 +-
.../brooklyn/entity/nosql/riak/RiakNode.java | 2 +-
.../entity/nosql/riak/RiakNodeSshDriver.java | 2 +-
.../entity/osgi/karaf/KarafContainer.java | 2 +-
.../entity/osgi/karaf/KarafContainerTest.java | 2 +-
.../brooklyn/entity/proxy/LoadBalancer.java | 2 +-
.../entity/proxy/nginx/NginxController.java | 2 +-
.../brooklyn/entity/proxy/nginx/UrlMapping.java | 2 +-
.../entity/webapp/DynamicWebAppClusterImpl.java | 2 +-
.../entity/webapp/JavaWebAppService.java | 2 +-
.../spi/dsl/BrooklynDslDeferredSupplier.java | 2 +-
.../camp/brooklyn/EntitiesYamlTest.java | 2 +-
.../TestSensorAndEffectorInitializer.java | 4 +-
.../brooklyn/VanillaBashNetcatYamlTest.java | 2 +-
.../brooklyn/test/lite/CampYamlLiteTest.java | 4 +-
.../qa/load/SimulatedMySqlNodeImpl.java | 2 +-
.../testing/mocks/RestMockSimpleEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntityImpl.java | 2 +-
.../test/osgi/entities/more/MoreEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntityImpl.java | 2 +-
.../test/osgi/entities/more/MoreEntity.java | 2 +-
.../test/osgi/entities/more/MoreEntityImpl.java | 2 +-
158 files changed, 3694 insertions(+), 3690 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/AbstractEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/AbstractEffector.java b/core/src/main/java/org/apache/brooklyn/core/effector/AbstractEffector.java
new file mode 100644
index 0000000..4acd0e0
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/AbstractEffector.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * The abstract {@link Effector} implementation.
+ *
+ * The concrete subclass (often anonymous) will supply the {@link #call(Entity, Map)} implementation,
+ * and the fields in the constructor.
+ */
+public abstract class AbstractEffector<T> extends EffectorBase<T> implements EffectorWithBody<T> {
+
+ private static final long serialVersionUID = 1832435915652457843L;
+
+ @SuppressWarnings("unused")
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractEffector.class);
+
+ public AbstractEffector(String name, Class<T> returnType, List<ParameterType<?>> parameters, String description) {
+ super(name, returnType, parameters, description);
+ }
+
+ public abstract T call(Entity entity, @SuppressWarnings("rawtypes") Map parameters);
+
+ /** Convenience for named-parameter syntax (needs map in first argument) */
+ public T call(Entity entity) { return call(ImmutableMap.of(), entity); }
+
+ /** Convenience for named-parameter syntax (needs map in first argument) */
+ public T call(@SuppressWarnings("rawtypes") Map parameters, Entity entity) { return call(entity, parameters); }
+
+ /** @deprecated since 0.7.0 use {@link #getFlagsForTaskInvocationAt(Entity, Effector, ConfigBag)} */ @Deprecated
+ protected final Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity) {
+ return getFlagsForTaskInvocationAt(entity, this, null);
+ }
+ /** subclasses may override to add additional flags, but they should include the flags returned here
+ * unless there is very good reason not to */
+ protected Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity, Effector<T> effector, ConfigBag parameters) {
+ return EffectorUtils.getTaskFlagsForEffectorInvocation(entity, effector, parameters);
+ }
+
+ /** not meant for overriding; subclasses should override the abstract {@link #call(Entity, Map)} method in this class */
+ @Override
+ public final EffectorTaskFactory<T> getBody() {
+ return new EffectorTaskFactory<T>() {
+ @Override
+ public Task<T> newTask(final Entity entity, final Effector<T> effector, final ConfigBag parameters) {
+ return new DynamicSequentialTask<T>(
+ getFlagsForTaskInvocationAt(entity, AbstractEffector.this, parameters),
+ new Callable<T>() {
+ @Override public T call() {
+ return AbstractEffector.this.call(parameters.getAllConfig(), entity);
+ }
+ });
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/AddChildrenEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/AddChildrenEffector.java b/core/src/main/java/org/apache/brooklyn/core/effector/AddChildrenEffector.java
new file mode 100644
index 0000000..f2730ca
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/AddChildrenEffector.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.Effectors.EffectorBuilder;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
+import org.apache.brooklyn.core.mgmt.EntityManagementUtils.CreationResult;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.gson.Gson;
+
+/** Entity initializer which defines an effector which adds a child blueprint to an entity.
+ * <p>
+ * One of the config keys {@link #BLUEPRINT_YAML} (containing a YAML blueprint (map or string))
+ * or {@link #BLUEPRINT_TYPE} (containing a string referring to a catalog type) should be supplied, but not both.
+ * Parameters defined here are supplied as config during the entity creation.
+ *
+ * @since 0.7.0 */
+@Beta
+public class AddChildrenEffector extends AddEffector {
+
+ private static final Logger log = LoggerFactory.getLogger(AddChildrenEffector.class);
+
+ public static final ConfigKey<Object> BLUEPRINT_YAML = ConfigKeys.newConfigKey(Object.class, "blueprint_yaml");
+ public static final ConfigKey<String> BLUEPRINT_TYPE = ConfigKeys.newStringConfigKey("blueprint_type");
+ public static final ConfigKey<Boolean> AUTO_START = ConfigKeys.newBooleanConfigKey("auto_start");
+
+ public AddChildrenEffector(ConfigBag params) {
+ super(newEffectorBuilder(params).build());
+ }
+
+ public AddChildrenEffector(Map<String,String> params) {
+ this(ConfigBag.newInstance(params));
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static EffectorBuilder<List<String>> newEffectorBuilder(ConfigBag params) {
+ EffectorBuilder<List<String>> eff = (EffectorBuilder) AddEffector.newEffectorBuilder(List.class, params);
+ eff.impl(new Body(eff.buildAbstract(), params));
+ return eff;
+ }
+
+ protected static class Body extends EffectorBody<List<String>> {
+
+ private final Effector<?> effector;
+ private final String blueprintBase;
+ private final Boolean autostart;
+
+ public Body(Effector<?> eff, ConfigBag params) {
+ this.effector = eff;
+ String newBlueprint = null;
+ Object yaml = params.get(BLUEPRINT_YAML);
+ if (yaml instanceof Map) {
+ newBlueprint = new Gson().toJson(yaml);
+ } else if (yaml instanceof String) {
+ newBlueprint = (String) yaml;
+ } else if (yaml!=null) {
+ throw new IllegalArgumentException(this+" requires map or string in "+BLUEPRINT_YAML+"; not "+yaml.getClass()+" ("+yaml+")");
+ }
+ String blueprintType = params.get(BLUEPRINT_TYPE);
+ if (blueprintType!=null) {
+ if (newBlueprint!=null) {
+ throw new IllegalArgumentException(this+" cannot take both "+BLUEPRINT_TYPE+" and "+BLUEPRINT_YAML);
+ }
+ newBlueprint = "services: [ { type: "+blueprintType+" } ]";
+ }
+ if (newBlueprint==null) {
+ throw new IllegalArgumentException(this+" requires either "+BLUEPRINT_TYPE+" or "+BLUEPRINT_YAML);
+ }
+ blueprintBase = newBlueprint;
+ autostart = params.get(AUTO_START);
+ }
+
+ @Override
+ public List<String> call(ConfigBag params) {
+ params = getMergedParams(effector, params);
+
+ String blueprint = blueprintBase;
+ if (!params.isEmpty()) {
+ blueprint = blueprint+"\n"+"brooklyn.config: "+
+ new Gson().toJson(params.getAllConfig());
+ }
+
+ log.debug(this+" adding children to "+entity()+":\n"+blueprint);
+ CreationResult<List<Entity>, List<String>> result = EntityManagementUtils.addChildren(entity(), blueprint, autostart);
+ log.debug(this+" added children to "+entity()+": "+result.get());
+ return result.task().getUnchecked();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/AddEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/AddEffector.java b/core/src/main/java/org/apache/brooklyn/core/effector/AddEffector.java
new file mode 100644
index 0000000..9590bcf
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/AddEffector.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.MapConfigKey;
+import org.apache.brooklyn.core.effector.Effectors.EffectorBuilder;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.text.Strings;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+/**
+ * Entity initializer which adds an effector to an entity.
+ * <p>
+ * This instance provides a {@link #newEffectorBuilder(Class, ConfigBag)}
+ * which returns an abstract (body-less) effector defining:
+ * <li> the name from {@link #EFFECTOR_NAME};
+ * <li> the description from {@link #EFFECTOR_DESCRIPTION}
+ * <li> the parameters from {@link #EFFECTOR_PARAMETER_DEFS}
+ * <p>
+ * Callers should pass the effector to instantiate into the constructor.
+ * Often subclasses will supply a constructor which takes a ConfigBag of parameters,
+ * and a custom {@link #newEffectorBuilder(Class, ConfigBag)} which adds the body
+ * before passing to this class.
+ * <p>
+ * Note that the parameters passed to the call method in the body of the effector implementation
+ * are only those supplied by a user at runtime; in order to merge with default
+ * values, use {@link #getMergedParams(Effector, ConfigBag)}.
+ *
+ * @since 0.7.0 */
+@Beta
+public class AddEffector implements EntityInitializer {
+
+ public static final ConfigKey<String> EFFECTOR_NAME = ConfigKeys.newStringConfigKey("name");
+ public static final ConfigKey<String> EFFECTOR_DESCRIPTION = ConfigKeys.newStringConfigKey("description");
+
+ public static final ConfigKey<Map<String,Object>> EFFECTOR_PARAMETER_DEFS = new MapConfigKey<Object>(Object.class, "parameters");
+
+ final Effector<?> effector;
+
+ public AddEffector(Effector<?> effector) {
+ this.effector = Preconditions.checkNotNull(effector, "effector");
+ }
+
+ @Override
+ public void apply(EntityLocal entity) {
+ ((EntityInternal)entity).getMutableEntityType().addEffector(effector);
+ }
+
+ public static <T> EffectorBuilder<T> newEffectorBuilder(Class<T> type, ConfigBag params) {
+ String name = Preconditions.checkNotNull(params.get(EFFECTOR_NAME), "name must be supplied when defining an effector: %s", params);
+ EffectorBuilder<T> eff = Effectors.effector(type, name);
+ eff.description(params.get(EFFECTOR_DESCRIPTION));
+
+ Map<String, Object> paramDefs = params.get(EFFECTOR_PARAMETER_DEFS);
+ if (paramDefs!=null) {
+ for (Map.Entry<String, Object> paramDef: paramDefs.entrySet()){
+ if (paramDef!=null) {
+ String paramName = paramDef.getKey();
+ Object value = paramDef.getValue();
+ if (value==null) value = Collections.emptyMap();
+ if (!(value instanceof Map)) {
+ if (value instanceof CharSequence && Strings.isBlank((CharSequence) value))
+ value = Collections.emptyMap();
+ }
+ if (!(value instanceof Map))
+ throw new IllegalArgumentException("Illegal argument of type "+value.getClass()+" value '"+value+"' supplied as parameter definition "
+ + "'"+paramName);
+ eff.parameter(ConfigKeys.DynamicKeys.newNamedInstance(paramName, (Map<?, ?>) value));
+ }
+ }
+ }
+
+ return eff;
+ }
+
+ /** returns a ConfigBag containing the merger of the supplied parameters with default values on the effector-defined parameters */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static ConfigBag getMergedParams(Effector<?> eff, ConfigBag params) {
+ ConfigBag result = ConfigBag.newInstanceCopying(params);
+ for (ParameterType<?> param: eff.getParameters()) {
+ ConfigKey key = Effectors.asConfigKey(param);
+ if (!result.containsKey(key))
+ result.configure(key, params.get(key));
+ }
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
new file mode 100644
index 0000000..3c08831
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.javalang.Boxing;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+/**
+ * Creates a new {@link AttributeSensor} on an entity.
+ * <p>
+ * The configuration can include the sensor {@code name}, {@code period} and {@code targetType}.
+ * For the targetType, currently this only supports classes on the initial classpath, not those in
+ * OSGi bundles added at runtime.
+ *
+ * @since 0.7.0
+ */
+@Beta
+public class AddSensor<T> implements EntityInitializer {
+
+ public static final ConfigKey<String> SENSOR_NAME = ConfigKeys.newStringConfigKey("name", "The name of the sensor to create");
+ public static final ConfigKey<Duration> SENSOR_PERIOD = ConfigKeys.newConfigKey(Duration.class, "period", "Period, including units e.g. 1m or 5s or 200ms; default 5 minutes", Duration.FIVE_MINUTES);
+ public static final ConfigKey<String> SENSOR_TYPE = ConfigKeys.newStringConfigKey("targetType", "Target type for the value; default String", "java.lang.String");
+
+ protected final String name;
+ protected final Duration period;
+ protected final String type;
+ protected final AttributeSensor<T> sensor;
+
+ public AddSensor(Map<String, String> params) {
+ this(ConfigBag.newInstance(params));
+ }
+
+ public AddSensor(final ConfigBag params) {
+ this.name = Preconditions.checkNotNull(params.get(SENSOR_NAME), "Name must be supplied when defining a sensor");
+ this.period = params.get(SENSOR_PERIOD);
+ this.type = params.get(SENSOR_TYPE);
+ this.sensor = newSensor();
+ }
+
+ @Override
+ public void apply(EntityLocal entity) {
+ ((EntityInternal) entity).getMutableEntityType().addSensor(sensor);
+ }
+
+ private AttributeSensor<T> newSensor() {
+ String className = getFullClassName(type);
+ Class<T> clazz = getType(className);
+ return Sensors.newSensor(clazz, name);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Class<T> getType(String className) {
+ try {
+ // TODO use OSGi loader (low priority however); also ensure that allows primitives
+ Maybe<Class<?>> primitive = Boxing.getPrimitiveType(className);
+ if (primitive.isPresent()) return (Class<T>) primitive.get();
+ return (Class<T>) Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ if (!className.contains(".")) {
+ // could be assuming "java.lang" package; try again with that
+ try {
+ return (Class<T>) Class.forName("java.lang."+className);
+ } catch (ClassNotFoundException e2) {
+ throw new IllegalArgumentException("Invalid target type for sensor "+name+": " + className+" (also tried java.lang."+className+")");
+ }
+ } else {
+ throw new IllegalArgumentException("Invalid target type for sensor "+name+": " + className);
+ }
+ }
+ }
+
+ protected String getFullClassName(String className) {
+ if (className.equalsIgnoreCase("string")) {
+ return "java.lang.String";
+ } else if (className.equalsIgnoreCase("int") || className.equalsIgnoreCase("integer")) {
+ return "java.lang.Integer";
+ } else if (className.equalsIgnoreCase("long")) {
+ return "java.lang.Long";
+ } else if (className.equalsIgnoreCase("float")) {
+ return "java.lang.Float";
+ } else if (className.equalsIgnoreCase("double")) {
+ return "java.lang.Double";
+ } else if (className.equalsIgnoreCase("bool") || className.equalsIgnoreCase("boolean")) {
+ return "java.lang.Boolean";
+ } else if (className.equalsIgnoreCase("byte")) {
+ return "java.lang.Byte";
+ } else if (className.equalsIgnoreCase("char") || className.equalsIgnoreCase("character")) {
+ return "java.lang.Character";
+ } else if (className.equalsIgnoreCase("object")) {
+ return "java.lang.Object";
+ } else {
+ return className;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java b/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
new file mode 100644
index 0000000..eb0417f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/BasicParameterType.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.ParameterType;
+
+import com.google.common.base.Objects;
+
+public class BasicParameterType<T> implements ParameterType<T> {
+ private static final long serialVersionUID = -5521879180483663919L;
+
+ private String name;
+ private Class<T> type;
+ private String description;
+ private Boolean hasDefaultValue = null;
+ private T defaultValue = null;
+
+ public BasicParameterType() {
+ this(Collections.emptyMap());
+ }
+
+ @SuppressWarnings("unchecked")
+ public BasicParameterType(Map<?, ?> arguments) {
+ if (arguments.containsKey("name")) name = (String) arguments.get("name");
+ if (arguments.containsKey("type")) type = (Class<T>) arguments.get("type");
+ if (arguments.containsKey("description")) description = (String) arguments.get("description");
+ if (arguments.containsKey("defaultValue")) defaultValue = (T) arguments.get("defaultValue");
+ }
+
+ public BasicParameterType(String name, Class<T> type) {
+ this(name, type, null, null, false);
+ }
+
+ public BasicParameterType(String name, Class<T> type, String description) {
+ this(name, type, description, null, false);
+ }
+
+ public BasicParameterType(String name, Class<T> type, String description, T defaultValue) {
+ this(name, type, description, defaultValue, true);
+ }
+
+ public BasicParameterType(String name, Class<T> type, String description, T defaultValue, boolean hasDefaultValue) {
+ this.name = name;
+ this.type = type;
+ this.description = description;
+ this.defaultValue = defaultValue;
+ if (defaultValue!=null && !defaultValue.getClass().equals(Object.class)) {
+ // if default value is null (or is an Object, which is ambiguous on resolution to to rebind),
+ // don't bother to set this as it creates noise in the persistence files
+ this.hasDefaultValue = hasDefaultValue;
+ }
+ }
+
+ @Override
+ public String getName() { return name; }
+
+ @Override
+ public Class<T> getParameterClass() { return type; }
+
+ @Override
+ public String getParameterClassName() { return type.getCanonicalName(); }
+
+ @Override
+ public String getDescription() { return description; }
+
+ @Override
+ public T getDefaultValue() {
+ return hasDefaultValue() ? defaultValue : null;
+ }
+
+ public boolean hasDefaultValue() {
+ // a new Object() was previously used to indicate no default value, but that doesn't work well across serialization boundaries!
+ return hasDefaultValue!=null ? hasDefaultValue : defaultValue!=null && !defaultValue.getClass().equals(Object.class);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).omitNullValues()
+ .add("name", name).add("description", description).add("type", getParameterClassName())
+ .add("defaultValue", defaultValue)
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, description, type, defaultValue);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof ParameterType) &&
+ Objects.equal(name, ((ParameterType<?>)obj).getName()) &&
+ Objects.equal(description, ((ParameterType<?>)obj).getDescription()) &&
+ Objects.equal(type, ((ParameterType<?>)obj).getParameterClass()) &&
+ Objects.equal(defaultValue, ((ParameterType<?>)obj).getDefaultValue());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorAndBody.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorAndBody.java b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorAndBody.java
new file mode 100644
index 0000000..49e85b8
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorAndBody.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Objects;
+
+@Beta // added in 0.6.0
+public class EffectorAndBody<T> extends EffectorBase<T> implements EffectorWithBody<T> {
+
+ private static final long serialVersionUID = -6023389678748222968L;
+ private final EffectorTaskFactory<T> body;
+
+ public EffectorAndBody(Effector<T> original, EffectorTaskFactory<T> body) {
+ this(original.getName(), original.getReturnType(), original.getParameters(), original.getDescription(), body);
+ }
+
+ public EffectorAndBody(String name, Class<T> returnType, List<ParameterType<?>> parameters, String description, EffectorTaskFactory<T> body) {
+ super(name, returnType, parameters, description);
+ this.body = body;
+ }
+
+ @Override
+ public EffectorTaskFactory<T> getBody() {
+ return body;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), getBody());
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return super.equals(other) && Objects.equal(getBody(), ((EffectorAndBody<?>)other).getBody());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBase.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBase.java b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBase.java
new file mode 100644
index 0000000..68132c4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBase.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+
+/** concrete implementation of Effector interface,
+ * but not (at this level of the hirarchy) defining an implementation
+ * (see {@link EffectorTaskFactory} and {@link EffectorWithBody}) */
+public class EffectorBase<T> implements Effector<T> {
+
+ @SuppressWarnings("unused")
+ private static final Logger log = LoggerFactory.getLogger(EffectorBase.class);
+
+ private static final long serialVersionUID = -4153962199078384835L;
+
+ private final String name;
+ private final Class<T> returnType;
+ private final List<ParameterType<?>> parameters;
+ private final String description;
+
+ public EffectorBase(String name, Class<T> returnType, List<ParameterType<?>> parameters, String description) {
+ this.name = name;
+ this.returnType = returnType;
+ this.parameters = new ArrayList<ParameterType<?>>(parameters);
+ this.description = description;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Class<T> getReturnType() {
+ return returnType;
+ }
+
+ @Override
+ public String getReturnTypeName() {
+ return returnType.getCanonicalName();
+ }
+
+ @Override
+ public List<ParameterType<?>> getParameters() {
+ return parameters;
+ }
+
+ @Override
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String toString() {
+ List<String> parameterNames = new ArrayList<String>(parameters.size());
+ for (ParameterType<?> parameter: parameters) {
+ String parameterName = (parameter.getName() != null) ? parameter.getName() : "<unknown>";
+ parameterNames.add(parameterName);
+ }
+ return name+"["+Joiner.on(",").join(parameterNames)+"]";
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(name, returnType, parameters, description);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof EffectorBase)) return false;
+ if (!(other.getClass().equals(getClass()))) return false;
+ if (!Objects.equal(hashCode(), other.hashCode())) return false;
+ return Objects.equal(getName(), ((EffectorBase<?>)other).getName()) &&
+ Objects.equal(getReturnType(), ((EffectorBase<?>)other).getReturnType()) &&
+ Objects.equal(getParameters(), ((EffectorBase<?>)other).getParameters()) &&
+ Objects.equal(getDescription(), ((EffectorBase<?>)other).getDescription());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBody.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBody.java b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBody.java
new file mode 100644
index 0000000..b1643ba
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorBody.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.Tasks;
+
+import com.google.common.annotations.Beta;
+
+/** Typical implementations override {@link #main(ConfigBag)} to do the work of the effector
+ * <p>
+ * See also {@link EffectorTasks}: possibly this will be deleted in preference for an approach based on {@link EffectorTasks}.
+ *
+ * @since 0.6.0
+ **/
+@Beta
+public abstract class EffectorBody<T> {
+ /** Does the work of the effector, either in place, or (better) by building up
+ * subtasks, which can by added using {@link DynamicTasks} methods
+ * (and various convenience methods which do that automatically; see subclasses of EffectorBody
+ * for more info on usage; or see {@link DynamicSequentialTask} for details of the threading model
+ * by which added tasks are placed in a secondary thread)
+ * <p>
+ * The associated entity can be accessed through the {@link #entity()} method.
+ */
+ public abstract T call(ConfigBag parameters);
+
+ // NB: we could also support an 'init' method which is done at creation,
+ // as a place where implementers can describe the structure of the task before it executes
+ // (and init gets invoked in EffectorBodyTaskFactory.newTask _before_ the task is submitted and main is called)
+
+
+ // ---- convenience method(s) for implementers of main -- see subclasses and *Tasks statics for more
+
+ protected EntityInternal entity() {
+ return (EntityInternal) BrooklynTaskTags.getTargetOrContextEntity(Tasks.current());
+ }
+
+ protected <V extends TaskAdaptable<?>> V queue(V task) {
+ return DynamicTasks.queue(task);
+ }
+
+ protected <V extends TaskAdaptable<?>> void queue(V task1, V task2, V ...tasks) {
+ DynamicTasks.queue(task1);
+ DynamicTasks.queue(task2);
+ for (V task: tasks)
+ DynamicTasks.queue(task);
+ }
+
+ protected <V extends TaskFactory<?>> void queue(V task1, V task2, V ...tasks) {
+ DynamicTasks.queue(task1.newTask());
+ DynamicTasks.queue(task2.newTask());
+ for (V task: tasks)
+ DynamicTasks.queue(task.newTask());
+ }
+
+ protected <U extends TaskAdaptable<?>> U queue(TaskFactory<U> task) {
+ return DynamicTasks.queue(task.newTask());
+ }
+
+ /** see {@link DynamicTasks#waitForLast()} */
+ protected Task<?> waitForLast() {
+ return DynamicTasks.waitForLast();
+ }
+
+ /** Returns the result of the last task queued in this context, coerced to the given type */
+ protected <V> V last(Class<V> type) {
+ Task<?> last = waitForLast();
+ if (last==null)
+ throw new IllegalStateException("No last task available (in "+DynamicTasks.getTaskQueuingContext()+")");
+ if (!Tasks.isQueuedOrSubmitted(last))
+ throw new IllegalStateException("Last task "+last+" has not been queued or submitted; will not block on its result");
+
+ return TypeCoercions.coerce(last.getUnchecked(), type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
new file mode 100644
index 0000000..39eb79b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
+import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.TaskBuilder;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.javalang.Reflections;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+
+/**
+ * Miscellaneous tasks which are useful in effectors.
+ * @since 0.6.0
+ */
+@Beta
+public class EffectorTasks {
+
+ @SuppressWarnings("unused")
+ private static final Logger log = LoggerFactory.getLogger(EffectorTasks.class);
+
+ public interface EffectorTaskFactory<T> {
+ public abstract TaskAdaptable<T> newTask(Entity entity, Effector<T> effector, ConfigBag parameters);
+ }
+
+ /** wrapper for {@link EffectorBody} which simply runs that body on each invocation;
+ * the body must be thread safe and ideally stateless */
+ public static class EffectorBodyTaskFactory<T> implements EffectorTaskFactory<T> {
+ private final EffectorBody<T> effectorBody;
+ public EffectorBodyTaskFactory(EffectorBody<T> effectorBody) {
+ this.effectorBody = effectorBody;
+ }
+
+ @Override
+ public Task<T> newTask(final Entity entity, final org.apache.brooklyn.api.effector.Effector<T> effector, final ConfigBag parameters) {
+ final AtomicReference<DynamicSequentialTask<T>> dst = new AtomicReference<DynamicSequentialTask<T>>();
+
+ dst.set(new DynamicSequentialTask<T>(
+ getFlagsForTaskInvocationAt(entity, effector, parameters),
+ new Callable<T>() {
+ @Override
+ public T call() throws Exception {
+ try {
+ DynamicTasks.setTaskQueueingContext(dst.get());
+ return effectorBody.call(parameters);
+ } finally {
+ DynamicTasks.removeTaskQueueingContext();
+ }
+ }
+ }) {
+ @Override
+ public void handleException(Throwable throwable) throws Exception {
+ EffectorUtils.handleEffectorException(entity, effector, throwable);
+ }
+ });
+ return dst.get();
+ };
+
+ /** @deprecated since 0.7.0 use {@link #getFlagsForTaskInvocationAt(Entity, Effector, ConfigBag)} */ @Deprecated
+ protected final Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity, Effector<?> effector) {
+ return getFlagsForTaskInvocationAt(entity, effector, null);
+ }
+ /** subclasses may override to add additional flags, but they should include the flags returned here
+ * unless there is very good reason not to; default impl returns a MutableMap */
+ protected Map<Object,Object> getFlagsForTaskInvocationAt(Entity entity, Effector<?> effector, ConfigBag parameters) {
+ return EffectorUtils.getTaskFlagsForEffectorInvocation(entity, effector, parameters);
+ }
+ }
+
+ /** wrapper for {@link EffectorTaskFactory} which ensures effector task tags are applied to it if needed
+ * (wrapping in a task if needed); without this, {@link EffectorBody}-based effectors get it by
+ * virtue of the call to {@link #getFlagsForTaskInvocationAt(Entity,Effector,ConfigBag)} therein
+ * but {@link EffectorTaskFactory}-based effectors generate a task without the right tags
+ * to be able to tell using {@link BrooklynTaskTags} the effector-context of the task
+ * <p>
+ * this gets applied automatically so marked as package-private */
+ static class EffectorMarkingTaskFactory<T> implements EffectorTaskFactory<T> {
+ private final EffectorTaskFactory<T> effectorTaskFactory;
+ public EffectorMarkingTaskFactory(EffectorTaskFactory<T> effectorTaskFactory) {
+ this.effectorTaskFactory = effectorTaskFactory;
+ }
+
+ @Override
+ public Task<T> newTask(final Entity entity, final org.apache.brooklyn.api.effector.Effector<T> effector, final ConfigBag parameters) {
+ if (effectorTaskFactory instanceof EffectorBodyTaskFactory)
+ return effectorTaskFactory.newTask(entity, effector, parameters).asTask();
+ // if we're in an effector context for this effector already, then also pass through
+ if (BrooklynTaskTags.isInEffectorTask(Tasks.current(), entity, effector, false))
+ return effectorTaskFactory.newTask(entity, effector, parameters).asTask();
+ // otherwise, create the task inside an appropriate effector body so tags, name, etc are set correctly
+ return new EffectorBodyTaskFactory<T>(new EffectorBody<T>() {
+ @Override
+ public T call(ConfigBag parameters) {
+ TaskAdaptable<T> t = DynamicTasks.queue(effectorTaskFactory.newTask(entity, effector, parameters));
+ return t.asTask().getUnchecked();
+ }
+ }).newTask(entity, effector, parameters);
+ }
+ }
+
+ public static <T> ConfigKey<T> asConfigKey(ParameterType<T> t) {
+ return ConfigKeys.newConfigKey(t.getParameterClass(), t.getName());
+ }
+
+ public static <T> ParameterTask<T> parameter(ParameterType<T> t) {
+ return new ParameterTask<T>(asConfigKey(t)).
+ name("parameter "+t);
+ }
+ public static <T> ParameterTask<T> parameter(Class<T> type, String name) {
+ return new ParameterTask<T>(ConfigKeys.newConfigKey(type, name)).
+ name("parameter "+name+" ("+type+")");
+ }
+ public static <T> ParameterTask<T> parameter(final ConfigKey<T> p) {
+ return new ParameterTask<T>(p);
+ }
+ public static class ParameterTask<T> implements EffectorTaskFactory<T> {
+ final ConfigKey<T> p;
+ private TaskBuilder<T> builder;
+ public ParameterTask(ConfigKey<T> p) {
+ this.p = p;
+ this.builder = Tasks.<T>builder().name("parameter "+p);
+ }
+ public ParameterTask<T> name(String taskName) {
+ builder.name(taskName);
+ return this;
+ }
+ @Override
+ public Task<T> newTask(Entity entity, Effector<T> effector, final ConfigBag parameters) {
+ return builder.body(new Callable<T>() {
+ @Override
+ public T call() throws Exception {
+ return parameters.get(p);
+ }
+
+ }).build();
+ }
+
+ }
+
+ public static <T> EffectorTaskFactory<T> of(final Task<T> task) {
+ return new EffectorTaskFactory<T>() {
+ @Override
+ public Task<T> newTask(Entity entity, Effector<T> effector, ConfigBag parameters) {
+ return task;
+ }
+ };
+ }
+
+ /** Finds the entity where this task is running
+ * @throws NullPointerException if there is none (no task, or no context entity for that task) */
+ public static Entity findEntity() {
+ return Preconditions.checkNotNull(BrooklynTaskTags.getTargetOrContextEntity(Tasks.current()),
+ "This must be executed in a task whose execution context has a target or context entity " +
+ "(i.e. it must be run from within an effector)");
+ }
+
+ /** Finds the entity where this task is running, casted to the given Entity subtype
+ * @throws NullPointerException if there is none
+ * @throws IllegalArgumentException if it is not of the indicated type */
+ public static <T extends Entity> T findEntity(Class<T> type) {
+ Entity t = findEntity();
+ return Reflections.cast(t, type);
+ }
+
+ /** Finds a unique {@link SshMachineLocation} attached to the entity
+ * where this task is running
+ * @throws NullPointerException if {@link #findEntity()} fails
+ * @throws IllegalStateException if call to {@link #getSshMachine(Entity)} fails */
+ public static SshMachineLocation findSshMachine() {
+ return getSshMachine(findEntity());
+ }
+
+ /** Finds a unique {@link SshMachineLocation} attached to the supplied entity
+ * @throws IllegalStateException if there is not a unique such {@link SshMachineLocation} */
+ public static SshMachineLocation getSshMachine(Entity entity) {
+ try {
+ return Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
+ } catch (Exception e) {
+ throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single SshMachineLocation, but has "+entity.getLocations(), e);
+ }
+ }
+
+ /** Finds a unique {@link WinRmMachineLocation} attached to the supplied entity
+ * @throws IllegalStateException if there is not a unique such {@link WinRmMachineLocation} */
+ public static WinRmMachineLocation getWinRmMachine(Entity entity) {
+ try {
+ return Machines.findUniqueWinRmMachineLocation(entity.getLocations()).get();
+ } catch (Exception e) {
+ throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single WinRmMachineLocation, but has "+entity.getLocations(), e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorWithBody.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorWithBody.java b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorWithBody.java
new file mode 100644
index 0000000..67dba14
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorWithBody.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+
+import com.google.common.annotations.Beta;
+
+@Beta // added in 0.6.0
+public interface EffectorWithBody<T> extends Effector<T> {
+
+ /** returns the body of the effector, i.e. a factory which can generate tasks which can run */
+ public EffectorTaskFactory<T> getBody();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java b/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
new file mode 100644
index 0000000..63ea52d
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/Effectors.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorBodyTaskFactory;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorMarkingTaskFactory;
+import org.apache.brooklyn.core.effector.EffectorTasks.EffectorTaskFactory;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class Effectors {
+
+ private static final Logger log = LoggerFactory.getLogger(Effectors.class);
+
+ public static class EffectorBuilder<T> {
+ private Class<T> returnType;
+ private String effectorName;
+ private String description;
+ private Map<String,ParameterType<?>> parameters = new LinkedHashMap<String,ParameterType<?>>();
+ private EffectorTaskFactory<T> impl;
+
+ private EffectorBuilder(Class<T> returnType, String effectorName) {
+ this.returnType = returnType;
+ this.effectorName = effectorName;
+ }
+ public EffectorBuilder<T> description(String description) {
+ this.description = description;
+ return this;
+ }
+ public EffectorBuilder<T> parameter(Class<?> paramType, String paramName) {
+ return parameter(paramType, paramName, null, null);
+ }
+ public EffectorBuilder<T> parameter(Class<?> paramType, String paramName, String paramDescription) {
+ return parameter(paramType, paramName, paramDescription, null);
+ }
+ public <V> EffectorBuilder<T> parameter(Class<V> paramType, String paramName, String paramDescription, V defaultValue) {
+ return parameter(new BasicParameterType<V>(paramName, paramType, paramDescription, defaultValue));
+ }
+ public <V> EffectorBuilder<T> parameter(ConfigKey<V> key) {
+ return parameter(asParameterType(key));
+ }
+ public EffectorBuilder<T> parameter(ParameterType<?> p) {
+ // allow redeclaring, e.g. for the case where we are overriding an existing effector
+ parameters.put(p.getName(), p);
+ return this;
+ }
+ public EffectorBuilder<T> impl(EffectorTaskFactory<T> taskFactory) {
+ this.impl = new EffectorMarkingTaskFactory<T>(taskFactory);
+ return this;
+ }
+ public EffectorBuilder<T> impl(EffectorBody<T> effectorBody) {
+ this.impl = new EffectorBodyTaskFactory<T>(effectorBody);
+ return this;
+ }
+ /** returns the effector, with an implementation (required); @see {@link #buildAbstract()} */
+ public Effector<T> build() {
+ Preconditions.checkNotNull(impl, "Cannot create effector %s with no impl (did you forget impl? or did you mean to buildAbstract?)", effectorName);
+ return new EffectorAndBody<T>(effectorName, returnType, ImmutableList.copyOf(parameters.values()), description, impl);
+ }
+
+ /** returns an abstract effector, where the body will be defined later/elsewhere
+ * (impl must not be set) */
+ public Effector<T> buildAbstract() {
+ Preconditions.checkArgument(impl==null, "Cannot create abstract effector {} as an impl is defined", effectorName);
+ return new EffectorBase<T>(effectorName, returnType, ImmutableList.copyOf(parameters.values()), description);
+ }
+ }
+
+ /** creates a new effector builder with the given name and return type */
+ public static <T> EffectorBuilder<T> effector(Class<T> returnType, String effectorName) {
+ return new EffectorBuilder<T>(returnType, effectorName);
+ }
+
+ /** creates a new effector builder to _override_ the given effector */
+ public static <T> EffectorBuilder<T> effector(Effector<T> base) {
+ EffectorBuilder<T> builder = new EffectorBuilder<T>(base.getReturnType(), base.getName());
+ for (ParameterType<?> p: base.getParameters())
+ builder.parameter(p);
+ builder.description(base.getDescription());
+ if (base instanceof EffectorWithBody)
+ builder.impl(((EffectorWithBody<T>) base).getBody());
+ return builder;
+ }
+
+ /** as {@link #invocation(Entity, Effector, Map)} but convenience for passing a {@link ConfigBag} */
+ public static <T> TaskAdaptable<T> invocation(Entity entity, Effector<T> eff, ConfigBag parameters) {
+ return invocation(entity, eff, parameters==null ? ImmutableMap.of() : parameters.getAllConfig());
+ }
+
+ /** returns an unsubmitted task which invokes the given effector; use {@link Entities#invokeEffector(EntityLocal, Entity, Effector, Map)} for a submitted variant */
+ public static <T> TaskAdaptable<T> invocation(Entity entity, Effector<T> eff, @Nullable Map<?,?> parameters) {
+ @SuppressWarnings("unchecked")
+ Effector<T> eff2 = (Effector<T>) ((EntityInternal)entity).getEffector(eff.getName());
+ if (log.isTraceEnabled()) {
+ Object eff1Body = (eff instanceof EffectorWithBody<?> ? ((EffectorWithBody<?>) eff).getBody() : "bodyless");
+ String message = String.format("Invoking %s/%s on entity %s", eff, eff1Body, entity);
+ if (eff != eff2) {
+ Object eff2Body = (eff2 instanceof EffectorWithBody<?> ? ((EffectorWithBody<?>) eff2).getBody() : "bodyless");
+ message += String.format(" (actually %s/%s)", eff2, eff2Body);
+ }
+ log.trace(message);
+ }
+ if (eff2 != null) {
+ if (eff2 != eff) {
+ if (eff2 instanceof EffectorWithBody) {
+ log.debug("Replacing invocation of {} on {} with {} which is the impl defined at that entity", new Object[] { eff, entity, eff2 });
+ return ((EffectorWithBody<T>)eff2).getBody().newTask(entity, eff2, ConfigBag.newInstance().putAll(parameters));
+ } else {
+ log.warn("Effector {} defined on {} has no body; invoking caller-supplied {} instead", new Object[] { eff2, entity, eff });
+ }
+ }
+ } else {
+ log.debug("Effector {} does not exist on {}; attempting to invoke anyway", new Object[] { eff, entity });
+ }
+
+ if (eff instanceof EffectorWithBody) {
+ return ((EffectorWithBody<T>)eff).getBody().newTask(entity, eff, ConfigBag.newInstance().putAll(parameters));
+ }
+
+ throw new UnsupportedOperationException("No implementation registered for effector "+eff+" on "+entity);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <V> ParameterType<V> asParameterType(ConfigKey<V> key) {
+ return key.hasDefaultValue()
+ ? new BasicParameterType<V>(key.getName(), (Class)key.getType(), key.getDescription(), key.getDefaultValue())
+ : new BasicParameterType<V>(key.getName(), (Class)key.getType(), key.getDescription());
+ }
+
+ public static <V> ConfigKey<V> asConfigKey(ParameterType<V> paramType) {
+ return ConfigKeys.newConfigKey(paramType.getParameterClass(), paramType.getName(), paramType.getDescription(), paramType.getDefaultValue());
+ }
+
+ /** returns an unsubmitted task which will invoke the given effector on the given entities;
+ * return type is Task<List<T>> (but haven't put in the blood sweat toil and tears to make the generics work) */
+ public static TaskAdaptable<List<?>> invocation(Effector<?> eff, Map<?,?> params, Iterable<? extends Entity> entities) {
+ List<TaskAdaptable<?>> tasks = new ArrayList<TaskAdaptable<?>>();
+ for (Entity e: entities) tasks.add(invocation(e, eff, params));
+ return Tasks.parallel("invoking "+eff+" on "+tasks.size()+" node"+(Strings.s(tasks.size())), tasks.toArray(new TaskAdaptable[tasks.size()]));
+ }
+
+ /** returns an unsubmitted task which will invoke the given effector on the given entities
+ * (this form of method is a convenience for {@link #invocation(Effector, Map, Iterable)}) */
+ public static TaskAdaptable<List<?>> invocation(Effector<?> eff, MutableMap<?, ?> params, Entity ...entities) {
+ return invocation(eff, params, Arrays.asList(entities));
+ }
+
+ public static boolean sameSignature(Effector<?> e1, Effector<?> e2) {
+ return Objects.equal(e1.getName(), e2.getName()) &&
+ Objects.equal(e1.getParameters(), e2.getParameters()) &&
+ Objects.equal(e1.getReturnType(), e2.getReturnType());
+ }
+
+ // TODO sameSignatureAndBody
+
+ public static boolean sameInstance(Effector<?> e1, Effector<?> e2) {
+ return e1 == e2;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/ExplicitEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/ExplicitEffector.java b/core/src/main/java/org/apache/brooklyn/core/effector/ExplicitEffector.java
new file mode 100644
index 0000000..65c1f0c
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/ExplicitEffector.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import groovy.lang.Closure;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+
+public abstract class ExplicitEffector<I,T> extends AbstractEffector<T> {
+ public ExplicitEffector(String name, Class<T> type, String description) {
+ this(name, type, ImmutableList.<ParameterType<?>>of(), description);
+ }
+ public ExplicitEffector(String name, Class<T> type, List<ParameterType<?>> parameters, String description) {
+ super(name, type, parameters, description);
+ }
+
+ public T call(Entity entity, Map parameters) {
+ return invokeEffector((I) entity, (Map<String,?>)parameters );
+ }
+
+ public abstract T invokeEffector(I trait, Map<String,?> parameters);
+
+ /** convenience to create an effector supplying a closure; annotations are preferred,
+ * and subclass here would be failback, but this is offered as
+ * workaround for bug GROOVY-5122, as discussed in test class CanSayHi
+ */
+ public static <I,T> ExplicitEffector<I,T> create(String name, Class<T> type, List<ParameterType<?>> parameters, String description, Closure body) {
+ return new ExplicitEffectorFromClosure<I,T>(name, type, parameters, description, body);
+ }
+
+ private static class ExplicitEffectorFromClosure<I,T> extends ExplicitEffector<I,T> {
+ private static final long serialVersionUID = -5771188171702382236L;
+ final Closure<T> body;
+ public ExplicitEffectorFromClosure(String name, Class<T> type, List<ParameterType<?>> parameters, String description, Closure<T> body) {
+ super(name, type, parameters, description);
+ this.body = body;
+ }
+ public T invokeEffector(I trait, Map<String,?> parameters) { return body.call(trait, parameters); }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), body);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return super.equals(other) && Objects.equal(body, ((ExplicitEffectorFromClosure<?,?>)other).body);
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/core/src/main/java/org/apache/brooklyn/core/effector/MethodEffector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/MethodEffector.java b/core/src/main/java/org/apache/brooklyn/core/effector/MethodEffector.java
new file mode 100644
index 0000000..ad53adb
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/MethodEffector.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.effector;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.brooklyn.api.effector.Effector;
+import org.apache.brooklyn.api.effector.ParameterType;
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.core.annotation.EffectorParam;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
+import org.codehaus.groovy.runtime.MethodClosure;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+/** concrete class for providing an Effector implementation that gets its information from annotations on a method;
+ * see Effector*Test for usage example.
+ * <p>
+ * note that the method must be on an interface in order for it to be remoted, with the current implementation.
+ * see comments in {@link #call(Entity, Map)} for more details.
+ */
+public class MethodEffector<T> extends AbstractEffector<T> {
+
+ private static final long serialVersionUID = 6989688364011965968L;
+ private static final Logger log = LoggerFactory.getLogger(MethodEffector.class);
+
+ @SuppressWarnings("rawtypes")
+ public static Effector<?> create(Method m) {
+ return new MethodEffector(m);
+ }
+
+ protected static class AnnotationsOnMethod {
+ final Class<?> clazz;
+ final String name;
+ final String description;
+ final Class<?> returnType;
+ final List<ParameterType<?>> parameters;
+
+ public AnnotationsOnMethod(Class<?> clazz, String methodName) {
+ this(clazz, inferBestMethod(clazz, methodName));
+ }
+
+ public AnnotationsOnMethod(Class<?> clazz, Method method) {
+ this.clazz = clazz;
+ this.name = method.getName();
+ this.returnType = method.getReturnType();
+
+ // Get the description
+ org.apache.brooklyn.core.annotation.Effector effectorAnnotation = method.getAnnotation(org.apache.brooklyn.core.annotation.Effector.class);
+ description = (effectorAnnotation != null) ? effectorAnnotation.description() : null;
+
+ // Get the parameters
+ parameters = Lists.newArrayList();
+ int numParameters = method.getParameterTypes().length;
+ for (int i = 0; i < numParameters; i++) {
+ parameters.add(toParameterType(method, i));
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected static ParameterType<?> toParameterType(Method method, int paramIndex) {
+ Annotation[] anns = method.getParameterAnnotations()[paramIndex];
+ Class<?> type = method.getParameterTypes()[paramIndex];
+ EffectorParam paramAnnotation = findAnnotation(anns, EffectorParam.class);
+
+ // TODO if blank, could do "param"+(i+1); would that be better?
+ // TODO this will now give "" if name is blank, rather than previously null. Is that ok?!
+ String name = (paramAnnotation != null) ? paramAnnotation.name() : null;
+
+ String paramDescription = (paramAnnotation == null || EffectorParam.MAGIC_STRING_MEANING_NULL.equals(paramAnnotation.description())) ? null : paramAnnotation.description();
+ String description = (paramDescription != null) ? paramDescription : null;
+
+ String paramDefaultValue = (paramAnnotation == null || EffectorParam.MAGIC_STRING_MEANING_NULL.equals(paramAnnotation.defaultValue())) ? null : paramAnnotation.defaultValue();
+ Object defaultValue = (paramDefaultValue != null) ? TypeCoercions.coerce(paramDefaultValue, type) : null;
+
+ return new BasicParameterType(name, type, description, defaultValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static <T extends Annotation> T findAnnotation(Annotation[] anns, Class<T> type) {
+ for (Annotation ann : anns) {
+ if (type.isInstance(ann)) return (T) ann;
+ }
+ return null;
+ }
+
+ protected static Method inferBestMethod(Class<?> clazz, String methodName) {
+ Method best = null;
+ for (Method it : clazz.getMethods()) {
+ if (it.getName().equals(methodName)) {
+ if (best==null || best.getParameterTypes().length < it.getParameterTypes().length) best=it;
+ }
+ }
+ if (best==null) {
+ throw new IllegalStateException("Cannot find method "+methodName+" on "+clazz.getCanonicalName());
+ }
+ return best;
+ }
+ }
+
+ /** Defines a new effector whose details are supplied as annotations on the given type and method name */
+ public MethodEffector(Class<?> whereEffectorDefined, String methodName) {
+ this(new AnnotationsOnMethod(whereEffectorDefined, methodName), null);
+ }
+
+ public MethodEffector(Method method) {
+ this(new AnnotationsOnMethod(method.getDeclaringClass(), method), null);
+ }
+
+ public MethodEffector(MethodClosure mc) {
+ this(new AnnotationsOnMethod((Class<?>)mc.getDelegate(), mc.getMethod()), null);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected MethodEffector(AnnotationsOnMethod anns, String description) {
+ super(anns.name, (Class<T>)anns.returnType, anns.parameters, GroovyJavaMethods.<String>elvis(description, anns.description));
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public T call(Entity entity, Map parameters) {
+ Object[] parametersArray = EffectorUtils.prepareArgsForEffector(this, parameters);
+ if (entity instanceof AbstractEntity) {
+ return EffectorUtils.invokeMethodEffector(entity, this, parametersArray);
+ } else {
+ // we are dealing with a proxy here
+ // this implementation invokes the method on the proxy
+ // (requiring it to be on the interface)
+ // and letting the proxy deal with the remoting / runAtEntity;
+ // alternatively we could create the task here and pass it to runAtEntity;
+ // the latter may allow us to simplify/remove a lot of the stuff from
+ // EffectorUtils and possibly Effectors and Entities
+
+ // TODO Should really find method with right signature, rather than just the right args.
+ // TODO prepareArgs can miss things out that have "default values"! Code below will probably fail if that happens.
+ Method[] methods = entity.getClass().getMethods();
+ for (Method method : methods) {
+ if (method.getName().equals(getName())) {
+ if (parametersArray.length == method.getParameterTypes().length) {
+ try {
+ return (T) method.invoke(entity, parametersArray);
+ } catch (Exception e) {
+ // exception handled by the proxy invocation (which leads to EffectorUtils.invokeEffectorMethod...)
+ throw Exceptions.propagate(e);
+ }
+ }
+ }
+ }
+ String msg = "Could not find method for effector "+getName()+" with "+parametersArray.length+" parameters on "+entity;
+ log.warn(msg+" (throwing); available methods are: "+Arrays.toString(methods));
+ throw new IllegalStateException(msg);
+ }
+ }
+
+}
[16/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
Rename o.a.b.sensor.core to o.a.b.core.sensor
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/2a78e273
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/2a78e273
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/2a78e273
Branch: refs/heads/master
Commit: 2a78e273dae0caf2e7a3b791f365d7c839a9b20b
Parents: 8dbb0e4
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 22:42:32 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 19 22:48:55 2015 +0100
----------------------------------------------------------------------
.../apache/brooklyn/core/config/ConfigKeys.java | 8 +-
.../brooklyn/core/effector/AddSensor.java | 2 +-
.../brooklyn/core/entity/AbstractEntity.java | 8 +-
.../apache/brooklyn/core/entity/Attributes.java | 10 +-
.../core/entity/BrooklynConfigKeys.java | 4 +-
.../apache/brooklyn/core/entity/Entities.java | 2 +-
.../brooklyn/core/entity/EntityTasks.java | 2 +-
.../brooklyn/core/entity/trait/Changeable.java | 4 +-
.../core/location/dynamic/LocationOwner.java | 4 +-
.../core/mgmt/persist/XmlMementoSerializer.java | 2 +-
.../mgmt/rebind/dto/BasicEntityMemento.java | 2 +-
.../brooklyn/core/sensor/AttributeMap.java | 202 +++++
.../sensor/AttributeSensorAndConfigKey.java | 147 ++++
.../core/sensor/BasicAttributeSensor.java | 62 ++
.../BasicAttributeSensorAndConfigKey.java | 114 +++
.../core/sensor/BasicNotificationSensor.java | 36 +
.../brooklyn/core/sensor/BasicSensor.java | 114 +++
.../brooklyn/core/sensor/BasicSensorEvent.java | 112 +++
.../core/sensor/DependentConfiguration.java | 823 +++++++++++++++++++
.../brooklyn/core/sensor/HttpRequestSensor.java | 96 +++
.../sensor/PortAttributeSensorAndConfigKey.java | 141 ++++
.../apache/brooklyn/core/sensor/Sensors.java | 164 ++++
.../brooklyn/core/sensor/StaticSensor.java | 72 ++
...platedStringAttributeSensorAndConfigKey.java | 66 ++
.../core/server/entity/BrooklynMetrics.java | 4 +-
.../brooklyn/entity/group/AbstractGroup.java | 2 +-
.../brooklyn/entity/group/DynamicCluster.java | 6 +-
.../brooklyn/entity/group/DynamicFabric.java | 2 +-
.../brooklyn/entity/group/DynamicGroup.java | 2 +-
.../entity/group/DynamicMultiGroup.java | 2 +-
.../brooklyn/entity/stock/DelegateEntity.java | 4 +-
.../winrm/AdvertiseWinrmLoginPolicy.java | 2 +-
.../brooklyn/sensor/core/AttributeMap.java | 202 -----
.../core/AttributeSensorAndConfigKey.java | 147 ----
.../sensor/core/BasicAttributeSensor.java | 62 --
.../core/BasicAttributeSensorAndConfigKey.java | 114 ---
.../sensor/core/BasicNotificationSensor.java | 36 -
.../brooklyn/sensor/core/BasicSensor.java | 114 ---
.../brooklyn/sensor/core/BasicSensorEvent.java | 112 ---
.../sensor/core/DependentConfiguration.java | 823 -------------------
.../brooklyn/sensor/core/HttpRequestSensor.java | 96 ---
.../core/PortAttributeSensorAndConfigKey.java | 141 ----
.../apache/brooklyn/sensor/core/Sensors.java | 164 ----
.../brooklyn/sensor/core/StaticSensor.java | 72 --
...platedStringAttributeSensorAndConfigKey.java | 66 --
.../sensor/enricher/AbstractTransformer.java | 2 +-
.../AbstractTypeTransformingEnricher.java | 2 +-
.../sensor/enricher/AddingEnricher.java | 2 +-
.../brooklyn/sensor/enricher/Combiner.java | 2 +-
.../apache/brooklyn/sensor/enricher/Joiner.java | 2 +-
.../sensor/feed/ConfigToAttributes.java | 4 +-
.../apache/brooklyn/sensor/feed/FeedConfig.java | 2 +-
.../windows/WindowsPerformanceCounterFeed.java | 2 +-
.../brooklyn/util/core/flags/TypeCoercions.java | 2 +-
.../util/core/text/TemplateProcessor.java | 4 +-
...apListAndOtherStructuredConfigKeyTest.groovy | 2 +-
.../brooklyn/core/entity/AttributeMapTest.java | 4 +-
.../brooklyn/core/entity/AttributeTest.java | 2 +-
.../entity/ConfigEntityInheritanceTest.java | 4 +-
.../core/entity/DependentConfigurationTest.java | 2 +-
.../core/entity/EntitySubscriptionTest.java | 2 +-
.../brooklyn/core/entity/EntityTypeTest.java | 4 +-
.../brooklyn/core/entity/hello/HelloEntity.java | 4 +-
.../core/entity/hello/LocalEntitiesTest.java | 4 +-
.../core/entity/internal/ConfigMapTest.java | 2 +-
.../EntityConfigMapUsageLegacyTest.java | 2 +-
.../internal/EntityConfigMapUsageTest.java | 2 +-
.../entity/lifecycle/ServiceStateLogicTest.java | 2 +-
.../core/location/TestPortSupplierLocation.java | 2 +-
.../access/PortForwardManagerRebindTest.java | 2 +-
.../internal/EntityExecutionManagerTest.java | 2 +-
.../mgmt/rebind/RebindCatalogEntityTest.java | 2 +-
.../core/mgmt/rebind/RebindEnricherTest.java | 2 +-
.../core/mgmt/rebind/RebindEntityTest.java | 8 +-
.../core/mgmt/rebind/RebindFeedTest.java | 2 +-
.../core/policy/basic/PolicyConfigTest.java | 2 +-
.../policy/basic/PolicySubscriptionTest.java | 2 +-
.../core/sensor/HttpRequestSensorTest.java | 85 ++
.../brooklyn/core/sensor/StaticSensorTest.java | 55 ++
.../core/test/entity/TestApplication.java | 2 +-
.../brooklyn/core/test/entity/TestEntity.java | 4 +-
.../brooklyn/entity/group/DynamicGroupTest.java | 2 +-
.../entity/group/DynamicMultiGroupTest.java | 2 +-
.../brooklyn/entity/stock/DataEntityTest.java | 2 +-
.../sensor/core/HttpRequestSensorTest.java | 85 --
.../brooklyn/sensor/core/StaticSensorTest.java | 55 --
...stomAggregatingEnricherDeprecatedTest.groovy | 2 +-
.../enricher/CustomAggregatingEnricherTest.java | 2 +-
.../brooklyn/sensor/enricher/EnrichersTest.java | 2 +-
...SensorPropagatingEnricherDeprecatedTest.java | 2 +-
.../enricher/SensorPropagatingEnricherTest.java | 4 +-
.../TransformingEnricherDeprecatedTest.groovy | 2 +-
.../enricher/TransformingEnricherTest.java | 2 +-
.../YamlRollingTimeWindowMeanEnricherTest.java | 4 +-
.../YamlTimeWeightedDeltaEnricherTest.java | 4 +-
.../sensor/feed/ConfigToAttributesTest.java | 4 +-
.../sensor/feed/function/FunctionFeedTest.java | 2 +-
.../feed/http/HttpFeedIntegrationTest.java | 2 +-
.../brooklyn/sensor/feed/http/HttpFeedTest.java | 2 +-
.../feed/shell/ShellFeedIntegrationTest.java | 2 +-
.../sensor/feed/ssh/SshFeedIntegrationTest.java | 2 +-
.../WindowsPerformanceCounterFeedLiveTest.java | 2 +-
.../WindowsPerformanceCounterFeedTest.java | 2 +-
.../brooklyn/util/core/task/TasksTest.java | 2 +-
.../util/core/text/TemplateProcessorTest.java | 2 +-
.../brooklyn/demo/GlobalWebFabricExample.java | 2 +-
.../brooklyn/demo/CumulusRDFApplication.java | 2 +-
.../brooklyn/demo/NodeJsTodoApplication.java | 4 +-
.../demo/WebClusterDatabaseExample.java | 6 +-
.../demo/WebClusterDatabaseExampleApp.java | 6 +-
.../demo/WebClusterDatabaseExampleGroovy.groovy | 4 +-
.../policy/jclouds/os/CreateUserPolicy.java | 2 +-
.../policy/autoscaling/AutoScalerPolicy.java | 2 +-
.../policy/enricher/HttpLatencyDetector.java | 2 +-
.../policy/followthesun/FollowTheSunPool.java | 2 +-
.../policy/ha/ConnectionFailureDetector.java | 2 +-
.../apache/brooklyn/policy/ha/HASensors.java | 2 +-
.../policy/ha/ServiceFailureDetector.java | 2 +-
.../brooklyn/policy/ha/ServiceReplacer.java | 2 +-
.../brooklyn/policy/ha/ServiceRestarter.java | 2 +-
.../policy/ha/SshMachineFailureDetector.java | 2 +-
.../loadbalancing/BalanceableContainer.java | 2 +-
.../loadbalancing/BalanceableWorkerPool.java | 2 +-
.../brooklyn/policy/loadbalancing/Movable.java | 2 +-
.../autoscaling/AutoScalerPolicyMetricTest.java | 4 +-
.../autoscaling/AutoScalerPolicyRebindTest.java | 4 +-
.../AutoScalerPolicyReconfigurationTest.java | 2 +-
.../autoscaling/AutoScalerPolicyTest.java | 2 +-
.../policy/enricher/DeltaEnrichersTests.groovy | 2 +-
.../enricher/HttpLatencyDetectorTest.java | 2 +-
.../policy/enricher/RebindEnricherTest.java | 2 +-
.../enricher/RollingMeanEnricherTest.groovy | 2 +-
.../RollingTimeWindowMeanEnricherTest.groovy | 2 +-
.../enricher/TimeFractionDeltaEnricherTest.java | 4 +-
.../AbstractLoadBalancingPolicyTest.java | 2 +-
.../policy/loadbalancing/MockItemEntity.java | 2 +-
.../entity/database/derby/DerbyDatabase.java | 4 +-
.../entity/database/derby/DerbySchema.java | 2 +-
.../postgresql/PostgreSqlNodeSaltImpl.java | 2 +-
.../apache/brooklyn/entity/salt/SaltConfig.java | 2 +-
.../brooklyn/entity/salt/SaltStackMaster.java | 4 +-
.../monitoring/zabbix/ZabbixMonitored.java | 4 +-
.../entity/monitoring/zabbix/ZabbixServer.java | 2 +-
.../nosql/hazelcast/HazelcastCluster.java | 4 +-
.../entity/nosql/hazelcast/HazelcastNode.java | 6 +-
.../nosql/infinispan/Infinispan5Server.java | 4 +-
.../entity/brooklynnode/BrooklynCluster.java | 2 +-
.../brooklynnode/BrooklynEntityMirror.java | 2 +-
.../brooklynnode/BrooklynEntityMirrorImpl.java | 2 +-
.../entity/brooklynnode/BrooklynNode.java | 10 +-
.../entity/java/JmxAttributeSensor.java | 4 +-
.../brooklyn/entity/java/UsesJavaMXBeans.java | 4 +-
.../apache/brooklyn/entity/java/UsesJmx.java | 6 +-
.../brooklyn/entity/java/VanillaJavaApp.java | 2 +-
.../entity/machine/MachineAttributes.java | 2 +-
.../entity/machine/pool/ServerPool.java | 2 +-
.../entity/machine/pool/ServerPoolImpl.java | 2 +-
.../AbstractSoftwareProcessWinRmDriver.java | 2 +-
.../software/base/AbstractVanillaProcess.java | 2 +-
.../entity/software/base/SameServerEntity.java | 2 +-
.../entity/software/base/SoftwareProcess.java | 4 +-
.../software/base/SoftwareProcessImpl.java | 2 +-
.../software/base/VanillaWindowsProcess.java | 2 +-
.../brooklyn/sensor/ssh/SshCommandSensor.java | 2 +-
.../winrm/WindowsPerformanceCounterSensors.java | 2 +-
.../entity/brooklynnode/MockBrooklynNode.java | 2 +-
.../brooklyn/entity/java/EntityPollingTest.java | 2 +-
.../entity/java/VanillaJavaAppRebindTest.java | 2 +-
.../base/SoftwareProcessEntityLatchTest.java | 2 +-
.../base/SoftwareProcessEntityTest.java | 2 +-
.../MachineLifecycleEffectorTasksTest.java | 4 +-
.../PortAttributeSensorAndConfigKeyTest.java | 2 +-
.../test/ssh/SshCommandIntegrationTest.java | 2 +-
.../brooklyn/sensor/feed/jmx/JmxFeedTest.java | 6 +-
.../sensor/feed/jmx/RebindJmxFeedTest.java | 2 +-
.../entity/database/DatastoreMixins.java | 2 +-
.../entity/database/crate/CrateNode.java | 8 +-
.../entity/database/mariadb/MariaDbNode.java | 8 +-
.../entity/database/mysql/MySqlCluster.java | 4 +-
.../entity/database/mysql/MySqlClusterImpl.java | 4 +-
.../entity/database/mysql/MySqlNode.java | 8 +-
.../database/postgresql/PostgreSqlNode.java | 4 +-
.../postgresql/PostgreSqlSshDriver.java | 2 +-
.../entity/database/rubyrep/RubyRepNode.java | 6 +-
.../database/rubyrep/RubyRepNodeImpl.java | 2 +-
.../entity/messaging/MessageBroker.java | 2 +-
.../apache/brooklyn/entity/messaging/Queue.java | 4 +-
.../apache/brooklyn/entity/messaging/Topic.java | 2 +-
.../messaging/activemq/ActiveMQBroker.java | 8 +-
.../entity/messaging/amqp/AmqpExchange.java | 2 +-
.../entity/messaging/amqp/AmqpServer.java | 4 +-
.../brooklyn/entity/messaging/kafka/Kafka.java | 2 +-
.../entity/messaging/kafka/KafkaBroker.java | 4 +-
.../entity/messaging/kafka/KafkaCluster.java | 4 +-
.../entity/messaging/kafka/KafkaZooKeeper.java | 2 +-
.../entity/messaging/qpid/QpidBroker.java | 4 +-
.../entity/messaging/rabbit/RabbitBroker.java | 6 +-
.../brooklyn/entity/messaging/storm/Storm.java | 6 +-
.../entity/messaging/storm/StormSshDriver.java | 2 +-
.../entity/zookeeper/ZooKeeperEnsemble.java | 4 +-
.../entity/zookeeper/ZooKeeperNode.java | 6 +-
.../storm/StormAbstractCloudLiveTest.java | 2 +-
.../entity/monitoring/monit/MonitNode.java | 6 +-
.../monitoring/monit/MonitIntegrationTest.java | 2 +-
.../entity/network/bind/BindDnsServer.java | 4 +-
.../network/bind/PrefixAndIdEnricher.java | 2 +-
.../nosql/cassandra/CassandraDatacenter.java | 4 +-
.../entity/nosql/cassandra/CassandraNode.java | 6 +-
.../nosql/cassandra/CassandraNodeImpl.java | 4 +-
.../nosql/cassandra/CassandraNodeSshDriver.java | 2 +-
.../nosql/couchbase/CouchbaseCluster.java | 2 +-
.../nosql/couchbase/CouchbaseClusterImpl.java | 2 +-
.../entity/nosql/couchbase/CouchbaseNode.java | 6 +-
.../nosql/couchbase/CouchbaseNodeSshDriver.java | 2 +-
.../nosql/couchbase/CouchbaseSyncGateway.java | 6 +-
.../CouchbaseSyncGatewaySshDriver.java | 2 +-
.../entity/nosql/couchdb/CouchDBCluster.java | 4 +-
.../entity/nosql/couchdb/CouchDBNode.java | 2 +-
.../elasticsearch/ElasticSearchCluster.java | 2 +-
.../nosql/elasticsearch/ElasticSearchNode.java | 8 +-
.../nosql/mongodb/AbstractMongoDBServer.java | 6 +-
.../nosql/mongodb/MongoDBClientSshDriver.java | 2 +-
.../entity/nosql/mongodb/MongoDBReplicaSet.java | 2 +-
.../entity/nosql/mongodb/MongoDBServer.java | 4 +-
.../sharding/CoLocatedMongoDBRouter.java | 2 +-
.../sharding/CoLocatedMongoDBRouterImpl.java | 2 +-
.../sharding/MongoDBConfigServerCluster.java | 2 +-
.../nosql/mongodb/sharding/MongoDBRouter.java | 2 +-
.../mongodb/sharding/MongoDBRouterCluster.java | 2 +-
.../sharding/MongoDBShardedDeployment.java | 2 +-
.../sharding/MongoDBShardedDeploymentImpl.java | 2 +-
.../entity/nosql/redis/RedisClusterImpl.java | 2 +-
.../brooklyn/entity/nosql/redis/RedisStore.java | 6 +-
.../brooklyn/entity/nosql/riak/RiakCluster.java | 2 +-
.../entity/nosql/riak/RiakClusterImpl.java | 2 +-
.../brooklyn/entity/nosql/riak/RiakNode.java | 6 +-
.../entity/nosql/riak/RiakNodeImpl.java | 2 +-
.../brooklyn/entity/nosql/solr/SolrServer.java | 4 +-
.../cassandra/CassandraNodeIntegrationTest.java | 2 +-
.../entity/osgi/karaf/KarafContainer.java | 6 +-
.../entity/dns/AbstractGeoDnsService.java | 2 +-
.../dns/geoscaling/GeoscalingDnsService.java | 2 +-
.../entity/proxy/AbstractController.java | 2 +-
.../brooklyn/entity/proxy/LoadBalancer.java | 6 +-
.../entity/proxy/nginx/NginxController.java | 4 +-
.../brooklyn/entity/proxy/nginx/UrlMapping.java | 2 +-
.../webapp/ControlledDynamicWebAppCluster.java | 4 +-
.../entity/webapp/DynamicWebAppCluster.java | 2 +-
.../entity/webapp/DynamicWebAppFabric.java | 2 +-
.../entity/webapp/JavaWebAppService.java | 2 +-
.../entity/webapp/WebAppServiceConstants.java | 6 +-
.../entity/webapp/WebAppServiceMetrics.java | 8 +-
.../entity/webapp/jboss/JBoss6Server.java | 2 +-
.../entity/webapp/jboss/JBoss7Server.java | 8 +-
.../entity/webapp/jetty/Jetty6Server.java | 4 +-
.../entity/webapp/tomcat/Tomcat8Server.java | 2 +-
.../entity/webapp/tomcat/TomcatServer.java | 6 +-
.../brooklyn/entity/proxy/StubAppServer.java | 2 +-
.../nginx/NginxHttpsSslIntegrationTest.java | 2 +-
.../app/ClusterWebServerDatabaseSample.java | 6 +-
.../spi/dsl/methods/BrooklynDslCommon.java | 2 +-
.../brooklyn/spi/dsl/methods/DslComponent.java | 4 +-
.../camp/brooklyn/DslAndRebindYamlTest.java | 2 +-
.../EnrichersSlightlySimplerYamlTest.java | 2 +-
.../camp/brooklyn/EntitiesYamlTest.java | 2 +-
.../TestSensorAndEffectorInitializer.java | 2 +-
.../brooklyn/VanillaBashNetcatYamlTest.java | 2 +-
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 4 +-
.../qa/longevity/webcluster/WebClusterApp.java | 2 +-
.../rest/resources/ApplicationResource.java | 2 +-
.../brooklyn/rest/resources/SensorResource.java | 2 +-
.../brooklyn/rest/domain/SensorSummaryTest.java | 2 +-
.../rest/resources/DescendantsTest.java | 2 +-
.../rest/resources/SensorResourceTest.java | 2 +-
.../testing/mocks/RestMockSimpleEntity.java | 2 +-
275 files changed, 2667 insertions(+), 2667 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
index 167e208..df03c29 100644
--- a/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/config/ConfigKeys.java
@@ -24,10 +24,10 @@ import javax.annotation.Nonnull;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey.BasicConfigKeyOverwriting;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.TemplatedStringAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
index 3c08831..d35068f 100644
--- a/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/AddSensor.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.javalang.Boxing;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index ea6bda7..994961c 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -77,10 +77,10 @@ import org.apache.brooklyn.core.objs.AbstractBrooklynObject;
import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
import org.apache.brooklyn.core.objs.AbstractEntityAdjunct.AdjunctTagSupport;
import org.apache.brooklyn.core.policy.AbstractPolicy;
-import org.apache.brooklyn.sensor.core.AttributeMap;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.AttributeMap;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.sensor.feed.AbstractFeed;
import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/entity/Attributes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/Attributes.java b/core/src/main/java/org/apache/brooklyn/core/entity/Attributes.java
index e585e5d..80ed765 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/Attributes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/Attributes.java
@@ -27,11 +27,11 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.net.UserAndHostAndPort;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java b/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
index 716f934..cedccb8 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.TemplatedStringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.internal.ssh.ShellTool;
import org.apache.brooklyn.util.core.internal.ssh.SshTool;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
index ca561e1..c1a77ad 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/Entities.java
@@ -77,7 +77,7 @@ import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.mgmt.internal.NonDeploymentManagementContext;
import org.apache.brooklyn.core.objs.BrooklynObjectInternal;
import org.apache.brooklyn.core.objs.proxy.EntityProxyImpl;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/entity/EntityTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntityTasks.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntityTasks.java
index ba2992f..c4f383d 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntityTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntityTasks.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.core.entity;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/entity/trait/Changeable.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Changeable.java b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Changeable.java
index d8fec0e..388eb17 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/trait/Changeable.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/trait/Changeable.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.core.entity.trait;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
/**
* A collection of entities that can change.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java b/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java
index 1d4d4c1..718b97e 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/dynamic/LocationOwner.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.location.LocationDefinition;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.annotations.Beta;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
index e1d704b..b232ce4 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/persist/XmlMementoSerializer.java
@@ -59,7 +59,7 @@ import org.apache.brooklyn.core.mgmt.rebind.dto.BasicFeedMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicLocationMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.BasicPolicyMemento;
import org.apache.brooklyn.core.mgmt.rebind.dto.MutableBrooklynMemento;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.util.core.xstream.XmlSerializer;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicEntityMemento.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicEntityMemento.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicEntityMemento.java
index 7da8441..7418813 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicEntityMemento.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/BasicEntityMemento.java
@@ -39,7 +39,7 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.Sanitizer;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.objs.BrooklynTypes;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.Lists;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeMap.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeMap.java b/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeMap.java
new file mode 100644
index 0000000..b584f24
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeMap.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.BrooklynLogging;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Objects;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+
+/**
+ * A {@link Map} of {@link Entity} attribute values.
+ */
+public final class AttributeMap implements Serializable {
+
+ private static final long serialVersionUID = -6834883734250888344L;
+
+ static final Logger log = LoggerFactory.getLogger(AttributeMap.class);
+
+ private static enum Marker {
+ NULL;
+ }
+
+ private final AbstractEntity entity;
+
+ // Assumed to be something like a ConcurrentMap passed in.
+ private final Map<Collection<String>, Object> values;
+
+ /**
+ * Creates a new AttributeMap.
+ *
+ * @param entity the EntityLocal this AttributeMap belongs to.
+ * @throws IllegalArgumentException if entity is null
+ */
+ public AttributeMap(AbstractEntity entity, Map<Collection<String>, Object> storage) {
+ this.entity = checkNotNull(entity, "entity must be specified");
+ this.values = checkNotNull(storage, "storage map must not be null");
+ }
+
+ public Map<Collection<String>, Object> asRawMap() {
+ return ImmutableMap.copyOf(values);
+ }
+
+ public Map<String, Object> asMap() {
+ Map<String, Object> result = Maps.newLinkedHashMap();
+ for (Map.Entry<Collection<String>, Object> entry : values.entrySet()) {
+ String sensorName = Joiner.on('.').join(entry.getKey());
+ Object val = (isNull(entry.getValue())) ? null : entry.getValue();
+ result.put(sensorName, val);
+ }
+ return result;
+ }
+
+ /**
+ * Updates the value.
+ *
+ * @param path the path to the value.
+ * @param newValue the new value
+ * @return the old value.
+ * @throws IllegalArgumentException if path is null or empty
+ */
+ // TODO path must be ordered(and legal to contain duplicates like "a.b.a"; list would be better
+ public <T> T update(Collection<String> path, T newValue) {
+ checkPath(path);
+
+ if (newValue == null) {
+ newValue = typedNull();
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace("setting sensor {}={} for {}", new Object[] {path, newValue, entity});
+ }
+
+ @SuppressWarnings("unchecked")
+ T oldValue = (T) values.put(path, newValue);
+ return (isNull(oldValue)) ? null : oldValue;
+ }
+
+ private void checkPath(Collection<String> path) {
+ Preconditions.checkNotNull(path, "path can't be null");
+ Preconditions.checkArgument(!path.isEmpty(), "path can't be empty");
+ }
+
+ public <T> T update(AttributeSensor<T> attribute, T newValue) {
+ T oldValue = updateWithoutPublishing(attribute, newValue);
+ entity.emitInternal(attribute, newValue);
+ return oldValue;
+ }
+
+ public <T> T updateWithoutPublishing(AttributeSensor<T> attribute, T newValue) {
+ if (log.isTraceEnabled()) {
+ Object oldValue = getValue(attribute);
+ if (!Objects.equal(oldValue, newValue != null)) {
+ log.trace("setting attribute {} to {} (was {}) on {}", new Object[] {attribute.getName(), newValue, oldValue, entity});
+ } else {
+ log.trace("setting attribute {} to {} (unchanged) on {}", new Object[] {attribute.getName(), newValue, this});
+ }
+ }
+
+ T oldValue = (T) update(attribute.getNameParts(), newValue);
+
+ return (isNull(oldValue)) ? null : oldValue;
+ }
+
+ /**
+ * Where atomicity is desired, the methods in this class synchronize on the {@link #values} map.
+ */
+ public <T> T modify(AttributeSensor<T> attribute, Function<? super T, Maybe<T>> modifier) {
+ synchronized (values) {
+ T oldValue = getValue(attribute);
+ Maybe<? extends T> newValue = modifier.apply(oldValue);
+
+ if (newValue.isPresent()) {
+ if (log.isTraceEnabled()) log.trace("modified attribute {} to {} (was {}) on {}", new Object[] {attribute.getName(), newValue, oldValue, entity});
+ return update(attribute, newValue.get());
+ } else {
+ if (log.isTraceEnabled()) log.trace("modified attribute {} unchanged; not emitting on {}", new Object[] {attribute.getName(), newValue, this});
+ return oldValue;
+ }
+ }
+ }
+
+ public void remove(AttributeSensor<?> attribute) {
+ BrooklynLogging.log(log, BrooklynLogging.levelDebugOrTraceIfReadOnly(entity),
+ "removing attribute {} on {}", attribute.getName(), entity);
+
+ remove(attribute.getNameParts());
+ }
+
+ // TODO path must be ordered(and legal to contain duplicates like "a.b.a"; list would be better
+ public void remove(Collection<String> path) {
+ checkPath(path);
+
+ if (log.isTraceEnabled()) {
+ log.trace("removing sensor {} for {}", new Object[] {path, entity});
+ }
+
+ values.remove(path);
+ }
+
+ /**
+ * Gets the value
+ *
+ * @param path the path of the value to get
+ * @return the value
+ * @throws IllegalArgumentException path is null or empty.
+ */
+ public Object getValue(Collection<String> path) {
+ // TODO previously this would return a map of the sub-tree if the path matched a prefix of a group of sensors,
+ // or the leaf value if only one value. Arguably that is not required - what is/was the use-case?
+ //
+ checkPath(path);
+ Object result = values.get(path);
+ return (isNull(result)) ? null : result;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> T getValue(AttributeSensor<T> sensor) {
+ return (T) TypeCoercions.coerce(getValue(sensor.getNameParts()), sensor.getType());
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T> T typedNull() {
+ return (T) Marker.NULL;
+ }
+
+ private boolean isNull(Object t) {
+ return t == Marker.NULL;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
new file mode 100644
index 0000000..940d949
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/AttributeSensorAndConfigKey.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.reflect.TypeToken;
+
+/**
+* A {@link Sensor} describing an attribute that can be configured with inputs that are used to derive the final value.
+* <p>
+* The {@link ConfigKey} will have the same name and description as the sensor but not necessarily the same type.
+* Conversion to set the sensor value from the config key must be supplied in a subclass.
+* <p>
+* {@link ConfigToAttributes#apply(EntityLocal, AttributeSensorAndConfigKey)} is useful to set the attribute from the sensor.
+*/
+public abstract class AttributeSensorAndConfigKey<ConfigType,SensorType> extends BasicAttributeSensor<SensorType>
+ implements ConfigKey.HasConfigKey<ConfigType> {
+ private static final long serialVersionUID = -3103809215973264600L;
+ private static final Logger log = LoggerFactory.getLogger(AttributeSensorAndConfigKey.class);
+
+ private ConfigKey<ConfigType> configKey;
+
+ public AttributeSensorAndConfigKey(Class<ConfigType> configType, Class<SensorType> sensorType, String name) {
+ this(configType, sensorType, name, name, null);
+ }
+
+ public AttributeSensorAndConfigKey(Class<ConfigType> configType, Class<SensorType> sensorType, String name, String description) {
+ this(TypeToken.of(configType), TypeToken.of(sensorType), name, description, null);
+ }
+
+ public AttributeSensorAndConfigKey(Class<ConfigType> configType, Class<SensorType> sensorType, String name, String description, Object defaultValue) {
+ this(TypeToken.of(configType), TypeToken.of(sensorType), name, description, defaultValue);
+ }
+
+ public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, TypeToken<SensorType> sensorType, String name) {
+ this(configType, sensorType, name, null);
+ }
+
+ public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, TypeToken<SensorType> sensorType, String name, String description) {
+ this(configType, sensorType, name, description, null);
+ }
+
+ public AttributeSensorAndConfigKey(TypeToken<ConfigType> configType, TypeToken<SensorType> sensorType, String name, String description, Object defaultValue) {
+ super(sensorType, name, description);
+ ConfigType defaultValueTyped;
+ try {
+ defaultValueTyped = TypeCoercions.coerce(defaultValue, configType);
+ } catch (Exception e) {
+ log.warn("Invalid default value '"+defaultValue+"' for "+name+" (rethrowing: "+e, e);
+ throw Exceptions.propagate(e);
+ }
+ configKey = new BasicConfigKey<ConfigType>(configType, name, description, defaultValueTyped);
+ }
+
+ public AttributeSensorAndConfigKey(AttributeSensorAndConfigKey<ConfigType,SensorType> orig, ConfigType defaultValue) {
+ super(orig.getTypeToken(), orig.getName(), orig.getDescription());
+ configKey = ConfigKeys.newConfigKeyWithDefault(orig.configKey,
+ TypeCoercions.coerce(defaultValue, orig.configKey.getTypeToken()));
+ }
+
+ public ConfigKey<ConfigType> getConfigKey() { return configKey; }
+
+ /** returns the sensor value for this attribute on the given entity, if present,
+ * otherwise works out what the sensor value should be based on the config key's value
+ * <p>
+ * calls to this may allocate resources (e.g. ports) so should be called only once and
+ * then (if non-null) assigned as the sensor's value
+ * <p>
+ * <b>(for this reason this method should generally not be invoked by callers except in tests and by the framework,
+ * and similarly should not be overridden; implement {@link #convertConfigToSensor(Object, Entity)} instead for single-execution calls.
+ * the framework calls this from {@link AbstractEntity#setAttribute(AttributeSensorAndConfigKey)}
+ * typically via {@link ConfigToAttributes#apply(EntityLocal)} e.g. from SoftwareProcessImpl.preStart().)
+ * </b>
+ */
+ public SensorType getAsSensorValue(Entity e) {
+ SensorType sensorValue = e.getAttribute(this);
+ if (sensorValue!=null) return sensorValue;
+
+ ConfigType v = ((EntityLocal)e).getConfig(this);
+ try {
+ return convertConfigToSensor(v, e);
+ } catch (Throwable t) {
+ throw new IllegalArgumentException("Cannot convert config value "+v+" for sensor "+this+": "+t, t);
+ }
+ }
+
+ /**
+ * @see {@link #getAsSensorValue(Entity)}
+ *
+ * Differs in that the config value is converted based on just the management context, rather
+ * than for a specific entity. For example, useful if using {@link BrooklynConfigKeys} in BrooklynWebServer.
+ * </b>
+ */
+ public SensorType getAsSensorValue(ManagementContext managementContext) {
+ ConfigType v = managementContext.getConfig().getConfig(this);
+ try {
+ return convertConfigToSensor(v, managementContext);
+ } catch (Throwable t) {
+ throw new IllegalArgumentException("Cannot convert config value "+v+" for sensor "+this+": "+t, t);
+ }
+ }
+
+ /** converts the given ConfigType value to the corresponding SensorType value,
+ * with respect to the given entity
+ * <p>
+ * this is invoked after checks whether the entity already has a value for the sensor,
+ * and the entity-specific config value is passed for convenience if set,
+ * otherwise the config key default value is passed for convenience
+ * <p>
+ * this message should be allowed to return null if the conversion cannot be completed at this time */
+ protected abstract SensorType convertConfigToSensor(ConfigType value, Entity entity);
+
+ /**
+ * @see {@link #convertConfigToSensor(Object, Entity)}
+ */
+ protected abstract SensorType convertConfigToSensor(ConfigType value, ManagementContext entity);
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java
new file mode 100644
index 0000000..978e4a4
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensor.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+
+import com.google.common.reflect.TypeToken;
+
+/**
+ * A {@link Sensor} describing an attribute change.
+ */
+public class BasicAttributeSensor<T> extends BasicSensor<T> implements AttributeSensor<T> {
+ private static final long serialVersionUID = -2493209215974820300L;
+
+ private final SensorPersistenceMode persistence;
+
+ public BasicAttributeSensor(Class<T> type, String name) {
+ this(type, name, name);
+ }
+
+ public BasicAttributeSensor(Class<T> type, String name, String description) {
+ this(TypeToken.of(type), name, description);
+ }
+
+ public BasicAttributeSensor(TypeToken<T> typeToken, String name) {
+ this(typeToken, name, name);
+ }
+
+ public BasicAttributeSensor(TypeToken<T> typeToken, String name, String description) {
+ this(typeToken, name, description, SensorPersistenceMode.REQUIRED);
+ }
+
+ public BasicAttributeSensor(TypeToken<T> typeToken, String name, String description, SensorPersistenceMode persistence) {
+ super(typeToken, name, description);
+ this.persistence = checkNotNull(persistence, "persistence");
+ }
+
+ @Override
+ public SensorPersistenceMode getPersistenceMode() {
+ // persistence could be null if deserializing state written by an old version; in which case default to 'required'
+ return (persistence != null) ? persistence : SensorPersistenceMode.REQUIRED;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensorAndConfigKey.java
new file mode 100644
index 0000000..7c86112
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicAttributeSensorAndConfigKey.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.config.ConfigKey;
+
+import com.google.common.reflect.TypeToken;
+
+/**
+ * A {@link Sensor} describing an attribute that can be configured with a default value.
+ *
+ * The {@link ConfigKey} has the same type, name and description as the sensor,
+ * and is typically used to populate the sensor's value at runtime.
+ */
+public class BasicAttributeSensorAndConfigKey<T> extends AttributeSensorAndConfigKey<T,T> {
+
+ private static final long serialVersionUID = -2204916730008559688L;
+
+ public BasicAttributeSensorAndConfigKey(Class<T> type, String name) {
+ this(type, name, name, null);
+ }
+ public BasicAttributeSensorAndConfigKey(Class<T> type, String name, String description) {
+ this(type, name, description, null);
+ }
+ public BasicAttributeSensorAndConfigKey(Class<T> type, String name, String description, T defaultValue) {
+ super(type, type, name, description, defaultValue);
+ }
+
+ public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name) {
+ super(type, type, name);
+ }
+
+ public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name, String description) {
+ super(type, type, name, description);
+ }
+
+ public BasicAttributeSensorAndConfigKey(TypeToken<T> type, String name, String description, Object defaultValue) {
+ super(type, type, name, description, defaultValue);
+ }
+
+ public BasicAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<T,T> orig, T defaultValue) {
+ super(orig, defaultValue);
+ }
+
+ @Override
+ protected T convertConfigToSensor(T value, Entity entity) { return value; }
+
+ @Override
+ protected T convertConfigToSensor(T value, ManagementContext managementContext) { return value; }
+
+ public static class StringAttributeSensorAndConfigKey extends BasicAttributeSensorAndConfigKey<String> {
+
+ private static final long serialVersionUID = 810512615528081865L;
+
+ public StringAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<String,String> orig, String defaultValue) {
+ super(orig, defaultValue);
+ }
+
+ public StringAttributeSensorAndConfigKey(String name, String description, String defaultValue) {
+ super(String.class, name, description, defaultValue);
+ }
+
+ public StringAttributeSensorAndConfigKey(String name, String description) {
+ super(String.class, name, description);
+ }
+
+ public StringAttributeSensorAndConfigKey(String name) {
+ super(String.class, name);
+ }
+
+ }
+
+ public static class IntegerAttributeSensorAndConfigKey extends BasicAttributeSensorAndConfigKey<Integer> {
+
+ private static final long serialVersionUID = 7159564523829723929L;
+
+ public IntegerAttributeSensorAndConfigKey(AttributeSensorAndConfigKey<Integer,Integer> orig, Integer defaultValue) {
+ super(orig, defaultValue);
+ }
+
+ public IntegerAttributeSensorAndConfigKey(String name, String description, Integer defaultValue) {
+ super(Integer.class, name, description, defaultValue);
+ }
+
+ public IntegerAttributeSensorAndConfigKey(String name, String description) {
+ super(Integer.class, name, description);
+ }
+
+ public IntegerAttributeSensorAndConfigKey(String name) {
+ super(Integer.class, name);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/BasicNotificationSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicNotificationSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicNotificationSensor.java
new file mode 100644
index 0000000..d3a11cf
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicNotificationSensor.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.sensor.Sensor;
+
+/**
+ * A {@link Sensor} used to notify subscribers about events.
+ */
+public class BasicNotificationSensor<T> extends BasicSensor<T> {
+ private static final long serialVersionUID = -7670909215973264600L;
+
+ public BasicNotificationSensor(Class<T> type, String name) {
+ this(type, name, name);
+ }
+
+ public BasicNotificationSensor(Class<T> type, String name, String description) {
+ super(type, name, description);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java
new file mode 100644
index 0000000..efb610f
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensor.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.util.guava.TypeTokens;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * Parent for all {@link Sensor}s.
+ */
+public class BasicSensor<T> implements Sensor<T> {
+ private static final long serialVersionUID = -3762018534086101323L;
+
+ private static final Splitter dots = Splitter.on('.');
+
+ private TypeToken<T> typeToken;
+ private Class<? super T> type;
+ private String name;
+ private String description;
+ private transient List<String> nameParts;
+
+ // FIXME In groovy, fields were `public final` with a default constructor; do we need the gson?
+ public BasicSensor() { /* for gson */ }
+
+ /** name is typically a dot-separated identifier; description is optional */
+ public BasicSensor(Class<T> type, String name) {
+ this(type, name, name);
+ }
+
+ public BasicSensor(Class<T> type, String name, String description) {
+ this(TypeToken.of(type), name, description);
+ }
+
+ public BasicSensor(TypeToken<T> typeToken, String name, String description) {
+ this.typeToken = TypeTokens.getTypeTokenIfNotRaw(checkNotNull(typeToken, "typeToken"));
+ this.type = TypeTokens.getRawTypeIfRaw(typeToken);
+ this.name = checkNotNull(name, "name");
+ this.description = description;
+ }
+
+ /** @see Sensor#getTypeToken() */
+ public TypeToken<T> getTypeToken() { return TypeTokens.getTypeToken(typeToken, type); }
+
+ /** @see Sensor#getType() */
+ public Class<? super T> getType() { return TypeTokens.getRawType(typeToken, type); }
+
+ /** @see Sensor#getTypeName() */
+ public String getTypeName() {
+ return getType().getName();
+ }
+
+ /** @see Sensor#getName() */
+ public String getName() { return name; }
+
+ /** @see Sensor#getNameParts() */
+ public synchronized List<String> getNameParts() {
+ if (nameParts==null) nameParts = ImmutableList.copyOf(dots.split(name));
+ return nameParts;
+ }
+
+ /** @see Sensor#getDescription() */
+ public String getDescription() { return description; }
+
+ /** @see Sensor#newEvent(Entity, Object) */
+ public SensorEvent<T> newEvent(Entity producer, T value) {
+ return new BasicSensorEvent<T>(this, producer, value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(getTypeName(), name, description);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this==other) return true;
+ if (!(other instanceof BasicSensor)) return false;
+ BasicSensor<?> o = (BasicSensor<?>) other;
+
+ return Objects.equal(getTypeName(), o.getTypeName()) && Objects.equal(name, o.name) && Objects.equal(description, o.description);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Sensor: %s (%s)", name, getTypeName());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensorEvent.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensorEvent.java b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensorEvent.java
new file mode 100644
index 0000000..44453fc
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/BasicSensorEvent.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import java.util.ConcurrentModificationException;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects;
+
+/**
+ * A {@link SensorEvent} containing data from a {@link Sensor} generated by an {@link Entity}.
+ */
+public class BasicSensorEvent<T> implements SensorEvent<T> {
+
+ private static final Logger log = LoggerFactory.getLogger(BasicSensorEvent.class);
+
+ private final Sensor<T> sensor;
+ private final Entity source;
+ private final T value;
+ private final long timestamp;
+
+ public T getValue() { return value; }
+
+ public Sensor<T> getSensor() { return sensor; }
+
+ public Entity getSource() { return source; }
+
+ public long getTimestamp() { return timestamp; }
+
+ /** arguments should not be null (except in certain limited testing situations) */
+ public BasicSensorEvent(Sensor<T> sensor, Entity source, T value) {
+ this(sensor, source, value, System.currentTimeMillis());
+ }
+
+ public BasicSensorEvent(Sensor<T> sensor, Entity source, T value, long timestamp) {
+ this.sensor = sensor;
+ this.source = source;
+ this.value = value;
+ this.timestamp = timestamp;
+ }
+
+ public static <T> SensorEvent<T> of(Sensor<T> sensor, Entity source, T value, long timestamp) {
+ return new BasicSensorEvent<T>(sensor, source, value, timestamp);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> SensorEvent<T> ofUnchecked(Sensor<T> sensor, Entity source, Object value, long timestamp) {
+ return new BasicSensorEvent<T>(sensor, source, (T)value, timestamp);
+ }
+
+ public static <T> SensorEvent<T> of(Sensor<T> sensor, Entity source, T value) {
+ return new BasicSensorEvent<T>(sensor, source, value);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> SensorEvent<T> ofUnchecked(Sensor<T> sensor, Entity source, Object value) {
+ return new BasicSensorEvent<T>(sensor, source, (T)value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(sensor, source, value);
+ }
+
+ /**
+ * Any SensorEvents are equal if their sensor, source and value are equal.
+ * Ignore timestamp for ease of use in unit tests.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof SensorEvent)) return false;
+ SensorEvent<?> other = (SensorEvent<?>) o;
+ return Objects.equal(sensor, other.getSensor()) && Objects.equal(source, other.getSource()) &&
+ Objects.equal(value, other.getValue());
+ }
+
+ @Override
+ public String toString() {
+ try {
+ return source+"."+sensor+"="+value+" @ "+timestamp;
+ } catch (ConcurrentModificationException e) {
+ // TODO occasional CME observed on shutdown, wrt map, e.g. in UrlMappingTest
+ // transformations should set a copy of the map; see e.g. in ServiceStateLogic.updateMapSensor
+ String result = getClass()+":"+source+"."+sensor+"@"+timestamp;
+ log.warn("Error creating string for " + result + " (ignoring): " + e);
+ if (log.isDebugEnabled())
+ log.debug("Trace for error creating string for " + result + " (ignoring): " + e, e);
+ return result;
+ }
+ }
+}
[35/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
Rename o.a.b.sensor.enricher to o.a.b.core.enricher
- and o.a.b.enricher.stock for actual enricher impls
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6f15e8a6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6f15e8a6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6f15e8a6
Branch: refs/heads/master
Commit: 6f15e8a6d61c2e648547cf7faba03fbc06716421
Parents: daf4091
Author: Aled Sage <al...@gmail.com>
Authored: Wed Aug 19 23:07:28 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Aug 19 23:07:28 2015 +0100
----------------------------------------------------------------------
.../core/enricher/AbstractEnricher.java | 115 +++
.../core/enricher/EnricherDynamicType.java | 43 +
.../core/enricher/EnricherTypeSnapshot.java | 39 +
.../brooklyn/core/entity/AbstractEntity.java | 2 +-
.../entity/lifecycle/ServiceStateLogic.java | 8 +-
.../mgmt/rebind/BasicEnricherRebindSupport.java | 2 +-
.../mgmt/rebind/BasicEntityRebindSupport.java | 2 +-
.../core/mgmt/rebind/RebindIteration.java | 2 +-
.../core/mgmt/rebind/RebindManagerImpl.java | 2 +-
.../mgmt/rebind/dto/MementosGenerators.java | 2 +-
.../core/objs/AbstractEntityAdjunct.java | 2 +-
.../brooklyn/core/objs/BrooklynTypes.java | 2 +-
.../core/objs/proxy/InternalPolicyFactory.java | 2 +-
.../brooklyn/core/sensor/StaticSensor.java | 2 +-
.../stock/AbstractAggregatingEnricher.java | 174 ++++
.../enricher/stock/AbstractAggregator.java | 238 ++++++
.../stock/AbstractMultipleSensorAggregator.java | 169 ++++
.../enricher/stock/AbstractTransformer.java | 101 +++
.../stock/AbstractTransformingEnricher.java | 38 +
.../stock/AbstractTypeTransformingEnricher.java | 68 ++
.../brooklyn/enricher/stock/AddingEnricher.java | 107 +++
.../brooklyn/enricher/stock/Aggregator.java | 222 +++++
.../brooklyn/enricher/stock/Combiner.java | 138 ++++
.../stock/CustomAggregatingEnricher.java | 320 +++++++
.../brooklyn/enricher/stock/Enrichers.java | 825 +++++++++++++++++++
.../apache/brooklyn/enricher/stock/Joiner.java | 127 +++
.../brooklyn/enricher/stock/Propagator.java | 201 +++++
.../stock/SensorPropagatingEnricher.java | 181 ++++
.../stock/SensorTransformingEnricher.java | 106 +++
.../brooklyn/enricher/stock/Transformer.java | 103 +++
.../brooklyn/enricher/stock/UpdatingMap.java | 159 ++++
.../YamlRollingTimeWindowMeanEnricher.java | 178 ++++
.../stock/YamlTimeWeightedDeltaEnricher.java | 83 ++
.../entity/group/DynamicFabricImpl.java | 2 +-
.../entity/stock/DelegateEntityImpl.java | 2 +-
.../enricher/AbstractAggregatingEnricher.java | 173 ----
.../sensor/enricher/AbstractAggregator.java | 237 ------
.../sensor/enricher/AbstractEnricher.java | 115 ---
.../AbstractMultipleSensorAggregator.java | 169 ----
.../sensor/enricher/AbstractTransformer.java | 100 ---
.../enricher/AbstractTransformingEnricher.java | 38 -
.../AbstractTypeTransformingEnricher.java | 67 --
.../sensor/enricher/AddingEnricher.java | 106 ---
.../brooklyn/sensor/enricher/Aggregator.java | 221 -----
.../brooklyn/sensor/enricher/Combiner.java | 137 ---
.../enricher/CustomAggregatingEnricher.java | 320 -------
.../sensor/enricher/EnricherDynamicType.java | 43 -
.../sensor/enricher/EnricherTypeSnapshot.java | 39 -
.../brooklyn/sensor/enricher/Enrichers.java | 824 ------------------
.../apache/brooklyn/sensor/enricher/Joiner.java | 126 ---
.../brooklyn/sensor/enricher/Propagator.java | 200 -----
.../enricher/SensorPropagatingEnricher.java | 180 ----
.../enricher/SensorTransformingEnricher.java | 106 ---
.../brooklyn/sensor/enricher/Transformer.java | 103 ---
.../brooklyn/sensor/enricher/UpdatingMap.java | 158 ----
.../YamlRollingTimeWindowMeanEnricher.java | 178 ----
.../enricher/YamlTimeWeightedDeltaEnricher.java | 83 --
.../core/enricher/BasicEnricherTest.java | 119 +++
.../core/enricher/EnricherConfigTest.java | 147 ++++
.../brooklyn/core/entity/EntitySpecTest.java | 2 +-
.../BrooklynMementoPersisterTestFixture.java | 2 +-
.../core/mgmt/rebind/RebindEnricherTest.java | 4 +-
.../core/mgmt/rebind/RebindFailuresTest.java | 2 +-
.../core/mgmt/rebind/RebindPolicyTest.java | 2 +-
.../core/policy/basic/EnricherTypeTest.java | 2 +-
.../brooklyn/core/test/policy/TestEnricher.java | 2 +-
...stomAggregatingEnricherDeprecatedTest.groovy | 368 +++++++++
.../stock/CustomAggregatingEnricherTest.java | 556 +++++++++++++
.../brooklyn/enricher/stock/EnrichersTest.java | 501 +++++++++++
...SensorPropagatingEnricherDeprecatedTest.java | 108 +++
.../stock/SensorPropagatingEnricherTest.java | 218 +++++
.../TransformingEnricherDeprecatedTest.groovy | 83 ++
.../stock/TransformingEnricherTest.java | 71 ++
.../YamlRollingTimeWindowMeanEnricherTest.java | 179 ++++
.../YamlTimeWeightedDeltaEnricherTest.java | 107 +++
.../sensor/enricher/BasicEnricherTest.java | 119 ---
...stomAggregatingEnricherDeprecatedTest.groovy | 367 ---------
.../enricher/CustomAggregatingEnricherTest.java | 556 -------------
.../sensor/enricher/EnricherConfigTest.java | 147 ----
.../brooklyn/sensor/enricher/EnrichersTest.java | 501 -----------
...SensorPropagatingEnricherDeprecatedTest.java | 108 ---
.../enricher/SensorPropagatingEnricherTest.java | 218 -----
.../TransformingEnricherDeprecatedTest.groovy | 82 --
.../enricher/TransformingEnricherTest.java | 71 --
.../YamlRollingTimeWindowMeanEnricherTest.java | 179 ----
.../YamlTimeWeightedDeltaEnricherTest.java | 107 ---
.../brooklyn/demo/ResilientMongoDbApp.java | 2 +-
.../demo/WebClusterDatabaseExample.java | 2 +-
.../demo/WebClusterDatabaseExampleApp.java | 2 +-
...lusterDatabaseExampleAppIntegrationTest.java | 2 +-
.../brooklyn/policy/enricher/DeltaEnricher.java | 2 +-
.../policy/enricher/HttpLatencyDetector.java | 2 +-
.../policy/enricher/RollingMeanEnricher.java | 2 +-
.../enricher/RollingTimeWindowMeanEnricher.java | 4 +-
.../enricher/TimeFractionDeltaEnricher.java | 2 +-
.../enricher/TimeWeightedDeltaEnricher.java | 4 +-
.../brooklynnode/BrooklynClusterImpl.java | 2 +-
.../entity/brooklynnode/BrooklynNodeImpl.java | 2 +-
.../software/base/SoftwareProcessImpl.java | 2 +-
.../system_service/SystemServiceEnricher.java | 2 +-
.../entity/database/crate/CrateNodeImpl.java | 2 +-
.../entity/database/mysql/MySqlClusterImpl.java | 2 +-
.../messaging/kafka/KafkaClusterImpl.java | 2 +-
.../messaging/storm/StormDeploymentImpl.java | 2 +-
.../bind/BindDnsServerIntegrationTest.java | 2 +-
.../network/bind/PrefixAndIdEnricher.java | 2 +-
.../cassandra/CassandraDatacenterImpl.java | 2 +-
.../nosql/couchbase/CouchbaseClusterImpl.java | 2 +-
.../nosql/mongodb/MongoDBReplicaSetImpl.java | 2 +-
.../sharding/CoLocatedMongoDBRouterImpl.java | 2 +-
.../sharding/MongoDBShardedDeploymentImpl.java | 2 +-
.../entity/nosql/redis/RedisClusterImpl.java | 2 +-
.../entity/nosql/riak/RiakClusterImpl.java | 2 +-
.../entity/nosql/riak/RiakNodeImpl.java | 2 +-
.../entity/proxy/nginx/NginxControllerImpl.java | 2 +-
.../ControlledDynamicWebAppClusterImpl.java | 2 +-
.../entity/webapp/DynamicWebAppClusterImpl.java | 2 +-
.../entity/webapp/DynamicWebAppFabricImpl.java | 2 +-
.../entity/webapp/jboss/JBoss6ServerImpl.java | 2 +-
.../entity/webapp/jboss/JBoss7ServerImpl.java | 2 +-
.../entity/webapp/jetty/Jetty6ServerImpl.java | 2 +-
.../app/ClusterWebServerDatabaseSample.java | 4 +-
.../camp/brooklyn/EnrichersYamlTest.java | 2 +-
.../camp/brooklyn/TestReferencingEnricher.java | 2 +-
...est-app-with-enrichers-slightly-simpler.yaml | 12 +-
.../test-webapp-with-averaging-enricher.yaml | 4 +-
.../apache/brooklyn/cli/lister/ClassFinder.java | 2 +-
.../qa/load/SimulatedJBoss7ServerImpl.java | 2 +-
.../brooklyn/qa/load/SimulatedTheeTierApp.java | 2 +-
.../webcluster/SinusoidalLoadGenerator.java | 2 +-
.../qa/longevity/webcluster/WebClusterApp.java | 2 +-
.../rest/util/BrooklynRestResourceUtils.java | 2 +-
132 files changed, 6271 insertions(+), 6257 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/enricher/AbstractEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/enricher/AbstractEnricher.java b/core/src/main/java/org/apache/brooklyn/core/enricher/AbstractEnricher.java
new file mode 100644
index 0000000..0dc36f6
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/enricher/AbstractEnricher.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.enricher;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.rebind.RebindSupport;
+import org.apache.brooklyn.api.mgmt.rebind.mementos.EnricherMemento;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.EnricherType;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.mgmt.rebind.BasicEnricherRebindSupport;
+import org.apache.brooklyn.core.objs.AbstractEntityAdjunct;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.Maps;
+
+/**
+* Base {@link Enricher} implementation; all enrichers should extend this or its children
+*/
+public abstract class AbstractEnricher extends AbstractEntityAdjunct implements Enricher {
+
+ public static final ConfigKey<Boolean> SUPPRESS_DUPLICATES = ConfigKeys.newBooleanConfigKey("enricher.suppressDuplicates",
+ "Whether duplicate values published by this enricher should be suppressed");
+
+ private final EnricherDynamicType enricherType;
+ protected Boolean suppressDuplicates;
+
+ public AbstractEnricher() {
+ this(Maps.newLinkedHashMap());
+ }
+
+ public AbstractEnricher(Map<?,?> flags) {
+ super(flags);
+
+ enricherType = new EnricherDynamicType(this);
+
+ if (isLegacyConstruction() && !isLegacyNoConstructionInit()) {
+ init();
+ }
+ }
+
+ @Override
+ public RebindSupport<EnricherMemento> getRebindSupport() {
+ return new BasicEnricherRebindSupport(this);
+ }
+
+ @Override
+ public EnricherType getEnricherType() {
+ return enricherType.getSnapshot();
+ }
+
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ Boolean suppressDuplicates = getConfig(SUPPRESS_DUPLICATES);
+ if (suppressDuplicates!=null)
+ this.suppressDuplicates = suppressDuplicates;
+ }
+
+ @Override
+ protected void onChanged() {
+ requestPersist();
+ }
+
+ @Override
+ protected <T> void emit(Sensor<T> sensor, Object val) {
+ checkState(entity != null, "entity must first be set");
+ if (val == Entities.UNCHANGED) {
+ return;
+ }
+ if (val == Entities.REMOVE) {
+ ((EntityInternal)entity).removeAttribute((AttributeSensor<T>) sensor);
+ return;
+ }
+
+ T newVal = TypeCoercions.coerce(val, sensor.getTypeToken());
+ if (sensor instanceof AttributeSensor) {
+ if (Boolean.TRUE.equals(suppressDuplicates)) {
+ T oldValue = entity.getAttribute((AttributeSensor<T>)sensor);
+ if (Objects.equal(oldValue, newVal))
+ return;
+ }
+ entity.setAttribute((AttributeSensor<T>)sensor, newVal);
+ } else {
+ entity.emit(sensor, newVal);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherDynamicType.java b/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherDynamicType.java
new file mode 100644
index 0000000..b6a0b23
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherDynamicType.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.enricher;
+
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.EnricherType;
+import org.apache.brooklyn.core.objs.BrooklynDynamicType;
+
+public class EnricherDynamicType extends BrooklynDynamicType<Enricher, AbstractEnricher> {
+
+ public EnricherDynamicType(Class<? extends Enricher> type) {
+ super(type);
+ }
+
+ public EnricherDynamicType(AbstractEnricher enricher) {
+ super(enricher);
+ }
+
+ public EnricherType getSnapshot() {
+ return (EnricherType) super.getSnapshot();
+ }
+
+ @Override
+ protected EnricherTypeSnapshot newSnapshot() {
+ return new EnricherTypeSnapshot(name, value(configKeys));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherTypeSnapshot.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherTypeSnapshot.java b/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherTypeSnapshot.java
new file mode 100644
index 0000000..240d884
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/core/enricher/EnricherTypeSnapshot.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.enricher;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.sensor.EnricherType;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.objs.BrooklynTypeSnapshot;
+
+public class EnricherTypeSnapshot extends BrooklynTypeSnapshot implements EnricherType {
+ private static final long serialVersionUID = 4670930188951106009L;
+
+ EnricherTypeSnapshot(String name, Map<String, ConfigKey<?>> configKeys) {
+ super(name, configKeys);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ return (obj instanceof EnricherTypeSnapshot) && super.equals(obj);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
index 0ec5903..fb8f2d0 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/AbstractEntity.java
@@ -59,6 +59,7 @@ import org.apache.brooklyn.core.BrooklynFeatureEnablement;
import org.apache.brooklyn.core.BrooklynLogging;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.internal.EntityConfigMap;
import org.apache.brooklyn.core.entity.lifecycle.PolicyDescriptor;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
@@ -83,7 +84,6 @@ import org.apache.brooklyn.core.sensor.AttributeMap;
import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java b/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
index 654662f..c2606c1 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogic.java
@@ -42,16 +42,16 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.BrooklynLogging;
import org.apache.brooklyn.core.BrooklynLogging.LoggingLevel;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityAdjuncts;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle.Transition;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.enricher.AbstractMultipleSensorAggregator;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
-import org.apache.brooklyn.sensor.enricher.UpdatingMap;
+import org.apache.brooklyn.enricher.stock.AbstractMultipleSensorAggregator;
+import org.apache.brooklyn.enricher.stock.Enrichers;
+import org.apache.brooklyn.enricher.stock.UpdatingMap;
import org.apache.brooklyn.util.collections.CollectionFunctionals;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEnricherRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEnricherRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEnricherRebindSupport.java
index 89e11e2..3903655 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEnricherRebindSupport.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEnricherRebindSupport.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.core.mgmt.rebind;
import org.apache.brooklyn.api.mgmt.rebind.RebindContext;
import org.apache.brooklyn.api.mgmt.rebind.mementos.EnricherMemento;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
index 2a5e92e..0d80698 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/BasicEntityRebindSupport.java
@@ -32,13 +32,13 @@ import org.apache.brooklyn.api.mgmt.rebind.mementos.EntityMemento;
import org.apache.brooklyn.api.objs.BrooklynObjectType;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.feed.AbstractFeed;
import org.apache.brooklyn.core.mgmt.rebind.dto.MementosGenerators;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.entity.group.AbstractGroupImpl;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
index e9478ef..3f468ba 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
@@ -64,6 +64,7 @@ import org.apache.brooklyn.core.BrooklynLogging;
import org.apache.brooklyn.core.BrooklynLogging.LoggingLevel;
import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.EntityInternal;
@@ -86,7 +87,6 @@ import org.apache.brooklyn.core.objs.proxy.InternalFactory;
import org.apache.brooklyn.core.objs.proxy.InternalLocationFactory;
import org.apache.brooklyn.core.objs.proxy.InternalPolicyFactory;
import org.apache.brooklyn.core.policy.AbstractPolicy;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java
index fdce617..52b984a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindManagerImpl.java
@@ -46,6 +46,7 @@ import org.apache.brooklyn.api.objs.BrooklynObject;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.BrooklynFeatureEnablement;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.ha.HighAvailabilityManagerImpl;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
@@ -55,7 +56,6 @@ import org.apache.brooklyn.core.mgmt.persist.PersistenceActivityMetrics;
import org.apache.brooklyn.core.mgmt.persist.BrooklynPersistenceUtils.CreateBackupMode;
import org.apache.brooklyn.core.mgmt.rebind.transformer.CompoundTransformer;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.QuorumCheck;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
index 929b63c..36daf49 100644
--- a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
+++ b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/dto/MementosGenerators.java
@@ -49,6 +49,7 @@ import org.apache.brooklyn.api.sensor.Feed;
import org.apache.brooklyn.api.sensor.AttributeSensor.SensorPersistenceMode;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.catalog.internal.CatalogItemDo;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.feed.AbstractFeed;
@@ -58,7 +59,6 @@ import org.apache.brooklyn.core.mgmt.rebind.AbstractBrooklynObjectRebindSupport;
import org.apache.brooklyn.core.mgmt.rebind.TreeUtils;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.core.policy.AbstractPolicy;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.FlagUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
index efd89d1..e85cc73 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/AbstractEntityAdjunct.java
@@ -44,10 +44,10 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigMap;
import org.apache.brooklyn.config.ConfigKey.HasConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.internal.SubscriptionTracker;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.FlagUtils;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java b/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
index b6e68ff..4170613 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/BrooklynTypes.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.api.sensor.Enricher;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.enricher.EnricherDynamicType;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.policy.PolicyDynamicType;
-import org.apache.brooklyn.sensor.enricher.EnricherDynamicType;
import org.apache.brooklyn.util.exceptions.Exceptions;
import com.google.common.collect.Maps;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalPolicyFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalPolicyFactory.java b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalPolicyFactory.java
index 4e45580..aaee778 100644
--- a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalPolicyFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/InternalPolicyFactory.java
@@ -27,10 +27,10 @@ import org.apache.brooklyn.api.sensor.Enricher;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.api.sensor.Feed;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.policy.AbstractPolicy;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java b/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
index 4a7b1d4..b017315 100644
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
+++ b/core/src/main/java/org/apache/brooklyn/core/sensor/StaticSensor.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.AddSensor;
-import org.apache.brooklyn.sensor.enricher.Propagator;
+import org.apache.brooklyn.enricher.stock.Propagator;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.core.task.ValueResolver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java
new file mode 100644
index 0000000..2d25a75
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregatingEnricher.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.entity.trait.Changeable;
+import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+
+
+/**
+ * AggregatingEnrichers implicitly subscribes to the same sensor<S> on all entities inside an
+ * {@link Group} and should emit an aggregate<T> on the target sensor
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers.builder()}
+ * @see Aggregator if need to sub-class
+ */
+public abstract class AbstractAggregatingEnricher<S,T> extends AbstractEnricher implements SensorEventListener<S> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractAggregatingEnricher.class);
+
+ AttributeSensor<? extends S> source;
+ protected AttributeSensor<T> target;
+ protected S defaultValue;
+
+ Set<Entity> producers;
+ List<Entity> hardCodedProducers;
+ boolean allMembers;
+ Predicate<Entity> filter;
+
+ /**
+ * Users of values should either on it synchronize when iterating over its entries or use
+ * copyOfValues to obtain an immutable copy of the map.
+ */
+ // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
+ protected final Map<Entity, S> values = Collections.synchronizedMap(new LinkedHashMap<Entity, S>());
+
+ public AbstractAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target) {
+ this(flags, source, target, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public AbstractAggregatingEnricher(Map<String,?> flags, AttributeSensor<? extends S> source, AttributeSensor<T> target, S defaultValue) {
+ super(flags);
+ this.source = source;
+ this.target = target;
+ this.defaultValue = defaultValue;
+ hardCodedProducers = (List<Entity>) (flags.containsKey("producers") ? flags.get("producers") : Collections.emptyList());
+ allMembers = (Boolean) (flags.containsKey("allMembers") ? flags.get("allMembers") : false);
+ filter = flags.containsKey("filter") ? GroovyJavaMethods.<Entity>castToPredicate(flags.get("filter")) : Predicates.<Entity>alwaysTrue();
+ }
+
+ public void addProducer(Entity producer) {
+ if (LOG.isDebugEnabled()) LOG.debug("{} linked ({}, {}) to {}", new Object[] {this, producer, source, target});
+ subscribe(producer, source, this);
+ synchronized (values) {
+ S vo = values.get(producer);
+ if (vo==null) {
+ S initialVal = ((EntityLocal)producer).getAttribute(source);
+ values.put(producer, initialVal != null ? initialVal : defaultValue);
+ //we might skip in onEvent in the short window while !values.containsKey(producer)
+ //but that's okay because the put which would have been done there is done here now
+ } else {
+ //vo will be null unless some weird race with addProducer+removeProducer is occuring
+ //(and that's something we can tolerate i think)
+ if (LOG.isDebugEnabled()) LOG.debug("{} already had value ({}) for producer ({}); but that producer has just been added", new Object[] {this, vo, producer});
+ }
+ }
+ onUpdated();
+ }
+
+ // TODO If producer removed but then get (queued) event from it after this method returns,
+ public S removeProducer(Entity producer) {
+ if (LOG.isDebugEnabled()) LOG.debug("{} unlinked ({}, {}) from {}", new Object[] {this, producer, source, target});
+ unsubscribe(producer);
+ S removed = values.remove(producer);
+ onUpdated();
+ return removed;
+ }
+
+ @Override
+ public void onEvent(SensorEvent<S> event) {
+ Entity e = event.getSource();
+ synchronized (values) {
+ if (values.containsKey(e)) {
+ values.put(e, event.getValue());
+ } else {
+ if (LOG.isDebugEnabled()) LOG.debug("{} received event for unknown producer ({}); presumably that producer has recently been removed", this, e);
+ }
+ }
+ onUpdated();
+ }
+
+ /**
+ * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
+ * Defaults to no-op
+ */
+ // TODO should this be abstract?
+ protected void onUpdated() {
+ // no-op
+ }
+
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+
+ for (Entity producer : hardCodedProducers) {
+ if (filter.apply(producer)) {
+ addProducer(producer);
+ }
+ }
+
+ if (allMembers) {
+ subscribe(entity, Changeable.MEMBER_ADDED, new SensorEventListener<Entity>() {
+ @Override public void onEvent(SensorEvent<Entity> it) {
+ if (filter.apply(it.getValue())) addProducer(it.getValue());
+ }
+ });
+ subscribe(entity, Changeable.MEMBER_REMOVED, new SensorEventListener<Entity>() {
+ @Override public void onEvent(SensorEvent<Entity> it) {
+ removeProducer(it.getValue());
+ }
+ });
+
+ if (entity instanceof Group) {
+ for (Entity member : ((Group)entity).getMembers()) {
+ if (filter.apply(member)) {
+ addProducer(member);
+ }
+ }
+ }
+ }
+ }
+
+ protected Map<Entity, S> copyOfValues() {
+ synchronized (values) {
+ return ImmutableMap.copyOf(values);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregator.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregator.java
new file mode 100644
index 0000000..926b769
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractAggregator.java
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.Group;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.entity.trait.Changeable;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+/** Abstract superclass for enrichers which aggregate from children and/or members */
+@SuppressWarnings("serial")
+public abstract class AbstractAggregator<T,U> extends AbstractEnricher implements SensorEventListener<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractAggregator.class);
+
+ public static final ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer", "The entity whose children/members will be aggregated");
+
+ public static final ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+
+ // FIXME this is not just for "members" i think -Alex
+ public static final ConfigKey<?> DEFAULT_MEMBER_VALUE = ConfigKeys.newConfigKey(Object.class, "enricher.defaultMemberValue");
+
+ public static final ConfigKey<Set<? extends Entity>> FROM_HARDCODED_PRODUCERS = ConfigKeys.newConfigKey(new TypeToken<Set<? extends Entity>>() {}, "enricher.aggregating.fromHardcodedProducers");
+
+ public static final ConfigKey<Boolean> FROM_MEMBERS = ConfigKeys.newBooleanConfigKey("enricher.aggregating.fromMembers",
+ "Whether this enricher looks at members; only supported if a Group producer is supplier; defaults to true for Group entities");
+
+ public static final ConfigKey<Boolean> FROM_CHILDREN = ConfigKeys.newBooleanConfigKey("enricher.aggregating.fromChildren",
+ "Whether this enricher looks at children; this is the default for non-Group producers");
+
+ public static final ConfigKey<Predicate<? super Entity>> ENTITY_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<? super Entity>>() {}, "enricher.aggregating.entityFilter");
+
+ public static final ConfigKey<Predicate<?>> VALUE_FILTER = ConfigKeys.newConfigKey(new TypeToken<Predicate<?>>() {}, "enricher.aggregating.valueFilter");
+
+ protected Entity producer;
+ protected Sensor<U> targetSensor;
+ protected T defaultMemberValue;
+ protected Set<? extends Entity> fromHardcodedProducers;
+ protected Boolean fromMembers;
+ protected Boolean fromChildren;
+ protected Predicate<? super Entity> entityFilter;
+ protected Predicate<? super T> valueFilter;
+
+ public AbstractAggregator() {}
+
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ setEntityLoadingConfig();
+
+ if (fromHardcodedProducers == null && producer == null) producer = entity;
+ checkState(fromHardcodedProducers != null ^ producer != null, "must specify one of %s (%s) or %s (%s)",
+ PRODUCER.getName(), producer, FROM_HARDCODED_PRODUCERS.getName(), fromHardcodedProducers);
+
+ if (fromHardcodedProducers != null) {
+ for (Entity producer : Iterables.filter(fromHardcodedProducers, entityFilter)) {
+ addProducerHardcoded(producer);
+ }
+ }
+
+ if (isAggregatingMembers()) {
+ setEntityBeforeSubscribingProducerMemberEvents(entity);
+ setEntitySubscribeProducerMemberEvents();
+ setEntityAfterSubscribingProducerMemberEvents();
+ }
+
+ if (isAggregatingChildren()) {
+ setEntityBeforeSubscribingProducerChildrenEvents();
+ setEntitySubscribingProducerChildrenEvents();
+ setEntityAfterSubscribingProducerChildrenEvents();
+ }
+
+ onUpdated();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ protected void setEntityLoadingConfig() {
+ this.producer = getConfig(PRODUCER);
+ this.fromHardcodedProducers= getConfig(FROM_HARDCODED_PRODUCERS);
+ this.defaultMemberValue = (T) getConfig(DEFAULT_MEMBER_VALUE);
+ this.fromMembers = Maybe.fromNullable(getConfig(FROM_MEMBERS)).or(fromMembers);
+ this.fromChildren = Maybe.fromNullable(getConfig(FROM_CHILDREN)).or(fromChildren);
+ this.entityFilter = (Predicate<? super Entity>) (getConfig(ENTITY_FILTER) == null ? Predicates.alwaysTrue() : getConfig(ENTITY_FILTER));
+ this.valueFilter = (Predicate<? super T>) (getConfig(VALUE_FILTER) == null ? getDefaultValueFilter() : getConfig(VALUE_FILTER));
+
+ setEntityLoadingTargetConfig();
+ }
+
+ protected Predicate<?> getDefaultValueFilter() {
+ return Predicates.alwaysTrue();
+ }
+
+ @SuppressWarnings({ "unchecked" })
+ protected void setEntityLoadingTargetConfig() {
+ this.targetSensor = (Sensor<U>) getRequiredConfig(TARGET_SENSOR);
+ }
+
+ protected void setEntityBeforeSubscribingProducerMemberEvents(EntityLocal entity) {
+ checkState(producer instanceof Group, "Producer must be a group when fromMembers true: producer=%s; entity=%s; "
+ + "hardcodedProducers=%s", getConfig(PRODUCER), entity, fromHardcodedProducers);
+ }
+
+ protected void setEntitySubscribeProducerMemberEvents() {
+ subscribe(producer, Changeable.MEMBER_ADDED, new SensorEventListener<Entity>() {
+ @Override public void onEvent(SensorEvent<Entity> event) {
+ if (entityFilter.apply(event.getValue())) {
+ addProducerMember(event.getValue());
+ onUpdated();
+ }
+ }
+ });
+ subscribe(producer, Changeable.MEMBER_REMOVED, new SensorEventListener<Entity>() {
+ @Override public void onEvent(SensorEvent<Entity> event) {
+ removeProducer(event.getValue());
+ onUpdated();
+ }
+ });
+ }
+
+ protected void setEntityAfterSubscribingProducerMemberEvents() {
+ if (producer instanceof Group) {
+ for (Entity member : Iterables.filter(((Group)producer).getMembers(), entityFilter)) {
+ addProducerMember(member);
+ }
+ }
+ }
+
+ protected void setEntityBeforeSubscribingProducerChildrenEvents() {
+ }
+
+ protected void setEntitySubscribingProducerChildrenEvents() {
+ subscribe(producer, AbstractEntity.CHILD_REMOVED, new SensorEventListener<Entity>() {
+ @Override public void onEvent(SensorEvent<Entity> event) {
+ removeProducer(event.getValue());
+ onUpdated();
+ }
+ });
+ subscribe(producer, AbstractEntity.CHILD_ADDED, new SensorEventListener<Entity>() {
+ @Override public void onEvent(SensorEvent<Entity> event) {
+ if (entityFilter.apply(event.getValue())) {
+ addProducerChild(event.getValue());
+ onUpdated();
+ }
+ }
+ });
+ }
+
+ protected void setEntityAfterSubscribingProducerChildrenEvents() {
+ for (Entity child : Iterables.filter(producer.getChildren(), entityFilter)) {
+ addProducerChild(child);
+ }
+ }
+
+ /** true if this should aggregate members */
+ protected boolean isAggregatingMembers() {
+ if (Boolean.TRUE.equals(fromMembers)) return true;
+ if (Boolean.TRUE.equals(fromChildren)) return false;
+ if (fromHardcodedProducers!=null) return false;
+ if (producer instanceof Group) return true;
+ return false;
+ }
+
+ /** true if this should aggregate members */
+ protected boolean isAggregatingChildren() {
+ if (Boolean.TRUE.equals(fromChildren)) return true;
+ if (Boolean.TRUE.equals(fromMembers)) return false;
+ if (fromHardcodedProducers!=null) return false;
+ if (producer instanceof Group) return false;
+ return true;
+ }
+
+ protected abstract void addProducerHardcoded(Entity producer);
+ protected abstract void addProducerMember(Entity producer);
+ protected abstract void addProducerChild(Entity producer);
+
+ // TODO If producer removed but then get (queued) event from it after this method returns,
+ protected void removeProducer(Entity producer) {
+ if (LOG.isDebugEnabled()) LOG.debug("{} stopped listening to {}", new Object[] {this, producer });
+ unsubscribe(producer);
+ onProducerRemoved(producer);
+ }
+
+ protected abstract void onProducerAdded(Entity producer);
+
+ protected abstract void onProducerRemoved(Entity producer);
+
+
+ /**
+ * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
+ */
+ protected void onUpdated() {
+ try {
+ emit(targetSensor, compute());
+ } catch (Throwable t) {
+ LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
+ throw Exceptions.propagate(t);
+ }
+ }
+
+ protected abstract Object compute();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractMultipleSensorAggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractMultipleSensorAggregator.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractMultipleSensorAggregator.java
new file mode 100644
index 0000000..1d76168
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractMultipleSensorAggregator.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.BrooklynLogging;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+
+/** Building on {@link AbstractAggregator} for a single source sensor (on multiple children and/or members) */
+public abstract class AbstractMultipleSensorAggregator<U> extends AbstractAggregator<Object,U> implements SensorEventListener<Object> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractMultipleSensorAggregator.class);
+
+
+ /** access via {@link #getValues(Sensor)} */
+ private final Map<String, Map<Entity,Object>> values = Collections.synchronizedMap(new LinkedHashMap<String, Map<Entity,Object>>());
+
+ public AbstractMultipleSensorAggregator() {}
+
+ protected abstract Collection<Sensor<?>> getSourceSensors();
+
+ @Override
+ protected void setEntityLoadingConfig() {
+ super.setEntityLoadingConfig();
+ Preconditions.checkNotNull(getSourceSensors(), "sourceSensors must be set");
+ }
+
+ @Override
+ protected void setEntityBeforeSubscribingProducerChildrenEvents() {
+ BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
+ "{} subscribing to children of {}", this, producer);
+ for (Sensor<?> sourceSensor: getSourceSensors()) {
+ subscribeToChildren(producer, sourceSensor, this);
+ }
+ }
+
+ @Override
+ protected void addProducerHardcoded(Entity producer) {
+ for (Sensor<?> sourceSensor: getSourceSensors()) {
+ subscribe(producer, sourceSensor, this);
+ }
+ onProducerAdded(producer);
+ }
+
+ @Override
+ protected void addProducerChild(Entity producer) {
+ // no `subscribe` call needed here, due to previous subscribeToChildren call
+ onProducerAdded(producer);
+ }
+
+ @Override
+ protected void addProducerMember(Entity producer) {
+ addProducerHardcoded(producer);
+ }
+
+ @Override
+ protected void onProducerAdded(Entity producer) {
+ BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
+ "{} listening to {}", this, producer);
+ synchronized (values) {
+ for (Sensor<?> sensor: getSourceSensors()) {
+ Map<Entity,Object> vs = values.get(sensor.getName());
+ if (vs==null) {
+ vs = new LinkedHashMap<Entity,Object>();
+ values.put(sensor.getName(), vs);
+ }
+
+ Object vo = vs.get(producer);
+ if (vo==null) {
+ Object initialVal;
+ if (sensor instanceof AttributeSensor) {
+ initialVal = producer.getAttribute((AttributeSensor<?>)sensor);
+ } else {
+ initialVal = null;
+ }
+ vs.put(producer, initialVal != null ? initialVal : defaultMemberValue);
+ // NB: see notes on possible race, in Aggregator#onProducerAdded
+ }
+
+ }
+ }
+ }
+
+ @Override
+ protected void onProducerRemoved(Entity producer) {
+ synchronized (values) {
+ for (Sensor<?> sensor: getSourceSensors()) {
+ Map<Entity,Object> vs = values.get(sensor.getName());
+ if (vs!=null)
+ vs.remove(producer);
+ }
+ }
+ onUpdated();
+ }
+
+ @Override
+ public void onEvent(SensorEvent<Object> event) {
+ Entity e = event.getSource();
+ synchronized (values) {
+ Map<Entity,Object> vs = values.get(event.getSensor().getName());
+ if (vs==null) {
+ LOG.debug(this+" received event when no entry for sensor ("+event+"); likely just added or removed, and will initialize subsequently if needed");
+ } else {
+ vs.put(e, event.getValue());
+ }
+ }
+ onUpdated();
+ }
+
+ public <T> Map<Entity,T> getValues(Sensor<T> sensor) {
+ Map<Entity, T> valuesCopy = copyValues(sensor);
+ return coerceValues(valuesCopy, sensor.getType());
+ }
+
+ private <T> Map<Entity, T> coerceValues(Map<Entity, T> values, Class<? super T> type) {
+ Map<Entity, T> typedValues = MutableMap.of();
+ for (Entry<Entity, T> entry : values.entrySet()) {
+ @SuppressWarnings("unchecked")
+ T typedValue = (T) TypeCoercions.coerce(entry.getValue(), type);
+ typedValues.put(entry.getKey(), typedValue);
+ }
+ return typedValues;
+ }
+
+ private <T> Map<Entity, T> copyValues(Sensor<T> sensor) {
+ synchronized (values) {
+ @SuppressWarnings("unchecked")
+ Map<Entity, T> sv = (Map<Entity, T>) values.get(sensor.getName());
+ //use MutableMap because of potentially null values
+ return MutableMap.copyOf(sv).asUnmodifiable();
+ }
+ }
+
+ @Override
+ protected abstract Object compute();
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
new file mode 100644
index 0000000..ab41c1a
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformer.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.reflect.TypeToken;
+
+@SuppressWarnings("serial")
+public abstract class AbstractTransformer<T,U> extends AbstractEnricher implements SensorEventListener<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractTransformer.class);
+
+ public static ConfigKey<Entity> PRODUCER = ConfigKeys.newConfigKey(Entity.class, "enricher.producer");
+
+ public static ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
+
+ public static ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
+
+ protected Entity producer;
+ protected Sensor<T> sourceSensor;
+ protected Sensor<U> targetSensor;
+
+ public AbstractTransformer() {
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+
+ Function<SensorEvent<T>, U> transformation = getTransformation();
+ this.producer = getConfig(PRODUCER) == null ? entity: getConfig(PRODUCER);
+ this.sourceSensor = (Sensor<T>) getRequiredConfig(SOURCE_SENSOR);
+ Sensor<?> targetSensorSpecified = getConfig(TARGET_SENSOR);
+ this.targetSensor = targetSensorSpecified!=null ? (Sensor<U>) targetSensorSpecified : (Sensor<U>) this.sourceSensor;
+ if (producer.equals(entity) && targetSensorSpecified==null) {
+ LOG.error("Refusing to add an enricher which reads and publishes on the same sensor: "+
+ producer+"."+sourceSensor+" (computing "+transformation+")");
+ // we don't throw because this error may manifest itself after a lengthy deployment,
+ // and failing it at that point simply because of an enricher is not very pleasant
+ // (at least not until we have good re-run support across the board)
+ return;
+ }
+
+ subscribe(producer, sourceSensor, this);
+
+ if (sourceSensor instanceof AttributeSensor) {
+ Object value = producer.getAttribute((AttributeSensor<?>)sourceSensor);
+ // TODO would be useful to have a convenience to "subscribeAndThenIfItIsAlreadySetRunItOnce"
+ if (value!=null) {
+ onEvent(new BasicSensorEvent(sourceSensor, producer, value, -1));
+ }
+ }
+ }
+
+ /** returns a function for transformation, for immediate use only (not for caching, as it may change) */
+ protected abstract Function<SensorEvent<T>, U> getTransformation();
+
+ @Override
+ public void onEvent(SensorEvent<T> event) {
+ emit(targetSensor, compute(event));
+ }
+
+ protected Object compute(SensorEvent<T> event) {
+ // transformation is not going to change, but this design makes it easier to support changing config in future.
+ // if it's an efficiency hole we can switch to populate the transformation at start.
+ U result = getTransformation().apply(event);
+ if (LOG.isTraceEnabled())
+ LOG.trace("Enricher "+this+" computed "+result+" from "+event);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformingEnricher.java
new file mode 100644
index 0000000..a29cc7b
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTransformingEnricher.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.Sensor;
+
+/**
+ * Convenience base for transforming a single sensor into a single new sensor of the same type
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers.builder()}
+ */
+public abstract class AbstractTransformingEnricher<T> extends AbstractTypeTransformingEnricher<T,T> {
+
+ public AbstractTransformingEnricher() { // for rebinding
+ }
+
+ public AbstractTransformingEnricher(Entity producer, Sensor<T> source, Sensor<T> target) {
+ super(producer, source, target);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTypeTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTypeTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTypeTransformingEnricher.java
new file mode 100644
index 0000000..1469829
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AbstractTypeTransformingEnricher.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+
+/**
+ * Convenience base for transforming a single sensor into a single new sensor of the same type
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers.builder()}
+ */
+public abstract class AbstractTypeTransformingEnricher<T,U> extends AbstractEnricher implements SensorEventListener<T> {
+
+ @SetFromFlag
+ private Entity producer;
+
+ @SetFromFlag
+ private Sensor<T> source;
+
+ @SetFromFlag
+ protected Sensor<U> target;
+
+ public AbstractTypeTransformingEnricher() { // for rebind
+ }
+
+ public AbstractTypeTransformingEnricher(Entity producer, Sensor<T> source, Sensor<U> target) {
+ this.producer = producer;
+ this.source = source;
+ this.target = target;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ if (producer==null) producer = entity;
+ subscribe(producer, source, this);
+
+ if (source instanceof AttributeSensor) {
+ Object value = producer.getAttribute((AttributeSensor)source);
+ // TODO Aled didn't you write a convenience to "subscribeAndRunIfSet" ? (-Alex)
+ if (value!=null)
+ onEvent(new BasicSensorEvent(source, producer, value, -1));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/AddingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/AddingEnricher.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/AddingEnricher.java
new file mode 100644
index 0000000..941d745
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/AddingEnricher.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+
+/**
+ * enricher which adds multiple sensors on an entity to produce a new sensor
+ *
+ * Instead, consider calling:
+ * <pre>
+ * {@code
+ * addEnricher(Enrichers.builder()
+ * .combining(sources)
+ * .publishing(target)
+ * .computeSum()
+ * .build());
+ * }
+ * </pre>
+ * <p>
+ *
+ * @deprecated since 0.7.0; use {@link Enrichers.builder()}
+ * @see Combiner if need to sub-class
+ */
+public class AddingEnricher extends AbstractEnricher implements SensorEventListener {
+
+ private Sensor[] sources;
+ private Sensor<? extends Number> target;
+
+ public AddingEnricher(Sensor sources[], Sensor<? extends Number> target) {
+ this.sources = sources;
+ this.target = target;
+ }
+
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+
+ for (Sensor source: sources) {
+ subscribe(entity, source, this);
+ if (source instanceof AttributeSensor) {
+ Object value = entity.getAttribute((AttributeSensor)source);
+ if (value!=null)
+ onEvent(new BasicSensorEvent(source, entity, value, -1));
+ }
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public void onEvent(SensorEvent event) {
+ Number value = recompute();
+ Number typedValue = cast(value, (Class<? extends Number>)target.getType());
+ if (target instanceof AttributeSensor) {
+ entity.setAttribute((AttributeSensor)target, typedValue);
+ } else if (typedValue!=null)
+ entity.emit((Sensor)target, typedValue);
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <V> V cast(Number value, Class<V> type) {
+ if (value==null) return null;
+ if (type.isInstance(value)) return (V)value;
+
+ if (type==Integer.class) return (V) (Integer) (int)Math.round(value.doubleValue());
+ if (type==Long.class) return (V) (Long) Math.round(value.doubleValue());
+ if (type==Double.class) return (V) (Double) value.doubleValue();
+ if (type==Float.class) return (V) (Float) value.floatValue();
+ if (type==Byte.class) return (V) (Byte) (byte)Math.round(value.doubleValue());
+ if (type==Short.class) return (V) (Short) (short)Math.round(value.doubleValue());
+
+ throw new UnsupportedOperationException("conversion of mathematical operation to "+type+" not supported");
+ }
+
+ protected Number recompute() {
+ if (sources.length==0) return null;
+ Double result = 0d;
+ for (Sensor source: sources) {
+ Object value = entity.getAttribute((AttributeSensor) source);
+ if (value==null) return null;
+ result += ((Number)value).doubleValue();
+ }
+ return result;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java b/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
new file mode 100644
index 0000000..e42d2cb
--- /dev/null
+++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Aggregator.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.Sensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.BrooklynLogging;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.enricher.stock.Enrichers.ComputingAverage;
+import org.apache.brooklyn.util.collections.MutableList;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+
+/** Building on {@link AbstractAggregator} for a single source sensor (on multiple children and/or members) */
+@SuppressWarnings("serial")
+//@Catalog(name="Aggregator", description="Aggregates attributes from multiple entities into a single attribute value; see Enrichers.builder().aggregating(...)")
+public class Aggregator<T,U> extends AbstractAggregator<T,U> implements SensorEventListener<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Aggregator.class);
+
+ public static final ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
+
+ @SetFromFlag("transformation")
+ public static final ConfigKey<Object> TRANSFORMATION_UNTYPED = ConfigKeys.newConfigKey(Object.class, "enricher.transformation.untyped",
+ "Specifies a transformation, as a function from a collection to the value, or as a string matching a pre-defined named transformation, "
+ + "such as 'average' (for numbers), 'sum' (for numbers), or 'list' (the default, putting any collection of items into a list)");
+ public static final ConfigKey<Function<? super Collection<?>, ?>> TRANSFORMATION = ConfigKeys.newConfigKey(new TypeToken<Function<? super Collection<?>, ?>>() {}, "enricher.transformation");
+
+ public static final ConfigKey<Boolean> EXCLUDE_BLANK = ConfigKeys.newBooleanConfigKey("enricher.aggregator.excludeBlank", "Whether explicit nulls or blank strings should be excluded (default false); this only applies if no value filter set", false);
+
+ protected Sensor<T> sourceSensor;
+ protected Function<? super Collection<T>, ? extends U> transformation;
+
+ /**
+ * Users of values should either on it synchronize when iterating over its entries or use
+ * copyOfValues to obtain an immutable copy of the map.
+ */
+ // We use a synchronizedMap over a ConcurrentHashMap for entities that store null values.
+ protected final Map<Entity, T> values = Collections.synchronizedMap(new LinkedHashMap<Entity, T>());
+
+ public Aggregator() {}
+
+ @SuppressWarnings("unchecked")
+ protected void setEntityLoadingConfig() {
+ super.setEntityLoadingConfig();
+ this.sourceSensor = (Sensor<T>) getRequiredConfig(SOURCE_SENSOR);
+
+ this.transformation = (Function<? super Collection<T>, ? extends U>) config().get(TRANSFORMATION);
+
+ Object t1 = config().get(TRANSFORMATION_UNTYPED);
+ Function<? super Collection<?>, ?> t2 = null;
+ if (t1 instanceof String) {
+ t2 = lookupTransformation((String)t1);
+ if (t2==null) {
+ LOG.warn("Unknown transformation '"+t1+"' for "+this+"; will use default transformation");
+ }
+ }
+
+ if (this.transformation==null) {
+ this.transformation = (Function<? super Collection<T>, ? extends U>) t2;
+ } else if (t1!=null && !Objects.equals(t2, this.transformation)) {
+ throw new IllegalStateException("Cannot supply both "+TRANSFORMATION_UNTYPED+" and "+TRANSFORMATION+" unless they are equal.");
+ }
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ protected Function<? super Collection<?>, ?> lookupTransformation(String t1) {
+ if ("average".equalsIgnoreCase(t1)) return new Enrichers.ComputingAverage(null, null, targetSensor.getTypeToken());
+ if ("sum".equalsIgnoreCase(t1)) return new Enrichers.ComputingAverage(null, null, targetSensor.getTypeToken());
+ if ("list".equalsIgnoreCase(t1)) return new ComputingList();
+ return null;
+ }
+
+ private class ComputingList<TT> implements Function<Collection<TT>, List<TT>> {
+ @Override
+ public List<TT> apply(Collection<TT> input) {
+ if (input==null) return null;
+ return MutableList.copyOf(input).asUnmodifiable();
+ }
+
+ }
+
+ @Override
+ protected void setEntityBeforeSubscribingProducerChildrenEvents() {
+ BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
+ "{} subscribing to children of {}", this, producer);
+ subscribeToChildren(producer, sourceSensor, this);
+ }
+
+ @Override
+ protected void addProducerHardcoded(Entity producer) {
+ subscribe(producer, sourceSensor, this);
+ onProducerAdded(producer);
+ }
+
+ @Override
+ protected void addProducerChild(Entity producer) {
+ // no subscription needed here, due to the subscribeToChildren call
+ onProducerAdded(producer);
+ }
+
+ @Override
+ protected void addProducerMember(Entity producer) {
+ subscribe(producer, sourceSensor, this);
+ onProducerAdded(producer);
+ }
+
+ @Override
+ protected void onProducerAdded(Entity producer) {
+ BrooklynLogging.log(LOG, BrooklynLogging.levelDebugOrTraceIfReadOnly(producer),
+ "{} listening to {}", this, producer);
+ synchronized (values) {
+ T vo = values.get(producer);
+ if (vo==null) {
+ T initialVal;
+ if (sourceSensor instanceof AttributeSensor) {
+ initialVal = producer.getAttribute((AttributeSensor<T>)sourceSensor);
+ } else {
+ initialVal = null;
+ }
+ values.put(producer, initialVal != null ? initialVal : defaultMemberValue);
+ //we might skip in onEvent in the short window while !values.containsKey(producer)
+ //but that's okay because the put which would have been done there is done here now
+ } else {
+ //vo will be null unless some weird race with addProducer+removeProducer is occuring
+ //(and that's something we can tolerate i think)
+ if (LOG.isDebugEnabled()) LOG.debug("{} already had value ({}) for producer ({}); but that producer has just been added", new Object[] {this, vo, producer});
+ }
+ }
+ }
+
+ @Override
+ protected Predicate<?> getDefaultValueFilter() {
+ if (getConfig(EXCLUDE_BLANK))
+ return StringPredicates.isNonBlank();
+ else
+ return Predicates.alwaysTrue();
+ }
+
+ @Override
+ protected void onProducerRemoved(Entity producer) {
+ values.remove(producer);
+ onUpdated();
+ }
+
+ @Override
+ public void onEvent(SensorEvent<T> event) {
+ Entity e = event.getSource();
+ synchronized (values) {
+ if (values.containsKey(e)) {
+ values.put(e, event.getValue());
+ } else {
+ if (LOG.isDebugEnabled()) LOG.debug("{} received event for unknown producer ({}); presumably that producer has recently been removed", this, e);
+ }
+ }
+ onUpdated();
+ }
+
+ protected void onUpdated() {
+ try {
+ emit(targetSensor, compute());
+ } catch (Throwable t) {
+ LOG.warn("Error calculating and setting aggregate for enricher "+this, t);
+ throw Exceptions.propagate(t);
+ }
+ }
+
+ @Override
+ protected Object compute() {
+ synchronized (values) {
+ // TODO Could avoid copying when filter not needed
+ List<T> vs = MutableList.copyOf(Iterables.filter(values.values(), valueFilter));
+ if (transformation==null) return vs;
+ return transformation.apply(vs);
+ }
+ }
+
+ protected Map<Entity, T> copyOfValues() {
+ // Don't use ImmutableMap, as can contain null values
+ synchronized (values) {
+ return Collections.unmodifiableMap(MutableMap.copyOf(values));
+ }
+ }
+
+}
[11/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
index f5b9e5a..17b7f15 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/java/EntityPollingTest.java
@@ -24,6 +24,7 @@ import javax.management.ObjectName;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.java.VanillaJavaAppImpl;
@@ -31,7 +32,6 @@ import org.apache.brooklyn.entity.java.VanillaJavaAppSshDriver;
import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.apache.brooklyn.test.EntityTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppRebindTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppRebindTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppRebindTest.java
index 2bcb978..d10f43a 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppRebindTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/java/VanillaJavaAppRebindTest.java
@@ -27,12 +27,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.java.VanillaJavaApp;
import org.apache.brooklyn.entity.java.VanillaJavaAppImpl;
import org.apache.brooklyn.entity.java.JavaOptsTest.TestingJavaOptsVanillaJavaAppImpl;
import org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityLatchTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityLatchTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityLatchTest.java
index 6910154..6da0269 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityLatchTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityLatchTest.java
@@ -33,6 +33,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcessEntityTest.MyService;
@@ -44,7 +45,6 @@ import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.core.task.TaskInternal;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
index 0b1515b..2b5ec4a 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
@@ -54,6 +54,7 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
@@ -68,7 +69,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwarePara
import org.apache.brooklyn.entity.software.base.SoftwareProcess.RestartSoftwareParameters.RestartMachineMode;
import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwareParameters.StopMode;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasksTest;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasksTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasksTest.java
index 117540c..d336ad0 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasksTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/MachineLifecycleEffectorTasksTest.java
@@ -33,6 +33,8 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
@@ -40,8 +42,6 @@ import org.apache.brooklyn.entity.software.base.SoftwareProcess.StopSoftwarePara
import org.apache.brooklyn.entity.stock.BasicEntity;
import org.apache.brooklyn.entity.stock.BasicEntityImpl;
import org.apache.brooklyn.location.jclouds.BailOutJcloudsLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.core.task.TaskInternal;
import org.apache.brooklyn.util.core.task.ValueResolver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
index f1889a0..179a6f4 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/sensor/core/PortAttributeSensorAndConfigKeyTest.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
import org.testng.annotations.Test;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import com.google.common.collect.ImmutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
index 8f7b6bf..c57711f 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
@@ -30,9 +30,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.ssh.SshCommandEffector;
import org.apache.brooklyn.sensor.ssh.SshCommandSensor;
import org.apache.brooklyn.test.EntityTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
index bf2cdf9..8f722b2 100644
--- a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
@@ -51,6 +51,9 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
import org.apache.brooklyn.core.test.entity.TestEntity;
@@ -60,9 +63,6 @@ import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
index fb8f516..9ed0031 100644
--- a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
@@ -31,13 +31,13 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
index c2acfab..534c0eb 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.Effectors;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.stream.KnownSizeInputStream;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
index cdcbefb..f22381a 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
@@ -24,15 +24,15 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJavaMXBeans;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@ImplementedBy(CrateNodeImpl.class)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
index 4063aef..3c78d99 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
@@ -27,13 +27,13 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.database.DatabaseNode;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@Catalog(name="MariaDB Node", description="MariaDB is an open source relational database management system (RDBMS)", iconUrl="classpath:///mariadb-logo-180x119.png")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java
index 955bde6..d860d04 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlCluster.java
@@ -25,13 +25,13 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import com.google.common.reflect.TypeToken;
import org.apache.brooklyn.entity.database.DatastoreMixins.HasDatastoreUrl;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
@ImplementedBy(MySqlClusterImpl.class)
@Catalog(name="MySql Master-Slave cluster", description="Sets up a cluster of MySQL nodes using master-slave relation and binary logging", iconUrl="classpath:///mysql-logo-110x57.png")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
index 2d28ac7..e106728 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlClusterImpl.java
@@ -36,9 +36,9 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
index aa11eb4..484606e 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
@@ -30,12 +30,12 @@ import org.apache.brooklyn.core.config.MapConfigKey;
import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@Catalog(name="MySql Node", description="MySql is an open source relational database management system (RDBMS)", iconUrl="classpath:///mysql-logo-110x57.png")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
index 6cb9cde..cd97719 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
@@ -26,12 +26,12 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.database.DatabaseNode;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
index f9e80f7..5ff70fe 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
@@ -41,8 +41,8 @@ import javax.annotation.Nullable;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNode.java
index 608b45d..e6580bb 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNode.java
@@ -24,12 +24,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@Catalog(name = "RubyRep Node", description = "RubyRep is a database replication system", iconUrl = "classpath:///rubyrep-logo.jpeg")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNodeImpl.java
index 8340794..429c7aa 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/rubyrep/RubyRepNodeImpl.java
@@ -21,9 +21,9 @@ package org.apache.brooklyn.entity.database.rubyrep;
import java.net.URI;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.time.Duration;
public class RubyRepNodeImpl extends SoftwareProcessImpl implements RubyRepNode {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/MessageBroker.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/MessageBroker.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/MessageBroker.java
index 5718aaf..23260d2 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/MessageBroker.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/MessageBroker.java
@@ -20,7 +20,7 @@ package org.apache.brooklyn.entity.messaging;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
/**
* Marker interface identifying message brokers.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Queue.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Queue.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Queue.java
index cfe2ab2..190d5bf 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Queue.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Queue.java
@@ -19,8 +19,8 @@
package org.apache.brooklyn.entity.messaging;
import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
/**
* An interface that describes a messaging queue.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Topic.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Topic.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Topic.java
index f4d2539..c4ed3b7 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Topic.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/Topic.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.entity.messaging;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
/**
* An interface that describes a messaging topic.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBroker.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBroker.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBroker.java
index b52306e..aa79613 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBroker.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/activemq/ActiveMQBroker.java
@@ -24,14 +24,14 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.messaging.MessageBroker;
import org.apache.brooklyn.entity.messaging.jms.JMSBroker;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpExchange.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpExchange.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpExchange.java
index a188a6e..0d3171c 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpExchange.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpExchange.java
@@ -19,7 +19,7 @@
package org.apache.brooklyn.entity.messaging.amqp;
import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpServer.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpServer.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpServer.java
index 80638f2..80b49ee 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpServer.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/amqp/AmqpServer.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.messaging.amqp;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
/**
* Marker interface identifying AMQP servers.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/Kafka.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/Kafka.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/Kafka.java
index 0d26997..6a2322c 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/Kafka.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/Kafka.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.messaging.kafka;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBroker.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBroker.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBroker.java
index c7d7829..1b54cdf 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBroker.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaBroker.java
@@ -24,12 +24,12 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.messaging.MessageBroker;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaCluster.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaCluster.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaCluster.java
index 4e48dc3..fba4e1c 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaCluster.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaCluster.java
@@ -29,11 +29,11 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.trait.Resizable;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.group.Cluster;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaZooKeeper.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaZooKeeper.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaZooKeeper.java
index 8de5a5f..5aee6d2 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaZooKeeper.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/kafka/KafkaZooKeeper.java
@@ -23,9 +23,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperNode;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBroker.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBroker.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBroker.java
index 2d66ef5..89189f7 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBroker.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/qpid/QpidBroker.java
@@ -26,13 +26,13 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.messaging.MessageBroker;
import org.apache.brooklyn.entity.messaging.amqp.AmqpServer;
import org.apache.brooklyn.entity.messaging.jms.JMSBroker;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitBroker.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitBroker.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitBroker.java
index c4190cd..fc4eddf 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitBroker.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/rabbit/RabbitBroker.java
@@ -28,12 +28,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.messaging.MessageBroker;
import org.apache.brooklyn.entity.messaging.amqp.AmqpServer;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/Storm.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/Storm.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/Storm.java
index 827a23d..9b927cd 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/Storm.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/Storm.java
@@ -25,12 +25,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperEnsemble;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormSshDriver.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormSshDriver.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormSshDriver.java
index 8236e5b..66578e6 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormSshDriver.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/messaging/storm/StormSshDriver.java
@@ -28,13 +28,13 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Machines;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.zookeeper.ZooKeeperEnsemble;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java
index ad4d6a6..a5ba570 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperEnsemble.java
@@ -25,9 +25,9 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperNode.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperNode.java b/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperNode.java
index 2de34f9..18cb6c6 100644
--- a/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperNode.java
+++ b/software/messaging/src/main/java/org/apache/brooklyn/entity/zookeeper/ZooKeeperNode.java
@@ -23,10 +23,10 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/messaging/src/test/java/org/apache/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
----------------------------------------------------------------------
diff --git a/software/messaging/src/test/java/org/apache/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java b/software/messaging/src/test/java/org/apache/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
index ef67a65..5633f74 100644
--- a/software/messaging/src/test/java/org/apache/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
+++ b/software/messaging/src/test/java/org/apache/brooklyn/entity/messaging/storm/StormAbstractCloudLiveTest.java
@@ -18,12 +18,12 @@
*/
package org.apache.brooklyn.entity.messaging.storm;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
import static org.apache.brooklyn.entity.messaging.storm.Storm.NIMBUS_HOSTNAME;
import static org.apache.brooklyn.entity.messaging.storm.Storm.ZOOKEEPER_ENSEMBLE;
import static org.apache.brooklyn.entity.messaging.storm.Storm.Role.NIMBUS;
import static org.apache.brooklyn.entity.messaging.storm.Storm.Role.SUPERVISOR;
import static org.apache.brooklyn.entity.messaging.storm.Storm.Role.UI;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
import java.io.File;
import java.util.Map;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNode.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNode.java b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNode.java
index fa61039..2e3798c 100644
--- a/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNode.java
+++ b/software/monitoring/src/main/java/org/apache/brooklyn/entity/monitoring/monit/MonitNode.java
@@ -27,10 +27,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java b/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
index 2a26c6c..685f662 100644
--- a/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
+++ b/software/monitoring/src/test/java/org/apache/brooklyn/entity/monitoring/monit/MonitIntegrationTest.java
@@ -30,12 +30,12 @@ import java.util.concurrent.Callable;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.MachineDetails;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.software.base.SameServerEntity;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
index 96c56fb..f5b5e21 100644
--- a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServer.java
@@ -33,10 +33,10 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicGroup;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.net.Cidr;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
----------------------------------------------------------------------
diff --git a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
index 6a90e83..c32e2ce 100644
--- a/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
+++ b/software/network/src/test/java/org/apache/brooklyn/entity/network/bind/PrefixAndIdEnricher.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
index 2f92c47..d9d2bbf 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
@@ -31,11 +31,11 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.PosNeg63TokenGenerator;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
index b945bdd..d5c7e2f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNode.java
@@ -31,13 +31,13 @@ import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.java.UsesJavaMXBeans;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index 0a7e638..d549776 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -41,14 +41,14 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.policy.enricher.RollingTimeWindowMeanEnricher;
import org.apache.brooklyn.policy.enricher.TimeWeightedDeltaEnricher;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
index 11d919e..193b49f 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
@@ -36,6 +36,7 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,7 +48,6 @@ import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java
index 2ba961f..dfff6a4 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseCluster.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
index bef9fa5..c065897 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
@@ -41,12 +41,12 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
index b592af8..8bde2f3 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
@@ -31,10 +31,10 @@ import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.text.ByteSizeStrings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index a5a821e..5da3c47 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -40,10 +40,10 @@ import org.apache.brooklyn.core.entity.drivers.downloads.BasicDownloadRequiremen
import org.apache.brooklyn.core.entity.drivers.downloads.DownloadProducerFromUrlAttribute;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.http.HttpTool;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGateway.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGateway.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGateway.java
index 9d7d000..9576549 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGateway.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGateway.java
@@ -23,10 +23,10 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@ImplementedBy(CouchbaseSyncGatewayImpl.class)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
index 524e661..8a5a25e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseSyncGatewaySshDriver.java
@@ -32,9 +32,9 @@ import org.apache.brooklyn.api.entity.drivers.downloads.DownloadResolver;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.ssh.BashCommands;
import org.apache.brooklyn.util.time.Duration;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBCluster.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBCluster.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBCluster.java
index 464e492..c341945 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBCluster.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBCluster.java
@@ -20,9 +20,9 @@ package org.apache.brooklyn.entity.nosql.couchdb;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNode.java
index dd7aef7..fa9506a 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchdb/CouchDBNode.java
@@ -22,9 +22,9 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.WebAppService;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java
index 116e18e..e0fbc7e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchCluster.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.nosql.elasticsearch;
import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
index 1cf108e..90d8d02 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/elasticsearch/ElasticSearchNode.java
@@ -24,13 +24,13 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.webapp.WebAppServiceConstants;
import org.apache.brooklyn.entity.database.DatastoreMixins;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.StringAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
index 159314c..52e24d8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/AbstractMongoDBServer.java
@@ -21,10 +21,10 @@ package org.apache.brooklyn.entity.nosql.mongodb;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
public interface AbstractMongoDBServer extends SoftwareProcess, Entity {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
index 5682bd0..bd5e552 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClientSshDriver.java
@@ -25,11 +25,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouter;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBRouterCluster;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.math.MathPredicates;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
index f057d46..14d0eb8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBReplicaSet.java
@@ -25,9 +25,9 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.Cluster;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
index 6c33c3c..2ec38dc 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBServer.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.sensor.AttributeSensor.SensorPersistenceMode;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
@Catalog(name="MongoDB Server",
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouter.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouter.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouter.java
index 490455c..55bad2e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouter.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouter.java
@@ -26,8 +26,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.SameServerEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
index d468f60..e27cb4b 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/CoLocatedMongoDBRouterImpl.java
@@ -24,8 +24,8 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.trait.Startable;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.entity.software.base.SameServerEntityImpl;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import com.google.common.base.Predicates;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerCluster.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerCluster.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerCluster.java
index 0c102ac..73ac77d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerCluster.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBConfigServerCluster.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.nosql.mongodb.sharding;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java
index 840925b..9191391 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/sharding/MongoDBRouter.java
@@ -23,8 +23,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.nosql.mongodb.AbstractMongoDBServer;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.time.Duration;
import com.google.common.reflect.TypeToken;
[31/36] incubator-brooklyn git commit: Rename o.a.b.sensor.enricher
to o.a.b.core.enricher
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricher.java
deleted file mode 100644
index 51d3d48..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricher.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-
-/**
- * an enricher policy which just listens for the target sensor(s) on a child entity and passes it up.
- * now superseded by syntax such as:
- *
- * <pre>{@code Enrichers.builder().propagating(XXX).from(source).build()}</pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- *
- * @see Propagator if need to sub-class
- */
-public class SensorPropagatingEnricher extends AbstractEnricher implements SensorEventListener<Object> {
-
- public static final Logger log = LoggerFactory.getLogger(SensorPropagatingEnricher.class);
-
- /** the entity to listen to */
- private final Entity source;
-
- /** the sensors to listen to */
- private final Set<Sensor<?>> sensors;
-
- /** the sensors to listen to */
- private final Map<Sensor<?>, Sensor<?>> sensorMappings;
-
- public static SensorPropagatingEnricher newInstanceListeningToAllSensors(Entity source) {
- return newInstanceListeningToAllSensorsBut(source);
- }
- public static SensorPropagatingEnricher newInstanceListeningToAllSensorsBut(Entity source, Sensor<?>... excludes) {
- Set<Sensor<?>> excluded = ImmutableSet.copyOf(excludes);
- Set<Sensor<?>> includes = Sets.newLinkedHashSet();
-
- for (Sensor<?> it : source.getEntityType().getSensors()) {
- if (!excluded.contains(it)) includes.add(it);
- }
- return new SensorPropagatingEnricher(source, includes);
- }
-
- public static SensorPropagatingEnricher newInstanceListeningTo(Entity source, Sensor<?>... includes) {
- return new SensorPropagatingEnricher(source, includes);
- }
-
- /**
- * listens to sensors from source, propagates them here renamed according to the map
- *
- * Instead, consider calling:
- * <pre>
- * {@code
- * addEnricher(Enrichers.builder()
- * .propagating(mapOfOldSensorNamesToNewSensorNames)
- * .from(source)
- * .build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public static SensorPropagatingEnricher newInstanceRenaming(Entity source, Map<? extends Sensor<?>, ? extends Sensor<?>> sensors) {
- return new SensorPropagatingEnricher(source, sensors);
- }
-
- /**
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public SensorPropagatingEnricher(Entity source, Sensor<?>... sensors) {
- this(source, ImmutableList.copyOf(sensors));
- }
-
- /**
- * Instead, consider calling:
- * <pre>
- * {@code
- * addEnricher(Enrichers.builder()
- * .propagating(sensors)
- * .from(source)
- * .build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers#builder()}
- */
- public SensorPropagatingEnricher(Entity source, Collection<Sensor<?>> sensors) {
- this.source = source;
- this.sensors = ImmutableSet.copyOf(sensors);
- this.sensorMappings = ImmutableMap.of();
- }
-
- public SensorPropagatingEnricher(Entity source, Map<? extends Sensor<?>, ? extends Sensor<?>> sensors) {
- this.source = source;
- this.sensors = ImmutableSet.copyOf(sensors.keySet());
- this.sensorMappings = ImmutableMap.copyOf(sensors);
- }
-
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- for (Sensor<?> s: sensors) {
- subscribe(source, s, this);
- }
- }
-
- @Override
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public void onEvent(SensorEvent<Object> event) {
- // propagate upwards
- Sensor<?> sourceSensor = event.getSensor();
- Sensor<?> destinationSensor = getDestinationSensor(sourceSensor);
-
- if (log.isTraceEnabled()) log.trace("policy {} got {}, propagating via {}{}",
- new Object[] {this, event, entity, (sourceSensor == destinationSensor ? "" : " (as "+destinationSensor+")")});
-
- if (event.getSensor() instanceof AttributeSensor) {
- entity.setAttribute((AttributeSensor)destinationSensor, event.getValue());
- } else {
- entity.emit((Sensor)destinationSensor, event.getValue());
- }
- }
-
- /** useful post-addition to emit current values */
- public void emitAllAttributes() {
- emitAllAttributes(false);
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void emitAllAttributes(boolean includeNullValues) {
- for (Sensor s: sensors) {
- if (s instanceof AttributeSensor) {
- AttributeSensor destinationSensor = (AttributeSensor<?>) getDestinationSensor(s);
- Object v = source.getAttribute((AttributeSensor)s);
- if (v != null || includeNullValues) entity.setAttribute(destinationSensor, v);
- }
- }
- }
-
- /** convenience, to be called by the host */
- public SensorPropagatingEnricher addToEntityAndEmitAll(Entity host) {
- host.addEnricher(this);
- emitAllAttributes();
- return this;
- }
-
- private Sensor<?> getDestinationSensor(Sensor<?> sourceSensor) {
- return sensorMappings.containsKey(sourceSensor) ? sensorMappings.get(sourceSensor): sourceSensor;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorTransformingEnricher.java
deleted file mode 100644
index 2ad1bdf..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/SensorTransformingEnricher.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.util.groovy.GroovyJavaMethods;
-import org.apache.brooklyn.util.javalang.JavaClassNames;
-import org.apache.brooklyn.util.time.Duration;
-
-import groovy.lang.Closure;
-
-import com.google.common.base.Function;
-
-/**
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- * @see Transformer if need to sub-class
- */
-public class SensorTransformingEnricher<T,U> extends AbstractTypeTransformingEnricher {
-
- private Function<? super T, ? extends U> transformation;
-
- public SensorTransformingEnricher(Entity producer, Sensor<T> source, Sensor<U> target, Function<? super T, ? extends U> transformation) {
- super(producer, source, target);
- this.transformation = transformation;
- this.uniqueTag = JavaClassNames.simpleClassName(getClass())+":"+source.getName()+"*->"+target.getName();;
- }
-
- public SensorTransformingEnricher(Entity producer, Sensor<T> source, Sensor<U> target, Closure transformation) {
- this(producer, source, target, GroovyJavaMethods.functionFromClosure(transformation));
- }
-
- public SensorTransformingEnricher(Sensor<T> source, Sensor<U> target, Function<T,U> transformation) {
- this(null, source, target, transformation);
- }
-
- public SensorTransformingEnricher(Sensor<T> source, Sensor<U> target, Closure transformation) {
- this(null, source, target, GroovyJavaMethods.functionFromClosure(transformation));
- }
-
- @Override
- public void onEvent(SensorEvent event) {
- if (accept((T)event.getValue())) {
- if (target instanceof AttributeSensor)
- entity.setAttribute((AttributeSensor)target, compute((T)event.getValue()));
- else
- entity.emit(target, compute((T)event.getValue()));
- }
- }
-
- protected boolean accept(T value) {
- return true;
- }
-
- protected U compute(T value) {
- return transformation.apply(value);
- }
-
- /**
- * creates an enricher which listens to a source (from the producer),
- * transforms it and publishes it under the target
- *
- * Instead, consider calling:
- * <pre>
- * {@code
- * addEnricher(Enrichers.builder()
- * .transforming(source)
- * .publishing(target)
- * .from(producer)
- * .computing(transformation)
- * .build());
- * }
- * </pre>
- *
- * @deprecated since 0.7.0; use {@link Enrichers.builder()}
- */
- public static <U,V> SensorTransformingEnricher<U,V> newInstanceTransforming(Entity producer, AttributeSensor<U> source,
- Function<U,V> transformation, AttributeSensor<V> target) {
- return new SensorTransformingEnricher<U,V>(producer, source, target, transformation);
- }
-
- /** as {@link #newInstanceTransforming(Entity, AttributeSensor, Function, AttributeSensor)}
- * using the same sensor as the source and the target */
- public static <T> SensorTransformingEnricher<T,T> newInstanceTransforming(Entity producer, AttributeSensor<T> sensor,
- Function<T,T> transformation) {
- return newInstanceTransforming(producer, sensor, transformation, sensor);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/Transformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Transformer.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Transformer.java
deleted file mode 100644
index f77bd8c..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Transformer.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.util.collections.MutableSet;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.reflect.TypeToken;
-
-//@Catalog(name="Transformer", description="Transforms attributes of an entity; see Enrichers.builder().transforming(...)")
-@SuppressWarnings("serial")
-public class Transformer<T,U> extends AbstractTransformer<T,U> {
-
- @SuppressWarnings("unused")
- private static final Logger LOG = LoggerFactory.getLogger(Transformer.class);
-
- // exactly one of these should be supplied to set a value
- public static ConfigKey<?> TARGET_VALUE = ConfigKeys.newConfigKey(Object.class, "enricher.targetValue");
- public static ConfigKey<Function<?, ?>> TRANSFORMATION_FROM_VALUE = ConfigKeys.newConfigKey(new TypeToken<Function<?, ?>>() {}, "enricher.transformation");
- public static ConfigKey<Function<?, ?>> TRANSFORMATION_FROM_EVENT = ConfigKeys.newConfigKey(new TypeToken<Function<?, ?>>() {}, "enricher.transformation.fromevent");
-
- public Transformer() {
- }
-
- /** returns a function for transformation, for immediate use only (not for caching, as it may change) */
- @Override
- @SuppressWarnings("unchecked")
- protected Function<SensorEvent<T>, U> getTransformation() {
- MutableSet<Object> suppliers = MutableSet.of();
- suppliers.addIfNotNull(config().getRaw(TARGET_VALUE).orNull());
- suppliers.addIfNotNull(config().getRaw(TRANSFORMATION_FROM_EVENT).orNull());
- suppliers.addIfNotNull(config().getRaw(TRANSFORMATION_FROM_VALUE).orNull());
- checkArgument(suppliers.size()==1,
- "Must set exactly one of: %s, %s, %s", TARGET_VALUE.getName(), TRANSFORMATION_FROM_VALUE.getName(), TRANSFORMATION_FROM_EVENT.getName());
-
- Function<?, ?> fromEvent = config().get(TRANSFORMATION_FROM_EVENT);
- if (fromEvent != null) {
- return (Function<SensorEvent<T>, U>) fromEvent;
- }
-
- final Function<T, U> fromValueFn = (Function<T, U>) config().get(TRANSFORMATION_FROM_VALUE);
- if (fromValueFn != null) {
- // named class not necessary as result should not be serialized
- return new Function<SensorEvent<T>, U>() {
- @Override public U apply(SensorEvent<T> input) {
- return fromValueFn.apply(input.getValue());
- }
- @Override
- public String toString() {
- return ""+fromValueFn;
- }
- };
- }
-
- // from target value
- // named class not necessary as result should not be serialized
- final Object targetValueRaw = config().getRaw(TARGET_VALUE).orNull();
- return new Function<SensorEvent<T>, U>() {
- @Override public U apply(SensorEvent<T> input) {
- // evaluate immediately, or return null
- // PRETTY_QUICK/200ms seems a reasonable compromise for tasks which require BG evaluation
- // but which are non-blocking
- // TODO better would be to have a mode in which tasks are not permitted to block on
- // external events; they can submit tasks and block on them (or even better, have a callback architecture);
- // however that is a non-trivial refactoring
- return (U) Tasks.resolving(targetValueRaw).as(targetSensor.getType())
- .context(entity)
- .description("Computing sensor "+targetSensor+" from "+targetValueRaw)
- .timeout(ValueResolver.PRETTY_QUICK_WAIT)
- .getMaybe().orNull();
- }
- public String toString() {
- return ""+targetValueRaw;
- }
- };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/UpdatingMap.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/UpdatingMap.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/UpdatingMap.java
deleted file mode 100644
index 6ae48a7..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/UpdatingMap.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.flags.SetFromFlag;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-import com.google.common.collect.Maps;
-import com.google.common.reflect.TypeToken;
-
-/**
- * Enricher which updates an entry in a sensor map ({@link #TARGET_SENSOR})
- * based on the value of another sensor ({@link #SOURCE_SENSOR}.
- * <p>
- * The key used defaults to the name of the source sensor but can be specified with {@link #KEY_IN_TARGET_SENSOR}.
- * The value placed in the map is the result of applying the function in {@link #COMPUTING} to the sensor value,
- * with default behaviour being to remove an entry if <code>null</code> is returned
- * but this can be overriden by setting {@link #REMOVING_IF_RESULT_IS_NULL} false.
- * {@link Entities#REMOVE} and {@link Entities#UNCHANGED} are also respeced as return values for the computation
- * (ignoring generics).
- * Unlike most other enrichers, this defaults to {@link AbstractEnricher#SUPPRESS_DUPLICATES} being true
- *
- * @author alex
- *
- * @param <S> source sensor type
- * @param <TKey> key type in target sensor map
- * @param <TVal> value type in target sensor map
- */
-@SuppressWarnings("serial")
-public class UpdatingMap<S,TKey,TVal> extends AbstractEnricher implements SensorEventListener<S> {
-
- private static final Logger LOG = LoggerFactory.getLogger(UpdatingMap.class);
-
- @SetFromFlag("fromSensor")
- public static final ConfigKey<Sensor<?>> SOURCE_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.sourceSensor");
- @SetFromFlag("targetSensor")
- public static final ConfigKey<Sensor<?>> TARGET_SENSOR = ConfigKeys.newConfigKey(new TypeToken<Sensor<?>>() {}, "enricher.targetSensor");
- @SetFromFlag("key")
- public static final ConfigKey<?> KEY_IN_TARGET_SENSOR = ConfigKeys.newConfigKey(Object.class, "enricher.updatingMap.keyInTargetSensor",
- "Key to update in the target sensor map, defaulting to the name of the source sensor");
- @SetFromFlag("computing")
- public static final ConfigKey<Function<?, ?>> COMPUTING = ConfigKeys.newConfigKey(new TypeToken<Function<?,?>>() {}, "enricher.updatingMap.computing");
- @SetFromFlag("removingIfResultIsNull")
- public static final ConfigKey<Boolean> REMOVING_IF_RESULT_IS_NULL = ConfigKeys.newBooleanConfigKey("enricher.updatingMap.removingIfResultIsNull",
- "Whether the key in the target map is removed if the result if the computation is null");
-
- protected AttributeSensor<S> sourceSensor;
- protected AttributeSensor<Map<TKey,TVal>> targetSensor;
- protected TKey key;
- protected Function<S,? extends TVal> computing;
- protected Boolean removingIfResultIsNull;
-
- public UpdatingMap() {
- this(Maps.newLinkedHashMap());
- }
-
- public UpdatingMap(Map<Object, Object> flags) {
- super(flags);
- // this always suppresses duplicates, but it updates the same map *in place* so the usual suppress duplicates logic should not be applied
- // TODO clean up so that we have synchronization guarantees and can inspect the item to see whether it has changed
- suppressDuplicates = false;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- this.sourceSensor = (AttributeSensor<S>) getRequiredConfig(SOURCE_SENSOR);
- this.targetSensor = (AttributeSensor<Map<TKey,TVal>>) getRequiredConfig(TARGET_SENSOR);
- this.key = (TKey) getConfig(KEY_IN_TARGET_SENSOR);
- this.computing = (Function) getRequiredConfig(COMPUTING);
- this.removingIfResultIsNull = getConfig(REMOVING_IF_RESULT_IS_NULL);
-
- subscribe(entity, sourceSensor, this);
- onUpdated();
- }
-
- @Override
- public void onEvent(SensorEvent<S> event) {
- onUpdated();
- }
-
- /**
- * Called whenever the values for the set of producers changes (e.g. on an event, or on a member added/removed).
- */
- @SuppressWarnings("unchecked")
- protected void onUpdated() {
- try {
- Object v = computing.apply(entity.getAttribute(sourceSensor));
- if (v == null && !Boolean.FALSE.equals(removingIfResultIsNull)) {
- v = Entities.REMOVE;
- }
- if (v == Entities.UNCHANGED) {
- // nothing
- } else {
- // TODO check synchronization
- TKey key = this.key;
- if (key==null) key = (TKey) sourceSensor.getName();
-
- Map<TKey, TVal> map = entity.getAttribute(targetSensor);
-
- boolean created = (map==null);
- if (created) map = MutableMap.of();
-
- boolean changed;
- if (v == Entities.REMOVE) {
- changed = map.containsKey(key);
- if (changed)
- map.remove(key);
- } else {
- TVal oldV = map.get(key);
- if (oldV==null)
- changed = (v!=null || !map.containsKey(key));
- else
- changed = !oldV.equals(v);
- if (changed)
- map.put(key, (TVal)v);
- }
- if (changed || created)
- emit(targetSensor, map);
- }
- } catch (Throwable t) {
- LOG.warn("Error calculating map update for enricher "+this, t);
- throw Exceptions.propagate(t);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricher.java
deleted file mode 100644
index dc65fa8..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricher.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.base.Function;
-
-/**
- * Transforms {@link Sensor} data into a rolling average based on a time window.
- *
- * All values within the window are weighted or discarded based on the timestamps associated with
- * them (discards occur when a new value is added or an average is requested)
- * <p>
- * This will not extrapolate figures - it is assumed a value is valid and correct for the entire
- * time period between it and the previous value. Normally, the average attribute is only updated
- * when a new value arrives so it can give a fully informed average, but there is a danger of this
- * going stale.
- * <p>
- * When an average is requested, it is likely there will be a segment of the window for which there
- * isn't a value. Instead of extrapolating a value and providing different extrapolation techniques,
- * the average is reported with a confidence value which reflects the fraction of the time
- * window for which the values were valid.
- * <p>
- * Consumers of the average may ignore the confidence value and just use the last known average.
- * They could multiply the returned value by the confidence value to get a decay-type behavior as
- * the window empties. A third alternative is to, at a certain confidence threshold, report that
- * the average is no longer meaningful.
- * <p>
- * The default average when no data has been received is 0, with a confidence of 0
- */
-public class YamlRollingTimeWindowMeanEnricher<T extends Number> extends AbstractTransformer<T,Double> {
-
- public static ConfigKey<Duration> WINDOW_DURATION = ConfigKeys.newConfigKey(Duration.class, "enricher.window.duration",
- "Duration for which this window should store data, default one minute", Duration.ONE_MINUTE);
-
- public static ConfigKey<Double> CONFIDENCE_REQUIRED_TO_PUBLISH = ConfigKeys.newDoubleConfigKey("enricher.window.confidenceRequired",
- "Minimum confidence level (ie period covered) required to publish a rolling average", 0.8d);
-
- public static class ConfidenceQualifiedNumber {
- final Double value;
- final double confidence;
-
- public ConfidenceQualifiedNumber(Double value, double confidence) {
- this.value = value;
- this.confidence = confidence;
- }
-
- @Override
- public String toString() {
- return ""+value+" ("+(int)(confidence*100)+"%)";
- }
-
- }
-
- private final LinkedList<T> values = new LinkedList<T>();
- private final LinkedList<Long> timestamps = new LinkedList<Long>();
- volatile ConfidenceQualifiedNumber lastAverage = new ConfidenceQualifiedNumber(0d,0d);
-
- @Override
- protected Function<SensorEvent<T>, Double> getTransformation() {
- return new Function<SensorEvent<T>, Double>() {
- @Override
- public Double apply(SensorEvent<T> event) {
- long eventTime = event.getTimestamp();
- if (event.getValue()==null) {
- return null;
- }
- values.addLast(event.getValue());
- timestamps.addLast(eventTime);
- if (eventTime>0) {
- ConfidenceQualifiedNumber average = getAverage(eventTime, 0);
-
- if (average.confidence > getConfig(CONFIDENCE_REQUIRED_TO_PUBLISH)) {
- // without confidence, we might publish wildly varying estimates,
- // causing spurious resizes, so allow it to be configured, and
- // by default require a high value
-
- // TODO would be nice to include timestamp, etc
- return average.value;
- }
- }
- return null;
- }
- };
- }
-
- public ConfidenceQualifiedNumber getAverage(long fromTime, long graceAllowed) {
- if (timestamps.isEmpty()) {
- return lastAverage = new ConfidenceQualifiedNumber(lastAverage.value, 0.0d);
- }
-
- long firstTimestamp = -1;
- Iterator<Long> ti = timestamps.iterator();
- while (ti.hasNext()) {
- firstTimestamp = ti.next();
- if (firstTimestamp>0) break;
- }
- if (firstTimestamp<=0) {
- // no values with reasonable timestamps
- return lastAverage = new ConfidenceQualifiedNumber(values.get(values.size()-1).doubleValue(), 0.0d);
- }
-
- long lastTimestamp = timestamps.get(timestamps.size()-1);
-
- long now = fromTime;
- if (lastTimestamp > fromTime - graceAllowed) {
- // without this, if the computation takes place X seconds after the publish,
- // we treat X seconds as time for which we have no confidence in the data
- now = lastTimestamp;
- }
- pruneValues(now);
-
- Duration timePeriod = getConfig(WINDOW_DURATION);
- long windowStart = Math.max(now-timePeriod.toMilliseconds(), firstTimestamp);
- long windowEnd = Math.max(now-timePeriod.toMilliseconds(), lastTimestamp);
- Double confidence = ((double)(windowEnd - windowStart)) / timePeriod.toMilliseconds();
- if (confidence <= 0.0000001d) {
- // not enough timestamps in window
- double lastValue = values.get(values.size()-1).doubleValue();
- return lastAverage = new ConfidenceQualifiedNumber(lastValue, 0.0d);
- }
-
- long start = windowStart;
- long end;
- double weightedAverage = 0.0d;
-
- Iterator<T> valuesIter = values.iterator();
- Iterator<Long> timestampsIter = timestamps.iterator();
- while (valuesIter.hasNext()) {
- // Ignores null and out-of-date values (and also values that are received out-of-order, but that shouldn't happen!)
- Number val = valuesIter.next();
- Long timestamp = timestampsIter.next();
- if (val!=null && timestamp >= start) {
- end = timestamp;
- weightedAverage += ((end - start) / (confidence * timePeriod.toMilliseconds())) * val.doubleValue();
- start = timestamp;
- }
- }
-
- return lastAverage = new ConfidenceQualifiedNumber(weightedAverage, confidence);
- }
-
- /**
- * Discards out-of-date values, but keeps at least one value.
- */
- private void pruneValues(long now) {
- // keep one value from before the period, so that we can tell the window's start time
- Duration timePeriod = getConfig(WINDOW_DURATION);
- while(timestamps.size() > 1 && timestamps.get(1) < (now - timePeriod.toMilliseconds())) {
- timestamps.removeFirst();
- values.removeFirst();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricher.java
deleted file mode 100644
index c49ac26..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricher.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.enricher;
-
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.enricher.AbstractTransformer;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Function;
-
-/**
- * Converts an absolute count sensor into a delta sensor (i.e. the diff between the current and previous value),
- * presented as a units/timeUnit based on the event timing.
- * <p>
- * For example, given a requests.count sensor, this can make a requests.per_sec sensor with {@link #DELTA_PERIOD} set to "1s" (the default).
- * <p>
- * Suitable for configuration from YAML.
- */
-public class YamlTimeWeightedDeltaEnricher<T extends Number> extends AbstractTransformer<T,Double> {
- private static final Logger LOG = LoggerFactory.getLogger(YamlTimeWeightedDeltaEnricher.class);
-
- transient Object lock = new Object();
- Number lastValue;
- long lastTime = -1;
-
- public static ConfigKey<Duration> DELTA_PERIOD = ConfigKeys.newConfigKey(Duration.class, "enricher.delta.period",
- "Duration that this delta should compute for, default per second", Duration.ONE_SECOND);
-
- @Override
- protected Function<SensorEvent<T>, Double> getTransformation() {
- return new Function<SensorEvent<T>, Double>() {
- @Override
- public Double apply(SensorEvent<T> event) {
- synchronized (lock) {
- Double current = TypeCoercions.coerce(event.getValue(), Double.class);
-
- if (current == null) return null;
-
- long eventTime = event.getTimestamp();
- long unitMillis = getConfig(DELTA_PERIOD).toMilliseconds();
- Double result = null;
-
- if (eventTime > 0 && eventTime > lastTime) {
- if (lastValue == null || lastTime < 0) {
- // cannot calculate time-based delta with a single value
- if (LOG.isTraceEnabled()) LOG.trace("{} received event but no last value so will not emit, null -> {} at {}", new Object[] {this, current, eventTime});
- } else {
- double duration = eventTime - lastTime;
- result = (current - lastValue.doubleValue()) / (duration / unitMillis);
- }
- }
-
- lastValue = current;
- lastTime = eventTime;
-
- return result;
- }
- }
- };
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/enricher/BasicEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/enricher/BasicEnricherTest.java b/core/src/test/java/org/apache/brooklyn/core/enricher/BasicEnricherTest.java
new file mode 100644
index 0000000..be87f1f
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/enricher/BasicEnricherTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.enricher;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.Enricher;
+import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestApplicationNoEnrichersImpl;
+import org.apache.brooklyn.util.collections.MutableSet;
+import org.apache.brooklyn.util.core.flags.SetFromFlag;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Iterables;
+
+/**
+ * Test that enricher can be created and accessed, by construction and by spec
+ */
+public class BasicEnricherTest extends BrooklynAppUnitTestSupport {
+
+ // TODO These tests are a copy of BasicPolicyTest, which is a code smell.
+ // However, the src/main/java code does not contain as much duplication.
+
+ protected void setUpApp() {
+ EntitySpec<TestApplication> appSpec = EntitySpec.create(TestApplication.class, TestApplicationNoEnrichersImpl.class)
+ .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, shouldSkipOnBoxBaseDirResolution());
+ app = ApplicationBuilder.newManagedApp(appSpec, mgmt);
+ }
+
+ public static class MyEnricher extends AbstractEnricher {
+ @SetFromFlag("intKey")
+ public static final BasicConfigKey<Integer> INT_KEY = new BasicConfigKey<Integer>(Integer.class, "bkey", "b key");
+
+ @SetFromFlag("strKey")
+ public static final ConfigKey<String> STR_KEY = new BasicConfigKey<String>(String.class, "akey", "a key");
+ public static final ConfigKey<Integer> INT_KEY_WITH_DEFAULT = new BasicConfigKey<Integer>(Integer.class, "ckey", "c key", 1);
+ public static final ConfigKey<String> STR_KEY_WITH_DEFAULT = new BasicConfigKey<String>(String.class, "strKey", "str key", "str key default");
+
+ MyEnricher(Map<?,?> flags) {
+ super(flags);
+ }
+
+ public MyEnricher() {
+ super();
+ }
+ }
+
+ @Test
+ public void testAddInstance() throws Exception {
+ MyEnricher enricher = new MyEnricher();
+ enricher.setDisplayName("Bob");
+ enricher.config().set(MyEnricher.STR_KEY, "aval");
+ enricher.config().set(MyEnricher.INT_KEY, 2);
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getDisplayName(), "Bob");
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testAddSpec() throws Exception {
+ MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class)
+ .displayName("Bob")
+ .configure(MyEnricher.STR_KEY, "aval").configure(MyEnricher.INT_KEY, 2));
+
+ assertEquals(enricher.getDisplayName(), "Bob");
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testTagsFromSpec() throws Exception {
+ MyEnricher enricher = app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x"));
+
+ assertEquals(enricher.tags().getTags(), MutableSet.of("x", 99));
+ assertEquals(enricher.getUniqueTag(), "x");
+ }
+
+ @Test
+ public void testSameUniqueTagEnricherNotAddedTwice() throws Exception {
+ app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(99).uniqueTag("x"));
+ app.addEnricher(EnricherSpec.create(MyEnricher.class).tag(94).uniqueTag("x"));
+
+ assertEquals(app.getEnrichers().size(), 1);
+ // the more recent one should dominate
+ Enricher enricher = Iterables.getOnlyElement(app.getEnrichers());
+ Assert.assertTrue(enricher.tags().containsTag(94));
+ Assert.assertFalse(enricher.tags().containsTag(99));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/enricher/EnricherConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/enricher/EnricherConfigTest.java b/core/src/test/java/org/apache/brooklyn/core/enricher/EnricherConfigTest.java
new file mode 100644
index 0000000..150a09b
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/enricher/EnricherConfigTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.enricher;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.enricher.BasicEnricherTest.MyEnricher;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.testng.annotations.Test;
+
+/**
+ * Test that configuration properties are usable and inherited correctly.
+ */
+public class EnricherConfigTest extends BrooklynAppUnitTestSupport {
+
+ // TODO These tests are a copy of PolicyConfigTest, which is a code smell.
+ // However, the src/main/java code does not contain as much duplication.
+
+ private BasicConfigKey<String> differentKey = new BasicConfigKey<String>(String.class, "differentkey", "diffval");
+
+ @Test
+ public void testConfigFlagsPassedInAtConstructionIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put("strKey", "aval")
+ .put("intKey", 2)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ // this is set, because key name matches annotation on STR_KEY
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "aval");
+ }
+
+ @Test
+ public void testUnknownConfigPassedInAtConstructionIsWarnedAndIgnored() throws Exception {
+ // TODO Also assert it's warned
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(differentKey, "aval")
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(differentKey), null);
+ assertEquals(enricher.getEnricherType().getConfigKey(differentKey.getName()), null);
+ }
+
+ @Test
+ public void testConfigPassedInAtConstructionIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY, "aval")
+ .put(MyEnricher.INT_KEY, 2)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ // this is not set (contrast with above)
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), MyEnricher.STR_KEY_WITH_DEFAULT.getDefaultValue());
+ }
+
+ @Test
+ public void testConfigSetToGroovyTruthFalseIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.INT_KEY_WITH_DEFAULT, 0)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY_WITH_DEFAULT), (Integer)0);
+ }
+
+ @Test
+ public void testConfigSetToNullIsAvailable() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY_WITH_DEFAULT, null)
+ .build());
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), null);
+ }
+
+ @Test
+ public void testConfigCanBeSetOnEnricher() throws Exception {
+ MyEnricher enricher = new MyEnricher();
+ enricher.config().set(MyEnricher.STR_KEY, "aval");
+ enricher.config().set(MyEnricher.INT_KEY, 2);
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "aval");
+ assertEquals(enricher.getConfig(MyEnricher.INT_KEY), (Integer)2);
+ }
+
+ @Test
+ public void testConfigSetterOverridesConstructorValue() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY, "aval")
+ .build());
+ enricher.config().set(MyEnricher.STR_KEY, "diffval");
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "diffval");
+ }
+
+ @Test
+ public void testConfigCannotBeSetAfterApplicationIsStarted() throws Exception {
+ MyEnricher enricher = new MyEnricher(MutableMap.builder()
+ .put(MyEnricher.STR_KEY, "origval")
+ .build());
+ app.addEnricher(enricher);
+
+ try {
+ enricher.config().set(MyEnricher.STR_KEY,"newval");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ // success
+ }
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY), "origval");
+ }
+
+ @Test
+ public void testConfigReturnsDefaultValueIfNotSet() throws Exception {
+ MyEnricher enricher = new MyEnricher();
+ app.addEnricher(enricher);
+
+ assertEquals(enricher.getConfig(MyEnricher.STR_KEY_WITH_DEFAULT), "str key default");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java
index d53bc87..1fec2e8 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySpecTest.java
@@ -30,6 +30,7 @@ import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.location.SimulatedLocation;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
@@ -37,7 +38,6 @@ import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.core.test.entity.TestEntityNoEnrichersImpl;
import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
index f751bcb..03a9c79 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/persist/BrooklynMementoPersisterTestFixture.java
@@ -46,7 +46,7 @@ import org.apache.brooklyn.core.mgmt.rebind.RecordingRebindExceptionHandler;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.policy.TestPolicy;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.testng.SkipException;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
index c4d295a..e79ba8a 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
@@ -34,6 +34,7 @@ import org.apache.brooklyn.api.sensor.Enricher;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
@@ -42,9 +43,8 @@ import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
+import org.apache.brooklyn.enricher.stock.Enrichers;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
-import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFailuresTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFailuresTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFailuresTest.java
index 26ee74f..e78f062 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFailuresTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFailuresTest.java
@@ -42,6 +42,7 @@ import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.config.ConfigMap;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.EntityFunctions;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
@@ -49,7 +50,6 @@ import org.apache.brooklyn.core.mgmt.rebind.RebindEntityTest.MyEntity;
import org.apache.brooklyn.core.mgmt.rebind.RebindEntityTest.MyEntityImpl;
import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.os.Os;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindPolicyTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindPolicyTest.java
index 28c9ba8..faff0c9 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindPolicyTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindPolicyTest.java
@@ -35,6 +35,7 @@ import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.mgmt.rebind.RebindEnricherTest.MyEnricher;
@@ -42,7 +43,6 @@ import org.apache.brooklyn.core.policy.AbstractPolicy;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/policy/basic/EnricherTypeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/policy/basic/EnricherTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/policy/basic/EnricherTypeTest.java
index a9f9655..12a6bff 100644
--- a/core/src/test/java/org/apache/brooklyn/core/policy/basic/EnricherTypeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/policy/basic/EnricherTypeTest.java
@@ -22,7 +22,7 @@ import static org.testng.Assert.assertEquals;
import org.apache.brooklyn.api.sensor.EnricherType;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/core/test/policy/TestEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/policy/TestEnricher.java b/core/src/test/java/org/apache/brooklyn/core/test/policy/TestEnricher.java
index 2340c51..42b52d2 100644
--- a/core/src/test/java/org/apache/brooklyn/core/test/policy/TestEnricher.java
+++ b/core/src/test/java/org/apache/brooklyn/core/test/policy/TestEnricher.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
+import org.apache.brooklyn.core.enricher.AbstractEnricher;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import com.google.common.reflect.TypeToken;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6f15e8a6/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.groovy
new file mode 100644
index 0000000..481e233
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/enricher/stock/CustomAggregatingEnricherDeprecatedTest.groovy
@@ -0,0 +1,368 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.enricher.stock
+
+import static org.testng.Assert.assertEquals
+
+import org.apache.brooklyn.api.entity.EntitySpec
+import org.apache.brooklyn.api.sensor.AttributeSensor
+import org.apache.brooklyn.core.test.entity.TestApplication
+import org.apache.brooklyn.core.test.entity.TestEntity
+import org.apache.brooklyn.enricher.stock.CustomAggregatingEnricher;
+import org.apache.brooklyn.core.entity.Entities
+import org.apache.brooklyn.entity.group.BasicGroup
+import org.apache.brooklyn.core.location.SimulatedLocation
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
+import org.apache.brooklyn.test.TestUtils
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+import org.testng.annotations.AfterMethod
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+
+import com.google.common.base.Function
+
+class CustomAggregatingEnricherDeprecatedTest {
+
+ public static final Logger log = LoggerFactory.getLogger(CustomAggregatingEnricherDeprecatedTest.class);
+
+ private static final long TIMEOUT_MS = 10*1000
+ private static final long SHORT_WAIT_MS = 250
+
+ TestApplication app
+ TestEntity producer
+
+ AttributeSensor<Integer> intSensor
+ AttributeSensor<Integer> target
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor")
+ target = new BasicAttributeSensor<Integer>(Long.class, "target sensor")
+
+ app.start([new SimulatedLocation()])
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() {
+ if (app!=null) Entities.destroyAll(app.getManagementContext());
+ }
+
+ @Test
+ public void testEnrichersWithNoProducers() {
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher([:], intSensor, target, 11, 40)
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), 40
+ }
+
+ @Test
+ public void testSummingEnricherWhenNoSensorValuesYet() {
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
+ intSensor, target, producers:[producer], 11, 40)
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), 11
+ }
+
+ @Test
+ public void testSingleProducerSum() {
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
+ intSensor, target, null, null, producers:[producer])
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), null
+ cae.onEvent(intSensor.newEvent(producer, 1))
+ assertEquals cae.getAggregate(), 1
+ }
+
+ @Test
+ public void testSummingEnricherWhenNoAndNullSensorValue() {
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
+ intSensor, target, null, null, producers:[producer])
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), null
+ cae.onEvent(intSensor.newEvent(producer, null))
+ assertEquals cae.getAggregate(), null
+ }
+
+ @Test
+ public void testSummingEnricherWhenNoAndNullSensorValueExplicitValue() {
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
+ intSensor, target, 3 /** if null */, 5 /** if none */, producers:[producer])
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), 3
+ cae.onEvent(intSensor.newEvent(producer, null))
+ assertEquals cae.getAggregate(), 3
+ cae.onEvent(intSensor.newEvent(producer, 1))
+ assertEquals cae.getAggregate(), 1
+ cae.onEvent(intSensor.newEvent(producer, 7))
+ assertEquals cae.getAggregate(), 7
+ }
+
+ @Test
+ public void testMultipleProducersSum() {
+ List<TestEntity> producers = [
+ app.createAndManageChild(EntitySpec.create(TestEntity.class)),
+ app.createAndManageChild(EntitySpec.create(TestEntity.class)),
+ app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ ]
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
+ intSensor, target, null, null, producers:producers)
+
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), null
+ cae.onEvent(intSensor.newEvent(producers[2], 1))
+ assertEquals cae.getAggregate(), 1
+ cae.onEvent(intSensor.newEvent(producers[0], 3))
+ assertEquals cae.getAggregate(), 4
+ cae.onEvent(intSensor.newEvent(producers[1], 3))
+ assertEquals cae.getAggregate(), 7
+
+ }
+
+ @Test
+ public void testAveragingEnricherWhenNoAndNullSensorValues() {
+ List<TestEntity> producers = [
+ app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ ]
+ CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
+ intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), null, null, producers:producers)
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), null
+ cae.onEvent(intSensor.newEvent(producers[0], null))
+ assertEquals cae.getAggregate(), null
+ }
+
+ @Test
+ public void testAveragingEnricherWhenNoAndNullSensorValuesExplicit() {
+ List<TestEntity> producers = [
+ app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ ]
+ CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
+ intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 3 /** if null */, 5 /** if none */,
+ producers:producers)
+ producer.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), 3d
+ cae.onEvent(intSensor.newEvent(producers[0], null))
+ assertEquals cae.getAggregate(), 3d
+ cae.onEvent(intSensor.newEvent(producers[0], 4))
+ assertEquals cae.getAggregate(), 4d
+ }
+
+ @Test
+ public void testAveragingEnricherWhenNoSensors() {
+ List<TestEntity> producers = [
+ ]
+ CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
+ intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 3 /** if null */, 5 /** if none */,
+ producers:producers)
+ producer.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), 5d
+ }
+
+ @Test
+ public void testMultipleProducersAverage() {
+ List<TestEntity> producers = [
+ app.createAndManageChild(EntitySpec.create(TestEntity.class)),
+ app.createAndManageChild(EntitySpec.create(TestEntity.class)),
+ app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ ]
+ CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
+ intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), null, null, producers:producers)
+
+ producer.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), null
+ cae.onEvent(intSensor.newEvent(producers[0], 3))
+ assertEquals cae.getAggregate(), 3d
+
+ cae.onEvent(intSensor.newEvent(producers[1], 3))
+ assertEquals cae.getAggregate(), 3d
+
+ cae.onEvent(intSensor.newEvent(producers[2], 6))
+ assertEquals cae.getAggregate(), 4d
+
+ // change p2's value to 7.5, average increase of 0.5.
+ cae.onEvent(intSensor.newEvent(producers[2], 7.5))
+ assertEquals cae.getAggregate(), 4.5d
+ }
+
+ @Test
+ public void testMultipleProducersAverageDefaultingZero() {
+ List<TestEntity> producers = [
+ app.createAndManageChild(EntitySpec.create(TestEntity.class)),
+ app.createAndManageChild(EntitySpec.create(TestEntity.class)),
+ app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ ]
+ CustomAggregatingEnricher<Double> cae = CustomAggregatingEnricher.<Double>newAveragingEnricher(
+ intSensor, new BasicAttributeSensor<Double>(Double.class, "target sensor"), 0, 0, producers:producers)
+
+ producer.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), 0d
+ cae.onEvent(intSensor.newEvent(producers[0], 3))
+ assertEquals cae.getAggregate(), 1d
+
+ cae.onEvent(intSensor.newEvent(producers[1], 3))
+ assertEquals cae.getAggregate(), 2d
+
+ cae.onEvent(intSensor.newEvent(producers[2], 6))
+ assertEquals cae.getAggregate(), 4d
+
+ // change p2's value to 7.5, average increase of 0.5.
+ cae.onEvent(intSensor.newEvent(producers[2], 7.5))
+ assertEquals cae.getAggregate(), 4.5d
+ }
+
+ @Test
+ public void testAddingAndRemovingProducers() {
+ TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(
+ intSensor, target, null, null, producers:[p1])
+
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), null
+
+ // Event by initial producer
+ cae.onEvent(intSensor.newEvent(p1, 1))
+ assertEquals cae.getAggregate(), 1
+
+ // Add producer and fire event
+ cae.addProducer(p2)
+ cae.onEvent(intSensor.newEvent(p2, 4))
+ assertEquals cae.getAggregate(), 5
+
+ cae.removeProducer(p2)
+ assertEquals cae.getAggregate(), 1
+ }
+
+ @Test
+ public void testAggregatesNewMembersOfGroup() {
+ try {
+ BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class))
+ log.debug("created $group and the entities it will contain $p1 $p2")
+
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(intSensor, target, 0, 0, allMembers:true)
+ group.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), 0
+
+ group.addMember(p1)
+ p1.setAttribute(intSensor, 1)
+ TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
+ assertEquals cae.getAggregate(), 1
+ }
+
+ group.addMember(p2)
+ p2.setAttribute(intSensor, 2)
+ TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
+ assertEquals cae.getAggregate(), 3
+ }
+
+ group.removeMember(p2)
+ TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
+ assertEquals cae.getAggregate(), 1
+ }
+ } catch (Exception e) {
+ log.error("testAggregatesNewMembersOfGroup failed (now cleaning up): "+e)
+ throw e;
+ }
+ }
+
+ @Test(groups = "Integration")
+ public void testAggregatesGroupMembersFiftyTimes() {
+ for (int i=0; i<50; i++) {
+ log.debug "testAggregatesNewMembersOfGroup $i"
+ testAggregatesNewMembersOfGroup();
+ }
+ }
+
+ @Test
+ public void testAggregatesExistingMembersOfGroup() {
+ BasicGroup group = app.addChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
+ TestEntity p2 = app.getManagementContext().getEntityManager().createEntity(EntitySpec.create(TestEntity.class).parent(group));
+ group.addMember(p1)
+ group.addMember(p2)
+ p1.setAttribute(intSensor, 1)
+ Entities.manage(group);
+
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(intSensor, target, null, null, allMembers:true)
+ group.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), 1
+
+ p2.setAttribute(intSensor, 2)
+ TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
+ assertEquals cae.getAggregate(), 3
+ }
+
+ group.removeMember(p2)
+ TestUtils.executeUntilSucceeds(timeout:TIMEOUT_MS) {
+ assertEquals cae.getAggregate(), 1
+ }
+ }
+
+ @Test
+ public void testAppliesFilterWhenAggregatingMembersOfGroup() {
+ BasicGroup group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
+ TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ TestEntity p3 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ group.addMember(p1)
+ group.addMember(p2)
+ p1.setAttribute(intSensor, 1)
+ p2.setAttribute(intSensor, 2)
+ p3.setAttribute(intSensor, 4)
+
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newSummingEnricher(intSensor, target, null, null, allMembers:true, filter:{it == p1})
+ group.addEnricher(cae)
+
+ assertEquals cae.getAggregate(), 1
+
+ group.addMember(p3)
+ TestUtils.assertSucceedsContinually(timeout:SHORT_WAIT_MS) {
+ assertEquals cae.getAggregate(), 1
+ }
+ }
+
+ @Test
+ public void testCustomAggregatingFunction() {
+ TestEntity p1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ Function<Collection<Integer>,Integer> aggregator = { Collection c ->
+ int result = 0; c.each { result += it*it }; return result;
+ } as Function
+
+ CustomAggregatingEnricher<Integer> cae = CustomAggregatingEnricher.<Integer>newEnricher(
+ intSensor, target, aggregator, 0, producers:[p1])
+
+ producer.addEnricher(cae)
+ assertEquals cae.getAggregate(), 0
+
+ // Event by producer
+ cae.onEvent(intSensor.newEvent(p1, 2))
+ assertEquals cae.getAggregate(), 4
+ }
+}
[04/36] incubator-brooklyn git commit: Rename o.a.b.effector.core to
o.a.b.core.effector
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
index da4a9ce..9e3d885 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandEffector.java
@@ -24,12 +24,12 @@ import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.effector.ParameterType;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.AddEffector;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.Effectors.EffectorBuilder;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks.SshEffectorTaskFactory;
+import org.apache.brooklyn.core.effector.AddEffector;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.Effectors.EffectorBuilder;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks.SshEffectorTaskFactory;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
index 8e28299..c3dd177 100644
--- a/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
+++ b/software/base/src/main/java/org/apache/brooklyn/sensor/ssh/SshCommandSensor.java
@@ -24,7 +24,7 @@ import org.apache.brooklyn.api.entity.EntityInitializer;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.AddSensor;
+import org.apache.brooklyn.core.effector.AddSensor;
import org.apache.brooklyn.entity.java.JmxAttributeSensor;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.sensor.core.HttpRequestSensor;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
index b9847ae..ff8884b 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/brooklynnode/SelectMasterEffectorTest.java
@@ -32,9 +32,9 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.brooklynnode.BrooklynCluster;
import org.apache.brooklyn.entity.brooklynnode.BrooklynClusterImpl;
import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
index 8de4bb0..a0bfba2 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverMySqlEntityLiveTest.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.chef.mysql;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
index 21d1d2f..7d3c895 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/chef/mysql/ChefSoloDriverToyMySqlEntity.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.mgmt.TaskFactory;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefConfig;
import org.apache.brooklyn.entity.chef.ChefConfigs;
import org.apache.brooklyn.entity.chef.ChefSoloDriver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
index 244adf8..69d1cfc 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareEffectorTest.java
@@ -24,11 +24,11 @@ import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks.SshEffectorBody;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks.SshEffectorBody;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
index 0b738aa..0b1515b 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessEntityTest.java
@@ -42,6 +42,7 @@ import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
@@ -55,7 +56,6 @@ import org.apache.brooklyn.core.location.Locations;
import org.apache.brooklyn.core.location.SimulatedLocation;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessDriver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessSubclassTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessSubclassTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessSubclassTest.java
index 338b1f3..29229ea 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessSubclassTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/SoftwareProcessSubclassTest.java
@@ -26,9 +26,9 @@ import java.util.List;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.effector.EffectorAndBody;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.effector.core.EffectorAndBody;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcessImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
index 82fd74f..8283637 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/AbstractToyMySqlEntityTest.java
@@ -21,11 +21,11 @@ package org.apache.brooklyn.entity.software.base.test.mysql;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
index 22a8d8d..65baf9a 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/mysql/DynamicToyMySqlEntityBuilder.java
@@ -26,10 +26,10 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.BasicOsDetails.OsVersions;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
import org.apache.brooklyn.entity.stock.BasicStartable;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
index 858576d..8f7b6bf 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/test/ssh/SshCommandIntegrationTest.java
@@ -27,11 +27,11 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.ssh.SshCommandEffector;
import org.apache.brooklyn.sensor.ssh.SshCommandSensor;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
index f08cd95..10e2e15 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/system_service/SystemServiceEnricherTest.java
@@ -22,12 +22,12 @@ import static org.testng.Assert.assertEquals;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.effector.core.EffectorTasks;
import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcessImpl;
import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcessSshDriver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
index 5536366..c2acfab 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/DatastoreMixins.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.ResourceUtils;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
index 1c803c2..3d8c982 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
@@ -20,8 +20,8 @@ package org.apache.brooklyn.entity.database.mariadb;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
index 81b4834..c7a4936 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
@@ -36,9 +36,9 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
index 79a12b8..aa11eb4 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
index f8f620f..71c73c6 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.entity.database.mysql;
import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
index 95f497d..313a583 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlSshDriver.java
@@ -38,10 +38,10 @@ import org.slf4j.LoggerFactory;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.BasicOsDetails.OsVersions;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
index 04e3c83..6cb9cde 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNode.java
@@ -24,8 +24,8 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.objs.HasShortName;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.location.PortRanges;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.database.DatabaseNode;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
index e557090..01fde1f 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeChefImplFromScratch.java
@@ -21,11 +21,11 @@ package org.apache.brooklyn.entity.database.postgresql;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Locations;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefConfig;
import org.apache.brooklyn.entity.chef.ChefLifecycleEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefServerTasks;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeImpl.java
index 15d280e..60a53c2 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlNodeImpl.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.entity.database.postgresql;
-import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
index cbb289b..f9e80f7 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSshDriver.java
@@ -39,8 +39,8 @@ import java.io.InputStream;
import javax.annotation.Nullable;
import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
----------------------------------------------------------------------
diff --git a/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java b/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
index bd9ec6b..6f1d014 100644
--- a/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
+++ b/software/database/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlChefTest.java
@@ -24,12 +24,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
-import org.apache.brooklyn.effector.core.EffectorTasks;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.chef.ChefLiveTestSupport;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
import org.apache.brooklyn.entity.database.VogellaExampleAccess;
import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.PortRanges;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
index 66263f5..2f92c47 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenter.java
@@ -29,8 +29,8 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.nosql.cassandra.TokenGenerators.PosNeg63TokenGenerator;
import org.apache.brooklyn.entity.database.DatastoreMixins;
import org.apache.brooklyn.entity.group.DynamicCluster;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
index 73d135f..13df45b 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraDatacenterImpl.java
@@ -35,13 +35,13 @@ import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.location.Machines;
-import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.entity.group.DynamicGroup;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
index 8f993fc..5d9a9ca 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraFabric.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.group.DynamicFabric;
import com.google.common.base.Function;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
index a096e33..0a7e638 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeImpl.java
@@ -36,11 +36,11 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.api.location.MachineProvisioningLocation;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
-import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.entity.java.JavaAppUtils;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
index 832a886..11d919e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/cassandra/CassandraNodeSshDriver.java
@@ -31,11 +31,11 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.TaskWrapper;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
index e0e91ed..bef9fa5 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseClusterImpl.java
@@ -34,13 +34,13 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.group.AbstractMembershipTrackingPolicy;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
index 0c06478..b592af8 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNode.java
@@ -28,9 +28,9 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.effector.Effectors;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.effector.core.Effectors;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
index 318ac74..bed5a3d 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeImpl.java
@@ -30,10 +30,10 @@ import org.apache.brooklyn.api.location.MachineProvisioningLocation;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
-import org.apache.brooklyn.effector.core.EffectorBody;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
index 7a8ae35..a5a821e 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/couchbase/CouchbaseNodeSshDriver.java
@@ -33,13 +33,13 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.Group;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.drivers.downloads.BasicDownloadRequirement;
import org.apache.brooklyn.core.entity.drivers.downloads.DownloadProducerFromUrlAttribute;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
index 5b8929c..4e124a7 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/mongodb/MongoDBClient.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.nosql.mongodb.sharding.MongoDBShardedDeployment;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
index e6b2258..4b43757 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNode.java
@@ -28,8 +28,8 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
index 943a193..f4fda89 100644
--- a/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
+++ b/software/nosql/src/main/java/org/apache/brooklyn/entity/nosql/riak/RiakNodeSshDriver.java
@@ -39,9 +39,9 @@ import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.lifecycle.ScriptHelper;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
index 8cad9f7..7bb7890 100644
--- a/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
+++ b/software/osgi/src/main/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainer.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.entity.java.UsesJmx;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
----------------------------------------------------------------------
diff --git a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
index ae525cd..624fc4e 100644
--- a/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
+++ b/software/osgi/src/test/java/org/apache/brooklyn/entity/osgi/karaf/KarafContainerTest.java
@@ -26,10 +26,10 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.NoMachinesAvailableException;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
index b65e15e..e4d6262 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/LoadBalancer.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.webapp.WebAppService;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
index c23989e..35e28ba 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/NginxController.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.proxy.AbstractController;
import org.apache.brooklyn.entity.proxy.ProxySslConfig;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
index 3349edb..8ccb4a2 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/proxy/nginx/UrlMapping.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.group.AbstractGroup;
import org.apache.brooklyn.entity.proxy.AbstractController;
import org.apache.brooklyn.entity.proxy.ProxySslConfig;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
index 5fe5950..10d21a1 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/DynamicWebAppClusterImpl.java
@@ -29,10 +29,10 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.mgmt.TaskAdaptable;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.group.DynamicClusterImpl;
import org.apache.brooklyn.sensor.enricher.Enrichers;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
index 05cfdd0..650b1e9 100644
--- a/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
+++ b/software/webapp/src/main/java/org/apache/brooklyn/entity/webapp/JavaWebAppService.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.java.UsesJava;
import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
index d729206..389fe69 100644
--- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
+++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslDeferredSupplier.java
@@ -27,9 +27,9 @@ import org.apache.brooklyn.camp.spi.Assembly;
import org.apache.brooklyn.camp.spi.AssemblyTemplate;
import org.apache.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.EffectorTasks;
import org.apache.brooklyn.util.core.task.DeferredSupplier;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
index 0e9e8f51..f9fe108 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/EntitiesYamlTest.java
@@ -41,6 +41,7 @@ import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent;
import org.apache.brooklyn.camp.brooklyn.spi.dsl.methods.DslComponent.Scope;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityFunctions;
@@ -50,7 +51,6 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.mgmt.internal.EntityManagerInternal;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.entity.group.DynamicCluster;
import org.apache.brooklyn.entity.software.base.SameServerEntity;
import org.apache.brooklyn.entity.stock.BasicEntity;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
index f5cd9cc..85b67af 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/TestSensorAndEffectorInitializer.java
@@ -24,9 +24,9 @@ import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.EntityInitializer;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.effector.EffectorBody;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.effector.core.EffectorBody;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.testng.Assert;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
index 3a6dcec..f3f0e50 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/VanillaBashNetcatYamlTest.java
@@ -23,11 +23,11 @@ import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.mgmt.Task;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.camp.brooklyn.BrooklynCampConstants;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
index 905c9db..cae1320 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/test/lite/CampYamlLiteTest.java
@@ -42,6 +42,8 @@ import org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog;
import org.apache.brooklyn.core.catalog.internal.CatalogDto;
import org.apache.brooklyn.core.catalog.internal.CatalogUtils;
import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.AddChildrenEffector;
+import org.apache.brooklyn.core.effector.Effectors;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
@@ -49,8 +51,6 @@ import org.apache.brooklyn.core.mgmt.osgi.OsgiStandaloneTest;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.effector.core.AddChildrenEffector;
-import org.apache.brooklyn.effector.core.Effectors;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.ResourceUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
index fc0aa4c..34c8ba4 100644
--- a/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
+++ b/usage/qa/src/main/java/org/apache/brooklyn/qa/load/SimulatedMySqlNodeImpl.java
@@ -23,7 +23,7 @@ import static java.lang.String.format;
import java.util.concurrent.Callable;
import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.effector.core.ssh.SshEffectorTasks;
+import org.apache.brooklyn.core.effector.ssh.SshEffectorTasks;
import org.apache.brooklyn.entity.database.mysql.MySqlNode;
import org.apache.brooklyn.entity.database.mysql.MySqlNodeImpl;
import org.apache.brooklyn.entity.database.mysql.MySqlSshDriver;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
index 740b411..e680bc1 100644
--- a/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
+++ b/usage/rest-server/src/test/java/org/apache/brooklyn/rest/testing/mocks/RestMockSimpleEntity.java
@@ -27,7 +27,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.BasicConfigKey;
-import org.apache.brooklyn.effector.core.MethodEffector;
+import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java b/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
index 81c6966..4efd1e3 100644
--- a/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
+++ b/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.test.osgi.entities.more;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.Effectors;
@ImplementedBy(MoreEntityImpl.class)
public interface MoreEntity extends Entity {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java b/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
index 17a8a41..c1eecd3 100644
--- a/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
+++ b/utils/test-bundles/more-entities-v1/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.test.osgi.entities.more;
-import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java b/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
index 8a75e9a..f0ace90 100644
--- a/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
+++ b/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
@@ -21,7 +21,7 @@ package org.apache.brooklyn.test.osgi.entities.more;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.Effectors;
@ImplementedBy(MoreEntityImpl.class)
public interface MoreEntity extends Entity {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java b/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
index 497069b..d2cfa08 100644
--- a/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
+++ b/utils/test-bundles/more-entities-v2-evil-twin/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
@@ -19,7 +19,7 @@
package org.apache.brooklyn.test.osgi.entities.more;
import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.util.core.config.ConfigBag;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java b/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
index edd650b..2124f86 100644
--- a/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
+++ b/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntity.java
@@ -22,7 +22,7 @@ import org.apache.brooklyn.api.catalog.Catalog;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.ImplementedBy;
-import org.apache.brooklyn.effector.core.Effectors;
+import org.apache.brooklyn.core.effector.Effectors;
@Catalog(name="More Entity v2")
@ImplementedBy(MoreEntityImpl.class)
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8dbb0e4b/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
----------------------------------------------------------------------
diff --git a/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java b/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
index fa27964..0aff562 100644
--- a/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
+++ b/utils/test-bundles/more-entities-v2/src/main/java/org/apache/brooklyn/test/osgi/entities/more/MoreEntityImpl.java
@@ -19,7 +19,7 @@
package org.apache.brooklyn.test.osgi.entities.more;
import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.core.effector.EffectorBody;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.util.core.config.ConfigBag;
[13/36] incubator-brooklyn git commit: Rename o.a.b.sensor.core to
o.a.b.core.sensor
Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/Sensors.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/Sensors.java b/core/src/main/java/org/apache/brooklyn/sensor/core/Sensors.java
deleted file mode 100644
index 5e9ed81..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/Sensors.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URL;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.AttributeSensor.SensorPersistenceMode;
-import org.apache.brooklyn.core.config.render.RendererHints;
-import org.apache.brooklyn.util.net.UserAndHostAndPort;
-import org.apache.brooklyn.util.text.StringFunctions;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Function;
-import com.google.common.net.HostAndPort;
-import com.google.common.reflect.TypeToken;
-
-public class Sensors {
-
- @Beta
- public static <T> Builder<T> builder(TypeToken<T> type, String name) {
- return new Builder<T>().type(type).name(name);
- }
-
- @Beta
- public static <T> Builder<T> builder(Class<T> type, String name) {
- return new Builder<T>().type(type).name(name);
- }
-
- @Beta
- public static class Builder<T> {
- private String name;
- private TypeToken<T> type;
- private String description;
- private SensorPersistenceMode persistence;
-
- protected Builder() { // use builder(type, name) instead
- }
- public Builder<T> name(String val) {
- this.name = checkNotNull(val, "name"); return this;
- }
- public Builder<T> type(Class<T> val) {
- return type(TypeToken.of(val));
- }
- public Builder<T> type(TypeToken<T> val) {
- this.type = checkNotNull(val, "type"); return this;
- }
- public Builder<T> description(String val) {
- this.description = val; return this;
- }
- public Builder<T> persistence(SensorPersistenceMode val) {
- this.persistence = val; return this;
- }
- public AttributeSensor<T> build() {
- return new BasicAttributeSensor<T>(type, name, description, persistence);
- }
- }
-
- public static <T> AttributeSensor<T> newSensor(Class<T> type, String name) {
- return new BasicAttributeSensor<T>(type, name);
- }
-
- public static <T> AttributeSensor<T> newSensor(Class<T> type, String name, String description) {
- return new BasicAttributeSensor<T>(type, name, description);
- }
-
- public static <T> AttributeSensor<T> newSensor(TypeToken<T> type, String name, String description) {
- return new BasicAttributeSensor<T>(type, name, description);
- }
-
- public static AttributeSensor<String> newStringSensor(String name) {
- return newSensor(String.class, name);
- }
-
- public static AttributeSensor<String> newStringSensor(String name, String description) {
- return newSensor(String.class, name, description);
- }
-
- public static AttributeSensor<Integer> newIntegerSensor(String name) {
- return newSensor(Integer.class, name);
- }
-
- public static AttributeSensor<Integer> newIntegerSensor(String name, String description) {
- return newSensor(Integer.class, name, description);
- }
-
- public static AttributeSensor<Long> newLongSensor(String name) {
- return newSensor(Long.class, name);
- }
-
- public static AttributeSensor<Long> newLongSensor(String name, String description) {
- return newSensor(Long.class, name, description);
- }
-
- public static AttributeSensor<Double> newDoubleSensor(String name) {
- return newSensor(Double.class, name);
- }
-
- public static AttributeSensor<Double> newDoubleSensor(String name, String description) {
- return newSensor(Double.class, name, description);
- }
-
- public static AttributeSensor<Boolean> newBooleanSensor(String name) {
- return newSensor(Boolean.class, name);
- }
-
- public static AttributeSensor<Boolean> newBooleanSensor(String name, String description) {
- return newSensor(Boolean.class, name, description);
- }
-
- // Extensions to sensors
-
- public static <T> AttributeSensor<T> newSensorRenamed(String newName, AttributeSensor<T> sensor) {
- return new BasicAttributeSensor<T>(sensor.getTypeToken(), newName, sensor.getDescription());
- }
-
- public static <T> AttributeSensor<T> newSensorWithPrefix(String prefix, AttributeSensor<T> sensor) {
- return newSensorRenamed(prefix+sensor.getName(), sensor);
- }
-
- // Display hints for common utility objects
-
- static {
- RendererHints.register(Duration.class, RendererHints.displayValue(Time.fromDurationToTimeStringRounded()));
- RendererHints.register(HostAndPort.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
- RendererHints.register(UserAndHostAndPort.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
- RendererHints.register(InetAddress.class, RendererHints.displayValue(new Function<InetAddress,String>() {
- @Override
- public String apply(@Nullable InetAddress input) {
- return input == null ? null : input.getHostAddress();
- }
- }));
-
- RendererHints.register(URL.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
- RendererHints.register(URL.class, RendererHints.openWithUrl(StringFunctions.toStringFunction()));
- RendererHints.register(URI.class, RendererHints.displayValue(StringFunctions.toStringFunction()));
- RendererHints.register(URI.class, RendererHints.openWithUrl(StringFunctions.toStringFunction()));
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java b/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
deleted file mode 100644
index 0c3a00f..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/StaticSensor.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.effector.AddSensor;
-import org.apache.brooklyn.sensor.enricher.Propagator;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.core.task.Tasks;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Supplier;
-
-/**
- * Provides an initializer/feed which simply sets a given value.
- * <p>
- * {@link Task}/{@link Supplier} values are resolved when written,
- * unlike config values which are resolved on each read.
- * <p>
- * This supports a {@link StaticSensor#SENSOR_PERIOD}
- * which can be useful if the supplied value is such a function.
- * However when the source is another sensor,
- * consider using {@link Propagator} which listens for changes instead. */
-public class StaticSensor<T> extends AddSensor<T> {
-
- private static final Logger log = LoggerFactory.getLogger(StaticSensor.class);
-
- public static final ConfigKey<Object> STATIC_VALUE = ConfigKeys.newConfigKey(Object.class, "static.value");
-
- private final Object value;
-
- public StaticSensor(ConfigBag params) {
- super(params);
- value = params.get(STATIC_VALUE);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- public void apply(EntityLocal entity) {
- super.apply(entity);
-
- Maybe<T> v = Tasks.resolving(value).as((Class<T>)sensor.getType()).timeout(ValueResolver.PRETTY_QUICK_WAIT).getMaybe();
- if (v.isPresent()) {
- log.debug(this+" setting sensor "+sensor+" to "+v.get());
- entity.setAttribute(sensor, v.get());
- } else {
- log.debug(this+" not setting sensor "+sensor+"; cannot resolve "+value);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/core/TemplatedStringAttributeSensorAndConfigKey.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/core/TemplatedStringAttributeSensorAndConfigKey.java b/core/src/main/java/org/apache/brooklyn/sensor/core/TemplatedStringAttributeSensorAndConfigKey.java
deleted file mode 100644
index 27367c3..0000000
--- a/core/src/main/java/org/apache/brooklyn/sensor/core/TemplatedStringAttributeSensorAndConfigKey.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.util.core.text.TemplateProcessor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableMap;
-
-/**
- * A {@link ConfigKey} which takes a freemarker-templated string,
- * and whose value is converted to a sensor by processing the template
- * with access to config and methods on the entity where it is set.
- */
-public class TemplatedStringAttributeSensorAndConfigKey extends BasicAttributeSensorAndConfigKey<String> {
- private static final long serialVersionUID = 4680651022807491321L;
-
- public static final Logger LOG = LoggerFactory.getLogger(TemplatedStringAttributeSensorAndConfigKey.class);
-
- public TemplatedStringAttributeSensorAndConfigKey(String name) {
- this(name, name, null);
- }
- public TemplatedStringAttributeSensorAndConfigKey(String name, String description) {
- this(name, description, null);
- }
- public TemplatedStringAttributeSensorAndConfigKey(String name, String description, String defaultValue) {
- super(String.class, name, description, defaultValue);
- }
- public TemplatedStringAttributeSensorAndConfigKey(TemplatedStringAttributeSensorAndConfigKey orig, String defaultValue) {
- super(orig, defaultValue);
- }
-
- @Override
- protected String convertConfigToSensor(String value, Entity entity) {
- if (value == null) return null;
- return TemplateProcessor.processTemplateContents(value, (EntityInternal)entity, ImmutableMap.<String,Object>of());
- }
-
- @Override
- protected String convertConfigToSensor(String value, ManagementContext managementContext) {
- if (value == null) return null;
- return TemplateProcessor.processTemplateContents(value, (ManagementContextInternal)managementContext, ImmutableMap.<String,Object>of());
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
index 09cf404..1ff7938 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTransformer.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
index c022da7..f66004c 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AbstractTypeTransformingEnricher.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
index 067c568..997f974 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/enricher/AddingEnricher.java
@@ -23,7 +23,7 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
/**
* enricher which adds multiple sensors on an entity to produce a new sensor
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
index 583ee7d..823b8b7 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Combiner.java
@@ -35,7 +35,7 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.slf4j.Logger;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
index 4ab4fe9..c6d9329 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/enricher/Joiner.java
@@ -28,7 +28,7 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.text.StringEscapes;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
index b3c156a..7938cc4 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/ConfigToAttributes.java
@@ -21,8 +21,8 @@ package org.apache.brooklyn.sensor.feed;
import org.apache.brooklyn.api.entity.EntityLocal;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.TemplatedStringAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
/** Simple config adapter for setting {@link AttributeSensorAndConfigKey} sensor values from the config value or config default */
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
index d3f7597..32ea2ab 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/FeedConfig.java
@@ -22,7 +22,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.guava.Functionals;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
index 95aba9f..e9767d9 100644
--- a/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/core/src/main/java/org/apache/brooklyn/sensor/feed/windows/WindowsPerformanceCounterFeed.java
@@ -42,10 +42,10 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.EffectorTasks;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.AbstractFeed;
import org.apache.brooklyn.sensor.feed.PollHandler;
import org.apache.brooklyn.sensor.feed.Poller;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java b/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
index 51b0456..ec49de7 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/flags/TypeCoercions.java
@@ -50,7 +50,7 @@ import org.apache.brooklyn.core.entity.factory.ConfigurableEntityFactory;
import org.apache.brooklyn.core.entity.factory.ConfigurableEntityFactoryFromEntityFactory;
import org.apache.brooklyn.core.internal.BrooklynInitialization;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.JavaGroovyEquivalents;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.collections.QuorumCheck;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java b/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
index afa2f71..58efcd4 100644
--- a/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
+++ b/core/src/main/java/org/apache/brooklyn/util/core/text/TemplateProcessor.java
@@ -34,8 +34,8 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy b/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
index e57c8cb..8516df5 100644
--- a/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
+++ b/core/src/test/java/org/apache/brooklyn/core/config/MapListAndOtherStructuredConfigKeyTest.groovy
@@ -33,7 +33,7 @@ import org.apache.brooklyn.core.test.entity.TestApplication
import org.apache.brooklyn.core.test.entity.TestEntity
import org.apache.brooklyn.core.entity.Entities
import org.apache.brooklyn.core.location.SimulatedLocation
-import org.apache.brooklyn.sensor.core.DependentConfiguration
+import org.apache.brooklyn.core.sensor.DependentConfiguration
import org.apache.brooklyn.util.collections.MutableMap
import org.apache.brooklyn.util.core.task.DeferredSupplier
import org.apache.brooklyn.util.exceptions.Exceptions
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/AttributeMapTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/AttributeMapTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/AttributeMapTest.java
index 565b34b..21529c8 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/AttributeMapTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/AttributeMapTest.java
@@ -32,10 +32,10 @@ import java.util.concurrent.Future;
import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.AttributeMap;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.sensor.core.AttributeMap;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.guava.Maybe;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/AttributeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/AttributeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/AttributeTest.java
index 614a275..68fe527 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/AttributeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/AttributeTest.java
@@ -22,8 +22,8 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/ConfigEntityInheritanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/ConfigEntityInheritanceTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/ConfigEntityInheritanceTest.java
index 2a8ae20..afcd340 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/ConfigEntityInheritanceTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/ConfigEntityInheritanceTest.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.internal.ConfigMapTest.MyOtherEntity;
+import org.apache.brooklyn.core.sensor.AttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.IntegerAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.IntegerAttributeSensorAndConfigKey;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/DependentConfigurationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/DependentConfigurationTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/DependentConfigurationTest.java
index 2c681f3..45fac8f 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/DependentConfigurationTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/DependentConfigurationTest.java
@@ -35,9 +35,9 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableList;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
index 6e2bd89..599d28c 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntitySubscriptionTest.java
@@ -25,10 +25,10 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
import org.apache.brooklyn.test.Asserts;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
index cead05a..5851c35 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/EntityTypeTest.java
@@ -51,11 +51,11 @@ import org.apache.brooklyn.core.effector.MethodEffector;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableSet;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
index a217514..5490868 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/hello/HelloEntity.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.core.annotation.Effector;
import org.apache.brooklyn.core.annotation.EffectorParam;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.effector.MethodEffector;
+import org.apache.brooklyn.core.sensor.BasicSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.group.AbstractGroup;
-import org.apache.brooklyn.sensor.core.BasicSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
@ImplementedBy(HelloEntityImpl.class)
public interface HelloEntity extends AbstractGroup {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/hello/LocalEntitiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/hello/LocalEntitiesTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/hello/LocalEntitiesTest.java
index 9fef5ba..28ee8c1 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/hello/LocalEntitiesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/hello/LocalEntitiesTest.java
@@ -18,8 +18,8 @@
*/
package org.apache.brooklyn.core.entity.hello;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.attributeWhenReady;
-import static org.apache.brooklyn.sensor.core.DependentConfiguration.transform;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.attributeWhenReady;
+import static org.apache.brooklyn.core.sensor.DependentConfiguration.transform;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/internal/ConfigMapTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/internal/ConfigMapTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/internal/ConfigMapTest.java
index 448ca07..0a0b3a2 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/internal/ConfigMapTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/internal/ConfigMapTest.java
@@ -41,8 +41,8 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.ConfigPredicates;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey.IntegerAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey.IntegerAttributeSensorAndConfigKey;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.BasicTask;
import org.apache.brooklyn.util.core.task.DeferredSupplier;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageLegacyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageLegacyTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageLegacyTest.java
index dcd40ee..11e3ca6 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageLegacyTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageLegacyTest.java
@@ -25,7 +25,6 @@ import static org.testng.Assert.fail;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.time.Time;
import org.testng.annotations.Test;
@@ -33,6 +32,7 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageTest.java
index e5b6299..9af2919 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/internal/EntityConfigMapUsageTest.java
@@ -32,9 +32,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogicTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogicTest.java b/core/src/test/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogicTest.java
index f461e4b..33d5e1c 100644
--- a/core/src/test/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogicTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/entity/lifecycle/ServiceStateLogicTest.java
@@ -32,11 +32,11 @@ import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ComputeServiceIndicatorsFromChildrenAndMembers;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceNotUpLogic;
import org.apache.brooklyn.core.entity.lifecycle.ServiceStateLogic.ServiceProblemsLogic;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.QuorumCheck.QuorumChecks;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java b/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
index 6b64cc1..a5b4294 100644
--- a/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
+++ b/core/src/test/java/org/apache/brooklyn/core/location/TestPortSupplierLocation.java
@@ -22,9 +22,9 @@ import static org.testng.Assert.assertEquals;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.location.PortRanges;
+import org.apache.brooklyn.core.sensor.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/location/access/PortForwardManagerRebindTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/location/access/PortForwardManagerRebindTest.java b/core/src/test/java/org/apache/brooklyn/core/location/access/PortForwardManagerRebindTest.java
index f123342..f14c4a3 100644
--- a/core/src/test/java/org/apache/brooklyn/core/location/access/PortForwardManagerRebindTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/location/access/PortForwardManagerRebindTest.java
@@ -37,9 +37,9 @@ import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
import org.apache.brooklyn.core.mgmt.rebind.RebindOptions;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
import org.apache.brooklyn.core.mgmt.rebind.RebindTestUtils;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.text.Identifiers;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/EntityExecutionManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/EntityExecutionManagerTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/EntityExecutionManagerTest.java
index d69294b..2bc73cb 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/EntityExecutionManagerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/internal/EntityExecutionManagerTest.java
@@ -43,10 +43,10 @@ import org.apache.brooklyn.core.mgmt.BrooklynTaskTags.WrappedEntity;
import org.apache.brooklyn.core.mgmt.internal.BrooklynGarbageCollector;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.BasicExecutionManager;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogEntityTest.java
index d437e92..4d03e05 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindCatalogEntityTest.java
@@ -42,7 +42,7 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.test.support.TestResourceUnavailableException;
import org.apache.brooklyn.util.core.javalang.UrlClassLoader;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
index 4afb361..c4d295a 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEnricherTest.java
@@ -38,11 +38,11 @@ import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityPredicates;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.entity.group.DynamicCluster;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.AbstractEnricher;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.test.Asserts;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityTest.java
index a427995..f912e55 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindEntityTest.java
@@ -62,15 +62,15 @@ import org.apache.brooklyn.core.entity.trait.Startable;
import org.apache.brooklyn.core.location.LocationConfigTest.MyLocation;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.rebind.BasicEntityRebindSupport;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl;
import org.apache.brooklyn.entity.group.AbstractGroupImpl;
import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
index cdfd87d..f0c6551 100644
--- a/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/mgmt/rebind/RebindFeedTest.java
@@ -32,9 +32,9 @@ import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.internal.BrooklynGarbageCollector;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.core.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicyConfigTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicyConfigTest.java b/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicyConfigTest.java
index cd07bc5..0b5c877 100644
--- a/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicyConfigTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicyConfigTest.java
@@ -27,9 +27,9 @@ import java.util.concurrent.CountDownLatch;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.policy.basic.BasicPolicyTest.MyPolicy;
+import org.apache.brooklyn.core.sensor.DependentConfiguration;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.DependentConfiguration;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicySubscriptionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicySubscriptionTest.java b/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicySubscriptionTest.java
index 6ed6918..ed4a9c0 100644
--- a/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicySubscriptionTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/policy/basic/PolicySubscriptionTest.java
@@ -25,9 +25,9 @@ import org.apache.brooklyn.api.mgmt.SubscriptionHandle;
import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
import org.apache.brooklyn.core.location.SimulatedLocation;
import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
import org.apache.brooklyn.test.Asserts;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/sensor/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/sensor/HttpRequestSensorTest.java b/core/src/test/java/org/apache/brooklyn/core/sensor/HttpRequestSensorTest.java
new file mode 100644
index 0000000..4715594
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/sensor/HttpRequestSensorTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.HttpRequestSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.TestHttpRequestHandler;
+import org.apache.brooklyn.core.test.TestHttpServer;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class HttpRequestSensorTest {
+ final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString");
+ final static String TARGET_TYPE = "java.lang.String";
+
+ private TestApplication app;
+ private EntityLocal entity;
+
+ private TestHttpServer server;
+ private String serverUrl;
+
+ @BeforeClass(alwaysRun=true)
+ public void setUp() throws Exception {
+ server = new TestHttpServer()
+ .handler("/myKey/myValue", new TestHttpRequestHandler().header("Content-Type", "application/json").response("{\"myKey\":\"myValue\"}"))
+ .start();
+ serverUrl = server.getUrl();
+
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+ .location(app.newLocalhostProvisioningLocation().obtain()));
+ app.start(ImmutableList.<Location>of());
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ server.stop();
+ }
+
+ @Test
+ public void testHttpSensor() throws Exception {
+ HttpRequestSensor<Integer> sensor = new HttpRequestSensor<Integer>(ConfigBag.newInstance()
+ .configure(HttpRequestSensor.SENSOR_PERIOD, Duration.millis(100))
+ .configure(HttpRequestSensor.SENSOR_NAME, SENSOR_STRING.getName())
+ .configure(HttpRequestSensor.SENSOR_TYPE, TARGET_TYPE)
+ .configure(HttpRequestSensor.JSON_PATH, "$.myKey")
+ .configure(HttpRequestSensor.SENSOR_URI, serverUrl + "/myKey/myValue"));
+ sensor.apply(entity);
+ entity.setAttribute(Attributes.SERVICE_UP, true);
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_STRING, "myValue");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/sensor/StaticSensorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/sensor/StaticSensorTest.java b/core/src/test/java/org/apache/brooklyn/core/sensor/StaticSensorTest.java
new file mode 100644
index 0000000..1e6efb1
--- /dev/null
+++ b/core/src/test/java/org/apache/brooklyn/core/sensor/StaticSensorTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.core.sensor;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.sensor.StaticSensor;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.entity.stock.BasicEntity;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableMap;
+
+public class StaticSensorTest extends BrooklynAppUnitTestSupport {
+
+ @Test
+ public void testAddsStaticSensorOfTypeString() {
+ BasicEntity entity = app.createAndManageChild(EntitySpec.create(BasicEntity.class)
+ .addInitializer(new StaticSensor<String>(ConfigBag.newInstance(ImmutableMap.of(
+ StaticSensor.SENSOR_NAME, "myname",
+ StaticSensor.SENSOR_TYPE, String.class.getName(),
+ StaticSensor.STATIC_VALUE, "myval")))));
+
+ EntityTestUtils.assertAttributeEquals(entity, Sensors.newSensor(String.class, "myname"), "myval");
+ }
+
+ @Test
+ public void testAddsStaticSensorOfTypeInteger() {
+ BasicEntity entity = app.createAndManageChild(EntitySpec.create(BasicEntity.class)
+ .addInitializer(new StaticSensor<Integer>(ConfigBag.newInstance(ImmutableMap.of(
+ StaticSensor.SENSOR_NAME, "myname",
+ StaticSensor.SENSOR_TYPE, Integer.class.getName(),
+ StaticSensor.STATIC_VALUE, "1")))));
+
+ EntityTestUtils.assertAttributeEquals(entity, Sensors.newSensor(Integer.class, "myname"), 1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/test/entity/TestApplication.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestApplication.java b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestApplication.java
index 2521b1f..974d4e6 100644
--- a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestApplication.java
+++ b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestApplication.java
@@ -29,8 +29,8 @@ import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.StartableApplication;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-import org.apache.brooklyn.sensor.core.Sensors;
/**
* Mock application for testing.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
index 8c185a0..be8ad3d 100644
--- a/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
+++ b/core/src/test/java/org/apache/brooklyn/core/test/entity/TestEntity.java
@@ -41,8 +41,8 @@ import org.apache.brooklyn.core.entity.Attributes;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.entity.trait.Startable;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.testng.collections.Lists;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/entity/group/DynamicGroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicGroupTest.java b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicGroupTest.java
index 7c43835..1b7ec97 100644
--- a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicGroupTest.java
+++ b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicGroupTest.java
@@ -42,12 +42,12 @@ import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.AbstractEntity;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityPredicates;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.AbstractGroup;
import org.apache.brooklyn.entity.group.DynamicGroup;
import org.apache.brooklyn.entity.group.DynamicGroupImpl;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/entity/group/DynamicMultiGroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicMultiGroupTest.java b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicMultiGroupTest.java
index f783b49..d0d1235 100644
--- a/core/src/test/java/org/apache/brooklyn/entity/group/DynamicMultiGroupTest.java
+++ b/core/src/test/java/org/apache/brooklyn/entity/group/DynamicMultiGroupTest.java
@@ -37,12 +37,12 @@ import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.BasicGroup;
import org.apache.brooklyn.entity.group.DynamicMultiGroup;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/entity/stock/DataEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/entity/stock/DataEntityTest.java b/core/src/test/java/org/apache/brooklyn/entity/stock/DataEntityTest.java
index f2c4a23..5d19d43 100644
--- a/core/src/test/java/org/apache/brooklyn/entity/stock/DataEntityTest.java
+++ b/core/src/test/java/org/apache/brooklyn/entity/stock/DataEntityTest.java
@@ -30,10 +30,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.entity.stock.DataEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/core/HttpRequestSensorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/core/HttpRequestSensorTest.java b/core/src/test/java/org/apache/brooklyn/sensor/core/HttpRequestSensorTest.java
deleted file mode 100644
index 1ac4432..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/core/HttpRequestSensorTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.test.TestHttpRequestHandler;
-import org.apache.brooklyn.core.test.TestHttpServer;
-import org.apache.brooklyn.core.test.entity.TestApplication;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.HttpRequestSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.time.Duration;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-
-public class HttpRequestSensorTest {
- final static AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString");
- final static String TARGET_TYPE = "java.lang.String";
-
- private TestApplication app;
- private EntityLocal entity;
-
- private TestHttpServer server;
- private String serverUrl;
-
- @BeforeClass(alwaysRun=true)
- public void setUp() throws Exception {
- server = new TestHttpServer()
- .handler("/myKey/myValue", new TestHttpRequestHandler().header("Content-Type", "application/json").response("{\"myKey\":\"myValue\"}"))
- .start();
- serverUrl = server.getUrl();
-
- app = TestApplication.Factory.newManagedInstanceForTests();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
- .location(app.newLocalhostProvisioningLocation().obtain()));
- app.start(ImmutableList.<Location>of());
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (app != null) Entities.destroyAll(app.getManagementContext());
- server.stop();
- }
-
- @Test
- public void testHttpSensor() throws Exception {
- HttpRequestSensor<Integer> sensor = new HttpRequestSensor<Integer>(ConfigBag.newInstance()
- .configure(HttpRequestSensor.SENSOR_PERIOD, Duration.millis(100))
- .configure(HttpRequestSensor.SENSOR_NAME, SENSOR_STRING.getName())
- .configure(HttpRequestSensor.SENSOR_TYPE, TARGET_TYPE)
- .configure(HttpRequestSensor.JSON_PATH, "$.myKey")
- .configure(HttpRequestSensor.SENSOR_URI, serverUrl + "/myKey/myValue"));
- sensor.apply(entity);
- entity.setAttribute(Attributes.SERVICE_UP, true);
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, SENSOR_STRING, "myValue");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/core/StaticSensorTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/core/StaticSensorTest.java b/core/src/test/java/org/apache/brooklyn/sensor/core/StaticSensorTest.java
deleted file mode 100644
index a62d985..0000000
--- a/core/src/test/java/org/apache/brooklyn/sensor/core/StaticSensorTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.sensor.core;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
-import org.apache.brooklyn.sensor.core.StaticSensor;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableMap;
-
-public class StaticSensorTest extends BrooklynAppUnitTestSupport {
-
- @Test
- public void testAddsStaticSensorOfTypeString() {
- BasicEntity entity = app.createAndManageChild(EntitySpec.create(BasicEntity.class)
- .addInitializer(new StaticSensor<String>(ConfigBag.newInstance(ImmutableMap.of(
- StaticSensor.SENSOR_NAME, "myname",
- StaticSensor.SENSOR_TYPE, String.class.getName(),
- StaticSensor.STATIC_VALUE, "myval")))));
-
- EntityTestUtils.assertAttributeEquals(entity, Sensors.newSensor(String.class, "myname"), "myval");
- }
-
- @Test
- public void testAddsStaticSensorOfTypeInteger() {
- BasicEntity entity = app.createAndManageChild(EntitySpec.create(BasicEntity.class)
- .addInitializer(new StaticSensor<Integer>(ConfigBag.newInstance(ImmutableMap.of(
- StaticSensor.SENSOR_NAME, "myname",
- StaticSensor.SENSOR_TYPE, Integer.class.getName(),
- StaticSensor.STATIC_VALUE, "1")))));
-
- EntityTestUtils.assertAttributeEquals(entity, Sensors.newSensor(Integer.class, "myname"), 1);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
index 0700c91..b35c329 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
@@ -27,7 +27,7 @@ import org.apache.brooklyn.core.test.entity.TestEntity
import org.apache.brooklyn.core.entity.Entities
import org.apache.brooklyn.entity.group.BasicGroup
import org.apache.brooklyn.core.location.SimulatedLocation
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
import org.apache.brooklyn.test.TestUtils
import org.slf4j.Logger
import org.slf4j.LoggerFactory
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
index 05e0fe3..30737b7 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/CustomAggregatingEnricherTest.java
@@ -26,10 +26,10 @@ import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.collections.MutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
index 1307bb5..ff76342 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/EnrichersTest.java
@@ -29,10 +29,10 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityAdjuncts;
import org.apache.brooklyn.core.entity.RecordingSensorEventListener;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.entity.group.BasicGroup;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
index 589c0fb..9b55006 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherDeprecatedTest.java
@@ -24,9 +24,9 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.SensorPropagatingEnricher;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.test.EntityTestUtils;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
index 241e581..82067c4 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/SensorPropagatingEnricherTest.java
@@ -25,10 +25,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.sensor.BasicNotificationSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.sensor.enricher.Propagator;
import org.apache.brooklyn.test.Asserts;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy b/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
index 2883a05..9db0d37 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherDeprecatedTest.groovy
@@ -26,7 +26,7 @@ import org.apache.brooklyn.core.test.entity.TestApplication
import org.apache.brooklyn.core.test.entity.TestEntity
import org.apache.brooklyn.core.entity.Entities
import org.apache.brooklyn.core.location.SimulatedLocation
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor
import org.apache.brooklyn.test.TestUtils
import org.apache.brooklyn.util.collections.MutableMap
import org.slf4j.Logger
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
index 70d5af5..d020a25 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/TransformingEnricherTest.java
@@ -21,9 +21,9 @@ package org.apache.brooklyn.sensor.enricher;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.location.SimulatedLocation;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.test.EntityTestUtils;
import org.apache.brooklyn.util.math.MathFunctions;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
index 96644a6..e7fbcd6 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlRollingTimeWindowMeanEnricherTest.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
import org.apache.brooklyn.sensor.enricher.YamlRollingTimeWindowMeanEnricher;
import org.apache.brooklyn.sensor.enricher.YamlTimeWeightedDeltaEnricher;
import org.apache.brooklyn.sensor.enricher.YamlRollingTimeWindowMeanEnricher.ConfidenceQualifiedNumber;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java b/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
index 140ed15..5b98168 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/enricher/YamlTimeWeightedDeltaEnricherTest.java
@@ -26,9 +26,9 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.EnricherSpec;
import org.apache.brooklyn.core.entity.AbstractApplication;
import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
+import org.apache.brooklyn.core.sensor.BasicSensorEvent;
import org.apache.brooklyn.entity.stock.BasicEntity;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
-import org.apache.brooklyn.sensor.core.BasicSensorEvent;
import org.apache.brooklyn.sensor.enricher.YamlTimeWeightedDeltaEnricher;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
index 2dd5bc4..b82aecf 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/ConfigToAttributesTest.java
@@ -24,10 +24,10 @@ import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.core.sensor.BasicAttributeSensorAndConfigKey;
+import org.apache.brooklyn.core.sensor.TemplatedStringAttributeSensorAndConfigKey;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
-import org.apache.brooklyn.sensor.core.TemplatedStringAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2a78e273/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java b/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
index fc1dc1d..71b44b8 100644
--- a/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
+++ b/core/src/test/java/org/apache/brooklyn/sensor/feed/function/FunctionFeedTest.java
@@ -38,9 +38,9 @@ import org.apache.brooklyn.api.sensor.SensorEvent;
import org.apache.brooklyn.api.sensor.SensorEventListener;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.entity.EntityInternal.FeedSupport;
+import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.sensor.core.Sensors;
import org.apache.brooklyn.sensor.feed.function.FunctionFeed;
import org.apache.brooklyn.sensor.feed.function.FunctionFeedTest;
import org.apache.brooklyn.sensor.feed.function.FunctionPollConfig;