You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2014/07/18 18:34:10 UTC
[01/13] git commit: fix intermittent issue with apache rat
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master f0b8f296d -> 4fa68908b
fix intermittent issue with apache rat
those files are not always considered binary, but they are not directly used by code
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/261afa87
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/261afa87
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/261afa87
Branch: refs/heads/master
Commit: 261afa87f535efbcfa3b16d3359d5591415617dd
Parents: 6325e50
Author: Andrea Turli <an...@gmail.com>
Authored: Wed Jul 16 17:08:38 2014 +0200
Committer: Andrea Turli <an...@gmail.com>
Committed: Wed Jul 16 17:08:38 2014 +0200
----------------------------------------------------------------------
usage/launcher/src/test/resources/client_cert | Bin 595 -> 0 bytes
usage/launcher/src/test/resources/server_cert | Bin 595 -> 0 bytes
2 files changed, 0 insertions(+), 0 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/261afa87/usage/launcher/src/test/resources/client_cert
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/resources/client_cert b/usage/launcher/src/test/resources/client_cert
deleted file mode 100644
index aea2a07..0000000
Binary files a/usage/launcher/src/test/resources/client_cert and /dev/null differ
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/261afa87/usage/launcher/src/test/resources/server_cert
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/resources/server_cert b/usage/launcher/src/test/resources/server_cert
deleted file mode 100644
index d8a172b..0000000
Binary files a/usage/launcher/src/test/resources/server_cert and /dev/null differ
[09/13] git commit: support effector parameters which are maps
(@sjcorbett just did this also; now this commit simply adds a test for this)
Posted by he...@apache.org.
support effector parameters which are maps (@sjcorbett just did this also; now this commit simply adds a test for this)
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/cefcda3b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/cefcda3b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/cefcda3b
Branch: refs/heads/master
Commit: cefcda3b862fbbc0ff0008daadf988f8c361522a
Parents: 8569120
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 00:39:24 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:26:20 2014 -0400
----------------------------------------------------------------------
.../brooklynnode/BrooklynNodeRestTest.java | 55 +++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cefcda3b/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java b/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
index 2cd97f0..2a3816b 100644
--- a/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
+++ b/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
@@ -1,7 +1,27 @@
+/*
+ * 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 brooklyn.entity.brooklynnode;
import java.net.URI;
+import java.util.concurrent.Callable;
+import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;
@@ -19,12 +39,17 @@ import brooklyn.launcher.camp.SimpleYamlLauncher;
import brooklyn.location.Location;
import brooklyn.management.Task;
import brooklyn.test.EntityTestUtils;
+import brooklyn.test.HttpTestUtils;
import brooklyn.test.entity.TestApplication;
import brooklyn.test.entity.TestEntity;
+import brooklyn.util.collections.Jsonya;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.collections.MutableSet;
import brooklyn.util.config.ConfigBag;
+import brooklyn.util.http.HttpTool;
+import brooklyn.util.http.HttpToolResponse;
import brooklyn.util.net.Urls;
+import brooklyn.util.repeat.Repeater;
import brooklyn.util.time.Duration;
import com.google.common.collect.Iterables;
@@ -40,7 +65,7 @@ public class BrooklynNodeRestTest {
// so feels worth it to have as a unit test
@Test
public void testBrooklynNodeRestDeployAndMirror() {
- SimpleYamlLauncher l = new SimpleYamlLauncherForTests();
+ final SimpleYamlLauncher l = new SimpleYamlLauncherForTests();
try {
TestApplication app = ApplicationBuilder.newManagedApp(TestApplication.class, l.getManagementContext());
@@ -84,6 +109,34 @@ public class BrooklynNodeRestTest {
EntityTestUtils.assertAttributeEqualsEventually(mirror, TestEntity.NAME, "foo");
log.info("Mirror successfully validated");
+ // also try deploying by invoking deploy through json
+ // (catch issues when effector params are map)
+ HttpClient client = HttpTool.httpClientBuilder().build();
+ HttpToolResponse result = HttpTool.httpPost(client, URI.create(Urls.mergePaths(uri.toString(), "/v1/applications/"+app.getId()+"/entities/"+bn.getId()
+ +"/effectors/deployBlueprint")),
+ MutableMap.of(com.google.common.net.HttpHeaders.CONTENT_TYPE, "application/json"),
+ Jsonya.newInstance()
+ .put("blueprintType", TestApplication.class.getName())
+ .put("blueprintConfig", MutableMap.of(TestEntity.CONF_NAME.getName(), "foo"))
+ .toString().getBytes());
+ log.info("Deploy effector invoked, result: "+result);
+ HttpTestUtils.assertHealthyStatusCode( result.getResponseCode() );
+
+ Repeater.create().every(Duration.millis(10)).until(new Callable<Boolean>() {
+ @Override
+ public Boolean call() throws Exception {
+ return l.getManagementContext().getApplications().size() == 3;
+ }
+ }).limitTimeTo(Duration.TEN_SECONDS);
+
+ apps = MutableSet.copyOf( l.getManagementContext().getApplications() );
+ apps.removeAll( MutableSet.of(app, newApp) );
+ Application newApp2 = Iterables.getOnlyElement(apps);
+ Entities.dumpInfo(newApp2);
+
+ EntityTestUtils.assertAttributeEqualsEventually(newApp2, Attributes.SERVICE_UP, true);
+ Assert.assertEquals(newApp2.getConfig(TestEntity.CONF_NAME), "foo");
+
} finally {
l.destroyAll();
}
[05/13] git commit: tidies of Brooklyn node (warnings, logging)
Posted by he...@apache.org.
tidies of Brooklyn node (warnings, logging)
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f94c2ae7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f94c2ae7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f94c2ae7
Branch: refs/heads/master
Commit: f94c2ae7c63b5170899c6c93587e22e709450140
Parents: f0b8f29
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 12:40:58 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:53:52 2014 -0400
----------------------------------------------------------------------
.../BrooklynNodeIntegrationTest.java | 31 +++++++++++++++-----
.../entity/brooklynnode/BrooklynNodeTest.java | 4 ---
2 files changed, 24 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f94c2ae7/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
index fa0fda2..ecc099f 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
@@ -42,7 +42,6 @@ import brooklyn.entity.basic.Entities;
import brooklyn.entity.brooklynnode.BrooklynNode.DeployBlueprintEffector;
import brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.event.feed.http.HttpValueFunctions;
import brooklyn.event.feed.http.JsonFunctions;
import brooklyn.location.Location;
import brooklyn.location.LocationSpec;
@@ -53,8 +52,11 @@ import brooklyn.test.HttpTestUtils;
import brooklyn.test.entity.TestApplication;
import brooklyn.util.collections.MutableMap;
import brooklyn.util.config.ConfigBag;
+import brooklyn.util.guava.Functionals;
import brooklyn.util.http.HttpTool;
import brooklyn.util.http.HttpToolResponse;
+import brooklyn.util.javalang.JavaClassNames;
+import brooklyn.util.os.Os;
import brooklyn.util.text.Strings;
import brooklyn.util.time.Time;
@@ -86,10 +88,10 @@ public class BrooklynNodeIntegrationTest {
@BeforeMethod(alwaysRun=true)
public void setUp() throws Exception {
- pseudoBrooklynPropertiesFile = File.createTempFile("brooklynnode-test", ".properties");
+ pseudoBrooklynPropertiesFile = Os.newTempFile("brooklynnode-test", ".properties");
pseudoBrooklynPropertiesFile.delete();
- pseudoBrooklynCatalogFile = File.createTempFile("brooklynnode-test", ".catalog");
+ pseudoBrooklynCatalogFile = Os.newTempFile("brooklynnode-test", ".catalog");
pseudoBrooklynCatalogFile.delete();
app = ApplicationBuilder.newManagedApp(TestApplication.class);
@@ -109,6 +111,7 @@ public class BrooklynNodeIntegrationTest {
BrooklynNode brooklynNode = app.createAndManageChild(EntitySpec.create(BrooklynNode.class)
.configure(BrooklynNode.WEB_CONSOLE_BIND_ADDRESS, "127.0.0.1"));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
EntityTestUtils.assertAttributeEqualsEventually(brooklynNode, BrooklynNode.SERVICE_UP, true);
@@ -122,6 +125,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.NO_WEB_CONSOLE_AUTHENTICATION, true)
.configure(BrooklynNode.MANAGEMENT_USER, (String)null));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
EntityTestUtils.assertAttributeEqualsEventually(brooklynNode, BrooklynNode.SERVICE_UP, true);
@@ -137,6 +141,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_REMOTE_PATH, pseudoBrooklynPropertiesFile.getAbsolutePath())
.configure(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_CONTENTS, "abc=def"));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(pseudoBrooklynPropertiesFile, Charsets.UTF_8), ImmutableList.of("abc=def"));
}
@@ -148,6 +153,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_REMOTE_PATH, pseudoBrooklynPropertiesFile.getAbsolutePath())
.configure(BrooklynNode.BROOKLYN_LOCAL_PROPERTIES_CONTENTS, "abc=def"));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(pseudoBrooklynPropertiesFile, Charsets.UTF_8), ImmutableList.of("abc=def"));
}
@@ -162,6 +168,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_REMOTE_PATH, pseudoBrooklynPropertiesFile.getAbsolutePath())
.configure(BrooklynNode.BROOKLYN_GLOBAL_PROPERTIES_URI, brooklynPropertiesSourceFile.toURI().toString()));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(pseudoBrooklynPropertiesFile, Charsets.UTF_8), ImmutableList.of("abc=def"));
}
@@ -173,6 +180,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.BROOKLYN_CATALOG_REMOTE_PATH, pseudoBrooklynCatalogFile.getAbsolutePath())
.configure(BrooklynNode.BROOKLYN_CATALOG_CONTENTS, "<catalog/>"));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(pseudoBrooklynCatalogFile, Charsets.UTF_8), ImmutableList.of("<catalog/>"));
}
@@ -187,6 +195,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.BROOKLYN_CATALOG_REMOTE_PATH, pseudoBrooklynCatalogFile.getAbsolutePath())
.configure(BrooklynNode.BROOKLYN_CATALOG_URI, brooklynCatalogSourceFile.toURI().toString()));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(pseudoBrooklynCatalogFile, Charsets.UTF_8), ImmutableList.of("abc=def"));
}
@@ -204,6 +213,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.RUN_DIR, tempDir.getAbsolutePath())
.configure(BrooklynNode.COPY_TO_RUNDIR, ImmutableMap.of(sourceFile.getAbsolutePath(), "${RUN}/myfile.txt")));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(expectedFile, Charsets.UTF_8), ImmutableList.of("abc=def"));
} finally {
@@ -231,6 +241,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.CLASSPATH, ImmutableList.of(classpathEntry1.getAbsolutePath(), classpathEntry2.getAbsolutePath()))
);
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(expectedFile1, Charsets.UTF_8), ImmutableList.of(content));
assertEquals(Files.readLines(expectedFile2, Charsets.UTF_8), ImmutableList.of(content));
@@ -261,9 +272,10 @@ public class BrooklynNodeIntegrationTest {
BrooklynNode brooklynNode = app.createAndManageChild(EntitySpec.create(BrooklynNode.class)
.configure(BrooklynNode.WEB_CONSOLE_BIND_ADDRESS, "127.0.0.1")
- .configure(BrooklynNode.SUGGESTED_RUN_DIR, tempDir.getAbsolutePath())
+ .configure(BrooklynNode.RUN_DIR, tempDir.getAbsolutePath())
);
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
assertEquals(Files.readLines(expectedFile1, Charsets.UTF_8), ImmutableList.of(content));
assertEquals(Files.readLines(expectedFile2, Charsets.UTF_8), ImmutableList.of(content));
@@ -282,6 +294,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.WEB_CONSOLE_BIND_ADDRESS, "127.0.0.1")
.configure(BrooklynNode.HTTP_PORT, PortRanges.fromString("45000+")));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
Integer httpPort = brooklynNode.getAttribute(BrooklynNode.HTTP_PORT);
URI webConsoleUri = brooklynNode.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
@@ -296,6 +309,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.NO_WEB_CONSOLE_AUTHENTICATION, true)
.configure(BrooklynNode.APP, BasicApplicationImpl.class.getName()));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
URI webConsoleUri = brooklynNode.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
String apps = HttpTestUtils.getContent(webConsoleUri.toString()+"/v1/applications");
@@ -308,6 +322,7 @@ public class BrooklynNodeIntegrationTest {
BrooklynNode brooklynNode = app.createAndManageChild(EntitySpec.create(BrooklynNode.class)
.configure(BrooklynNode.NO_WEB_CONSOLE_AUTHENTICATION, true));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
final String id = brooklynNode.invoke(BrooklynNode.DEPLOY_BLUEPRINT, ConfigBag.newInstance()
.configure(DeployBlueprintEffector.BLUEPRINT_TYPE, BasicApplication.class.getName())
@@ -342,6 +357,7 @@ public class BrooklynNodeIntegrationTest {
.configure(BrooklynNode.APP, BasicApplicationImpl.class.getName())
.configure(BrooklynNode.LOCATIONS, "named:mynamedloc"));
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
URI webConsoleUri = brooklynNode.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
@@ -388,6 +404,7 @@ public class BrooklynNodeIntegrationTest {
// .configure(BrooklynNode.HTTP_PORT, PortRanges.fromString("45000+"))
);
app.start(locs);
+ log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
URI webConsoleUri = brooklynNode.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
Assert.assertTrue(webConsoleUri.toString().startsWith("https://"), "web console not https: "+webConsoleUri);
@@ -411,7 +428,7 @@ public class BrooklynNodeIntegrationTest {
}
private <T> T parseJson(String json, List<String> elements, Class<T> clazz) {
- Function<String, T> func = HttpValueFunctions.chain(
+ Function<String, T> func = Functionals.chain(
JsonFunctions.asJson(),
JsonFunctions.walk(elements),
JsonFunctions.cast(clazz));
@@ -419,9 +436,9 @@ public class BrooklynNodeIntegrationTest {
}
private <T> List<T> parseJsonList(String json, List<String> elements, Class<T> clazz) {
- Function<String, List<T>> func = HttpValueFunctions.chain(
+ Function<String, List<T>> func = Functionals.chain(
JsonFunctions.asJson(),
- JsonFunctions.forEach(HttpValueFunctions.chain(
+ JsonFunctions.forEach(Functionals.chain(
JsonFunctions.walk(elements),
JsonFunctions.cast(clazz))));
return func.apply(json);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f94c2ae7/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
index 7c96416..8f7d561 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
@@ -20,7 +20,6 @@ package brooklyn.entity.brooklynnode;
import static org.testng.Assert.assertTrue;
-import java.io.File;
import java.util.List;
import org.testng.annotations.AfterMethod;
@@ -38,9 +37,6 @@ public class BrooklynNodeTest {
// TODO Need test for copying/setting classpath
- private static final File BROOKLYN_PROPERTIES_PATH = new File(System.getProperty("user.home")+"/.brooklyn/brooklyn.properties");
- private static final File BROOKLYN_PROPERTIES_BAK_PATH = new File(BROOKLYN_PROPERTIES_PATH+".test.bak");
-
private TestApplication app;
private SshMachineLocation loc;
[04/13] git commit: promote snake-yaml dependency and Yamls utility
to utils package,
and use yaml parsing for map coercion to be much more flexible in terms of
string-to-map coercion
Posted by he...@apache.org.
promote snake-yaml dependency and Yamls utility to utils package, and use yaml parsing for map coercion to be much more flexible in terms of string-to-map coercion
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/a4f7a4c0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/a4f7a4c0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/a4f7a4c0
Branch: refs/heads/master
Commit: a4f7a4c0e3db5220e936bcffb5d52c3731b22175
Parents: f94c2ae
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 23:29:12 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:53:52 2014 -0400
----------------------------------------------------------------------
camp/camp-base/pom.xml | 5 -
.../java/io/brooklyn/camp/spi/pdp/Artifact.java | 3 +-
.../camp/spi/pdp/ArtifactRequirement.java | 3 +-
.../java/io/brooklyn/camp/spi/pdp/Service.java | 3 +-
.../camp/spi/pdp/ServiceCharacteristic.java | 3 +-
.../brooklyn/camp/spi/resolve/PdpProcessor.java | 2 +-
.../main/java/io/brooklyn/util/yaml/Yamls.java | 89 +-------------
.../pdp/DeploymentPlanToyInterpreterTest.java | 2 +-
.../java/brooklyn/util/flags/TypeCoercions.java | 85 +++++++++-----
.../util/internal/TypeCoercionsTest.java | 72 ++++++++++--
usage/launcher/pom.xml | 7 ++
utils/common/pom.xml | 5 +
.../src/main/java/brooklyn/util/yaml/Yamls.java | 115 +++++++++++++++++++
13 files changed, 253 insertions(+), 141 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/pom.xml
----------------------------------------------------------------------
diff --git a/camp/camp-base/pom.xml b/camp/camp-base/pom.xml
index b80ef0c..e8638b1 100644
--- a/camp/camp-base/pom.xml
+++ b/camp/camp-base/pom.xml
@@ -57,11 +57,6 @@
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency>
- <dependency>
- <groupId>org.yaml</groupId>
- <artifactId>snakeyaml</artifactId>
- <version>${snakeyaml.version}</version>
- </dependency>
<!-- just for logging, not exported -->
<!--
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java
index 72f356e..697a3ba 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Artifact.java
@@ -18,8 +18,6 @@
*/
package io.brooklyn.camp.spi.pdp;
-import io.brooklyn.util.yaml.Yamls;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -27,6 +25,7 @@ import java.util.Map;
import org.apache.commons.lang3.builder.ToStringBuilder;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.yaml.Yamls;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java
index 50f5335..da9936a 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ArtifactRequirement.java
@@ -18,13 +18,12 @@
*/
package io.brooklyn.camp.spi.pdp;
-import io.brooklyn.util.yaml.Yamls;
-
import java.util.Map;
import org.apache.commons.lang3.builder.ToStringBuilder;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.yaml.Yamls;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java
index 241b80c..5921176 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/Service.java
@@ -18,8 +18,6 @@
*/
package io.brooklyn.camp.spi.pdp;
-import io.brooklyn.util.yaml.Yamls;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -27,6 +25,7 @@ import java.util.Map;
import org.apache.commons.lang3.builder.ToStringBuilder;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.yaml.Yamls;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java
index cc5227d..8b27e2a 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/pdp/ServiceCharacteristic.java
@@ -18,13 +18,12 @@
*/
package io.brooklyn.camp.spi.pdp;
-import io.brooklyn.util.yaml.Yamls;
-
import java.util.Map;
import org.apache.commons.lang3.builder.ToStringBuilder;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.yaml.Yamls;
import com.google.common.collect.ImmutableMap;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java
index 897ff23..3252aaf 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/camp/spi/resolve/PdpProcessor.java
@@ -27,7 +27,6 @@ import io.brooklyn.camp.spi.pdp.DeploymentPlan;
import io.brooklyn.camp.spi.pdp.Service;
import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationContext;
import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
-import io.brooklyn.util.yaml.Yamls;
import java.io.InputStream;
import java.io.Reader;
@@ -41,6 +40,7 @@ import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.yaml.snakeyaml.error.YAMLException;
import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.yaml.Yamls;
import com.google.common.annotations.VisibleForTesting;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java b/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java
index d275ce8..44974f0 100644
--- a/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java
+++ b/camp/camp-base/src/main/java/io/brooklyn/util/yaml/Yamls.java
@@ -18,90 +18,7 @@
*/
package io.brooklyn.util.yaml;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Iterables;
-
-public class Yamls {
-
- private static final Logger log = LoggerFactory.getLogger(Yamls.class);
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- public static <T> T getAs(Object x, Class<T> type) {
- if (x==null) return null;
- if (x instanceof Iterable || x instanceof Iterator) {
- List result = new ArrayList();
- Iterator xi;
- if (Iterator.class.isAssignableFrom(x.getClass())) {
- xi = (Iterator)x;
- } else {
- xi = ((Iterable)x).iterator();
- }
- while (xi.hasNext()) {
- result.add( xi.next() );
- }
- if (type.isAssignableFrom(Iterable.class)) return (T)result;
- if (type.isAssignableFrom(Iterator.class)) return (T)result.iterator();
- if (type.isAssignableFrom(List.class)) return (T)result;
- x = Iterables.getOnlyElement(result);
- }
- // TODO more coercion?
- return (T)x;
- }
-
- @SuppressWarnings("rawtypes")
- public static void dump(int depth, Object r) {
- if (r instanceof Iterable) {
- for (Object ri : ((Iterable)r))
- dump(depth+1, ri);
- } else if (r instanceof Map) {
- for (Object re: ((Map)r).entrySet()) {
- for (int i=0; i<depth; i++) System.out.print(" ");
- System.out.println(((Entry)re).getKey()+":");
- dump(depth+1, ((Entry)re).getValue());
- }
- } else {
- for (int i=0; i<depth; i++) System.out.print(" ");
- if (r==null) System.out.println("<null>");
- else System.out.println("<"+r.getClass().getSimpleName()+">"+" "+r);
- }
- }
-
- /** simplifies new Yaml().loadAll, and converts to list to prevent single-use iterable bug in yaml */
- @SuppressWarnings("unchecked")
- public static Iterable<Object> parseAll(String yaml) {
- Iterable<Object> result = new org.yaml.snakeyaml.Yaml().loadAll(yaml);
- return (List<Object>) getAs(result, List.class);
- }
-
- /** as {@link #parseAll(String)} */
- @SuppressWarnings("unchecked")
- public static Iterable<Object> parseAll(Reader yaml) {
- Iterable<Object> result = new org.yaml.snakeyaml.Yaml().loadAll(yaml);
- return (List<Object>) getAs(result, List.class);
- }
-
- public static Object removeMultinameAttribute(Map<String,Object> obj, String ...equivalentNames) {
- Object result = null;
- for (String name: equivalentNames) {
- Object candidate = obj.remove(name);
- if (candidate!=null) {
- if (result==null) result = candidate;
- else if (!result.equals(candidate)) {
- log.warn("Different values for attributes "+Arrays.toString(equivalentNames)+"; " +
- "preferring '"+result+"' to '"+candidate+"'");
- }
- }
- }
- return result;
- }
+/** @deprecated since 0.7.0 use {@link brooklyn.util.yaml.Yamls} */
+@Deprecated
+public class Yamls extends brooklyn.util.yaml.Yamls {
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/camp/camp-base/src/test/java/io/brooklyn/camp/spi/pdp/DeploymentPlanToyInterpreterTest.java
----------------------------------------------------------------------
diff --git a/camp/camp-base/src/test/java/io/brooklyn/camp/spi/pdp/DeploymentPlanToyInterpreterTest.java b/camp/camp-base/src/test/java/io/brooklyn/camp/spi/pdp/DeploymentPlanToyInterpreterTest.java
index de922a1..29f8abf 100644
--- a/camp/camp-base/src/test/java/io/brooklyn/camp/spi/pdp/DeploymentPlanToyInterpreterTest.java
+++ b/camp/camp-base/src/test/java/io/brooklyn/camp/spi/pdp/DeploymentPlanToyInterpreterTest.java
@@ -21,7 +21,6 @@ package io.brooklyn.camp.spi.pdp;
import io.brooklyn.camp.BasicCampPlatform;
import io.brooklyn.camp.spi.resolve.PlanInterpreter.PlanInterpreterAdapter;
import io.brooklyn.camp.spi.resolve.interpret.PlanInterpretationNode;
-import io.brooklyn.util.yaml.Yamls;
import java.util.Map;
@@ -32,6 +31,7 @@ import org.testng.annotations.Test;
import brooklyn.util.stream.Streams;
import brooklyn.util.text.Strings;
+import brooklyn.util.yaml.Yamls;
@Test
public class DeploymentPlanToyInterpreterTest {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
index 1ee45ae..7e92ed5 100644
--- a/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
+++ b/core/src/main/java/brooklyn/util/flags/TypeCoercions.java
@@ -18,7 +18,9 @@
*/
package brooklyn.util.flags;
-import java.io.IOException;
+import groovy.lang.Closure;
+import groovy.time.TimeDuration;
+
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -39,23 +41,9 @@ import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
-import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.CaseFormat;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Table;
-import com.google.common.net.HostAndPort;
-import com.google.common.primitives.Primitives;
-import com.google.common.reflect.TypeToken;
-
import brooklyn.entity.basic.ClosureEntityFactory;
import brooklyn.entity.basic.ConfigurableEntityFactory;
import brooklyn.entity.basic.ConfigurableEntityFactoryFromEntityFactory;
@@ -70,10 +58,23 @@ import brooklyn.util.net.Cidr;
import brooklyn.util.net.Networking;
import brooklyn.util.net.UserAndHostAndPort;
import brooklyn.util.text.StringEscapes.JavaStringEscapes;
+import brooklyn.util.text.Strings;
import brooklyn.util.time.Duration;
-import groovy.lang.Closure;
-import groovy.time.TimeDuration;
+import brooklyn.util.yaml.Yamls;
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Table;
+import com.google.common.net.HostAndPort;
+import com.google.common.primitives.Primitives;
+import com.google.common.reflect.TypeToken;
+
+@SuppressWarnings("rawtypes")
public class TypeCoercions {
private static final Logger log = LoggerFactory.getLogger(TypeCoercions.class);
@@ -103,7 +104,7 @@ public class TypeCoercions {
}
/** @see #coerce(Object, Class) */
- @SuppressWarnings({ "unchecked", "rawtypes" })
+ @SuppressWarnings({ "unchecked" })
public static <T> T coerce(Object value, TypeToken<T> targetTypeToken) {
if (value==null) return null;
// does not actually cast generified contents; that is left to the caller
@@ -433,12 +434,14 @@ public class TypeCoercions {
}
});
registerAdapter(Collection.class, Set.class, new Function<Collection,Set>() {
+ @SuppressWarnings("unchecked")
@Override
public Set apply(Collection input) {
return new LinkedHashSet(input);
}
});
registerAdapter(Collection.class, List.class, new Function<Collection,List>() {
+ @SuppressWarnings("unchecked")
@Override
public List apply(Collection input) {
return new ArrayList(input);
@@ -485,12 +488,14 @@ public class TypeCoercions {
}
});
registerAdapter(Closure.class, ConfigurableEntityFactory.class, new Function<Closure,ConfigurableEntityFactory>() {
+ @SuppressWarnings("unchecked")
@Override
public ConfigurableEntityFactory apply(Closure input) {
return new ClosureEntityFactory(input);
}
});
registerAdapter(EntityFactory.class, ConfigurableEntityFactory.class, new Function<EntityFactory,ConfigurableEntityFactory>() {
+ @SuppressWarnings("unchecked")
@Override
public ConfigurableEntityFactory apply(EntityFactory input) {
if (input instanceof ConfigurableEntityFactory) return (ConfigurableEntityFactory)input;
@@ -498,6 +503,7 @@ public class TypeCoercions {
}
});
registerAdapter(Closure.class, EntityFactory.class, new Function<Closure,EntityFactory>() {
+ @SuppressWarnings("unchecked")
@Override
public EntityFactory apply(Closure input) {
return new ClosureEntityFactory(input);
@@ -530,6 +536,7 @@ public class TypeCoercions {
}
});
registerAdapter(Object.class, TimeDuration.class, new Function<Object,TimeDuration>() {
+ @SuppressWarnings("deprecation")
@Override
public TimeDuration apply(final Object input) {
log.warn("deprecated automatic coercion of Object to TimeDuration (set breakpoint in TypeCoercions to inspect, convert to Duration)");
@@ -627,20 +634,40 @@ public class TypeCoercions {
registerAdapter(String.class, Map.class, new Function<String,Map>() {
@Override
public Map apply(final String input) {
- // Auto-detect JSON. This allows complex data structures to be received over the REST API.
+ Exception error = null;
+
+ // first try wrapping in braces if needed
+ if (!input.trim().startsWith("{")) {
+ try {
+ return apply("{ "+input+" }");
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ // prefer this error
+ error = e;
+ // fall back to parsing without braces, e.g. if it's multiline
+ }
+ }
+
try {
- if (!input.isEmpty() && input.charAt(0) == '{') {
- return new ObjectMapper().readValue(input, Map.class);
+ return Yamls.getAs( Yamls.parseAll(input), Map.class );
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ if (error!=null && input.indexOf('\n')==-1) {
+ // prefer the original error if it wasn't braced and wasn't multiline
+ e = error;
}
- } catch (IOException e) {
- // just fall through to the map parsing
+ throw new IllegalArgumentException("Cannot parse string as map with flexible YAML parsing; "+
+ (e instanceof ClassCastException ? "yaml treats it as a string" :
+ (e instanceof IllegalArgumentException && Strings.isNonEmpty(e.getMessage())) ? e.getMessage() :
+ ""+e) );
}
-
- // TODO would be nice to accept YAML for complex data structures too, but it's not as simple as JSON to auto-detect.
-
- // Simple map parsing - supports "key1=value1,key2=value2" style input
- // TODO we should respect quoted strings etc
- return ImmutableMap.copyOf(Splitter.on(",").trimResults().omitEmptyStrings().withKeyValueSeparator("=").split(input));
+
+ // NB: previously we supported this also, when we did json above;
+ // yaml support is better as it supports quotes (and better than json because it allows dropping quotes)
+ // snake-yaml, our parser, also accepts key=value -- although i'm not sure this is strictly yaml compliant;
+ // our tests will catch it if snake behaviour changes, and we can reinstate this
+ // (but note it doesn't do quotes; see http://code.google.com/p/guava-libraries/issues/detail?id=412 for that):
+// return ImmutableMap.copyOf(Splitter.on(",").trimResults().omitEmptyStrings().withKeyValueSeparator("=").split(input));
}
});
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java b/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
index 05b4c72..6efffa2 100644
--- a/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
+++ b/core/src/test/java/brooklyn/util/internal/TypeCoercionsTest.java
@@ -32,17 +32,17 @@ import org.slf4j.LoggerFactory;
import org.testng.Assert;
import org.testng.annotations.Test;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.util.flags.ClassCoercionException;
+import brooklyn.util.flags.TypeCoercions;
+import brooklyn.util.text.StringPredicates;
+
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.util.flags.ClassCoercionException;
-import brooklyn.util.flags.TypeCoercions;
-import brooklyn.util.text.StringPredicates;
-
public class TypeCoercionsTest {
private static final Logger log = LoggerFactory.getLogger(TypeCoercionsTest.class);
@@ -191,15 +191,65 @@ public class TypeCoercionsTest {
}
@Test
- public void testStringToMapCoercion() {
- Map<?,?> s = TypeCoercions.coerce("a=1,b=2,c=3", Map.class);
- Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", "2", "c", "3"));
+ public void testJsonStringToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("{ \"a\" : \"1\", b : 2 }", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2));
}
@Test
- public void testJsonStringToMapCoercion() {
- Map<?,?> s = TypeCoercions.coerce("{ \"a\" : \"1\", \"b\" : \"2\", \"c\" : \"3\" }", Map.class);
- Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", "2", "c", "3"));
+ public void testJsonStringWithoutQuotesToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("{ a : 1 }", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", 1));
+ }
+
+ @Test
+ public void testJsonComplexTypesToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("{ a : [1, \"2\", '\"3\"'], b: { c: d, 'e': \"f\" } }", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", ImmutableList.<Object>of(1, "2", "\"3\""),
+ "b", ImmutableMap.of("c", "d", "e", "f")));
+ }
+
+ @Test
+ public void testJsonStringWithoutBracesToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("a : 1", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", 1));
+ }
+
+ @Test
+ public void testJsonStringWithoutBracesWithMultipleToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("a : 1, b : 2", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", 1, "b", 2));
+ }
+
+ @Test
+ public void testKeyEqualsValueStringToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("a=1,b=2", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", "2"));
+ }
+
+ @Test(expectedExceptions=IllegalArgumentException.class)
+ public void testJsonStringWithoutBracesOrSpaceDisallowedAsMapCoercion() {
+ // yaml requires spaces after the colon
+ Map<?,?> s = TypeCoercions.coerce("a:1,b:2", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", 1, "b", 2));
+ }
+
+ @Test
+ public void testEqualsInBracesMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("{ a = 1, b = '2' }", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", 1, "b", "2"));
+ }
+
+ @Test
+ public void testKeyEqualsOrColonValueWithBracesStringToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("{ a=1, b: 2 }", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2));
+ }
+
+ @Test
+ public void testKeyEqualsOrColonValueWithoutBracesStringToMapCoercion() {
+ Map<?,?> s = TypeCoercions.coerce("a=1, b: 2", Map.class);
+ Assert.assertEquals(s, ImmutableMap.of("a", "1", "b", 2));
}
@Test
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/usage/launcher/pom.xml
----------------------------------------------------------------------
diff --git a/usage/launcher/pom.xml b/usage/launcher/pom.xml
index 57d3e24..1fb4fcd 100644
--- a/usage/launcher/pom.xml
+++ b/usage/launcher/pom.xml
@@ -86,6 +86,13 @@
</dependency>
<dependency>
<groupId>io.brooklyn</groupId>
+ <artifactId>brooklyn-software-base</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>io.brooklyn</groupId>
<artifactId>brooklyn-software-webapp</artifactId>
<version>${project.version}</version>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/utils/common/pom.xml
----------------------------------------------------------------------
diff --git a/utils/common/pom.xml b/utils/common/pom.xml
index 24dec9f..54de72a 100644
--- a/utils/common/pom.xml
+++ b/utils/common/pom.xml
@@ -56,6 +56,11 @@
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.yaml</groupId>
+ <artifactId>snakeyaml</artifactId>
+ <version>${snakeyaml.version}</version>
+ </dependency>
<dependency>
<groupId>org.testng</groupId>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a4f7a4c0/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java b/utils/common/src/main/java/brooklyn/util/yaml/Yamls.java
new file mode 100644
index 0000000..a22432f
--- /dev/null
+++ b/utils/common/src/main/java/brooklyn/util/yaml/Yamls.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 brooklyn.util.yaml;
+
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Iterables;
+
+public class Yamls {
+
+ private static final Logger log = LoggerFactory.getLogger(Yamls.class);
+
+ /** returns the given yaml object (map or list or primitive) as the given yaml-supperted type
+ * (map or list or primitive e.g. string, number, boolean).
+ * <p>
+ * if the object is an iterable containing a single element, and the type is not an iterable,
+ * this will attempt to unwrap it.
+ *
+ * @throws IllegalArgumentException if the input is an iterable not containing a single element,
+ * and the cast is requested to a non-iterable type
+ * @throws ClassCastException if cannot be casted */
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static <T> T getAs(Object x, Class<T> type) {
+ if (x==null) return null;
+ if (x instanceof Iterable || x instanceof Iterator) {
+ List result = new ArrayList();
+ Iterator xi;
+ if (Iterator.class.isAssignableFrom(x.getClass())) {
+ xi = (Iterator)x;
+ } else {
+ xi = ((Iterable)x).iterator();
+ }
+ while (xi.hasNext()) {
+ result.add( xi.next() );
+ }
+ if (type.isAssignableFrom(Iterable.class)) return (T)result;
+ if (type.isAssignableFrom(Iterator.class)) return (T)result.iterator();
+ if (type.isAssignableFrom(List.class)) return (T)result;
+ x = Iterables.getOnlyElement(result);
+ }
+ return (T)x;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static void dump(int depth, Object r) {
+ if (r instanceof Iterable) {
+ for (Object ri : ((Iterable)r))
+ dump(depth+1, ri);
+ } else if (r instanceof Map) {
+ for (Object re: ((Map)r).entrySet()) {
+ for (int i=0; i<depth; i++) System.out.print(" ");
+ System.out.println(((Entry)re).getKey()+":");
+ dump(depth+1, ((Entry)re).getValue());
+ }
+ } else {
+ for (int i=0; i<depth; i++) System.out.print(" ");
+ if (r==null) System.out.println("<null>");
+ else System.out.println("<"+r.getClass().getSimpleName()+">"+" "+r);
+ }
+ }
+
+ /** simplifies new Yaml().loadAll, and converts to list to prevent single-use iterable bug in yaml */
+ @SuppressWarnings("unchecked")
+ public static Iterable<Object> parseAll(String yaml) {
+ Iterable<Object> result = new org.yaml.snakeyaml.Yaml().loadAll(yaml);
+ return (List<Object>) getAs(result, List.class);
+ }
+
+ /** as {@link #parseAll(String)} */
+ @SuppressWarnings("unchecked")
+ public static Iterable<Object> parseAll(Reader yaml) {
+ Iterable<Object> result = new org.yaml.snakeyaml.Yaml().loadAll(yaml);
+ return (List<Object>) getAs(result, List.class);
+ }
+
+ public static Object removeMultinameAttribute(Map<String,Object> obj, String ...equivalentNames) {
+ Object result = null;
+ for (String name: equivalentNames) {
+ Object candidate = obj.remove(name);
+ if (candidate!=null) {
+ if (result==null) result = candidate;
+ else if (!result.equals(candidate)) {
+ log.warn("Different values for attributes "+Arrays.toString(equivalentNames)+"; " +
+ "preferring '"+result+"' to '"+candidate+"'");
+ }
+ }
+ }
+ return result;
+ }
+}
[11/13] git commit: This closes #76
Posted by he...@apache.org.
This closes #76
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/671fb174
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/671fb174
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/671fb174
Branch: refs/heads/master
Commit: 671fb174ca8033824e772af815e78107e4ed1f66
Parents: f0b8f29 fe0d9d3
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 12:31:36 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:31:36 2014 -0400
----------------------------------------------------------------------
.../internal/BrooklynGarbageCollector.java | 32 +-
.../util/task/BasicTaskExecutionTest.groovy | 370 ---------------
.../util/task/BasicTaskExecutionTest.java | 460 +++++++++++++++++++
.../util/task/ScheduledExecutionTest.groovy | 148 ------
.../util/task/ScheduledExecutionTest.java | 175 +++++++
.../task/SingleThreadedSchedulerTest.groovy | 154 -------
.../util/task/SingleThreadedSchedulerTest.java | 192 ++++++++
7 files changed, 853 insertions(+), 678 deletions(-)
----------------------------------------------------------------------
[03/13] git commit: Converts task tests from groovy to java
Posted by he...@apache.org.
Converts task tests from groovy to java
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/35363d61
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/35363d61
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/35363d61
Branch: refs/heads/master
Commit: 35363d613d4b09caa1bd067f0a2b47e10354611c
Parents: 6325e50
Author: Aled Sage <al...@gmail.com>
Authored: Wed Jul 16 23:47:35 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Jul 17 11:28:44 2014 +0100
----------------------------------------------------------------------
.../util/task/BasicTaskExecutionTest.groovy | 370 ---------------
.../util/task/BasicTaskExecutionTest.java | 460 +++++++++++++++++++
.../util/task/ScheduledExecutionTest.groovy | 148 ------
.../util/task/ScheduledExecutionTest.java | 175 +++++++
.../task/SingleThreadedSchedulerTest.groovy | 154 -------
.../util/task/SingleThreadedSchedulerTest.java | 192 ++++++++
6 files changed, 827 insertions(+), 672 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35363d61/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.groovy b/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.groovy
deleted file mode 100644
index 1d104a8..0000000
--- a/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.groovy
+++ /dev/null
@@ -1,370 +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 brooklyn.util.task;
-
-import static org.testng.Assert.*
-
-import java.util.concurrent.Callable
-import java.util.concurrent.CancellationException
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod
-import org.testng.annotations.Test
-
-import brooklyn.management.ExecutionManager
-import brooklyn.management.Task
-import brooklyn.test.TestUtils
-
-import com.google.common.base.Throwables
-
-/**
- * Test the operation of the {@link BasicTask} class.
- *
- * TODO clarify test purpose
- */
-public class BasicTaskExecutionTest {
- private static final Logger log = LoggerFactory.getLogger(BasicTaskExecutionTest.class)
-
- private static final int TIMEOUT_MS = 10*1000
-
- private BasicExecutionManager em;
- private Map data;
-
- @BeforeMethod
- public void setUp() {
- em = new BasicExecutionManager("mycontext");
-// assertTrue em.allTasks.isEmpty()
- data = Collections.synchronizedMap(new HashMap())
- data.clear()
- }
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- if (em != null) em.shutdownNow();
- }
-
- @Test
- public void runSimpleBasicTask() {
- data.clear()
- BasicTask t = [ { data.put(1, "b") } ]
- data.put(1, "a")
- BasicTask t2 = em.submit tag:"A", t
- assertEquals("a", t.get())
- assertEquals("b", data.get(1))
- }
-
- @Test
- public void runSimpleRunnable() {
- data.clear()
- data.put(1, "a")
- BasicTask t = em.submit tag:"A", new Runnable() { public void run() { data.put(1, "b") } }
- assertEquals(null, t.get())
- assertEquals("b", data.get(1))
- }
-
- @Test
- public void runSimpleCallable() {
- data.clear()
- data.put(1, "a")
- BasicTask t = em.submit tag:"A", new Callable() { public Object call() { data.put(1, "b") } }
- assertEquals("a", t.get())
- assertEquals("b", data.get(1))
- }
-
- @Test
- public void runBasicTaskWithWaits() {
- CountDownLatch signalStarted = new CountDownLatch(1);
- CountDownLatch allowCompletion = new CountDownLatch(1);
- data.clear()
- BasicTask t = [ {
- def result = data.put(1, "b")
- signalStarted.countDown();
- assertTrue(allowCompletion.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- result
- } ]
- data.put(1, "a")
-
- BasicTask t2 = em.submit tag:"A", t
- assertEquals(t, t2)
- assertFalse(t.isDone())
-
- assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- assertEquals("b", data.get(1))
- assertFalse(t.isDone())
-
- log.debug "runBasicTaskWithWaits, BasicTask status: {}", t.getStatusDetail(false)
-
- TestUtils.executeUntilSucceeds { t.getStatusDetail(false).toLowerCase().contains("waiting") }
- // "details="+t.getStatusDetail(false))
-
- allowCompletion.countDown();
- assertEquals("a", t.get())
- }
-
- @Test
- public void runMultipleBasicTasks() {
- data.clear()
- data.put(1, 1)
- BasicExecutionManager em = []
- 2.times { em.submit tag:"A", new BasicTask({ synchronized(data) { data.put(1, data.get(1)+1) } }) }
- 2.times { em.submit tag:"B", new BasicTask({ synchronized(data) { data.put(1, data.get(1)+1) } }) }
- int total = 0;
- em.getTaskTags().each {
- log.debug "tag {}", it
- em.getTasksWithTag(it).each {
- log.debug "BasicTask {}, has {}", it, it.get()
- total += it.get()
- }
- }
- assertEquals(10, total)
- //now that all have completed:
- assertEquals(5, data.get(1))
- }
-
- @Test
- public void runMultipleBasicTasksMultipleTags() {
- data.clear()
- data.put(1, 1)
- Collection<Task> tasks = []
- tasks += em.submit tag:"A", new BasicTask({ synchronized(data) { data.put(1, data.get(1)+1) } })
- tasks += em.submit tags:["A","B"], new BasicTask({ synchronized(data) { data.put(1, data.get(1)+1) } })
- tasks += em.submit tags:["B","C"], new BasicTask({ synchronized(data) { data.put(1, data.get(1)+1) } })
- tasks += em.submit tags:["D"], new BasicTask({ synchronized(data) { data.put(1, data.get(1)+1) } })
- int total = 0;
-
- tasks.each { Task t ->
- log.debug "BasicTask {}, has {}", t, t.get()
- total += t.get()
- }
- assertEquals(10, total)
-
- //now that all have completed:
- assertEquals data.get(1), 5
- assertEquals em.getTasksWithTag("A").size(), 2
- assertEquals em.getTasksWithAnyTag(["A"]).size(), 2
- assertEquals em.getTasksWithAllTags(["A"]).size(), 2
-
- assertEquals em.getTasksWithAnyTag(["A", "B"]).size(), 3
- assertEquals em.getTasksWithAllTags(["A", "B"]).size(), 1
- assertEquals em.getTasksWithAllTags(["B", "C"]).size(), 1
- assertEquals em.getTasksWithAnyTag(["A", "D"]).size(), 3
- }
-
- @Test
- public void testGetTaskById() {
- Task t = new BasicTask({ /*no-op*/ })
- em.submit tag:"A",t
- assertEquals(em.getTask(t.id), t);
- }
-
- @Test
- public void testRetrievingTasksWithTagsReturnsExpectedTask() {
- Task t = new BasicTask({ /*no-op*/ })
- em.submit tag:"A",t
- t.get();
-
- assertEquals(em.getTasksWithTag("A"), [t]);
- assertEquals(em.getTasksWithAnyTag(["A"]), [t]);
- assertEquals(em.getTasksWithAnyTag(["A","B"]), [t]);
- assertEquals(em.getTasksWithAllTags(["A"]), [t]);
- }
-
- @Test
- public void testRetrievingTasksWithTagsExcludesNonMatchingTasks() {
- Task t = new BasicTask({ /*no-op*/ })
- em.submit tag:"A",t
- t.get();
-
- assertEquals(em.getTasksWithTag("B"), []);
- assertEquals(em.getTasksWithAnyTag(["B"]), []);
- assertEquals(em.getTasksWithAllTags(["A","B"]), []);
- }
-
- @Test
- public void testRetrievingTasksWithMultipleTags() {
- Task t = new BasicTask({ /*no-op*/ })
- em.submit tags:["A","B"], t
- t.get();
-
- assertEquals(em.getTasksWithTag("A"), [t]);
- assertEquals(em.getTasksWithTag("B"), [t]);
- assertEquals(em.getTasksWithAnyTag(["A"]), [t]);
- assertEquals(em.getTasksWithAnyTag(["B"]), [t]);
- assertEquals(em.getTasksWithAnyTag(["A","B"]), [t]);
- assertEquals(em.getTasksWithAllTags(["A","B"]), [t]);
- assertEquals(em.getTasksWithAllTags(["A"]), [t]);
- assertEquals(em.getTasksWithAllTags(["B"]), [t]);
- }
-
- // ENGR-1796: if nothing matched first tag, then returned whatever matched second tag!
- @Test
- public void testRetrievingTasksWithAllTagsWhenFirstNotMatched() {
- Task t = new BasicTask({ /*no-op*/ })
- em.submit tags:["A"], t
- t.get();
-
- assertEquals(em.getTasksWithAllTags(["not_there","A"]), []);
- }
-
- @Test
- public void testRetrievedTasksIncludesTasksInProgress() {
- CountDownLatch runningLatch = new CountDownLatch(1);
- CountDownLatch finishLatch = new CountDownLatch(1);
- Task t = new BasicTask({ runningLatch.countDown(); finishLatch.await() })
- em.submit tags:["A"], t
-
- try {
- runningLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
-
- assertEquals(em.getTasksWithTag("A"), [t]);
- } finally {
- finishLatch.countDown();
- }
- }
-
- @Test
- public void cancelBeforeRun() {
- CountDownLatch blockForever = new CountDownLatch(1);
-
- BasicTask t = [ { blockForever.await(); return 42 } ]
- t.cancel true
- assertTrue(t.isCancelled())
- assertTrue(t.isDone())
- assertTrue(t.isError())
- em.submit tag:"A", t
- try { t.get(); fail("get should have failed due to cancel"); } catch (CancellationException e) {}
- assertTrue(t.isCancelled())
- assertTrue(t.isDone())
- assertTrue(t.isError())
-
- log.debug "cancelBeforeRun status: {}", t.getStatusDetail(false)
- assertTrue(t.getStatusDetail(false).toLowerCase().contains("cancel"))
- }
-
- @Test
- public void cancelDuringRun() {
- CountDownLatch signalStarted = new CountDownLatch(1);
- CountDownLatch blockForever = new CountDownLatch(1);
-
- BasicTask t = [ { synchronized (data) { signalStarted.countDown(); blockForever.await() }; return 42 } ]
- em.submit tag:"A", t
- assertFalse(t.isCancelled())
- assertFalse(t.isDone())
- assertFalse(t.isError())
-
- assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
- t.cancel true
-
- assertTrue(t.isCancelled())
- assertTrue(t.isError())
- try { t.get(); fail("get should have failed due to cancel"); } catch (CancellationException e) {}
- assertTrue(t.isCancelled())
- assertTrue(t.isDone())
- assertTrue(t.isError())
- }
-
- @Test
- public void cancelAfterRun() {
- BasicTask t = [ { return 42 } ]
- em.submit tag:"A", t
-
- assertEquals(42, t.get());
- t.cancel true
- assertFalse(t.isCancelled())
- assertFalse(t.isError())
- assertTrue(t.isDone())
- }
-
- @Test
- public void errorDuringRun() {
- BasicTask t = [ { throw new IllegalStateException("Aaargh"); } ]
-
- em.submit tag:"A", t
-
- try { t.get(); fail("get should have failed due to error"); } catch (Exception eo) { Exception e = Throwables.getRootCause(eo); assertEquals("Aaargh", e.getMessage()) }
-
- assertFalse(t.isCancelled())
- assertTrue(t.isError())
- assertTrue(t.isDone())
-
- log.debug "errorDuringRun status: {}", t.getStatusDetail(false)
- assertTrue(t.getStatusDetail(false).contains("Aaargh"), "details="+t.getStatusDetail(false))
- }
-
- @Test
- public void fieldsSetForSimpleBasicTask() {
- CountDownLatch signalStarted = new CountDownLatch(1);
- CountDownLatch allowCompletion = new CountDownLatch(1);
-
- BasicTask t = [ { signalStarted.countDown(); allowCompletion.await(); return 42 } ]
- assertEquals(null, t.submittedByTask)
- assertEquals(-1, t.submitTimeUtc)
- assertNull(t.getResult())
-
- em.submit tag:"A", t
- assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- assertTrue(t.submitTimeUtc > 0)
- assertTrue(t.startTimeUtc >= t.submitTimeUtc)
- assertNotNull(t.getResult())
- assertEquals(-1, t.endTimeUtc)
- assertEquals(false, t.isCancelled())
-
- allowCompletion.countDown()
- assertEquals(42, t.get())
- assertTrue(t.endTimeUtc >= t.startTimeUtc)
-
- log.debug "BasicTask duration (millis): {}", (t.endTimeUtc - t.submitTimeUtc)
- }
-
- @Test
- public void fieldsSetForBasicTaskSubmittedBasicTask() {
- //submitted BasicTask B is started by A, and waits for A to complete
- BasicTask t = new BasicTask( displayName: "sample", description: "some descr", {
- em.submit tag:"B", {
- assertEquals(45, em.getTasksWithTag("A").iterator().next().get());
- 46 };
- 45 } )
- em.submit tag:"A", t
-
- t.blockUntilEnded()
-
-// assertEquals em.getAllTasks().size(), 2
-
- BasicTask tb = em.getTasksWithTag("B").iterator().next();
- assertEquals( 46, tb.get() )
- assertEquals( t, em.getTasksWithTag("A").iterator().next() )
- assertNull( t.submittedByTask )
-
- BasicTask submitter = tb.submittedByTask;
- assertNotNull(submitter)
- assertEquals("sample", submitter.displayName)
- assertEquals("some descr", submitter.description)
- assertEquals(t, submitter)
-
- assertTrue(submitter.submitTimeUtc <= tb.submitTimeUtc)
- assertTrue(submitter.endTimeUtc <= tb.endTimeUtc)
-
- log.debug "BasicTask {} was submitted by {}", tb, submitter
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35363d61/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.java b/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.java
new file mode 100644
index 0000000..cd0d2b1
--- /dev/null
+++ b/core/src/test/java/brooklyn/util/task/BasicTaskExecutionTest.java
@@ -0,0 +1,460 @@
+/*
+ * 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 brooklyn.util.task;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.management.Task;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Callables;
+
+/**
+ * Test the operation of the {@link BasicTask} class.
+ *
+ * TODO clarify test purpose
+ */
+public class BasicTaskExecutionTest {
+ private static final Logger log = LoggerFactory.getLogger(BasicTaskExecutionTest.class);
+
+ private static final int TIMEOUT_MS = 10*1000;
+
+ private BasicExecutionManager em;
+ private Map<Object, Object> data;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() {
+ em = new BasicExecutionManager("mycontext");
+ data = Collections.synchronizedMap(new HashMap<Object, Object>());
+ data.clear();
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (em != null) em.shutdownNow();
+ if (data != null) data.clear();
+ }
+
+ @Test
+ public void runSimpleBasicTask() throws Exception {
+ BasicTask<Object> t = new BasicTask<Object>(newPutCallable(1, "b"));
+ data.put(1, "a");
+ Task<Object> t2 = em.submit(MutableMap.of("tag", "A"), t);
+ assertEquals("a", t.get());
+ assertEquals("a", t2.get());
+ assertEquals("b", data.get(1));
+ }
+
+ @Test
+ public void runSimpleRunnable() throws Exception {
+ data.put(1, "a");
+ Task<?> t = em.submit(MutableMap.of("tag", "A"), newPutRunnable(1, "b"));
+ assertEquals(null, t.get());
+ assertEquals("b", data.get(1));
+ }
+
+ @Test
+ public void runSimpleCallable() throws Exception {
+ data.put(1, "a");
+ Task<?> t = em.submit(MutableMap.of("tag", "A"), newPutCallable(1, "b"));
+ assertEquals("a", t.get());
+ assertEquals("b", data.get(1));
+ }
+
+ @Test
+ public void runBasicTaskWithWaits() throws Exception {
+ final CountDownLatch signalStarted = new CountDownLatch(1);
+ final CountDownLatch allowCompletion = new CountDownLatch(1);
+ final BasicTask<Object> t = new BasicTask<Object>(new Callable<Object>() {
+ public Object call() throws Exception {
+ Object result = data.put(1, "b");
+ signalStarted.countDown();
+ assertTrue(allowCompletion.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ return result;
+ }});
+ data.put(1, "a");
+
+ Task<?> t2 = em.submit(MutableMap.of("tag", "A"), t);
+ assertEquals(t, t2);
+ assertFalse(t.isDone());
+
+ assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ assertEquals("b", data.get(1));
+ assertFalse(t.isDone());
+
+ log.debug("runBasicTaskWithWaits, BasicTask status: {}", t.getStatusDetail(false));
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ String status = t.getStatusDetail(false);
+ assertTrue(status != null && status.toLowerCase().contains("waiting"), "status="+status);
+ }});
+
+ allowCompletion.countDown();
+ assertEquals("a", t.get());
+ }
+
+ @Test
+ public void runMultipleBasicTasks() throws Exception {
+ data.put(1, 1);
+ BasicExecutionManager em = new BasicExecutionManager("mycontext");
+ for (int i = 0; i < 2; i++) {
+ em.submit(MutableMap.of("tag", "A"), new BasicTask<Integer>(newIncrementCallable(1)));
+ em.submit(MutableMap.of("tag", "B"), new BasicTask<Integer>(newIncrementCallable((1))));
+ }
+ int total = 0;
+ for (Object tag : em.getTaskTags()) {
+ log.debug("tag {}", tag);
+ for (Task<?> task : em.getTasksWithTag(tag)) {
+ log.debug("BasicTask {}, has {}", task, task.get());
+ total += (Integer)task.get();
+ }
+ }
+ assertEquals(10, total);
+ //now that all have completed:
+ assertEquals(5, data.get(1));
+ }
+
+ @Test
+ public void runMultipleBasicTasksMultipleTags() throws Exception {
+ data.put(1, 1);
+ Collection<Task<Integer>> tasks = Lists.newArrayList();
+ tasks.add(em.submit(MutableMap.of("tag", "A"), new BasicTask<Integer>(newIncrementCallable(1))));
+ tasks.add(em.submit(MutableMap.of("tags", ImmutableList.of("A","B")), new BasicTask<Integer>(newIncrementCallable(1))));
+ tasks.add(em.submit(MutableMap.of("tags", ImmutableList.of("B","C")), new BasicTask<Integer>(newIncrementCallable(1))));
+ tasks.add(em.submit(MutableMap.of("tags", ImmutableList.of("D")), new BasicTask<Integer>(newIncrementCallable(1))));
+ int total = 0;
+
+ for (Task<Integer> t : tasks) {
+ log.debug("BasicTask {}, has {}", t, t.get());
+ total += t.get();
+ }
+ assertEquals(10, total);
+
+ //now that all have completed:
+ assertEquals(data.get(1), 5);
+ assertEquals(em.getTasksWithTag("A").size(), 2);
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A")).size(), 2);
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("A")).size(), 2);
+
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A", "B")).size(), 3);
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("A", "B")).size(), 1);
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("B", "C")).size(), 1);
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A", "D")).size(), 3);
+ }
+
+ @Test
+ public void testGetTaskById() throws Exception {
+ Task<?> t = new BasicTask<Void>(newNoop());
+ em.submit(MutableMap.of("tag", "A"), t);
+ assertEquals(em.getTask(t.getId()), t);
+ }
+
+ @Test
+ public void testRetrievingTasksWithTagsReturnsExpectedTask() throws Exception {
+ Task<?> t = new BasicTask<Void>(newNoop());
+ em.submit(MutableMap.of("tag", "A"), t);
+ t.get();
+
+ assertEquals(em.getTasksWithTag("A"), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A", "B")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("A")), ImmutableList.of(t));
+ }
+
+ @Test
+ public void testRetrievingTasksWithTagsExcludesNonMatchingTasks() throws Exception {
+ Task<?> t = new BasicTask<Void>(newNoop());
+ em.submit(MutableMap.of("tag", "A"), t);
+ t.get();
+
+ assertEquals(em.getTasksWithTag("B"), ImmutableSet.of());
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("B")), ImmutableSet.of());
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("A", "B")), ImmutableSet.of());
+ }
+
+ @Test
+ public void testRetrievingTasksWithMultipleTags() throws Exception {
+ Task<?> t = new BasicTask<Void>(newNoop());
+ em.submit(MutableMap.of("tags", ImmutableList.of("A", "B")), t);
+ t.get();
+
+ assertEquals(em.getTasksWithTag("A"), ImmutableList.of(t));
+ assertEquals(em.getTasksWithTag("B"), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("B")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAnyTag(ImmutableList.of("A", "B")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("A", "B")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("A")), ImmutableList.of(t));
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("B")), ImmutableList.of(t));
+ }
+
+ // ENGR-1796: if nothing matched first tag, then returned whatever matched second tag!
+ @Test
+ public void testRetrievingTasksWithAllTagsWhenFirstNotMatched() throws Exception {
+ Task<?> t = new BasicTask<Void>(newNoop());
+ em.submit(MutableMap.of("tags", ImmutableList.of("A")), t);
+ t.get();
+
+ assertEquals(em.getTasksWithAllTags(ImmutableList.of("not_there","A")), ImmutableSet.of());
+ }
+
+ @Test
+ public void testRetrievedTasksIncludesTasksInProgress() throws Exception {
+ final CountDownLatch runningLatch = new CountDownLatch(1);
+ final CountDownLatch finishLatch = new CountDownLatch(1);
+ Task<Void> t = new BasicTask<Void>(new Callable<Void>() {
+ public Void call() throws Exception {
+ runningLatch.countDown();
+ finishLatch.await();
+ return null;
+ }});
+ em.submit(MutableMap.of("tags", ImmutableList.of("A")), t);
+
+ try {
+ runningLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+
+ assertEquals(em.getTasksWithTag("A"), ImmutableList.of(t));
+ } finally {
+ finishLatch.countDown();
+ }
+ }
+
+ @Test
+ public void cancelBeforeRun() throws Exception {
+ final CountDownLatch blockForever = new CountDownLatch(1);
+
+ BasicTask<Integer> t = new BasicTask<Integer>(new Callable<Integer>() {
+ public Integer call() throws Exception {
+ blockForever.await(); return 42;
+ }});
+ t.cancel(true);
+ assertTrue(t.isCancelled());
+ assertTrue(t.isDone());
+ assertTrue(t.isError());
+ em.submit(MutableMap.of("tag", "A"), t);
+ try {
+ t.get();
+ fail("get should have failed due to cancel");
+ } catch (CancellationException e) {
+ // expected
+ }
+ assertTrue(t.isCancelled());
+ assertTrue(t.isDone());
+ assertTrue(t.isError());
+
+ log.debug("cancelBeforeRun status: {}", t.getStatusDetail(false));
+ assertTrue(t.getStatusDetail(false).toLowerCase().contains("cancel"));
+ }
+
+ @Test
+ public void cancelDuringRun() throws Exception {
+ final CountDownLatch signalStarted = new CountDownLatch(1);
+ final CountDownLatch blockForever = new CountDownLatch(1);
+
+ BasicTask<Integer> t = new BasicTask<Integer>(new Callable<Integer>() {
+ public Integer call() throws Exception {
+ synchronized (data) {
+ signalStarted.countDown();
+ blockForever.await();
+ }
+ return 42;
+ }});
+ em.submit(MutableMap.of("tag", "A"), t);
+ assertFalse(t.isCancelled());
+ assertFalse(t.isDone());
+ assertFalse(t.isError());
+
+ assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+ t.cancel(true);
+
+ assertTrue(t.isCancelled());
+ assertTrue(t.isError());
+ try {
+ t.get();
+ fail("get should have failed due to cancel");
+ } catch (CancellationException e) {
+ // expected
+ }
+ assertTrue(t.isCancelled());
+ assertTrue(t.isDone());
+ assertTrue(t.isError());
+ }
+
+ @Test
+ public void cancelAfterRun() throws Exception {
+ BasicTask<Integer> t = new BasicTask<Integer>(Callables.returning(42));
+ em.submit(MutableMap.of("tag", "A"), t);
+
+ assertEquals(t.get(), (Integer)42);
+ t.cancel(true);
+ assertFalse(t.isCancelled());
+ assertFalse(t.isError());
+ assertTrue(t.isDone());
+ }
+
+ @Test
+ public void errorDuringRun() throws Exception {
+ BasicTask<Void> t = new BasicTask<Void>(new Callable<Void>() {
+ public Void call() throws Exception {
+ throw new IllegalStateException("Simulating failure in errorDuringRun");
+ }});
+
+ em.submit(MutableMap.of("tag", "A"), t);
+
+ try {
+ t.get();
+ fail("get should have failed due to error");
+ } catch (Exception eo) {
+ Throwable e = Throwables.getRootCause(eo);
+ assertEquals("Simulating failure in errorDuringRun", e.getMessage());
+ }
+
+ assertFalse(t.isCancelled());
+ assertTrue(t.isError());
+ assertTrue(t.isDone());
+
+ log.debug("errorDuringRun status: {}", t.getStatusDetail(false));
+ assertTrue(t.getStatusDetail(false).contains("Simulating failure in errorDuringRun"), "details="+t.getStatusDetail(false));
+ }
+
+ @Test
+ public void fieldsSetForSimpleBasicTask() throws Exception {
+ final CountDownLatch signalStarted = new CountDownLatch(1);
+ final CountDownLatch allowCompletion = new CountDownLatch(1);
+
+ BasicTask<Integer> t = new BasicTask<Integer>(new Callable<Integer>() {
+ public Integer call() throws Exception {
+ signalStarted.countDown();
+ allowCompletion.await();
+ return 42;
+ }});
+ assertEquals(null, t.submittedByTask);
+ assertEquals(-1, t.submitTimeUtc);
+ assertNull(t.getResult());
+
+ em.submit(MutableMap.of("tag", "A"), t);
+ assertTrue(signalStarted.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+ assertTrue(t.submitTimeUtc > 0);
+ assertTrue(t.startTimeUtc >= t.submitTimeUtc);
+ assertNotNull(t.getResult());
+ assertEquals(-1, t.endTimeUtc);
+ assertEquals(false, t.isCancelled());
+
+ allowCompletion.countDown();
+ assertEquals(t.get(), (Integer)42);
+ assertTrue(t.endTimeUtc >= t.startTimeUtc);
+
+ log.debug("BasicTask duration (millis): {}", (t.endTimeUtc - t.submitTimeUtc));
+ }
+
+ @Test
+ public void fieldsSetForBasicTaskSubmittedBasicTask() throws Exception {
+ //submitted BasicTask B is started by A, and waits for A to complete
+ BasicTask<Integer> t = new BasicTask<Integer>(MutableMap.of("displayName", "sample", "description", "some descr"), new Callable<Integer>() {
+ public Integer call() throws Exception {
+ em.submit(MutableMap.of("tag", "B"), new Callable<Integer>() {
+ public Integer call() throws Exception {
+ assertEquals(45, em.getTasksWithTag("A").iterator().next().get());
+ return 46;
+ }});
+ return 45;
+ }});
+ em.submit(MutableMap.of("tag", "A"), t);
+
+ t.blockUntilEnded();
+
+// assertEquals(em.getAllTasks().size(), 2
+
+ BasicTask<?> tb = (BasicTask<?>) em.getTasksWithTag("B").iterator().next();
+ assertEquals( 46, tb.get() );
+ assertEquals( t, em.getTasksWithTag("A").iterator().next() );
+ assertNull( t.submittedByTask );
+
+ BasicTask<?> submitter = (BasicTask<?>) tb.submittedByTask;
+ assertNotNull(submitter);
+ assertEquals("sample", submitter.displayName);
+ assertEquals("some descr", submitter.description);
+ assertEquals(t, submitter);
+
+ assertTrue(submitter.submitTimeUtc <= tb.submitTimeUtc);
+ assertTrue(submitter.endTimeUtc <= tb.endTimeUtc);
+
+ log.debug("BasicTask {} was submitted by {}", tb, submitter);
+ }
+
+ private Callable<Object> newPutCallable(final Object key, final Object val) {
+ return new Callable<Object>() {
+ public Object call() {
+ return data.put(key, val);
+ }
+ };
+ }
+
+ private Callable<Integer> newIncrementCallable(final Object key) {
+ return new Callable<Integer>() {
+ public Integer call() {
+ synchronized (data) {
+ return (Integer) data.put(key, (Integer)data.get(key) + 1);
+ }
+ }
+ };
+ }
+
+ private Runnable newPutRunnable(final Object key, final Object val) {
+ return new Runnable() {
+ public void run() {
+ data.put(key, val);
+ }
+ };
+ }
+
+ private Runnable newNoop() {
+ return new Runnable() {
+ public void run() {
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35363d61/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.groovy b/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.groovy
deleted file mode 100644
index 1e4731d..0000000
--- a/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.groovy
+++ /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 brooklyn.util.task
-
-import static org.testng.Assert.*
-
-import java.util.concurrent.CopyOnWriteArrayList
-import java.util.concurrent.TimeUnit
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.Test
-
-import brooklyn.test.TestUtils
-import brooklyn.util.internal.TimeExtras
-
-import com.google.common.collect.Lists
-
-public class ScheduledExecutionTest {
-
- public static final Logger log = LoggerFactory.getLogger(ScheduledExecutionTest.class);
-
- static { TimeExtras.init() }
-
- @Test
- public void testScheduledTask() {
- int PERIOD = 20;
- BasicExecutionManager m = new BasicExecutionManager();
- int i=0;
- def t = new ScheduledTask(delay: 2*PERIOD*TimeUnit.MILLISECONDS, period: PERIOD*TimeUnit.MILLISECONDS, maxIterations: 5, { new BasicTask({
- log.debug "task running: "+Tasks.current()+" "+Tasks.current().getStatusDetail(false)
- ++i;
- }) } );
-
- log.info "submitting {} {}", t, t.getStatusDetail(false)
- m.submit(t);
- log.info "submitted {} {}", t, t.getStatusDetail(false)
- int interimResult = t.get()
- log.info "done one ({}) {} {}", interimResult, t, t.getStatusDetail(false)
- assertTrue(i>0)
- t.blockUntilEnded()
- int finalResult = t.get()
- log.info "ended ({}) {} {}", finalResult, t, t.getStatusDetail(false)
- assertEquals(finalResult, 5)
- assertEquals(i, 5)
- }
-
- /** like testScheduledTask but the loop is terminated by the task itself adjusting the period */
- @Test
- public void testScheduledTaskSelfEnding() {
- int PERIOD = 20;
- BasicExecutionManager m = new BasicExecutionManager();
- int i=0;
- def t = new ScheduledTask(delay: 2*PERIOD*TimeUnit.MILLISECONDS, period: PERIOD*TimeUnit.MILLISECONDS, { new BasicTask({
- if (i>=4) Tasks.current().submittedByTask.period = null
- log.info "task running (${i}): "+Tasks.current()+" "+Tasks.current().getStatusDetail(false)
- ++i;
- }) } );
-
- log.info "submitting {} {}", t, t.getStatusDetail(false)
- m.submit(t);
- log.info "submitted {} {}", t, t.getStatusDetail(false)
- int interimResult = t.get()
- log.info "done one ({}) {} {}", interimResult, t, t.getStatusDetail(false)
- assertTrue(i>0)
- t.blockUntilEnded()
- int finalResult = t.get()
- log.info "ended ({}) {} {}", finalResult, t, t.getStatusDetail(false)
- assertEquals(finalResult, 5)
- assertEquals(i, 5)
- }
-
- @Test
- public void testScheduledTaskCancelEnding() {
- int PERIOD = 20;
- BasicExecutionManager m = new BasicExecutionManager();
- int i=0;
- def t = new ScheduledTask(delay: 2*PERIOD*TimeUnit.MILLISECONDS, period: PERIOD*TimeUnit.MILLISECONDS, { new BasicTask({
- log.info "task running (${i}): "+Tasks.current()+" "+Tasks.current().getStatusDetail(false)
- ++i;
- if (i>=5) Tasks.current().submittedByTask.cancel()
- i
- }) } );
-
- log.info "submitting {} {}", t, t.getStatusDetail(false)
- m.submit(t);
- log.info "submitted {} {}", t, t.getStatusDetail(false)
- int interimResult = t.get()
- log.info "done one ({}) {} {}", interimResult, t, t.getStatusDetail(false)
- assertTrue(i>0)
- t.blockUntilEnded()
-// int finalResult = t.get()
- log.info "ended ({}) {} {}", i, t, t.getStatusDetail(false)
-// assertEquals(finalResult, 5)
- assertEquals(i, 5)
- }
-
- @Test(groups="Integration")
- public void testScheduledTaskTakesLongerThanPeriod() {
- final int PERIOD = 1;
- final int SLEEP_TIME = 100;
- final int EARLY_RETURN_GRACE = 10;
- BasicExecutionManager m = new BasicExecutionManager();
- final List<Long> execTimes = new CopyOnWriteArrayList<Long>();
-
- def t = new ScheduledTask(delay: PERIOD*TimeUnit.MILLISECONDS, period: PERIOD*TimeUnit.MILLISECONDS, { new BasicTask({
- execTimes.add(System.currentTimeMillis());
- Thread.sleep(100);
- }) } );
-
- m.submit(t);
-
- TestUtils.executeUntilSucceeds {
- execTimes.size() > 3;
- }
-
- List<Long> timeDiffs = Lists.newArrayList();
- long prevExecTime = -1;
- for (Long execTime : execTimes) {
- if (prevExecTime == -1) {
- prevExecTime = execTime;
- } else {
- timeDiffs.add(execTime - prevExecTime);
- prevExecTime = execTime;
- }
- }
-
- for (Long timeDiff : timeDiffs) {
- if (timeDiff < (SLEEP_TIME - EARLY_RETURN_GRACE)) fail("timeDiffs="+timeDiffs+"; execTimes="+execTimes);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35363d61/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.java b/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.java
new file mode 100644
index 0000000..9cda495
--- /dev/null
+++ b/core/src/test/java/brooklyn/util/task/ScheduledExecutionTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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 brooklyn.util.task;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.Test;
+
+import brooklyn.management.Task;
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.exceptions.Exceptions;
+
+import com.google.common.collect.Lists;
+
+public class ScheduledExecutionTest {
+
+ public static final Logger log = LoggerFactory.getLogger(ScheduledExecutionTest.class);
+
+ @Test
+ public void testScheduledTask() throws Exception {
+ int PERIOD = 20;
+ BasicExecutionManager m = new BasicExecutionManager("mycontextid");
+ final AtomicInteger i = new AtomicInteger(0);
+ ScheduledTask t = new ScheduledTask(MutableMap.of("delay", 2*PERIOD, "period", PERIOD, "maxIterations", 5), new Callable<Task<?>>() {
+ public Task<?> call() throws Exception {
+ return new BasicTask<Integer>(new Callable<Integer>() {
+ public Integer call() {
+ log.debug("task running: "+Tasks.current()+" "+Tasks.current().getStatusDetail(false));
+ return i.incrementAndGet();
+ }});
+ }});
+
+ log.info("submitting {} {}", t, t.getStatusDetail(false));
+ m.submit(t);
+ log.info("submitted {} {}", t, t.getStatusDetail(false));
+ Integer interimResult = (Integer) t.get();
+ log.info("done one ({}) {} {}", new Object[] {interimResult, t, t.getStatusDetail(false)});
+ assertTrue(i.get() > 0, "i="+i);
+ t.blockUntilEnded();
+ Integer finalResult = (Integer) t.get();
+ log.info("ended ({}) {} {}", new Object[] {finalResult, t, t.getStatusDetail(false)});
+ assertEquals(finalResult, (Integer)5);
+ assertEquals(i.get(), 5);
+ }
+
+ /** like testScheduledTask but the loop is terminated by the task itself adjusting the period */
+ @Test
+ public void testScheduledTaskSelfEnding() throws Exception {
+ int PERIOD = 20;
+ BasicExecutionManager m = new BasicExecutionManager("mycontextid");
+ final AtomicInteger i = new AtomicInteger(0);
+ ScheduledTask t = new ScheduledTask(MutableMap.of("delay", 2*PERIOD, "period", PERIOD), new Callable<Task<?>>() {
+ public Task<?> call() throws Exception {
+ return new BasicTask<Integer>(new Callable<Integer>() {
+ public Integer call() {
+ ScheduledTask submitter = (ScheduledTask) ((BasicTask)Tasks.current()).submittedByTask;
+ if (i.get() >= 4) submitter.period = null;
+ log.info("task running ("+i+"): "+Tasks.current()+" "+Tasks.current().getStatusDetail(false));
+ return i.incrementAndGet();
+ }});
+ }});
+
+ log.info("submitting {} {}", t, t.getStatusDetail(false));
+ m.submit(t);
+ log.info("submitted {} {}", t, t.getStatusDetail(false));
+ Integer interimResult = (Integer) t.get();
+ log.info("done one ({}) {} {}", new Object[] {interimResult, t, t.getStatusDetail(false)});
+ assertTrue(i.get() > 0);
+ t.blockUntilEnded();
+ Integer finalResult = (Integer) t.get();
+ log.info("ended ({}) {} {}", new Object[] {finalResult, t, t.getStatusDetail(false)});
+ assertEquals(finalResult, (Integer)5);
+ assertEquals(i.get(), 5);
+ }
+
+ @Test
+ public void testScheduledTaskCancelEnding() throws Exception {
+ int PERIOD = 20;
+ BasicExecutionManager m = new BasicExecutionManager("mycontextid");
+ final AtomicInteger i = new AtomicInteger();
+ ScheduledTask t = new ScheduledTask(MutableMap.of("delay", 2*PERIOD, "period", PERIOD), new Callable<Task<?>>() {
+ public Task<?> call() throws Exception {
+ return new BasicTask<Integer>(new Callable<Integer>() {
+ public Integer call() {
+ log.info("task running ("+i+"): "+Tasks.current()+" "+Tasks.current().getStatusDetail(false));
+ ScheduledTask submitter = (ScheduledTask) ((BasicTask)Tasks.current()).submittedByTask;
+ i.incrementAndGet();
+ if (i.get() >= 5) submitter.cancel();
+ return i.get();
+ }});
+ }});
+
+ log.info("submitting {} {}", t, t.getStatusDetail(false));
+ m.submit(t);
+ log.info("submitted {} {}", t, t.getStatusDetail(false));
+ Integer interimResult = (Integer) t.get();
+ log.info("done one ({}) {} {}", new Object[] {interimResult, t, t.getStatusDetail(false)});
+ assertTrue(i.get() > 0);
+ t.blockUntilEnded();
+// int finalResult = t.get()
+ log.info("ended ({}) {} {}", new Object[] {i, t, t.getStatusDetail(false)});
+// assertEquals(finalResult, 5)
+ assertEquals(i.get(), 5);
+ }
+
+ @Test(groups="Integration")
+ public void testScheduledTaskTakesLongerThanPeriod() throws Exception {
+ final int PERIOD = 1;
+ final int SLEEP_TIME = 100;
+ final int EARLY_RETURN_GRACE = 10;
+ BasicExecutionManager m = new BasicExecutionManager("mycontextid");
+ final List<Long> execTimes = new CopyOnWriteArrayList<Long>();
+
+ ScheduledTask t = new ScheduledTask(MutableMap.of("delay", PERIOD, "period", PERIOD), new Callable<Task<?>>() {
+ public Task<?> call() throws Exception {
+ return new BasicTask<Void>(new Runnable() {
+ public void run() {
+ execTimes.add(System.currentTimeMillis());
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ throw Exceptions.propagate(e);
+ }
+ }});
+ }});
+
+ m.submit(t);
+
+ Asserts.succeedsEventually(new Runnable() {
+ public void run() {
+ assertTrue(execTimes.size() > 3, "size="+execTimes.size());
+ }});
+
+ List<Long> timeDiffs = Lists.newArrayList();
+ long prevExecTime = -1;
+ for (Long execTime : execTimes) {
+ if (prevExecTime == -1) {
+ prevExecTime = execTime;
+ } else {
+ timeDiffs.add(execTime - prevExecTime);
+ prevExecTime = execTime;
+ }
+ }
+
+ for (Long timeDiff : timeDiffs) {
+ if (timeDiff < (SLEEP_TIME - EARLY_RETURN_GRACE)) fail("timeDiffs="+timeDiffs+"; execTimes="+execTimes);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35363d61/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.groovy b/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.groovy
deleted file mode 100644
index debc8e6..0000000
--- a/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.groovy
+++ /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 brooklyn.util.task
-
-import static brooklyn.test.TestUtils.*
-import static org.testng.Assert.*
-
-import java.util.concurrent.CancellationException
-import java.util.concurrent.CopyOnWriteArrayList
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.Future
-import java.util.concurrent.TimeUnit
-import java.util.concurrent.TimeoutException
-import java.util.concurrent.atomic.AtomicInteger
-
-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 SingleThreadedSchedulerTest {
-
- private static final Logger log = LoggerFactory.getLogger(SingleThreadedSchedulerTest)
-
- private BasicExecutionManager em
-
- @BeforeMethod
- public void setUp() {
- em = new BasicExecutionManager()
- em.setTaskSchedulerForTag("category1", SingleThreadedScheduler.class);
- }
-
- @AfterMethod
- public void tearDown() {
- em?.shutdownNow()
- }
-
- @Test
- public void testExecutesInOrder() {
- final int NUM_TIMES = 1000
- final List<Integer> result = new CopyOnWriteArrayList()
- for (i in 0..(NUM_TIMES-1)) {
- final counter = i
- em.submit(tag:"category1", { result.add(counter) })
- }
-
- executeUntilSucceeds {
- assertEquals(result.size(), NUM_TIMES)
- }
-
- for (i in 0..(NUM_TIMES-1)) {
- assertEquals(result.get(i), i)
- }
- }
-
- @Test
- public void testLargeQueueDoesNotConsumeTooManyThreads() {
- final int NUM_TIMES = 3000
- final CountDownLatch latch = new CountDownLatch(1)
- BasicTask blockingTask = [ { latch.await() } ]
- em.submit tag:"category1", blockingTask
-
- final AtomicInteger counter = new AtomicInteger(0)
- for (i in 1..NUM_TIMES) {
- BasicTask t = [ {counter.incrementAndGet()} ]
- em.submit tag:"category1", t
- if (i % 500 == 0) log.info("Submitted $i jobs...")
- }
-
- Thread.sleep(100) // give it more of a chance to create the threads before we let them execute
- latch.countDown()
-
- executeUntilSucceeds {
- assertEquals(counter.get(), NUM_TIMES)
- }
- }
-
- @Test
- public void testGetResultOfQueuedTaskBeforeItExecutes() {
- final CountDownLatch latch = new CountDownLatch(1)
- em.submit([tag:"category1"], { latch.await() })
-
- BasicTask t = [ {return 123} ]
- Future future = em.submit tag:"category1", t
-
- new Thread({Thread.sleep(10);latch.countDown()}).start();
- assertEquals(future.get(), 123)
- }
-
- @Test
- public void testGetResultOfQueuedTaskBeforeItExecutesWithTimeout() {
- final CountDownLatch latch = new CountDownLatch(1)
- em.submit([tag:"category1"], { latch.await() })
-
- BasicTask t = [ {return 123} ]
- Future future = em.submit tag:"category1", t
-
- try {
- assertEquals(future.get(10, TimeUnit.MILLISECONDS), 123)
- fail()
- } catch (TimeoutException e) {
- // success
- }
- }
-
- @Test
- public void testCancelQueuedTaskBeforeItExecutes() {
- final CountDownLatch latch = new CountDownLatch(1)
- em.submit([tag:"category1"], { latch.await() })
-
- boolean executed = false
- BasicTask t = [ {execututed = true} ]
- Future future = em.submit tag:"category1", t
-
- future.cancel(true)
- latch.countDown()
- Thread.sleep(10)
- try {
- future.get()
- } catch (CancellationException e) {
- // success
- }
- assertFalse(executed)
- }
-
- @Test
- public void testGetResultOfQueuedTaskAfterItExecutes() {
- final CountDownLatch latch = new CountDownLatch(1)
- em.submit([tag:"category1"], { latch.await() })
-
- BasicTask t = [ {return 123} ]
- Future future = em.submit tag:"category1", t
-
- latch.countDown()
- assertEquals(future.get(), 123)
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35363d61/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.java b/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.java
new file mode 100644
index 0000000..265956d
--- /dev/null
+++ b/core/src/test/java/brooklyn/util/task/SingleThreadedSchedulerTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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 brooklyn.util.task;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.test.Asserts;
+import brooklyn.util.collections.MutableMap;
+
+import com.google.common.util.concurrent.Callables;
+
+public class SingleThreadedSchedulerTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SingleThreadedSchedulerTest.class);
+
+ private BasicExecutionManager em;
+
+ @BeforeMethod
+ public void setUp() {
+ em = new BasicExecutionManager("mycontextid");
+ em.setTaskSchedulerForTag("category1", SingleThreadedScheduler.class);
+ }
+
+ @AfterMethod
+ public void tearDown() {
+ if (em != null) em.shutdownNow();
+ }
+
+ @Test
+ public void testExecutesInOrder() throws Exception {
+ final int NUM_TIMES = 1000;
+ final List<Integer> result = new CopyOnWriteArrayList<Integer>();
+ for (int i = 0; i < NUM_TIMES; i++) {
+ final int counter = i;
+ em.submit(MutableMap.of("tag", "category1"), new Runnable() {
+ public void run() {
+ result.add(counter);
+ }});
+ }
+
+ Asserts.succeedsEventually(new Runnable() {
+ @Override public void run() {
+ assertEquals(result.size(), NUM_TIMES);
+ }});
+
+ for (int i = 0; i < NUM_TIMES; i++) {
+ assertEquals(result.get(i), (Integer)i);
+ }
+ }
+
+ @Test
+ public void testLargeQueueDoesNotConsumeTooManyThreads() throws Exception {
+ final int NUM_TIMES = 3000;
+ final CountDownLatch latch = new CountDownLatch(1);
+ BasicTask<Void> blockingTask = new BasicTask<Void>(newLatchAwaiter(latch));
+ em.submit(MutableMap.of("tag", "category1"), blockingTask);
+
+ final AtomicInteger counter = new AtomicInteger(0);
+ for (int i = 0; i < NUM_TIMES; i++) {
+ BasicTask<Void> t = new BasicTask<Void>(new Runnable() {
+ public void run() {
+ counter.incrementAndGet();
+ }});
+ em.submit(MutableMap.of("tag", "category1"), t);
+ if (i % 500 == 0) log.info("Submitted "+i+" jobs...");
+ }
+
+ Thread.sleep(100); // give it more of a chance to create the threads before we let them execute
+ latch.countDown();
+
+ Asserts.succeedsEventually(new Runnable() {
+ @Override public void run() {
+ assertEquals(counter.get(), NUM_TIMES);
+ }});
+ }
+
+ @Test
+ public void testGetResultOfQueuedTaskBeforeItExecutes() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ em.submit(MutableMap.of("tag", "category1"), newLatchAwaiter(latch));
+
+ BasicTask<Integer> t = new BasicTask<Integer>(Callables.returning(123));
+ Future<Integer> future = em.submit(MutableMap.of("tag", "category1"), t);
+
+ Thread thread = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ latch.countDown();
+ }});
+ thread.start();
+ assertEquals(future.get(), (Integer)123);
+ }
+
+ @Test
+ public void testGetResultOfQueuedTaskBeforeItExecutesWithTimeout() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ em.submit(MutableMap.of("tag", "category1"), newLatchAwaiter(latch));
+
+ BasicTask<Integer> t = new BasicTask<Integer>(Callables.returning(123));
+ Future<Integer> future = em.submit(MutableMap.of("tag", "category1"), t);
+
+ try {
+ assertEquals(future.get(10, TimeUnit.MILLISECONDS), (Integer)123);
+ fail();
+ } catch (TimeoutException e) {
+ // success
+ }
+ }
+
+ @Test
+ public void testCancelQueuedTaskBeforeItExecutes() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ em.submit(MutableMap.of("tag", "category1"), newLatchAwaiter(latch));
+
+ final AtomicBoolean executed = new AtomicBoolean();
+ BasicTask<?> t = new BasicTask<Void>(new Runnable() {
+ public void run() {
+ executed.set(true);
+ }});
+ Future<?> future = em.submit(MutableMap.of("tag", "category1"), t);
+
+ future.cancel(true);
+ latch.countDown();
+ Thread.sleep(10);
+ try {
+ future.get();
+ } catch (CancellationException e) {
+ // success
+ }
+ assertFalse(executed.get());
+ }
+
+ @Test
+ public void testGetResultOfQueuedTaskAfterItExecutes() throws Exception {
+ final CountDownLatch latch = new CountDownLatch(1);
+ em.submit(MutableMap.of("tag", "category1"), newLatchAwaiter(latch));
+
+ BasicTask<Integer> t = new BasicTask<Integer>(Callables.returning(123));
+ Future<Integer> future = em.submit(MutableMap.of("tag", "category1"), t);
+
+ latch.countDown();
+ assertEquals(future.get(), (Integer)123);
+ }
+
+ private Callable<Void> newLatchAwaiter(final CountDownLatch latch) {
+ return new Callable<Void>() {
+ public Void call() throws Exception {
+ latch.await();
+ return null;
+ }
+ };
+ }
+}
[07/13] git commit: add an initializer for adding tags, with a test
Posted by he...@apache.org.
add an initializer for adding tags, with a test
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/1a294f76
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/1a294f76
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/1a294f76
Branch: refs/heads/master
Commit: 1a294f76a1e955582c5dc4d7c99526b60afef421
Parents: 78da216
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 12:25:48 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:26:20 2014 -0400
----------------------------------------------------------------------
.../entity/basic/EntityInitializers.java | 30 ++++++++++++++++++++
.../brooklyn/entity/basic/EntitiesTest.java | 6 ++--
.../test/java/brooklyn/util/net/UrlsTest.java | 5 ++++
3 files changed, 39 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1a294f76/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java b/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
new file mode 100644
index 0000000..62db62e
--- /dev/null
+++ b/core/src/main/java/brooklyn/entity/basic/EntityInitializers.java
@@ -0,0 +1,30 @@
+package brooklyn.entity.basic;
+
+import java.util.List;
+
+import brooklyn.entity.proxying.EntityInitializer;
+
+import com.google.common.collect.ImmutableList;
+
+public class EntityInitializers {
+
+ public static class AddTags implements EntityInitializer {
+ public final List<Object> tags;
+
+ public AddTags(Object... tags) {
+ this.tags = ImmutableList.copyOf(tags);
+ }
+
+ @Override
+ public void apply(EntityLocal entity) {
+ for (Object tag: tags)
+ entity.addTag(tag);
+ }
+ }
+
+
+ public static EntityInitializer addingTags(Object... tags) {
+ return new AddTags(tags);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1a294f76/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
index 3f72388..8acdf72 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/EntitiesTest.java
@@ -106,7 +106,9 @@ public class EntitiesTest extends BrooklynAppUnitTestSupport {
@Test
public void testCreateGetContainsAndRemoveTags() throws Exception {
- entity.addTag("foo");
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+ .addInitializer(EntityInitializers.addingTags("foo")));
+
entity.addTag(app);
Assert.assertTrue(entity.containsTag("foo"));
@@ -122,5 +124,5 @@ public class EntitiesTest extends BrooklynAppUnitTestSupport {
Assert.assertEquals(entity.getTags(), MutableSet.of(app));
}
-
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1a294f76/utils/common/src/test/java/brooklyn/util/net/UrlsTest.java
----------------------------------------------------------------------
diff --git a/utils/common/src/test/java/brooklyn/util/net/UrlsTest.java b/utils/common/src/test/java/brooklyn/util/net/UrlsTest.java
index 017ad3d..d0a615c 100644
--- a/utils/common/src/test/java/brooklyn/util/net/UrlsTest.java
+++ b/utils/common/src/test/java/brooklyn/util/net/UrlsTest.java
@@ -43,6 +43,11 @@ public class UrlsTest {
}
@Test
+ public void testPathEncode() throws Exception {
+ assertEquals(Urls.encode("name_with/%!"), "name_with%2F%25%21");
+ }
+
+ @Test
public void testIsUrlWithProtocol() {
Assert.assertTrue(Urls.isUrlWithProtocol("http://localhost/"));
Assert.assertTrue(Urls.isUrlWithProtocol("protocol:"));
[10/13] git commit: fix intermittent failing test by ensuring we wait
for persistence to complete
Posted by he...@apache.org.
fix intermittent failing test by ensuring we wait for persistence to complete
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ebfec154
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ebfec154
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ebfec154
Branch: refs/heads/master
Commit: ebfec154ae569ba5a7e9257e7415a928857b933c
Parents: cefcda3
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 09:51:15 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:26:21 2014 -0400
----------------------------------------------------------------------
.../BrooklynMementoPersisterInMemorySizeIntegrationTest.java | 7 +++++++
1 file changed, 7 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ebfec154/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
index 1d82962..d2638cf 100644
--- a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
@@ -49,6 +49,10 @@ public class BrooklynMementoPersisterInMemorySizeIntegrationTest extends Brookly
public void testPersistenceVolumeFast() throws IOException, TimeoutException, InterruptedException {
doTestPersistenceVolume(50*1000, false);
}
+ @Test(groups="Integration",invocationCount=20)
+ public void testPersistenceVolumeFastManyTimes() throws IOException, TimeoutException, InterruptedException {
+ doTestPersistenceVolume(50*1000, false);
+ }
@Test(groups="Integration")
public void testPersistenceVolumeWaiting() throws IOException, TimeoutException, InterruptedException {
// by waiting we ensure there aren't extra writes going on
@@ -58,6 +62,7 @@ public class BrooklynMementoPersisterInMemorySizeIntegrationTest extends Brookly
protected void doTestPersistenceVolume(int bigBlockSize, boolean forceDelay) throws IOException, TimeoutException, InterruptedException {
if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);
else recorder.blockUntilDataWrittenExceeds(512, Duration.FIVE_SECONDS);
+ localManagementContext.getRebindManager().waitForPendingComplete(Duration.FIVE_SECONDS);
long out1 = recorder.getBytesOut();
int filesOut1 = recorder.getCountDataOut();
@@ -68,6 +73,7 @@ public class BrooklynMementoPersisterInMemorySizeIntegrationTest extends Brookly
((EntityInternal)app).setAttribute(TestEntity.NAME, "hello world");
if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);
else recorder.blockUntilDataWrittenExceeds(out1+10, Duration.FIVE_SECONDS);
+ localManagementContext.getRebindManager().waitForPendingComplete(Duration.FIVE_SECONDS);
long out2 = recorder.getBytesOut();
Assert.assertTrue(out2-out1>10, "should have written more data");
@@ -80,6 +86,7 @@ public class BrooklynMementoPersisterInMemorySizeIntegrationTest extends Brookly
((EntityInternal)entity).setAttribute(TestEntity.NAME, Identifiers.makeRandomId(bigBlockSize));
if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);
else recorder.blockUntilDataWrittenExceeds(out2+bigBlockSize, Duration.FIVE_SECONDS);
+ localManagementContext.getRebindManager().waitForPendingComplete(Duration.FIVE_SECONDS);
long out3 = recorder.getBytesOut();
Assert.assertTrue(out3-out2 > bigBlockSize, "should have written 50k more data, only wrote "+out3+" compared with "+out2);
[08/13] git commit: more tests for BrooklynNode, including test which
uses REST API of local instance (and new "SameBrooklynNodeImpl" semi-mock);
and adds BrooklynEntityMirror with test
Posted by he...@apache.org.
more tests for BrooklynNode, including test which uses REST API of local instance (and new "SameBrooklynNodeImpl" semi-mock); and adds BrooklynEntityMirror with test
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/8569120c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/8569120c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/8569120c
Branch: refs/heads/master
Commit: 8569120c909e782b5ca2f90525795822f3e9395b
Parents: 1a294f7
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 23:50:20 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:26:20 2014 -0400
----------------------------------------------------------------------
.../brooklyn/config/BrooklynServerConfig.java | 6 +
.../config/BrooklynServiceAttributes.java | 2 +-
.../brooklynnode/BrooklynEntityMirror.java | 52 ++++++
.../brooklynnode/BrooklynEntityMirrorImpl.java | 169 +++++++++++++++++++
.../entity/brooklynnode/BrooklynNode.java | 3 +
.../entity/brooklynnode/BrooklynNodeImpl.java | 8 +-
.../entity/brooklynnode/BrooklynNodeTest.java | 18 ++
.../brooklynnode/SameBrooklynNodeImpl.java | 86 ++++++++++
.../camp/BrooklynCampPlatformLauncher.java | 7 +-
.../entity/basic/VanillaSoftwareYamlTest.java | 5 +-
.../brooklynnode/BrooklynNodeRestTest.java | 92 ++++++++++
.../launcher/BrooklynWebServerTest.java | 1 -
.../launcher/SimpleYamlLauncherForTests.java | 31 ++++
.../java/brooklyn/util/collections/Jsonya.java | 8 +
14 files changed, 480 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/core/src/main/java/brooklyn/config/BrooklynServerConfig.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/config/BrooklynServerConfig.java b/core/src/main/java/brooklyn/config/BrooklynServerConfig.java
index fccba64..adc41be 100644
--- a/core/src/main/java/brooklyn/config/BrooklynServerConfig.java
+++ b/core/src/main/java/brooklyn/config/BrooklynServerConfig.java
@@ -22,6 +22,7 @@ import static brooklyn.entity.basic.ConfigKeys.newStringConfigKey;
import io.brooklyn.camp.CampPlatform;
import java.io.File;
+import java.net.URI;
import java.util.Map;
import org.apache.commons.io.FileUtils;
@@ -164,4 +165,9 @@ public class BrooklynServerConfig {
return Maybe.absent("No CAMP Platform is registered with this Brooklyn management context.");
}
+ /** Returns {@link ManagementContext#getManagementNodeUri()}, located in this utility class for convenience. */
+ public static Maybe<URI> getBrooklynWebUri(ManagementContext mgmt) {
+ return mgmt.getManagementNodeUri();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/core/src/main/java/brooklyn/config/BrooklynServiceAttributes.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/config/BrooklynServiceAttributes.java b/core/src/main/java/brooklyn/config/BrooklynServiceAttributes.java
index 2eac234..840bf59 100644
--- a/core/src/main/java/brooklyn/config/BrooklynServiceAttributes.java
+++ b/core/src/main/java/brooklyn/config/BrooklynServiceAttributes.java
@@ -38,7 +38,7 @@ public class BrooklynServiceAttributes {
/** used to hold the instance of ManagementContext which should be used */
public static final String BROOKLYN_MANAGEMENT_CONTEXT = ManagementContext.class.getName();
-
+
/** poor-man's security, to specify a user to be automatically logged in
* (e.g. to bypass security, during dev/test); 'admin' is usually a sensible choice.
* if not specified (the default) username+password is required.
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
new file mode 100644
index 0000000..2773793
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirror.java
@@ -0,0 +1,52 @@
+/*
+ * 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 brooklyn.entity.brooklynnode;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.brooklynnode.BrooklynNode;
+import brooklyn.entity.proxying.ImplementedBy;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.util.time.Duration;
+
+/** Provides an entity which can sit in one brooklyn domain and reflect the status of an entity
+ * via the REST API of another domain */
+@ImplementedBy(BrooklynEntityMirrorImpl.class)
+public interface BrooklynEntityMirror extends Entity {
+
+ // caller must specify this:
+ public static final ConfigKey<String> MIRRORED_ENTITY_URL = ConfigKeys.newStringConfigKey("brooklyn.mirror.entity_url",
+ "URL for the entity in the remote Brooklyn mgmt endpoint");
+
+ // caller may specify this for reference:
+ public static final ConfigKey<String> MIRRORED_ENTITY_ID = ConfigKeys.newStringConfigKey("brooklyn.mirror.entity_id",
+ "Brooklyn ID of the entity being mirrored");
+
+ // must be specified if required (could be inherited if parent/config is available at init time, but it's not currently)
+ public static final ConfigKey<String> MANAGEMENT_USER = BrooklynNode.MANAGEMENT_USER;
+ public static final ConfigKey<String> MANAGEMENT_PASSWORD = BrooklynNode.MANAGEMENT_PASSWORD;
+
+ public static final ConfigKey<Duration> POLL_PERIOD = ConfigKeys.newConfigKey(Duration.class, "brooklyn.mirror.poll_period",
+ "Frequency to poll for client sensors", Duration.FIVE_SECONDS);
+
+ public static final AttributeSensor<String> MIRROR_STATUS = Sensors.newStringSensor("brooklyn.mirror.monitoring_status");
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.java
new file mode 100644
index 0000000..8407708
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynEntityMirrorImpl.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 brooklyn.entity.brooklynnode;
+
+import java.net.URI;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.HttpClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityFunctions;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.effector.EffectorBody;
+import brooklyn.event.AttributeSensor;
+import brooklyn.event.basic.Sensors;
+import brooklyn.event.feed.http.HttpFeed;
+import brooklyn.event.feed.http.HttpPollConfig;
+import brooklyn.util.collections.Jsonya;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.http.HttpTool;
+import brooklyn.util.http.HttpTool.HttpClientBuilder;
+import brooklyn.util.http.HttpToolResponse;
+import brooklyn.util.net.Urls;
+import brooklyn.util.stream.Streams;
+import brooklyn.util.task.Tasks;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
+import com.google.gson.Gson;
+
+public class BrooklynEntityMirrorImpl extends AbstractEntity implements BrooklynEntityMirror {
+
+ private static final Logger log = LoggerFactory.getLogger(BrooklynEntityMirrorImpl.class);
+
+ private HttpFeed mirror;
+
+ @Override
+ public void init() {
+ super.init();
+ connectSensors();
+ }
+
+ protected void connectSensors() {
+ Function<HttpToolResponse, Void> mirrorSensors = new Function<HttpToolResponse,Void>() {
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Void apply(HttpToolResponse input) {
+ Map sensors = new Gson().fromJson(input.getContentAsString(), Map.class);
+ for (Object kv: sensors.entrySet())
+ setAttribute(Sensors.newSensor(Object.class, ""+((Map.Entry)kv).getKey()), ((Map.Entry)kv).getValue());
+ setAttribute(MIRROR_STATUS, "normal");
+ return null;
+ }
+ };
+
+ String sensorsUri = Urls.mergePaths(
+ Preconditions.checkNotNull(getConfig(MIRRORED_ENTITY_URL), "Required config: "+MIRRORED_ENTITY_URL),
+ "sensors/current-state");
+
+ mirror = HttpFeed.builder().entity(this)
+ .baseUri(sensorsUri)
+ .credentialsIfNotNull(getConfig(BrooklynNode.MANAGEMENT_USER), getConfig(BrooklynNode.MANAGEMENT_PASSWORD))
+ .period(getConfig(POLL_PERIOD))
+ .poll(HttpPollConfig.forMultiple()
+ .onSuccess(mirrorSensors)
+ .onFailureOrException(EntityFunctions.settingSensorsConstantFunction(this, MutableMap.<AttributeSensor<?>,Object>of(
+ Attributes.SERVICE_STATE, Lifecycle.ON_FIRE,
+ MIRROR_STATUS, "error contacting service"
+ ))) )
+ .build();
+ }
+
+ protected void disconnectSensors() {
+ if (mirror != null) mirror.stop();
+ }
+
+ @Override
+ public void destroy() {
+ disconnectSensors();
+ }
+
+ public static class RemoteEffector<T> extends EffectorBody<T> {
+ public final String remoteEffectorName;
+ public final Function<byte[], T> resultParser;
+
+ /** creates an effector implementation which POSTs to a remote effector endpoint, optionally converting
+ * the byte[] response (if resultParser is null then null is returned) */
+ public RemoteEffector(String remoteEffectorName, @Nullable Function<byte[],T> resultParser) {
+ this.remoteEffectorName = remoteEffectorName;
+ this.resultParser = resultParser;
+ }
+
+ @Override
+ public T call(ConfigBag parameters) {
+ String baseUri = Preconditions.checkNotNull(entity().getConfig(MIRRORED_ENTITY_URL), "Cannot be invoked without an entity URL");
+ HttpClientBuilder builder = HttpTool.httpClientBuilder()
+ .trustAll()
+ .laxRedirect(true)
+ .uri(baseUri);
+ if (entity().getConfig(MANAGEMENT_USER)!=null)
+ builder.credentials(new UsernamePasswordCredentials(entity().getConfig(MANAGEMENT_USER), entity().getConfig(MANAGEMENT_PASSWORD)));
+ HttpClient client = builder.build();
+
+ byte[] result = submit(client, URI.create(Urls.mergePaths(baseUri, "effectors", Urls.encode(remoteEffectorName))), parameters.getAllConfig());
+ if (resultParser!=null) return resultParser.apply(result);
+ else return null;
+ }
+
+ @VisibleForTesting
+ public static byte[] submit(HttpClient client, URI uri, Map<String,Object> args) {
+ HttpToolResponse result = null;
+ byte[] content;
+ try {
+ result = HttpTool.httpPost(client, uri, MutableMap.of(com.google.common.net.HttpHeaders.CONTENT_TYPE, "application/json"),
+ Jsonya.of(args).toString().getBytes());
+ content = result.getContent();
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ throw new IllegalStateException("Invalid response invoking "+uri+": "+e, e);
+ }
+ Tasks.addTagDynamically(BrooklynTaskTags.tagForStream("http_response", Streams.byteArray(content)));
+ if (!HttpTool.isStatusCodeHealthy(result.getResponseCode())) {
+ log.warn("Invalid response invoking "+uri+": response code "+result.getResponseCode()+"\n"+result+": "+new String(content));
+ throw new IllegalStateException("Invalid response invoking "+uri+": response code "+result.getResponseCode());
+ }
+ return content;
+ }
+
+ }
+
+ public static class StopAndExpungeEffector extends RemoteEffector<Void> {
+ public StopAndExpungeEffector() {
+ super("stop", null);
+ }
+ @Override
+ public Void call(ConfigBag parameters) {
+ super.call(parameters);
+ Entities.unmanage(entity());
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
index e61fd25..75523e3 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNode.java
@@ -166,6 +166,7 @@ public interface BrooklynNode extends SoftwareProcess, UsesJava {
public static final ConfigKey<String> BROOKLYN_CATALOG_CONTENTS = ConfigKeys.newStringConfigKey(
"brooklynnode.brooklyncatalog.contents", "Contents for the brooklyn catalog.xml file (to upload to ~/.brooklyn/catalog.xml", null);
+ @SuppressWarnings({ "rawtypes", "unchecked" })
@SetFromFlag("enabledHttpProtocols")
public static final BasicAttributeSensorAndConfigKey<List<String>> ENABLED_HTTP_PROTOCOLS = new BasicAttributeSensorAndConfigKey(
List.class, "brooklynnode.webconsole.enabledHttpProtocols", "List of enabled protocols (e.g. http, https)", ImmutableList.of("http"));
@@ -186,10 +187,12 @@ public interface BrooklynNode extends SoftwareProcess, UsesJava {
public static final BasicAttributeSensorAndConfigKey<String> WEB_CONSOLE_BIND_ADDRESS = new BasicAttributeSensorAndConfigKey<String>(
String.class, "brooklynnode.webconsole.bindAddress", "Specifies the IP address of the NIC to bind the Brooklyn Management Console to", null);
+ @SuppressWarnings({ "rawtypes", "unchecked" })
@SetFromFlag("classpath")
public static final BasicAttributeSensorAndConfigKey<List<String>> CLASSPATH = new BasicAttributeSensorAndConfigKey(
List.class, "brooklynnode.classpath", "classpath to use, as list of URL entries", Lists.newArrayList());
+ @SuppressWarnings({ "rawtypes", "unchecked" })
@SetFromFlag("portMapper")
public static final ConfigKey<Function<? super Integer, ? extends Integer>> PORT_MAPPER = (ConfigKey) ConfigKeys.newConfigKey(Function.class,
"brooklynnode.webconsole.portMapper", "Function for mapping private to public ports, for use in inferring the brooklyn URI", Functions.<Integer>identity());
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 983cce5..5c29980 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -75,7 +75,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
}
@Override
- public Class getDriverInterface() {
+ public Class<?> getDriverInterface() {
return BrooklynNodeDriver.class;
}
@@ -90,6 +90,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
// TODO support YAML parsing
// TODO define a new type YamlMap for the config key which supports coercing from string and from map
+ @SuppressWarnings("unchecked")
public static Map<String,Object> asMap(ConfigBag parameters, ConfigKey<?> key) {
Object v = parameters.getStringKey(key.getName());
if (v==null || (v instanceof String && Strings.isBlank((String)v)))
@@ -121,8 +122,9 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
throw new IllegalArgumentException("Must supply plan or url");
Map<String, Object> config = asMap(parameters, BLUEPRINT_CONFIG);
+
if (planRaw==null) {
- planRaw = Jsonya.at("services").list().put("serviceType", url).put(config).getRootMap();
+ planRaw = Jsonya.at("services").list().put("serviceType", url).putIfNotNull("brooklyn.config", config).getRootMap();
} else {
if (config!=null)
throw new IllegalArgumentException("Cannot supply plan with config");
@@ -130,7 +132,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
// planRaw might be a yaml string, or a map; if a map, convert to string
if (planRaw instanceof Map)
- planRaw = Jsonya.of((Map)planRaw).toString();
+ planRaw = Jsonya.of((Map<?,?>)planRaw).toString();
if (!(planRaw instanceof String))
throw new IllegalArgumentException("Invalid "+JavaClassNames.simpleClassName(planRaw)+" value for CAMP plan: "+planRaw);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
index 8f7d561..9752ec1 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
@@ -22,16 +22,21 @@ import static org.testng.Assert.assertTrue;
import java.util.List;
+import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import brooklyn.entity.basic.Attributes;
import brooklyn.entity.basic.Entities;
import brooklyn.entity.drivers.downloads.DownloadResolver;
+import brooklyn.entity.proxying.EntitySpec;
import brooklyn.event.feed.ConfigToAttributes;
+import brooklyn.location.Location;
import brooklyn.location.basic.SshMachineLocation;
import brooklyn.test.entity.TestApplication;
import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
public class BrooklynNodeTest {
@@ -79,4 +84,17 @@ public class BrooklynNodeTest {
System.out.println("urls="+urls);
assertTrue(urls.contains(expectedUrl), "urls="+urls);
}
+
+ @Test
+ public void testCanStartSameNode() throws Exception {
+ // not very interesting as done not have REST when run in this project
+ // but test BrooklynNodeRestTest in downstream project does
+ BrooklynNode bn = app.createAndManageChild(EntitySpec.create(BrooklynNode.class, SameBrooklynNodeImpl.class));
+ bn.start(MutableSet.<Location>of());
+
+ Assert.assertEquals(bn.getAttribute(Attributes.SERVICE_UP), (Boolean)true);
+ // no URI
+ Assert.assertNull(bn.getAttribute(BrooklynNode.WEB_CONSOLE_URI));
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
new file mode 100644
index 0000000..76e918c
--- /dev/null
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/SameBrooklynNodeImpl.java
@@ -0,0 +1,86 @@
+/*
+ * 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 brooklyn.entity.brooklynnode;
+
+import java.net.URI;
+import java.util.Collection;
+
+import brooklyn.entity.basic.AbstractEntity;
+import brooklyn.entity.brooklynnode.BrooklynNodeImpl.DeployBlueprintEffectorBody;
+import brooklyn.event.feed.http.HttpFeed;
+import brooklyn.event.feed.http.HttpPollConfig;
+import brooklyn.event.feed.http.HttpValueFunctions;
+import brooklyn.location.Location;
+
+/** Implementation of BrooklynNode which just presents the node where this is running, for convenience;
+ *
+ * start/stop/restart have no effect;
+ * sensors are connected;
+ * deploy blueprint assumes that a REST endpoint is available */
+public class SameBrooklynNodeImpl extends AbstractEntity implements BrooklynNode {
+
+ private HttpFeed httpFeed;
+
+ @Override
+ public void start(Collection<? extends Location> locations) {
+ connectSensors();
+ }
+
+ @Override
+ public void stop() {
+ disconnectSensors();
+ }
+
+ @Override
+ public void restart() {
+ return;
+ }
+
+
+ @Override
+ public void init() {
+ super.init();
+ getMutableEntityType().addEffector(DeployBlueprintEffectorBody.DEPLOY_BLUEPRINT);
+ }
+
+ protected void connectSensors() {
+ URI webConsoleUri = getManagementContext().getManagementNodeUri().orNull();
+ setAttribute(WEB_CONSOLE_URI, webConsoleUri);
+
+ if (webConsoleUri != null) {
+ httpFeed = HttpFeed.builder()
+ .entity(this)
+ .period(200)
+ .baseUri(webConsoleUri)
+ .credentialsIfNotNull(getConfig(MANAGEMENT_USER), getConfig(MANAGEMENT_PASSWORD))
+ .poll(new HttpPollConfig<Boolean>(SERVICE_UP)
+ .onSuccess(HttpValueFunctions.responseCodeEquals(200))
+ .setOnFailureOrException(false))
+ .build();
+
+ } else {
+ setAttribute(SERVICE_UP, true);
+ }
+ }
+
+ protected void disconnectSensors() {
+ if (httpFeed != null) httpFeed.stop();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java b/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
index c05c94f..c8e7df4 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/camp/BrooklynCampPlatformLauncher.java
@@ -24,6 +24,7 @@ import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherAbstract;
import io.brooklyn.camp.spi.PlatformRootSummary;
import brooklyn.entity.basic.BrooklynShutdownHooks;
import brooklyn.launcher.BrooklynLauncher;
+import brooklyn.management.ManagementContext;
import brooklyn.management.internal.LocalManagementContext;
import com.google.common.annotations.Beta;
@@ -39,7 +40,7 @@ public class BrooklynCampPlatformLauncher extends BrooklynCampPlatformLauncherAb
public BrooklynCampPlatformLauncher launch() {
assert platform == null;
- mgmt = new LocalManagementContext();
+ mgmt = newManagementContext();
// We created the management context, so we are responsible for terminating it
BrooklynShutdownHooks.invokeTerminateOnShutdown(mgmt);
@@ -54,6 +55,10 @@ public class BrooklynCampPlatformLauncher extends BrooklynCampPlatformLauncherAb
return this;
}
+ protected ManagementContext newManagementContext() {
+ return new LocalManagementContext();
+ }
+
public static void main(String[] args) {
new BrooklynCampPlatformLauncher().launch();
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/usage/launcher/src/test/java/brooklyn/entity/basic/VanillaSoftwareYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/entity/basic/VanillaSoftwareYamlTest.java b/usage/launcher/src/test/java/brooklyn/entity/basic/VanillaSoftwareYamlTest.java
index 5ef622e..8fbca64 100644
--- a/usage/launcher/src/test/java/brooklyn/entity/basic/VanillaSoftwareYamlTest.java
+++ b/usage/launcher/src/test/java/brooklyn/entity/basic/VanillaSoftwareYamlTest.java
@@ -26,6 +26,7 @@ import org.testng.annotations.Test;
import brooklyn.entity.Application;
import brooklyn.entity.Entity;
import brooklyn.entity.trait.Startable;
+import brooklyn.launcher.SimpleYamlLauncherForTests;
import brooklyn.launcher.camp.SimpleYamlLauncher;
import brooklyn.test.Asserts;
import brooklyn.util.ResourceUtils;
@@ -40,7 +41,7 @@ public class VanillaSoftwareYamlTest {
@Test(groups="Integration")
public void testVanillaSoftwareYaml() {
- SimpleYamlLauncher l = new SimpleYamlLauncher();
+ SimpleYamlLauncher l = new SimpleYamlLauncherForTests();
try {
Application app = l.launchAppYaml("vanilla-software-blueprint.yaml");
log.info("started "+app);
@@ -76,7 +77,7 @@ public class VanillaSoftwareYamlTest {
/** yaml variant of VanillaSoftwareProcessAndChildrenIntegrationTest */
@Test(groups="Integration")
public void testVanillaSoftwareYamlWithChildStartedAfter() {
- SimpleYamlLauncher l = new SimpleYamlLauncher();
+ SimpleYamlLauncher l = new SimpleYamlLauncherForTests();
try {
Application app = l.launchAppYaml("vanilla-software-with-child-blueprint.yaml");
log.info("started "+app);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java b/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
new file mode 100644
index 0000000..2cd97f0
--- /dev/null
+++ b/usage/launcher/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeRestTest.java
@@ -0,0 +1,92 @@
+package brooklyn.entity.brooklynnode;
+
+import java.net.URI;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Application;
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.event.basic.BasicConfigKey;
+import brooklyn.launcher.SimpleYamlLauncherForTests;
+import brooklyn.launcher.camp.SimpleYamlLauncher;
+import brooklyn.location.Location;
+import brooklyn.management.Task;
+import brooklyn.test.EntityTestUtils;
+import brooklyn.test.entity.TestApplication;
+import brooklyn.test.entity.TestEntity;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.config.ConfigBag;
+import brooklyn.util.net.Urls;
+import brooklyn.util.time.Duration;
+
+import com.google.common.collect.Iterables;
+
+/** REST-accessible extension of {@link BrooklynNodeTest} */
+public class BrooklynNodeRestTest {
+
+ private static final Logger log = LoggerFactory.getLogger(BrooklynNodeRestTest.class);
+
+ // takes a while when run on its own, because initializing war and making some requests;
+ // but there are no waits (beyond 10ms), the delay is all classloading;
+ // and this tests a lot of things, REST API, Brooklyn Node, yaml deployment,
+ // so feels worth it to have as a unit test
+ @Test
+ public void testBrooklynNodeRestDeployAndMirror() {
+ SimpleYamlLauncher l = new SimpleYamlLauncherForTests();
+ try {
+ TestApplication app = ApplicationBuilder.newManagedApp(TestApplication.class, l.getManagementContext());
+
+ BrooklynNode bn = app.createAndManageChild(EntitySpec.create(BrooklynNode.class, SameBrooklynNodeImpl.class));
+ bn.start(MutableSet.<Location>of());
+
+ URI uri = bn.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
+ Assert.assertNotNull(uri);
+ EntityTestUtils.assertAttributeEqualsEventually(bn, Attributes.SERVICE_UP, true);
+ log.info("Created BrooklynNode: "+bn);
+
+ // deploy
+ Task<?> t = bn.invoke(BrooklynNode.DEPLOY_BLUEPRINT, ConfigBag.newInstance()
+ .configure(BrooklynNode.DeployBlueprintEffector.BLUEPRINT_TYPE, TestApplication.class.getName())
+ .configure(BrooklynNode.DeployBlueprintEffector.BLUEPRINT_CONFIG, MutableMap.<String,Object>of("x", 1, "y", "Y"))
+ .getAllConfig());
+ log.info("Deployment result: "+t.getUnchecked());
+
+ MutableSet<Application> apps = MutableSet.copyOf( l.getManagementContext().getApplications() );
+ Assert.assertEquals(apps.size(), 2);
+ apps.remove(app);
+
+ Application newApp = Iterables.getOnlyElement(apps);
+ Entities.dumpInfo(newApp);
+
+ Assert.assertEquals(newApp.getConfig(new BasicConfigKey<Integer>(Integer.class, "x")), (Integer)1);
+
+ // check mirror
+ String newAppId = newApp.getId();
+ BrooklynEntityMirror mirror = app.createAndManageChild(EntitySpec.create(BrooklynEntityMirror.class)
+ .configure(BrooklynEntityMirror.MIRRORED_ENTITY_URL,
+ Urls.mergePaths(uri.toString(), "/v1/applications/"+newAppId+"/entities/"+newAppId))
+ .configure(BrooklynEntityMirror.MIRRORED_ENTITY_ID, newAppId)
+ .configure(BrooklynEntityMirror.POLL_PERIOD, Duration.millis(10)));
+
+ Entities.dumpInfo(mirror);
+
+ EntityTestUtils.assertAttributeEqualsEventually(mirror, Attributes.SERVICE_UP, true);
+
+ ((EntityInternal)newApp).setAttribute(TestEntity.NAME, "foo");
+ EntityTestUtils.assertAttributeEqualsEventually(mirror, TestEntity.NAME, "foo");
+ log.info("Mirror successfully validated");
+
+ } finally {
+ l.destroyAll();
+ }
+ log.info("DONE");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/usage/launcher/src/test/java/brooklyn/launcher/BrooklynWebServerTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/launcher/BrooklynWebServerTest.java b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynWebServerTest.java
index db9b986..ac37889 100644
--- a/usage/launcher/src/test/java/brooklyn/launcher/BrooklynWebServerTest.java
+++ b/usage/launcher/src/test/java/brooklyn/launcher/BrooklynWebServerTest.java
@@ -32,7 +32,6 @@ import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
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;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/usage/launcher/src/test/java/brooklyn/launcher/SimpleYamlLauncherForTests.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/launcher/SimpleYamlLauncherForTests.java b/usage/launcher/src/test/java/brooklyn/launcher/SimpleYamlLauncherForTests.java
new file mode 100644
index 0000000..9ab8131
--- /dev/null
+++ b/usage/launcher/src/test/java/brooklyn/launcher/SimpleYamlLauncherForTests.java
@@ -0,0 +1,31 @@
+/*
+ * 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 brooklyn.launcher;
+
+import brooklyn.launcher.camp.SimpleYamlLauncher;
+import brooklyn.management.ManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
+
+public class SimpleYamlLauncherForTests extends SimpleYamlLauncher {
+
+ protected ManagementContext newManagementContext() {
+ return new LocalManagementContextForTests();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8569120c/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java b/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
index 2060dac..383b926 100644
--- a/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
+++ b/utils/common/src/main/java/brooklyn/util/collections/Jsonya.java
@@ -264,6 +264,14 @@ public class Jsonya {
return this;
}
+ public Navigator<T> putIfNotNull(Object k1, Object v1) {
+ if (v1!=null) {
+ map();
+ putInternal((Map)focus, k1, v1);
+ }
+ return this;
+ }
+
protected void putInternal(Map target, Object k1, Object v1, Object ...kvOthers) {
assert (kvOthers.length % 2) == 0 : "even number of arguments required for put";
target.put(translateKey(k1), translate(v1));
[06/13] git commit: remove dead code and tidy warnings in camp code
Posted by he...@apache.org.
remove dead code and tidy warnings in camp code
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/78da216c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/78da216c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/78da216c
Branch: refs/heads/master
Commit: 78da216ceb8897ec6378bd11a5ee5ea7e0c1a28a
Parents: a4f7a4c
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 23:32:55 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:53:53 2014 -0400
----------------------------------------------------------------------
.../brooklyn/spi/creation/BrooklynComponentTemplateResolver.java | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/78da216c/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
index 155342a..8a0f459 100644
--- a/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
+++ b/usage/camp/src/main/java/io/brooklyn/camp/brooklyn/spi/creation/BrooklynComponentTemplateResolver.java
@@ -241,6 +241,7 @@ public class BrooklynComponentTemplateResolver {
} else {
// If this is a concrete class, particularly for an Application class, we want the proxy
// to expose all interfaces it implements.
+ @SuppressWarnings("rawtypes")
Class interfaceclazz = (Application.class.isAssignableFrom(type)) ? Application.class : Entity.class;
List<Class<?>> additionalInterfaceClazzes = Reflections.getAllInterfaces(type);
spec = EntitySpec.create(interfaceclazz).impl(type).additionalInterfaces(additionalInterfaceClazzes);
[13/13] git commit: This closes #78
Posted by he...@apache.org.
This closes #78
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/4fa68908
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/4fa68908
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/4fa68908
Branch: refs/heads/master
Commit: 4fa68908bafc7fa7063cf56fdac7420d561e93dc
Parents: 562325a ebfec15
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 12:33:02 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:33:02 2014 -0400
----------------------------------------------------------------------
camp/camp-base/pom.xml | 5 -
.../java/io/brooklyn/camp/spi/pdp/Artifact.java | 3 +-
.../camp/spi/pdp/ArtifactRequirement.java | 3 +-
.../java/io/brooklyn/camp/spi/pdp/Service.java | 3 +-
.../camp/spi/pdp/ServiceCharacteristic.java | 3 +-
.../brooklyn/camp/spi/resolve/PdpProcessor.java | 2 +-
.../main/java/io/brooklyn/util/yaml/Yamls.java | 89 +---------
.../pdp/DeploymentPlanToyInterpreterTest.java | 2 +-
.../brooklyn/config/BrooklynServerConfig.java | 6 +
.../config/BrooklynServiceAttributes.java | 2 +-
.../entity/basic/EntityInitializers.java | 30 ++++
.../java/brooklyn/util/flags/TypeCoercions.java | 85 ++++++----
.../brooklyn/entity/basic/EntitiesTest.java | 6 +-
...ntoPersisterInMemorySizeIntegrationTest.java | 7 +
.../util/internal/TypeCoercionsTest.java | 72 ++++++--
.../brooklynnode/BrooklynEntityMirror.java | 52 ++++++
.../brooklynnode/BrooklynEntityMirrorImpl.java | 169 +++++++++++++++++++
.../entity/brooklynnode/BrooklynNode.java | 3 +
.../entity/brooklynnode/BrooklynNodeImpl.java | 8 +-
.../BrooklynNodeIntegrationTest.java | 31 +++-
.../entity/brooklynnode/BrooklynNodeTest.java | 22 ++-
.../brooklynnode/SameBrooklynNodeImpl.java | 86 ++++++++++
.../BrooklynComponentTemplateResolver.java | 1 +
usage/launcher/pom.xml | 7 +
.../camp/BrooklynCampPlatformLauncher.java | 7 +-
.../entity/basic/VanillaSoftwareYamlTest.java | 5 +-
.../brooklynnode/BrooklynNodeRestTest.java | 145 ++++++++++++++++
.../launcher/BrooklynWebServerTest.java | 1 -
.../launcher/SimpleYamlLauncherForTests.java | 31 ++++
utils/common/pom.xml | 5 +
.../java/brooklyn/util/collections/Jsonya.java | 8 +
.../src/main/java/brooklyn/util/yaml/Yamls.java | 115 +++++++++++++
.../test/java/brooklyn/util/net/UrlsTest.java | 5 +
33 files changed, 857 insertions(+), 162 deletions(-)
----------------------------------------------------------------------
[12/13] git commit: This closes #72
Posted by he...@apache.org.
This closes #72
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/562325a6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/562325a6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/562325a6
Branch: refs/heads/master
Commit: 562325a66b8a34a9712c4b38ae80114ce0744b66
Parents: 671fb17 261afa8
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 12:32:46 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 12:32:46 2014 -0400
----------------------------------------------------------------------
----------------------------------------------------------------------
[02/13] git commit: Reduce memory usage in BrooklynGarbageCollector
Posted by he...@apache.org.
Reduce memory usage in BrooklynGarbageCollector
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/fe0d9d3f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/fe0d9d3f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/fe0d9d3f
Branch: refs/heads/master
Commit: fe0d9d3f8747b74c42fbe788fc69e11ab3f5be39
Parents: 35363d6
Author: Aled Sage <al...@gmail.com>
Authored: Wed Jul 16 15:40:47 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Jul 17 11:28:44 2014 +0100
----------------------------------------------------------------------
.../internal/BrooklynGarbageCollector.java | 32 ++++++++++++++++----
1 file changed, 26 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fe0d9d3f/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java b/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
index a13458c..870b4fe 100644
--- a/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
+++ b/core/src/main/java/brooklyn/management/internal/BrooklynGarbageCollector.java
@@ -199,9 +199,25 @@ public class BrooklynGarbageCollector {
/**
* Deletes old tasks. The age/number of tasks to keep is controlled by fields like
- * {@link #maxTasksPerTag} and {@link #maxTaskAge}.
+ * {@link #maxTasksPerTag} and {@link #maxTaskAge}.
*/
private void gcTasks() {
+ // TODO Must be careful with memory usage here : saw an OOME when copying the tasks set to sort it.
+ // (This happened when there were a *lot* of tasks (e.g. 100,000s) due to a crazy trigger for
+ // effector calls.)
+ //
+ // At that point we have potentially three copies of the list in-memory:
+ // - original in ExecutionManager
+ // - copy returned by getTasksWithTag(tag)
+ // - copy for sortedTasks (but at least now that only contains done tasks)
+ //
+ // It's hard to avoid fewer copies: getTasksWithTag(tag) should continue to return copy rather than
+ // mutable underlying list; and if we're going to sort then we need to take a copy.
+ //
+ // An option is for getTasksWithTag(tag) to return an ArrayList rather than a LinkedHashSet. That
+ // is a far more memory efficient data structure (e.g. 4 bytes overhead per object rather than
+ // 32 bytes overhead per object for HashSet).
+
if (!running) return;
Set<Object> taskTags = executionManager.getTaskTags();
@@ -216,30 +232,34 @@ public class BrooklynGarbageCollector {
// For each tag, we find the tasks with that tag; we ignore sub-tasks
// as those will be automatically GC'ed by the parent task at the appropriate point.
Set<Task<?>> tasksWithTag = executionManager.getTasksWithTag(tag);
+
Iterable<Task<?>> topTasksWithTag = Iterables.filter(tasksWithTag, new Predicate<Task<?>>() {
@Override public boolean apply(Task<?> input) {
- return input != null && !input.getTags().contains(ManagementContextInternal.SUB_TASK_TAG);
+ return input != null && input.isDone() && !input.getTags().contains(ManagementContextInternal.SUB_TASK_TAG);
}});
int numTasksToDelete = (Iterables.size(topTasksWithTag) - maxTasksPerTag);
if (numTasksToDelete > 0 || maxTaskAge > 0) {
List<Task<?>> sortedTasks = Lists.newArrayList(topTasksWithTag);
+ topTasksWithTag = null;
+ tasksWithTag = null;
+
Collections.sort(sortedTasks, new Comparator<Task<?>>() {
@Override public int compare(Task<?> t1, Task<?> t2) {
- long end1 = t1.isDone() ? t1.getEndTimeUtc() : Long.MAX_VALUE;
- long end2 = t2.isDone() ? t2.getEndTimeUtc() : Long.MAX_VALUE;
+ // know that tasks are all done; filtered those above
+ long end1 = t1.getEndTimeUtc();
+ long end2 = t2.getEndTimeUtc();
return (end1 < end2) ? -1 : ((end1 == end2) ? 0 : 1);
}
});
if (numTasksToDelete > 0) {
for (Task<?> taskToDelete : sortedTasks.subList(0, numTasksToDelete)) {
- if (!taskToDelete.isDone()) break;
executionManager.deleteTask(taskToDelete);
}
}
if (maxTaskAge > 0) {
for (Task<?> taskContender : sortedTasks.subList((numTasksToDelete > 0 ? numTasksToDelete : 0), sortedTasks.size())) {
- if (taskContender.isDone() && (System.currentTimeMillis() - taskContender.getEndTimeUtc() > maxTaskAge)) {
+ if (System.currentTimeMillis() - taskContender.getEndTimeUtc() > maxTaskAge) {
executionManager.deleteTask(taskContender);
} else {
break; // all subsequent tasks will be newer; stop looking