Adds BrooklynDslCommon 'Functions', and adds string regexReplacement
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0779626f Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0779626f Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0779626f Branch: refs/heads/master Commit: 0779626f0a77515b8d30a2d6f723737ae656f4af Parents: c76db10 Author: Martin Harris <[email protected]> Authored: Mon Sep 21 10:31:56 2015 +0100 Committer: Martin Harris <[email protected]> Committed: Thu Oct 15 15:40:41 2015 +0100 ---------------------------------------------------------------------- .../core/sensor/DependentConfiguration.java | 67 +++++++++++---- .../brooklyn/enricher/stock/Transformer.java | 4 - .../core/entity/DependentConfigurationTest.java | 29 ++++++- .../spi/dsl/BrooklynDslInterpreter.java | 9 +- .../spi/dsl/methods/BrooklynDslCommon.java | 87 ++++++++++++++------ 5 files changed, 148 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0779626f/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 index 2bc5b6e..1229990 100644 --- a/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java +++ b/core/src/main/java/org/apache/brooklyn/core/sensor/DependentConfiguration.java @@ -483,9 +483,19 @@ public class DependentConfiguration { taskArgs); } + public static Task<String> regexReplacement(Object source, Object pattern, Object replacement) { + List<TaskAdaptable<Object>> taskArgs = getTaskAdaptable(source, pattern, replacement); + Function<List<Object>, String> transformer = new RegexTransformerString(source, pattern, replacement); + return transformMultiple( + MutableMap.of("displayName", String.format("creating regex replacement function (%s:%s)", pattern, replacement)), + transformer, + taskArgs + ); + } + public static Task<Function<String, String>> regexReplacement(Object pattern, Object replacement) { List<TaskAdaptable<Object>> taskArgs = getTaskAdaptable(pattern, replacement); - Function<List<Object>, Function<String, String>> transformer = new RegexTransformer(pattern, replacement); + Function<List<Object>, Function<String, String>> transformer = new RegexTransformerFunction(pattern, replacement); return transformMultiple( MutableMap.of("displayName", String.format("creating regex replacement function (%s:%s)", pattern, replacement)), transformer, @@ -505,12 +515,35 @@ public class DependentConfiguration { return taskArgs; } - public static class RegexTransformer implements Function<List<Object>, Function<String, String>> { + public static class RegexTransformerString implements Function<List<Object>, String> { + private final Object source; private final Object pattern; private final Object replacement; - public RegexTransformer(Object pattern, Object replacement){ + public RegexTransformerString(Object source, Object pattern, Object replacement){ + this.source = source; + this.pattern = pattern; + this.replacement = replacement; + } + + @Nullable + @Override + public String apply(@Nullable List<Object> input) { + Iterator<?> taskArgsIterator = input.iterator(); + String resolvedSource = resolveArgument(source, taskArgsIterator); + String resolvedPattern = resolveArgument(pattern, taskArgsIterator); + String resolvedReplacement = resolveArgument(replacement, taskArgsIterator); + return new RegexReplacer(resolvedPattern, resolvedReplacement).apply(resolvedSource); + } + } + + public static class RegexTransformerFunction implements Function<List<Object>, Function<String, String>> { + + private final Object pattern; + private final Object replacement; + + public RegexTransformerFunction(Object pattern, Object replacement){ this.pattern = pattern; this.replacement = replacement; } @@ -521,18 +554,24 @@ public class DependentConfiguration { return new RegexReplacer(resolveArgument(pattern, taskArgsIterator), resolveArgument(replacement, taskArgsIterator)); } - private String resolveArgument(Object argument, Iterator<?> taskArgsIterator) { - Object resolvedArgument; - if (argument instanceof TaskAdaptable || argument instanceof TaskFactory) { - resolvedArgument = taskArgsIterator.next(); - } else if (argument instanceof DeferredSupplier) { - resolvedArgument = ((DeferredSupplier<?>) argument).get(); - } else { - resolvedArgument = argument; - } - return String.valueOf(resolvedArgument); - } + } + /** + * Resolves the argument as follows: + * + * If the argument is a DeferredSupplier, we will block and wait for it to resolve. If the argument is TaskAdaptable or TaskFactory, + * we will assume that the resolved task has been queued on the {@code taskArgsIterator}, otherwise the argument has already been resolved. + */ + private static String resolveArgument(Object argument, Iterator<?> taskArgsIterator) { + Object resolvedArgument; + if (argument instanceof TaskAdaptable) { + resolvedArgument = taskArgsIterator.next(); + } else if (argument instanceof DeferredSupplier) { + resolvedArgument = ((DeferredSupplier<?>) argument).get(); + } else { + resolvedArgument = argument; + } + return String.valueOf(resolvedArgument); } public static class RegexReplacer implements Function<String, String> { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0779626f/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 index 815b07d..997a12e 100644 --- a/core/src/main/java/org/apache/brooklyn/enricher/stock/Transformer.java +++ b/core/src/main/java/org/apache/brooklyn/enricher/stock/Transformer.java @@ -44,10 +44,6 @@ public class Transformer<T,U> extends AbstractTransformer<T,U> { 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() { - System.out.println("Creating"); - } - /** returns a function for transformation, for immediate use only (not for caching, as it may change) */ @Override @SuppressWarnings("unchecked") http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0779626f/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 43c37e7..17cc6fd 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 @@ -113,7 +113,7 @@ public class DependentConfigurationTest extends BrooklynAppUnitTestSupport { } @Test - public void testRegexReplacementWithStrings() throws Exception { + public void testRegexReplacementFunctionWithStrings() throws Exception { Task<Function<String, String>> task = DependentConfiguration.regexReplacement("foo", "bar"); submit(task); Function<String, String> regexReplacer = task.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); @@ -121,9 +121,8 @@ public class DependentConfigurationTest extends BrooklynAppUnitTestSupport { } @Test - public void testRegexReplacementWithAttributeWhenReady() throws Exception { + public void testRegexReplacementFunctionWithAttributeWhenReady() throws Exception { AttributeSensor<Object> replacementSensor = Sensors.newSensor(Object.class, "test.replacement"); - DependentConfiguration.attributeWhenReady(entity, TestEntity.NAME); Task<String> pattern = DependentConfiguration.attributeWhenReady(entity, TestEntity.NAME); Task<Object> replacement = DependentConfiguration.attributeWhenReady(entity, replacementSensor); Task<Function<String, String>> task = DependentConfiguration.regexReplacement(pattern, replacement); @@ -135,6 +134,30 @@ public class DependentConfigurationTest extends BrooklynAppUnitTestSupport { } @Test + public void testRegexReplacementWithStrings() throws Exception { + Task<String> task = DependentConfiguration.regexReplacement("somefootext", "foo", "bar"); + submit(task); + String result = task.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + Assert.assertEquals(result, "somebartext"); + } + + @Test + public void testRegexReplacementWithAttributeWhenReady() throws Exception { + AttributeSensor<String> sourceSensor = Sensors.newStringSensor("test.source"); + AttributeSensor<String> replacementSensor = Sensors.newSensor(String.class, "test.replacement"); + Task<String> source = DependentConfiguration.attributeWhenReady(entity, sourceSensor); + Task<String> pattern = DependentConfiguration.attributeWhenReady(entity, TestEntity.NAME); + Task<String> replacement = DependentConfiguration.attributeWhenReady(entity, replacementSensor); + Task<String> task = DependentConfiguration.regexReplacement(source, pattern, replacement); + submit(task); + entity.sensors().set(sourceSensor, "somefootext"); + entity.sensors().set(TestEntity.NAME, "foo"); + entity.sensors().set(replacementSensor, "bar"); + String result = task.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); + Assert.assertEquals(result, "somebartext"); + } + + @Test public void testAttributeWhenReady() throws Exception { final Task<String> t = submit(DependentConfiguration.attributeWhenReady(entity, TestEntity.NAME)); assertNotDoneContinually(t); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0779626f/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java ---------------------------------------------------------------------- diff --git a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java index 2a7649e..f43d33c 100644 --- a/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java +++ b/usage/camp/src/main/java/org/apache/brooklyn/camp/brooklyn/spi/dsl/BrooklynDslInterpreter.java @@ -168,8 +168,15 @@ public class BrooklynDslInterpreter extends PlanInterpreterAdapter { String fn = f.getFunction(); fn = Strings.removeFromStart(fn, "$brooklyn:"); + if (fn.startsWith("function.")) { + // If the function name starts with 'function.', then we look for the function in BrooklynDslCommon.Functions + // As all functions in BrooklynDslCommon.Functions are static, we don't need to worry whether a class + // or an instance was passed into this method + o = BrooklynDslCommon.Functions.class; + fn = Strings.removeFromStart(fn, "function."); + } try { - List<Object> args = new ArrayList<Object>(); + List<Object> args = new ArrayList<>(); for (Object arg: f.getArgs()) { args.add( deepEvaluation ? evaluate(arg, true) : arg ); } http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0779626f/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 5139b06..1a7d20a 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 @@ -18,6 +18,7 @@ */ package org.apache.brooklyn.camp.brooklyn.spi.dsl.methods; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -193,28 +194,11 @@ public class BrooklynDslCommon { } } - - public static Object regexReplacement(final Object pattern, final Object replacement) { - if (DslUtils.resolved(pattern, replacement)) { - return new RegexReplacer(String.valueOf(pattern), String.valueOf(replacement)); + public static Object regexReplacement(final Object source, final Object pattern, final Object replacement) { + if (DslUtils.resolved(Arrays.asList(source, pattern, replacement))) { + return (new Functions.RegexReplacer(String.valueOf(pattern), String.valueOf(replacement))).apply(String.valueOf(source)); } else { - return new DslRegexReplacer(pattern, replacement); - } - } - - public static class RegexReplacer implements Function<String, String> { - private final String pattern; - private final String replacement; - - public RegexReplacer(String pattern, String replacement) { - this.pattern = pattern; - this.replacement = replacement; - } - - @Nullable - @Override - public String apply(@Nullable String s) { - return Strings.replaceAllRegex(s, pattern, replacement); + return new DslRegexReplacement(source, pattern, replacement); } } @@ -248,24 +232,28 @@ public class BrooklynDslCommon { } } - protected static class DslRegexReplacer extends BrooklynDslDeferredSupplier<Function<String, String>> { + + protected static class DslRegexReplacement extends BrooklynDslDeferredSupplier<String> { + + private Object source; private Object pattern; private Object replacement; - public DslRegexReplacer(Object pattern, Object replacement) { + public DslRegexReplacement(Object source, Object pattern, Object replacement) { this.pattern = pattern; this.replacement = replacement; + this.source = source; } @Override - public Task<Function<String, String>> newTask() { - return DependentConfiguration.regexReplacement(pattern, replacement); + public Task<String> newTask() { + return DependentConfiguration.regexReplacement(source, pattern, replacement); } @Override public String toString() { - return String.format("$brooklyn:regexReplace(%s:%s)", pattern, replacement); + return String.format("$brooklyn:regexReplace(%s:%s:%s)",source, pattern, replacement); } } @@ -395,4 +383,51 @@ public class BrooklynDslCommon { } } + public static class Functions { + public static Object regexReplacement(final Object pattern, final Object replacement) { + if (DslUtils.resolved(pattern, replacement)) { + return new RegexReplacer(String.valueOf(pattern), String.valueOf(replacement)); + } else { + return new DslRegexReplacer(pattern, replacement); + } + } + + public static class RegexReplacer implements Function<String, String> { + private final String pattern; + private final String replacement; + + public RegexReplacer(String pattern, String replacement) { + this.pattern = pattern; + this.replacement = replacement; + } + + @Nullable + @Override + public String apply(@Nullable String s) { + return s == null ? null : Strings.replaceAllRegex(s, pattern, replacement); + } + } + + protected static class DslRegexReplacer extends BrooklynDslDeferredSupplier<Function<String, String>> { + + private Object pattern; + private Object replacement; + + public DslRegexReplacer(Object pattern, Object replacement) { + this.pattern = pattern; + this.replacement = replacement; + } + + @Override + public Task<Function<String, String>> newTask() { + return DependentConfiguration.regexReplacement(pattern, replacement); + } + + @Override + public String toString() { + return String.format("$brooklyn:regexReplace(%s:%s)", pattern, replacement); + } + } + } + }
