You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2014/07/18 15:42:12 UTC

[01/12] git commit: port WebAppRunnerTest to java and improve shutdown

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 935236ec8 -> f0b8f296d


port WebAppRunnerTest to java and improve shutdown


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

Branch: refs/heads/master
Commit: 2f4367e0d6b4cd2b5f3e0be61ce079586145d915
Parents: 965a3d1
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 01:09:33 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 .../brooklyn/launcher/WebAppRunnerTest.groovy   | 163 -------------------
 .../brooklyn/launcher/WebAppRunnerTest.java     | 160 ++++++++++++++++++
 2 files changed, 160 insertions(+), 163 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2f4367e0/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.groovy
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.groovy b/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.groovy
deleted file mode 100644
index af62480..0000000
--- a/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.groovy
+++ /dev/null
@@ -1,163 +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.launcher
-
-import static java.util.concurrent.TimeUnit.*
-import static org.testng.Assert.*
-
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.testng.annotations.AfterMethod
-import org.testng.annotations.Test
-
-import brooklyn.config.BrooklynProperties
-import brooklyn.entity.basic.Entities
-import brooklyn.management.internal.LocalManagementContext
-import brooklyn.test.HttpTestUtils
-import brooklyn.util.internal.TimeExtras
-import brooklyn.util.net.Networking
-import brooklyn.util.time.Duration
-
-import com.google.common.collect.Lists
-
-
-/**
- * These tests require the brooklyn.war to work. (Should be placed by maven build.)
- */
-public class WebAppRunnerTest {
-    static { TimeExtras.init() }
-
-    public static final Logger log = LoggerFactory.getLogger(WebAppRunnerTest.class);
-            
-    private static Duration TIMEOUT_MS;
-    static { TIMEOUT_MS = Duration.THIRTY_SECONDS; }
-    
-    List<LocalManagementContext> managementContexts = Lists.newCopyOnWriteArrayList();
-    
-    @AfterMethod(alwaysRun=true)
-    public void tearDown() throws Exception {
-        for (LocalManagementContext managementContext : managementContexts) {
-            Entities.destroyAll(managementContext);
-        }
-        managementContexts.clear();
-    }
-    
-    LocalManagementContext newManagementContext(BrooklynProperties brooklynProperties) {
-        LocalManagementContext result = new LocalManagementContext(brooklynProperties);
-        managementContexts.add(result);
-        return result;
-    }
-    
-    BrooklynWebServer createWebServer(Map properties) {
-        Map bigProps = [:] + properties;
-        Map attributes = bigProps.attributes
-        if (attributes==null) {
-            attributes = [:]
-        } else {
-            attributes = [:] + attributes; //copy map, don't change what was supplied
-        }
-        bigProps.attributes = attributes;
-
-        BrooklynProperties brooklynProperties = BrooklynProperties.Factory.newDefault();
-        brooklynProperties.putAll(bigProps);
-        brooklynProperties.put("brooklyn.webconsole.security.provider","brooklyn.rest.security.provider.AnyoneSecurityProvider")
-        brooklynProperties.put("brooklyn.webconsole.security.https.required","false");
-        return new BrooklynWebServer(bigProps, newManagementContext(brooklynProperties));
-    }
-    
-    @Test
-    public void testStartWar1() {
-        if (!Networking.isPortAvailable(8090))
-            fail("Another process is using port 8090 which is required for this test.");
-        BrooklynWebServer server = createWebServer(port:8090);
-        assertNotNull(server);
-        
-        try {
-            server.start();
-            assertBrooklynEventuallyAt("http://localhost:8090/");
-        } finally {
-            server.stop();
-        }
-    }
-
-    public static void assertBrooklynEventuallyAt(String url) {
-        HttpTestUtils.assertContentEventuallyContainsText(url, "Brooklyn Web Console");
-    }
-    
-    @Test
-    public void testStartSecondaryWar() {
-        if (!Networking.isPortAvailable(8090))
-            fail("Another process is using port 8090 which is required for this test.");
-        BrooklynWebServer server = createWebServer(port:8090, war:"brooklyn.war", wars:["hello":"hello-world.war"]);
-        assertNotNull(server);
-        
-        try {
-            server.start();
-
-            assertBrooklynEventuallyAt("http://localhost:8090/");
-            HttpTestUtils.assertContentEventuallyContainsText("http://localhost:8090/hello",
-                "This is the home page for a sample application");
-
-        } finally {
-            server.stop();
-        }
-    }
-
-    @Test
-    public void testStartSecondaryWarAfter() {
-        if (!Networking.isPortAvailable(8090))
-            fail("Another process is using port 8090 which is required for this test.");
-        BrooklynWebServer server = createWebServer(port:8090, war:"brooklyn.war");
-        assertNotNull(server);
-        
-        try {
-            server.start();
-            server.deploy("/hello", "hello-world.war");
-
-            assertBrooklynEventuallyAt("http://localhost:8090/");
-            HttpTestUtils.assertContentEventuallyContainsText("http://localhost:8090/hello",
-                "This is the home page for a sample application");
-
-        } finally {
-            server.stop();
-        }
-    }
-
-    @Test
-    public void testStartWithLauncher() {
-        BrooklynLauncher launcher = BrooklynLauncher.newInstance()
-                .brooklynProperties("brooklyn.webconsole.security.provider",'brooklyn.rest.security.provider.AnyoneSecurityProvider')
-                .webapp("/hello", "hello-world.war")
-                .start();
-        BrooklynServerDetails details = launcher.getServerDetails();
-        
-        try {
-            details.getWebServer().deploy("/hello2", "hello-world.war");
-
-            assertBrooklynEventuallyAt(details.getWebServerUrl());
-            HttpTestUtils.assertContentEventuallyContainsText(details.getWebServerUrl()+"hello", "This is the home page for a sample application");
-            HttpTestUtils.assertContentEventuallyContainsText(details.getWebServerUrl()+"hello2", "This is the home page for a sample application");
-            HttpTestUtils.assertHttpStatusCodeEventuallyEquals(details.getWebServerUrl()+"hello0", 404);
-
-        } finally {
-            details.getWebServer().stop();
-        }
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2f4367e0/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.java b/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.java
new file mode 100644
index 0000000..2fbd131
--- /dev/null
+++ b/usage/launcher/src/test/java/brooklyn/launcher/WebAppRunnerTest.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.launcher;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
+
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.basic.Entities;
+import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.management.internal.ManagementContextInternal;
+import brooklyn.test.HttpTestUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.net.Networking;
+
+import com.google.common.collect.Lists;
+
+
+/**
+ * These tests require the brooklyn.war to work. (Should be placed by maven build.)
+ */
+public class WebAppRunnerTest {
+
+    public static final Logger log = LoggerFactory.getLogger(WebAppRunnerTest.class);
+            
+    List<LocalManagementContext> managementContexts = Lists.newCopyOnWriteArrayList();
+    
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        for (LocalManagementContext managementContext : managementContexts) {
+            Entities.destroyAll(managementContext);
+        }
+        managementContexts.clear();
+    }
+    
+    LocalManagementContext newManagementContext(BrooklynProperties brooklynProperties) {
+        LocalManagementContext result = new LocalManagementContext(brooklynProperties);
+        managementContexts.add(result);
+        return result;
+    }
+    
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    BrooklynWebServer createWebServer(Map properties) {
+        Map bigProps = MutableMap.copyOf(properties);
+        Map attributes = MutableMap.copyOf( (Map) bigProps.get("attributes") );
+        bigProps.put("attributes", attributes);
+
+        BrooklynProperties brooklynProperties = BrooklynProperties.Factory.newDefault();
+        brooklynProperties.putAll(bigProps);
+        brooklynProperties.put("brooklyn.webconsole.security.provider","brooklyn.rest.security.provider.AnyoneSecurityProvider");
+        brooklynProperties.put("brooklyn.webconsole.security.https.required","false");
+        return new BrooklynWebServer(bigProps, newManagementContext(brooklynProperties));
+    }
+    
+    @Test
+    public void testStartWar1() throws Exception {
+        if (!Networking.isPortAvailable(8090))
+            fail("Another process is using port 8090 which is required for this test.");
+        BrooklynWebServer server = createWebServer(MutableMap.of("port", 8090));
+        assertNotNull(server);
+        
+        try {
+            server.start();
+            assertBrooklynEventuallyAt("http://localhost:8090/");
+        } finally {
+            server.stop();
+        }
+    }
+
+    public static void assertBrooklynEventuallyAt(String url) {
+        HttpTestUtils.assertContentEventuallyContainsText(url, "Brooklyn Web Console");
+    }
+    
+    @Test
+    public void testStartSecondaryWar() throws Exception {
+        if (!Networking.isPortAvailable(8090))
+            fail("Another process is using port 8090 which is required for this test.");
+        BrooklynWebServer server = createWebServer(
+            MutableMap.of("port", 8090, "war", "brooklyn.war", "wars", MutableMap.of("hello", "hello-world.war")) );
+        assertNotNull(server);
+        
+        try {
+            server.start();
+
+            assertBrooklynEventuallyAt("http://localhost:8090/");
+            HttpTestUtils.assertContentEventuallyContainsText("http://localhost:8090/hello",
+                "This is the home page for a sample application");
+
+        } finally {
+            server.stop();
+        }
+    }
+
+    @Test
+    public void testStartSecondaryWarAfter() throws Exception {
+        if (!Networking.isPortAvailable(8090))
+            fail("Another process is using port 8090 which is required for this test.");
+        BrooklynWebServer server = createWebServer(MutableMap.of("port", 8090, "war", "brooklyn.war"));
+        assertNotNull(server);
+        
+        try {
+            server.start();
+            server.deploy("/hello", "hello-world.war");
+
+            assertBrooklynEventuallyAt("http://localhost:8090/");
+            HttpTestUtils.assertContentEventuallyContainsText("http://localhost:8090/hello",
+                "This is the home page for a sample application");
+
+        } finally {
+            server.stop();
+        }
+    }
+
+    @Test
+    public void testStartWithLauncher() throws Exception {
+        BrooklynLauncher launcher = BrooklynLauncher.newInstance()
+                .brooklynProperties("brooklyn.webconsole.security.provider","brooklyn.rest.security.provider.AnyoneSecurityProvider")
+                .webapp("/hello", "hello-world.war")
+                .start();
+        BrooklynServerDetails details = launcher.getServerDetails();
+        
+        try {
+            details.getWebServer().deploy("/hello2", "hello-world.war");
+
+            assertBrooklynEventuallyAt(details.getWebServerUrl());
+            HttpTestUtils.assertContentEventuallyContainsText(details.getWebServerUrl()+"hello", "This is the home page for a sample application");
+            HttpTestUtils.assertContentEventuallyContainsText(details.getWebServerUrl()+"hello2", "This is the home page for a sample application");
+            HttpTestUtils.assertHttpStatusCodeEventuallyEquals(details.getWebServerUrl()+"hello0", 404);
+
+        } finally {
+            details.getWebServer().stop();
+            ((ManagementContextInternal)details.getManagementContext()).terminate();
+        }
+    }
+    
+}


[10/12] git commit: test and rat fixes, and log message tidy

Posted by al...@apache.org.
test and rat fixes, and log message tidy


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

Branch: refs/heads/master
Commit: a882a87b0055ec06fa66eaad749935399504d1d3
Parents: 2f4367e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 00:38:46 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:18 2014 -0400

----------------------------------------------------------------------
 .../resources/fixtures/api-error-no-details.json  |  3 +--
 .../rest/util/DefaultExceptionMapper.java         |  3 ++-
 .../rest/resources/UsageResourceTest.java         |  2 +-
 .../util/exceptions/UserFacingException.java      | 18 ++++++++++++++++++
 4 files changed, 22 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a882a87b/usage/rest-api/src/test/resources/fixtures/api-error-no-details.json
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/test/resources/fixtures/api-error-no-details.json b/usage/rest-api/src/test/resources/fixtures/api-error-no-details.json
index 4cd16ca..5762f6f 100644
--- a/usage/rest-api/src/test/resources/fixtures/api-error-no-details.json
+++ b/usage/rest-api/src/test/resources/fixtures/api-error-no-details.json
@@ -1,4 +1,3 @@
 {
-    "message": "explanatory message",
-    "details": ""
+    "message": "explanatory message"
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a882a87b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
index 4a458ce..71bc945 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
@@ -88,7 +88,8 @@ public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
 
         if (!Exceptions.isPrefixBoring(throwable)) {
             if ( warnedUnknownExceptions.add( throwable.getClass() )) {
-                LOG.info("No exception mapping for " + throwable.getClass() + "; consider adding to "+getClass()+" (future warnings logged at debug)");
+                throwable.printStackTrace();
+                LOG.warn("REST call generated exception type "+throwable.getClass()+" unrecognized in "+getClass()+" (subsequent occurrences will be logged debug only): " + throwable);
             }
         }
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a882a87b/usage/rest-server/src/test/java/brooklyn/rest/resources/UsageResourceTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/UsageResourceTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/UsageResourceTest.java
index 82629da..1cadbcd 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/UsageResourceTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/UsageResourceTest.java
@@ -164,7 +164,7 @@ public class UsageResourceTest extends BrooklynRestResourceTest {
         assertAppUsage(usage, appId, ImmutableList.of(Status.STARTING, Status.RUNNING), roundDown(preStart), postStart);
         
         response = client().resource("/v1/usage/applications/" + appId + "?start=9999-01-01T00:00:00+0100").get(ClientResponse.class);
-        assertTrue(response.getStatus() >= 500, "end defaults to NOW, so future start should fail");
+        assertTrue(response.getStatus() >= 400, "end defaults to NOW, so future start should fail, instead got code "+response.getStatus());
         
         response = client().resource("/v1/usage/applications/" + appId + "?start=9999-01-01T00:00:00%2B0100&end=9999-01-02T00:00:00%2B0100").get(ClientResponse.class);
         usage = response.getEntity(new GenericType<UsageStatistics>() {});

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a882a87b/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java b/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
index 1d53d11..b7237ac 100644
--- a/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
+++ b/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
@@ -1,3 +1,21 @@
+/*
+ * 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.exceptions;
 
 /** marker interface, to show that an exception is suitable for pretty-printing to an end-user,


[09/12] git commit: deprecte ApplicationBuilder.newManagedInstance to encourage mgmt context to be supplied, and convert many existing usages to conveniences which load LocalManagementContextForTests (to speed up tests by preventng catalog parsing)

Posted by al...@apache.org.
deprecte ApplicationBuilder.newManagedInstance to encourage mgmt context to be supplied, and convert many existing usages to conveniences which load LocalManagementContextForTests (to speed up tests by preventng catalog parsing)


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

Branch: refs/heads/master
Commit: b15a4713d308302c698689d9e50dc41497773684
Parents: a882a87
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 01:26:47 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:18 2014 -0400

----------------------------------------------------------------------
 .../main/java/brooklyn/entity/basic/ApplicationBuilder.java  | 6 ++++++
 .../enricher/CustomAggregatingEnricherDeprecatedTest.groovy  | 3 ++-
 .../enricher/TransformingEnricherDeprecatedTest.groovy       | 2 +-
 .../test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy | 3 +--
 .../java/brooklyn/entity/basic/AbstractEntityLegacyTest.java | 4 ++--
 .../java/brooklyn/entity/basic/ConfigMapGroovyTest.groovy    | 2 +-
 .../java/brooklyn/entity/basic/EntitySubscriptionTest.groovy | 2 +-
 .../basic/MapListAndOtherStructuredConfigKeyTest.groovy      | 2 +-
 core/src/test/java/brooklyn/entity/group/GroupTest.java      | 3 +--
 .../java/brooklyn/entity/rebind/RebindManagerSorterTest.java | 4 ++--
 .../basic/AggregatingMachineProvisioningLocationTest.java    | 3 ++-
 .../brooklyn/location/basic/TestPortSupplierLocation.groovy  | 3 +--
 .../java/brooklyn/policy/basic/PolicySubscriptionTest.groovy | 2 +-
 core/src/test/java/brooklyn/test/entity/TestApplication.java | 8 +++++++-
 .../test/java/brooklyn/enricher/HttpLatencyDetectorTest.java | 2 +-
 .../brooklyn/enricher/TimeFractionDeltaEnricherTest.java     | 2 +-
 .../test/java/brooklyn/policy/ha/ServiceReplacerTest.java    | 3 +--
 .../java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java  | 4 +---
 .../test/java/brooklyn/entity/java/EntityPollingTest.java    | 2 +-
 .../test/java/brooklyn/entity/java/VanillaJavaAppTest.java   | 8 ++++----
 .../io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java   | 4 ++--
 .../test/java/brooklyn/rest/domain/SensorSummaryTest.java    | 3 +--
 22 files changed, 41 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/main/java/brooklyn/entity/basic/ApplicationBuilder.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/ApplicationBuilder.java b/core/src/main/java/brooklyn/entity/basic/ApplicationBuilder.java
index dd0c650..f3be0e0 100644
--- a/core/src/main/java/brooklyn/entity/basic/ApplicationBuilder.java
+++ b/core/src/main/java/brooklyn/entity/basic/ApplicationBuilder.java
@@ -70,6 +70,9 @@ public abstract class ApplicationBuilder {
 
     @SuppressWarnings("unchecked")
     @Beta
+    /** @deprecated since 0.7.0 the management context should normally be passed in;
+     * for TestApplication also see TestApplication.Factory.newManagedInstanceForTests() */ 
+    @Deprecated
     public static <T extends StartableApplication> T newManagedApp(Class<T> type) {
         if (type.isInterface()) {
             return (T) newManagedApp(EntitySpec.create(type));
@@ -80,6 +83,9 @@ public abstract class ApplicationBuilder {
 
     @SuppressWarnings("unchecked")
     @Beta
+    /** @deprecated since 0.7.0 the management context should normally be passed in;
+     * for TestApplication also see TestApplication.Factory.newManagedInstanceForTests() */ 
+    @Deprecated
     public static <T extends StartableApplication> T newManagedApp(EntitySpec<T> spec) {
         return (T) new ApplicationBuilder(spec) {
             @Override protected void doBuild() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
index c51a0e7..adba709 100644
--- a/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
+++ b/core/src/test/java/brooklyn/enricher/CustomAggregatingEnricherDeprecatedTest.groovy
@@ -34,6 +34,7 @@ import brooklyn.event.AttributeSensor
 import brooklyn.event.basic.BasicAttributeSensor
 import brooklyn.location.basic.SimulatedLocation
 import brooklyn.test.TestUtils
+import brooklyn.test.entity.LocalManagementContextForTests;
 import brooklyn.test.entity.TestApplication
 import brooklyn.test.entity.TestEntity
 
@@ -54,7 +55,7 @@ class CustomAggregatingEnricherDeprecatedTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         intSensor = new BasicAttributeSensor<Integer>(Integer.class, "int sensor")
         target = new BasicAttributeSensor<Integer>(Long.class, "target sensor")

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy b/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
index f0103a5..f880232 100644
--- a/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
+++ b/core/src/test/java/brooklyn/enricher/TransformingEnricherDeprecatedTest.groovy
@@ -53,7 +53,7 @@ public class TransformingEnricherDeprecatedTest {
 
     @BeforeMethod()
     public void before() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         intSensorA = new BasicAttributeSensor<Integer>(Integer.class, "int.sensor.a");
         target = new BasicAttributeSensor<Long>(Long.class, "long.sensor.target");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy b/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
index e13e2ea..9061a99 100644
--- a/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
+++ b/core/src/test/java/brooklyn/entity/EffectorSayHiGroovyTest.groovy
@@ -28,7 +28,6 @@ import org.testng.annotations.Test
 
 import brooklyn.entity.annotation.EffectorParam
 import brooklyn.entity.basic.AbstractEntity
-import brooklyn.entity.basic.ApplicationBuilder
 import brooklyn.entity.basic.BasicParameterType
 import brooklyn.entity.basic.BrooklynTaskTags
 import brooklyn.entity.basic.Entities
@@ -55,7 +54,7 @@ public class EffectorSayHiGroovyTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         e = app.createAndManageChild(EntitySpec.create(MyEntity.class));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java b/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
index 5507710..3c0bb1e 100644
--- a/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/AbstractEntityLegacyTest.java
@@ -108,7 +108,7 @@ public class AbstractEntityLegacyTest {
     
     @Test
     public void testNewStyleCallsConfigureAfterConstruction() throws Exception {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         MyEntity entity = app.addChild(EntitySpec.create(MyEntity.class));
         
         assertEquals(entity.getConfigureCount(), 1);
@@ -139,7 +139,7 @@ public class AbstractEntityLegacyTest {
     
     @Test
     public void testNewStyleSetsDefaultDisplayName() throws Exception {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         MyEntity entity = app.addChild(EntitySpec.create(MyEntity.class));
         
         assertTrue(entity.getDisplayName().startsWith("MyEntity:"+entity.getId().substring(0,4)), "displayName="+entity.getDisplayName());

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/basic/ConfigMapGroovyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/ConfigMapGroovyTest.groovy b/core/src/test/java/brooklyn/entity/basic/ConfigMapGroovyTest.groovy
index f9d905c..627b6f2 100644
--- a/core/src/test/java/brooklyn/entity/basic/ConfigMapGroovyTest.groovy
+++ b/core/src/test/java/brooklyn/entity/basic/ConfigMapGroovyTest.groovy
@@ -36,7 +36,7 @@ public class ConfigMapGroovyTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         entity = new MySubEntity(app);
         Entities.manage(entity);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.groovy b/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.groovy
index 23a612c..1317c12 100644
--- a/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.groovy
+++ b/core/src/test/java/brooklyn/entity/basic/EntitySubscriptionTest.groovy
@@ -56,7 +56,7 @@ public class EntitySubscriptionTest {
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
         loc = new SimulatedLocation();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         observedEntity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         observedChildEntity = observedEntity.createAndManageChild(EntitySpec.create(TestEntity.class));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy b/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
index f60d330..6462199 100644
--- a/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
+++ b/core/src/test/java/brooklyn/entity/basic/MapListAndOtherStructuredConfigKeyTest.groovy
@@ -49,7 +49,7 @@ public class MapListAndOtherStructuredConfigKeyTest {
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
         locs = ImmutableList.of(new SimulatedLocation());
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/group/GroupTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/group/GroupTest.java b/core/src/test/java/brooklyn/entity/group/GroupTest.java
index 1392175..43a31c0 100644
--- a/core/src/test/java/brooklyn/entity/group/GroupTest.java
+++ b/core/src/test/java/brooklyn/entity/group/GroupTest.java
@@ -25,7 +25,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.entity.Entity;
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.BasicGroup;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.proxying.EntitySpec;
@@ -52,7 +51,7 @@ public class GroupTest {
 
     @BeforeMethod
     public void setUp() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         loc = app.getManagementContext().getLocationManager().createLocation(LocationSpec.create(SimulatedLocation.class));
         group = app.createAndManageChild(EntitySpec.create(BasicGroup.class));
         entity1 = app.createAndManageChild(EntitySpec.create(TestEntity.class));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/entity/rebind/RebindManagerSorterTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindManagerSorterTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindManagerSorterTest.java
index 1b71e6a..991a000 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindManagerSorterTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindManagerSorterTest.java
@@ -54,7 +54,7 @@ public class RebindManagerSorterTest {
     
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         mgmts.add(managementContext = app.getManagementContext());
         rebindManager = (RebindManagerImpl) managementContext.getRebindManager();
     }
@@ -95,7 +95,7 @@ public class RebindManagerSorterTest {
     
     @Test
     public void testSortOrderMultipleApps() throws Exception {
-        TestApplication app2 = ApplicationBuilder.newManagedApp(TestApplication.class);
+        TestApplication app2 = TestApplication.Factory.newManagedInstanceForTests();
         mgmts.add(app2.getManagementContext());
 
         TestEntity e1a = app.createAndManageChild(EntitySpec.create(TestEntity.class));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java b/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
index 32ca4ea..e494a1f 100644
--- a/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
+++ b/core/src/test/java/brooklyn/location/basic/AggregatingMachineProvisioningLocationTest.java
@@ -34,6 +34,7 @@ import brooklyn.location.MachineProvisioningLocation;
 import brooklyn.location.NoMachinesAvailableException;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation.LocalhostMachine;
 import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -53,7 +54,7 @@ public class AggregatingMachineProvisioningLocationTest {
     @BeforeMethod(alwaysRun=true)
     @SuppressWarnings("unchecked")
     public void setUp() {
-        managementContext = new LocalManagementContext();
+        managementContext = new LocalManagementContextForTests();
         machine1a = newLocation(LocalhostMachine.class, "1a");
         machine1b = newLocation(LocalhostMachine.class, "1b");
         machine2a = newLocation(LocalhostMachine.class, "2a");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.groovy b/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.groovy
index 7d2fcb6..51579d6 100644
--- a/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.groovy
+++ b/core/src/test/java/brooklyn/location/basic/TestPortSupplierLocation.groovy
@@ -23,7 +23,6 @@ import org.testng.annotations.AfterMethod
 import org.testng.annotations.BeforeMethod
 import org.testng.annotations.Test
 
-import brooklyn.entity.basic.ApplicationBuilder
 import brooklyn.entity.basic.Entities
 import brooklyn.entity.proxying.EntitySpec
 import brooklyn.event.basic.PortAttributeSensorAndConfigKey
@@ -41,7 +40,7 @@ public class TestPortSupplierLocation {
     @BeforeMethod
     public void setup() {
         l = new SimulatedLocation();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         e = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         app.start([l]);
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.groovy
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.groovy b/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.groovy
index 415d1c4..2290c07 100644
--- a/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.groovy
+++ b/core/src/test/java/brooklyn/policy/basic/PolicySubscriptionTest.groovy
@@ -55,7 +55,7 @@ public class PolicySubscriptionTest {
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
         loc = new SimulatedLocation();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         entity2 = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         listener = new RecordingSensorEventListener();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/core/src/test/java/brooklyn/test/entity/TestApplication.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/test/entity/TestApplication.java b/core/src/test/java/brooklyn/test/entity/TestApplication.java
index 7614b35..cc0a628 100644
--- a/core/src/test/java/brooklyn/test/entity/TestApplication.java
+++ b/core/src/test/java/brooklyn/test/entity/TestApplication.java
@@ -19,6 +19,7 @@
 package brooklyn.test.entity;
 
 import brooklyn.entity.Entity;
+import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.StartableApplication;
 import brooklyn.entity.proxying.EntitySpec;
@@ -39,5 +40,10 @@ public interface TestApplication extends StartableApplication, EntityInternal {
     public <T extends Entity> T createAndManageChild(EntitySpec<T> spec);
 
     public LocalhostMachineProvisioningLocation newLocalhostProvisioningLocation();
-    
+
+    public static class Factory {
+        public static TestApplication newManagedInstanceForTests() {
+            return ApplicationBuilder.newManagedApp(TestApplication.class, new LocalManagementContextForTests());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java b/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
index 989b1ce..b8504ad 100644
--- a/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
+++ b/policy/src/test/java/brooklyn/enricher/HttpLatencyDetectorTest.java
@@ -57,7 +57,7 @@ public class HttpLatencyDetectorTest {
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
         loc = new LocalhostMachineProvisioningLocation();
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         app.start(ImmutableList.of(loc));
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/policy/src/test/java/brooklyn/enricher/TimeFractionDeltaEnricherTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/enricher/TimeFractionDeltaEnricherTest.java b/policy/src/test/java/brooklyn/enricher/TimeFractionDeltaEnricherTest.java
index f87a304..57abb98 100644
--- a/policy/src/test/java/brooklyn/enricher/TimeFractionDeltaEnricherTest.java
+++ b/policy/src/test/java/brooklyn/enricher/TimeFractionDeltaEnricherTest.java
@@ -51,7 +51,7 @@ public class TimeFractionDeltaEnricherTest {
     
     @BeforeMethod(alwaysRun=true)
     public void before() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         producer = app.createAndManageChild(EntitySpec.create(TestEntity.class));
         
         intSensor = Sensors.newIntegerSensor("int sensor");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
----------------------------------------------------------------------
diff --git a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
index 830f7e9..4b5a0d9 100644
--- a/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
+++ b/policy/src/test/java/brooklyn/policy/ha/ServiceReplacerTest.java
@@ -184,8 +184,7 @@ public class ServiceReplacerTest {
         assertEventuallyHasEntityReplacementFailedEvent(cluster);
     }
 
-    
-    @Test
+    @Test(groups="Integration")  // 1s wait
     public void testStopFailureOfOldEntityDoesNotSetClusterOnFire() throws Exception {
         app.subscribe(null, ServiceReplacer.ENTITY_REPLACEMENT_FAILED, eventListener);
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/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 4d37391..7c96416 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeTest.java
@@ -27,9 +27,7 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
-import brooklyn.entity.basic.EntityLocal;
 import brooklyn.entity.drivers.downloads.DownloadResolver;
 import brooklyn.event.feed.ConfigToAttributes;
 import brooklyn.location.basic.SshMachineLocation;
@@ -48,7 +46,7 @@ public class BrooklynNodeTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() throws Exception {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         loc = new SshMachineLocation(MutableMap.of("address", "localhost"));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java b/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
index cfabf98..7960a07 100644
--- a/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/EntityPollingTest.java
@@ -127,7 +127,7 @@ public class EntityPollingTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setUp() {
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         
         /*
          * Create an entity, using real entity code, but that swaps out the external process

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java b/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
index aaac6b8..851aebd 100644
--- a/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
+++ b/software/base/src/test/java/brooklyn/entity/java/VanillaJavaAppTest.java
@@ -45,7 +45,6 @@ import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityLocal;
 import brooklyn.entity.basic.Lifecycle;
@@ -81,8 +80,8 @@ public class VanillaJavaAppTest {
     private static final Object LONG_TIMEOUT_MS = 61*1000;
 
     private static String BROOKLYN_THIS_CLASSPATH = null;
-    private static Class MAIN_CLASS = ExampleVanillaMain.class;
-    private static Class MAIN_CPU_HUNGRY_CLASS = ExampleVanillaMainCpuHungry.class;
+    private static Class<?> MAIN_CLASS = ExampleVanillaMain.class;
+    private static Class<?> MAIN_CPU_HUNGRY_CLASS = ExampleVanillaMainCpuHungry.class;
     
     private TestApplication app;
     private LocalhostMachineProvisioningLocation loc;
@@ -92,7 +91,7 @@ public class VanillaJavaAppTest {
         if (BROOKLYN_THIS_CLASSPATH==null) {
             BROOKLYN_THIS_CLASSPATH = ResourceUtils.create(MAIN_CLASS).getClassLoaderDir();
         }
-        app = ApplicationBuilder.newManagedApp(TestApplication.class);
+        app = TestApplication.Factory.newManagedInstanceForTests();
         loc = new LocalhostMachineProvisioningLocation(MutableMap.of("address", "localhost"));
     }
 
@@ -307,6 +306,7 @@ public class VanillaJavaAppTest {
         final JMXServiceURL url;
         final Map<String,Object> env;
         
+        @SuppressWarnings("unchecked")
         public AsserterForJmxConnection(VanillaJavaApp e) throws MalformedURLException {
             this.entity = e;
             

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
index e405d5e..28e8ef5 100644
--- a/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
+++ b/usage/camp/src/test/java/io/brooklyn/camp/brooklyn/JavaWebAppsMatchingTest.java
@@ -38,7 +38,7 @@ import org.testng.annotations.Test;
 
 import brooklyn.entity.basic.Entities;
 import brooklyn.management.ManagementContext;
-import brooklyn.management.internal.LocalManagementContext;
+import brooklyn.test.entity.LocalManagementContextForTests;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.stream.Streams;
@@ -54,7 +54,7 @@ public class JavaWebAppsMatchingTest {
 
     @BeforeMethod(alwaysRun=true)
     public void setup() {
-        brooklynMgmt = new LocalManagementContext();
+        brooklynMgmt = new LocalManagementContextForTests();
         platform = new BrooklynCampPlatform(
               PlatformRootSummary.builder().name("Brooklyn CAMP Platform").build(),
               brooklynMgmt);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/b15a4713/usage/rest-server/src/test/java/brooklyn/rest/domain/SensorSummaryTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/domain/SensorSummaryTest.java b/usage/rest-server/src/test/java/brooklyn/rest/domain/SensorSummaryTest.java
index ba6ee4c..ccf1320 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/domain/SensorSummaryTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/domain/SensorSummaryTest.java
@@ -31,7 +31,6 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.config.render.RendererHints;
-import brooklyn.entity.basic.ApplicationBuilder;
 import brooklyn.entity.basic.Entities;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.event.AttributeSensor;
@@ -56,7 +55,7 @@ public class SensorSummaryTest {
   
   @BeforeMethod(alwaysRun=true)
   public void setUp() throws Exception {
-      app = ApplicationBuilder.newManagedApp(TestApplication.class);
+      app = TestApplication.Factory.newManagedInstanceForTests();
       mgmt = app.getManagementContext();
       entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
   }


[07/12] git commit: Add a UserFacingException which can be used to indicate to suppress stack traces, and tidy up how REST errors are reported and returned

Posted by al...@apache.org.
Add a UserFacingException which can be used to indicate to suppress stack traces, and tidy up how REST errors are reported and returned


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

Branch: refs/heads/master
Commit: e8f7283c20f34a8060400e20cc9d7a5974c96917
Parents: 9d61659
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 14:55:32 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 usage/cli/src/main/java/brooklyn/cli/Main.java  |  4 +-
 .../java/brooklyn/rest/domain/ApiError.java     | 24 +++++++++
 .../brooklyn/rest/resources/UsageResource.java  |  5 +-
 .../BrooklynPropertiesSecurityFilter.java       | 11 ++--
 .../rest/util/DefaultExceptionMapper.java       | 57 ++++++++++++--------
 .../brooklyn/util/exceptions/Exceptions.java    | 21 ++++----
 .../util/exceptions/FatalRuntimeException.java  |  2 +-
 .../util/exceptions/UserFacingException.java    | 21 ++++++++
 8 files changed, 106 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/usage/cli/src/main/java/brooklyn/cli/Main.java
----------------------------------------------------------------------
diff --git a/usage/cli/src/main/java/brooklyn/cli/Main.java b/usage/cli/src/main/java/brooklyn/cli/Main.java
index ae2696d..601ded2 100644
--- a/usage/cli/src/main/java/brooklyn/cli/Main.java
+++ b/usage/cli/src/main/java/brooklyn/cli/Main.java
@@ -66,6 +66,7 @@ import brooklyn.util.ResourceUtils;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.FatalConfigurationRuntimeException;
 import brooklyn.util.exceptions.FatalRuntimeException;
+import brooklyn.util.exceptions.UserFacingException;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.javalang.Enums;
 import brooklyn.util.net.Networking;
@@ -763,7 +764,8 @@ public class Main {
         } catch (Exception e) { // unexpected error during command execution
             log.error("Execution error: " + e.getMessage(), e);
             System.err.println("Execution error: " + e.getMessage());
-            e.printStackTrace();
+            if (!(e instanceof UserFacingException))
+                e.printStackTrace();
             System.exit(EXECUTION_ERROR);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/usage/rest-api/src/main/java/brooklyn/rest/domain/ApiError.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/domain/ApiError.java b/usage/rest-api/src/main/java/brooklyn/rest/domain/ApiError.java
index c293294..dd3dcbc 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/domain/ApiError.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/domain/ApiError.java
@@ -20,7 +20,13 @@ package brooklyn.rest.domain;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
 import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
 
 import brooklyn.util.text.Strings;
 
@@ -76,6 +82,11 @@ public class ApiError {
             return this;
         }
 
+        /** as {@link #prefixMessage(String, String)} with default separator of `: ` */
+        public Builder prefixMessage(String prefix) {
+            return prefixMessage(prefix, ": ");
+        }
+        
         /** puts a prefix in front of the message, with the given separator if there is already a message;
          * if there is no message, it simply sets the prefix as the message
          */
@@ -107,6 +118,8 @@ public class ApiError {
     }
 
     private final String message;
+    
+    @JsonSerialize(include=Inclusion.NON_EMPTY)
     private final String details;
 
     public ApiError(
@@ -145,4 +158,15 @@ public class ApiError {
                 .add("details", details)
                 .toString();
     }
+
+    public Response asBadRequestResponseJson() {
+        return asResponse(Status.BAD_REQUEST, MediaType.APPLICATION_JSON_TYPE);
+    }
+
+    public Response asResponse(Status status, MediaType type) {
+        return Response.status(status)
+            .type(type)
+            .entity(this)
+            .build();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java
index b8a1c78..88dfe3a 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java
@@ -40,6 +40,7 @@ import brooklyn.rest.api.UsageApi;
 import brooklyn.rest.domain.UsageStatistic;
 import brooklyn.rest.domain.UsageStatistics;
 import brooklyn.rest.transform.ApplicationTransformer;
+import brooklyn.util.exceptions.UserFacingException;
 import brooklyn.util.time.Time;
 
 import com.google.common.base.Objects;
@@ -249,8 +250,8 @@ public class UsageResource extends AbstractBrooklynRestResource implements Usage
     
     private void checkDates(Date startDate, Date endDate) {
         if (startDate.compareTo(endDate) > 0) {
-            throw new IllegalArgumentException("Start must be less than or equal to end: " + startDate + " > " + endDate + 
-                    " (" + startDate.getTime() + " > " + endDate.getTime() + ")");
+            throw new UserFacingException(new IllegalArgumentException("Start must be less than or equal to end: " + startDate + " > " + endDate + 
+                    " (" + startDate.getTime() + " > " + endDate.getTime() + ")"));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
index 74ab303..1331e1f 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
@@ -95,7 +95,12 @@ public class BrooklynPropertiesSecurityFilter implements Filter {
                         log.debug("  REST req {} parameters: {}", uid, ((HttpServletRequest)request).getParameterMap());
                     }
                     if (((HttpServletRequest)request).getContentLength()>0) {
-                        log.debug("  REST req {} upload content type {}", uid, ((HttpServletRequest)request).getContentType()+" length "+((HttpServletRequest)request).getContentLength());
+                        int len = ((HttpServletRequest)request).getContentLength();
+                        log.debug("  REST req {} upload content type {}", uid, ((HttpServletRequest)request).getContentType()+" length "+len
+                            // would be nice to do this, but the stream can only be read once;
+                            // TODO figure out how we could peek at it
+//                            +(len>0 && len<4096 ? ""+Streams.readFullyString(((HttpServletRequest)request).getInputStream()) : "") 
+                            );
                     }
                     
                     chain.doFilter(request, response);
@@ -107,9 +112,9 @@ public class BrooklynPropertiesSecurityFilter implements Filter {
                 } catch (Throwable e) {
                     // NB errors are typically already caught at this point
                     if (log.isDebugEnabled())
-                        log.debug("REST` failed processing request "+uri+" with "+entitlementContext+": "+e, e);
+                        log.debug("REST failed processing request "+uri+" with "+entitlementContext+": "+e, e);
                     
-                    log.warn("REST` failed processing request "+uri+" with "+entitlementContext+": "+e, e);
+                    log.warn("REST failed processing request "+uri+" with "+entitlementContext+": "+e, e);
                     throw Exceptions.propagate(e);
                     
                 } finally {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
index 0271998..4a458ce 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
@@ -18,6 +18,8 @@
  */
 package brooklyn.rest.util;
 
+import java.util.Set;
+
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
@@ -29,10 +31,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.yaml.snakeyaml.error.YAMLException;
 
-import com.google.common.base.Optional;
-
+import brooklyn.management.entitlement.Entitlements;
 import brooklyn.rest.domain.ApiError;
 import brooklyn.rest.domain.ApiError.Builder;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.exceptions.Exceptions;
+import brooklyn.util.exceptions.UserFacingException;
 import brooklyn.util.flags.ClassCoercionException;
 import brooklyn.util.text.Strings;
 
@@ -41,6 +45,8 @@ public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
 
     private static final Logger LOG = LoggerFactory.getLogger(DefaultExceptionMapper.class);
 
+    static Set<Class<?>> warnedUnknownExceptions = MutableSet.of();
+    
     /**
      * Maps a throwable to a response.
      * <p/>
@@ -51,38 +57,45 @@ public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
     @Override
     public Response toResponse(Throwable throwable) {
 
+        LOG.debug("REST request running as {} threw: {}", Entitlements.getEntitlementContext(), throwable);
         if (LOG.isTraceEnabled()) {
-            String message = Optional.fromNullable(throwable.getMessage()).or(throwable.getClass().getName());
-            LOG.trace("Request threw: " + message);
+            LOG.trace("Full details of "+Entitlements.getEntitlementContext()+" "+throwable, throwable);
         }
 
+        // Some methods will throw this, which gets converted automatically
         if (throwable instanceof WebApplicationException) {
             WebApplicationException wae = (WebApplicationException) throwable;
             return wae.getResponse();
         }
 
-        // Assume ClassCoercionExceptions are caused by TypeCoercions from input parameters gone wrong.
-        if (throwable instanceof ClassCoercionException)
-            return responseBadRequestJson(ApiError.of(throwable));
+        // The nicest way for methods to provide errors, wrap as this, and the stack trace will be suppressed
+        if (throwable instanceof UserFacingException) {
+            return ApiError.of(throwable.getMessage()).asBadRequestResponseJson();
+        }
 
-        if (throwable instanceof YAMLException)
-            return responseBadRequestJson(ApiError.builderFromThrowable(throwable).prefixMessage("Invalid YAML", ": ").build());
+        // For everything else, a trace is supplied
+        
+        // Assume ClassCoercionExceptions are caused by TypeCoercions from input parameters gone wrong
+        // And IllegalArgumentException for malformed input parameters.
+        if (throwable instanceof ClassCoercionException || throwable instanceof IllegalArgumentException) {
+            return ApiError.of(throwable).asBadRequestResponseJson();
+        }
+
+        // YAML exception 
+        if (throwable instanceof YAMLException) {
+            return ApiError.builder().message(throwable.getMessage()).prefixMessage("Invalid YAML").build().asBadRequestResponseJson();
+        }
+
+        if (!Exceptions.isPrefixBoring(throwable)) {
+            if ( warnedUnknownExceptions.add( throwable.getClass() )) {
+                LOG.info("No exception mapping for " + throwable.getClass() + "; consider adding to "+getClass()+" (future warnings logged at debug)");
+            }
+        }
         
-        LOG.info("No exception mapping for " + throwable.getClass() + ", responding 500", throwable);
         Builder rb = ApiError.builderFromThrowable(throwable);
         if (Strings.isBlank(rb.getMessage()))
-            rb.message("Internal error. Check server logs for details.");
-        return Response.status(Status.INTERNAL_SERVER_ERROR)
-                .type(MediaType.APPLICATION_JSON)
-                .entity(rb.build())
-                .build();
-    }
-
-    private Response responseBadRequestJson(ApiError build) {
-        return Response.status(Status.BAD_REQUEST)
-            .type(MediaType.APPLICATION_JSON)
-            .entity(build)
-            .build();
+            rb.message("Internal error. Contact server administrator to consult logs for more details.");
+        return rb.build().asResponse(Status.INTERNAL_SERVER_ERROR, MediaType.APPLICATION_JSON_TYPE);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/utils/common/src/main/java/brooklyn/util/exceptions/Exceptions.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/exceptions/Exceptions.java b/utils/common/src/main/java/brooklyn/util/exceptions/Exceptions.java
index 9a33566..a233b0c 100644
--- a/utils/common/src/main/java/brooklyn/util/exceptions/Exceptions.java
+++ b/utils/common/src/main/java/brooklyn/util/exceptions/Exceptions.java
@@ -27,7 +27,6 @@ import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 
-import brooklyn.util.collections.MutableList;
 import brooklyn.util.text.Strings;
 
 import com.google.common.base.Predicate;
@@ -38,11 +37,11 @@ import com.google.common.collect.Iterables;
 
 public class Exceptions {
 
-    private static final List<Class<? extends Throwable>> BORING_THROWABLES = ImmutableList.<Class<? extends Throwable>>of(
+    private static final List<Class<? extends Throwable>> BORING_THROWABLE_SUPERTYPES = ImmutableList.<Class<? extends Throwable>>of(
         ExecutionException.class, InvocationTargetException.class, PropagatedRuntimeException.class);
 
     private static boolean isBoring(Throwable t) {
-        for (Class<? extends Throwable> type: BORING_THROWABLES)
+        for (Class<? extends Throwable> type: BORING_THROWABLE_SUPERTYPES)
             if (type.isInstance(t)) return true;
         return false;
     }
@@ -54,13 +53,15 @@ public class Exceptions {
         }
     };
 
-    private static List<Class<? extends Throwable>> BORING_PREFIX_THROWABLES = MutableList.copyOf(BORING_THROWABLES)
-        .append(IllegalStateException.class).append(RuntimeException.class).append(CompoundRuntimeException.class)
-        .toImmutable();
+    private static List<Class<? extends Throwable>> BORING_PREFIX_THROWABLE_EXACT_TYPES = ImmutableList.<Class<? extends Throwable>>of(
+        IllegalStateException.class, RuntimeException.class, CompoundRuntimeException.class);
 
-    private static boolean isPrefixBoring(Throwable t) {
-        for (Class<? extends Throwable> type: BORING_PREFIX_THROWABLES)
-            if (type.isInstance(t)) return true;
+    /** Returns whether this is throwable either known to be boring or to have an unuseful prefix */
+    public static boolean isPrefixBoring(Throwable t) {
+        if (isBoring(t))
+            return true;
+        for (Class<? extends Throwable> type: BORING_PREFIX_THROWABLE_EXACT_TYPES)
+            if (t.getClass().equals(type)) return true;
         return false;
     }
 
@@ -68,7 +69,7 @@ public class Exceptions {
         String was;
         do {
             was = s;
-            for (Class<? extends Throwable> type: BORING_PREFIX_THROWABLES) {
+            for (Class<? extends Throwable> type: BORING_PREFIX_THROWABLE_EXACT_TYPES) {
                 s = Strings.removeAllFromStart(type.getCanonicalName(), type.getName(), type.getSimpleName(), ":", " ");
             }
         } while (!was.equals(s));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/utils/common/src/main/java/brooklyn/util/exceptions/FatalRuntimeException.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/exceptions/FatalRuntimeException.java b/utils/common/src/main/java/brooklyn/util/exceptions/FatalRuntimeException.java
index 28f7828..3ef9909 100644
--- a/utils/common/src/main/java/brooklyn/util/exceptions/FatalRuntimeException.java
+++ b/utils/common/src/main/java/brooklyn/util/exceptions/FatalRuntimeException.java
@@ -20,7 +20,7 @@ package brooklyn.util.exceptions;
 
 /** Exception indicating a fatal error, typically used in CLI routines.
  * The message supplied here should be suitable for display in a CLI response (without stack trace / exception class). */
-public class FatalRuntimeException extends RuntimeException {
+public class FatalRuntimeException extends UserFacingException {
 
     private static final long serialVersionUID = -3359163414517503809L;
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e8f7283c/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java b/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
new file mode 100644
index 0000000..1d53d11
--- /dev/null
+++ b/utils/common/src/main/java/brooklyn/util/exceptions/UserFacingException.java
@@ -0,0 +1,21 @@
+package brooklyn.util.exceptions;
+
+/** marker interface, to show that an exception is suitable for pretty-printing to an end-user,
+ * without including a stack trace */
+public class UserFacingException extends RuntimeException {
+
+    private static final long serialVersionUID = 2216885527195571323L;
+
+    public UserFacingException(String message) {
+        super(message);
+    }
+
+    public UserFacingException(Throwable cause) {
+        super(cause.getMessage(), cause);
+    }
+
+    public UserFacingException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}


[11/12] git commit: address review comments

Posted by al...@apache.org.
address review comments


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

Branch: refs/heads/master
Commit: 3fc4370f9dec8df26d4f86bf815048cb3ad9cce2
Parents: 01d6136
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 09:18:19 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:18:19 2014 -0400

----------------------------------------------------------------------
 .../java/brooklyn/management/internal/LocalLocationManager.java  | 2 ++
 .../brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java | 4 ++--
 .../src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java | 1 -
 3 files changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fc4370f/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
index 6c59f3b..d2fb3d7 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
@@ -41,12 +41,14 @@ import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.RuntimeInterruptedException;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
 
 public class LocalLocationManager implements LocationManager {
 
+    @Beta /* expect to remove when API returns LocationSpec or similar */
     public static final ConfigKey<Boolean> CREATE_UNMANAGED = ConfigKeys.newBooleanConfigKey("brooklyn.internal.location.createUnmanaged",
         "If set on a location or spec, causes the manager to create it in an unmanaged state (for peeking)", false);
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fc4370f/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
index 1331e1f..801344d 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
@@ -111,10 +111,10 @@ public class BrooklynPropertiesSecurityFilter implements Filter {
                     
                 } catch (Throwable e) {
                     // NB errors are typically already caught at this point
-                    if (log.isDebugEnabled())
+                    if (log.isDebugEnabled()) {
                         log.debug("REST failed processing request "+uri+" with "+entitlementContext+": "+e, e);
+                    }
                     
-                    log.warn("REST failed processing request "+uri+" with "+entitlementContext+": "+e, e);
                     throw Exceptions.propagate(e);
                     
                 } finally {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3fc4370f/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
index 71bc945..ea395bc 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/DefaultExceptionMapper.java
@@ -88,7 +88,6 @@ public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
 
         if (!Exceptions.isPrefixBoring(throwable)) {
             if ( warnedUnknownExceptions.add( throwable.getClass() )) {
-                throwable.printStackTrace();
                 LOG.warn("REST call generated exception type "+throwable.getClass()+" unrecognized in "+getClass()+" (subsequent occurrences will be logged debug only): " + throwable);
             }
         }


[03/12] git commit: suppress warning of DTO with no contents, when it has a description which says where the content comes from

Posted by al...@apache.org.
suppress warning of DTO with no contents, when it has a description which says where the content comes from


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

Branch: refs/heads/master
Commit: 1e36c3e503f76c4d9d55949fd05842d9a677b4e8
Parents: 935236e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 12:37:29 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 .../catalog/internal/BasicBrooklynCatalog.java  |  3 ++-
 .../brooklyn/catalog/internal/CatalogDto.java   | 25 +++++++++++++++++---
 .../catalog/internal/CatalogDtoUtils.java       |  5 +---
 .../internal/AbstractManagementContext.java     |  4 ++--
 .../catalog/internal/CatalogDtoTest.java        |  9 +++----
 5 files changed, 32 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1e36c3e5/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
index dfa966a..176975f 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -355,7 +355,8 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
         if (manualAdditionsCatalog!=null) return;
         CatalogDto manualAdditionsCatalogDto = CatalogDto.newNamedInstance(
                 "Manual Catalog Additions", "User-additions to the catalog while Brooklyn is running, " +
-        		"created "+Time.makeDateString());
+        		"created "+Time.makeDateString(),
+        		"manual-additions");
         CatalogDo manualAdditionsCatalog = catalog.addCatalog(manualAdditionsCatalogDto);
         if (manualAdditionsCatalog==null) {
             // not hard to support, but slightly messy -- probably have to use ID's to retrieve the loaded instance

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1e36c3e5/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java b/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
index d84b2f9..4a74ed9 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogDto.java
@@ -30,8 +30,10 @@ import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.PropagatedRuntimeException;
 import brooklyn.util.stream.Streams;
 
+import com.google.common.annotations.Beta;
 import com.google.common.base.Objects;
 
+@Beta
 public class CatalogDto {
 
     private static final Logger LOG = LoggerFactory.getLogger(CatalogDto.class);
@@ -53,7 +55,7 @@ public class CatalogDto {
 
     public static CatalogDto newDefaultLocalScanningDto(CatalogClasspathDo.CatalogScanningModes scanMode) {
         CatalogDo result = new CatalogDo(
-                CatalogDto.newNamedInstance("Local Scanned Catalog", "All annotated Brooklyn entities detected in the default classpath") );
+                newNamedInstance("Local Scanned Catalog", "All annotated Brooklyn entities detected in the default classpath", "scanning-local-classpath") );
         result.setClasspathScanForEntities(scanMode);
         return result.dto;
     }
@@ -78,10 +80,24 @@ public class CatalogDto {
         return result;
     }
 
-    public static CatalogDto newNamedInstance(String name, String description) {
+    /**
+     * Creates a DTO.
+     * <p>
+     * The way contents is treated may change; thus this (and much of catalog) should be treated as beta.
+     * 
+     * @param name
+     * @param description
+     * @param optionalContentsDescription optional description of contents; if null, we normally expect source 'contents' to be set later;
+     *   if the DTO has no 'contents' (ie XML source) then a description should be supplied so we know who is populating it
+     *   (e.g. manual additions); without this, warnings may be generated
+     *   
+     * @return a new Catalog DTO
+     */
+    public static CatalogDto newNamedInstance(String name, String description, String optionalContentsDescription) {
         CatalogDto result = new CatalogDto();
         result.name = name;
         result.description = description;
+        if (optionalContentsDescription!=null) result.contentsDescription = optionalContentsDescription;
         return result;
     }
 
@@ -97,8 +113,11 @@ public class CatalogDto {
             if (url != null) {
                 contents = ResourceUtils.create().getResourceAsString(url);
                 contentsDescription = url;
+            } else if (contentsDescription==null) {
+                LOG.warn("Catalog DTO has no contents and no description; ignoring call to populate it. Description should be set to suppress this warning.");
+                return;
             } else {
-                LOG.warn("Catalog DTO has no contents); ignoring call to populate it.");
+                LOG.debug("Nothing needs doing (no contents or URL) for catalog with contents described as "+contentsDescription+".");
                 return;
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1e36c3e5/core/src/main/java/brooklyn/catalog/internal/CatalogDtoUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/catalog/internal/CatalogDtoUtils.java b/core/src/main/java/brooklyn/catalog/internal/CatalogDtoUtils.java
index 237a473..cb44cb0 100644
--- a/core/src/main/java/brooklyn/catalog/internal/CatalogDtoUtils.java
+++ b/core/src/main/java/brooklyn/catalog/internal/CatalogDtoUtils.java
@@ -33,10 +33,7 @@ public class CatalogDtoUtils {
     private static final Logger log = LoggerFactory.getLogger(CatalogDtoUtils.class);
     
     public static CatalogDto newDefaultLocalScanningDto(CatalogScanningModes scanMode) {
-        CatalogDo result = new CatalogDo(
-                CatalogDto.newNamedInstance("Local Scanned Catalog", "All annotated Brooklyn entities detected in the default classpath") );
-        result.setClasspathScanForEntities(scanMode);
-        return result.dto;
+        return CatalogDto.newDefaultLocalScanningDto(scanMode);
     }
 
     /** throws if there are any problems in retrieving or copying */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1e36c3e5/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
index 2eb695a..46e751d 100644
--- a/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/AbstractManagementContext.java
@@ -336,7 +336,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte
             if (!Strings.isEmpty(catalogUrl)) {
                 catalog = new BasicBrooklynCatalog(this, CatalogDto.newDtoFromUrl(catalogUrl));
                 if (log.isDebugEnabled())
-                    log.debug("Loaded catalog from "+catalogUrl+": "+catalog);
+                    log.debug("Loading catalog from "+catalogUrl+": "+catalog);
             }
         } catch (Exception e) {
             if (Throwables.getRootCause(e) instanceof FileNotFoundException) {
@@ -345,7 +345,7 @@ public abstract class AbstractManagementContext implements ManagementContextInte
                     log.warn("Could not find catalog XML specified at "+nonDefaultUrl+"; using default (local classpath) catalog. Error was: "+e);
                 } else {
                     if (log.isDebugEnabled())
-                        log.debug("No default catalog file available; trying again using local classpath to populate catalog. Error was: "+e);
+                        log.debug("No default catalog file available at "+catalogUrl+"; trying again using local classpath to populate catalog. Error was: "+e);
                 }
             } else {
                 log.warn("Error importing catalog XML at "+catalogUrl+"; using default (local classpath) catalog. Error was: "+e, e);                

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/1e36c3e5/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java b/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
index e580182..4c07e5d 100644
--- a/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
+++ b/core/src/test/java/brooklyn/catalog/internal/CatalogDtoTest.java
@@ -83,10 +83,11 @@ public class CatalogDtoTest {
     public static CatalogDto buildExampleCatalog() {
         CatalogDo root = new CatalogDo(CatalogDto.newNamedInstance("My Local Catalog", 
                 "My favourite local settings, including remote catalogs -- " +
-        		"intended partly as a teaching example for what can be expressed, and how"));
+        		"intended partly as a teaching example for what can be expressed, and how",
+        		"contents-built-in-test"));
         root.setClasspathScanForEntities(CatalogScanningModes.NONE);
         
-        CatalogDo testEntitiesJavaCatalog = new CatalogDo(CatalogDto.newNamedInstance("Test Entities from Java", null));
+        CatalogDo testEntitiesJavaCatalog = new CatalogDo(CatalogDto.newNamedInstance("Test Entities from Java", null, "test-java"));
         testEntitiesJavaCatalog.setClasspathScanForEntities(CatalogScanningModes.NONE);
         testEntitiesJavaCatalog.addToClasspath(MavenRetriever.localUrl(BrooklynMavenArtifacts.artifact("", "brooklyn-core", "jar", "tests")));
         testEntitiesJavaCatalog.addEntry(CatalogItems.newTemplateFromJava(
@@ -95,13 +96,13 @@ public class CatalogDtoTest {
                 TestEntity.class.getCanonicalName(), "Test Entity from JAR"));
         root.addCatalog(testEntitiesJavaCatalog.dto);
 
-        CatalogDo testEntitiesJavaCatalogScanning = new CatalogDo(CatalogDto.newNamedInstance("Test Entities from Java Scanning", null));
+        CatalogDo testEntitiesJavaCatalogScanning = new CatalogDo(CatalogDto.newNamedInstance("Test Entities from Java Scanning", null, "test-java-scan"));
         testEntitiesJavaCatalogScanning.addToClasspath(MavenRetriever.localUrl(BrooklynMavenArtifacts.artifact("", "brooklyn-core", "jar", "tests")));
         testEntitiesJavaCatalogScanning.setClasspathScanForEntities(CatalogScanningModes.ANNOTATIONS);
         root.addCatalog(testEntitiesJavaCatalogScanning.dto);
         
         CatalogDo osgiCatalog = new CatalogDo(CatalogDto.newNamedInstance("Test Entities from OSGi",
-                "A catalog whose entries define their libraries as a list of OSGi bundles"));
+                "A catalog whose entries define their libraries as a list of OSGi bundles", "test-osgi-defined"));
         osgiCatalog.setClasspathScanForEntities(CatalogScanningModes.NONE);
         CatalogEntityItemDto osgiEntity = CatalogItems.newEntityFromJava(TestEntity.class.getCanonicalName(), "Test Entity from OSGi");
         // NB: this is not actually an OSGi bundle, but it's okay as we don't instantiate the bundles ahead of time (currently)


[04/12] git commit: better warnings when icons are missing

Posted by al...@apache.org.
better warnings when icons are missing


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

Branch: refs/heads/master
Commit: fa8cdb4c54b5a6f46a313366ae10ec31ce287c3b
Parents: 1e36c3e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 12:54:03 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 .../rest/resources/CatalogResource.java         | 24 ++++++++++++++++++--
 .../brooklyn/rest/util/WebResourceUtils.java    |  2 +-
 2 files changed, 23 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fa8cdb4c/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
index 007c19c..b553bf9 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/CatalogResource.java
@@ -24,6 +24,7 @@ import java.io.InputStreamReader;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 import javax.annotation.Nullable;
 import javax.ws.rs.core.MediaType;
@@ -49,6 +50,8 @@ import brooklyn.rest.domain.SummaryComparators;
 import brooklyn.rest.transform.CatalogTransformer;
 import brooklyn.rest.util.WebResourceUtils;
 import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableSet;
+import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.text.StringPredicates;
 import brooklyn.util.text.Strings;
 
@@ -78,6 +81,8 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
       return create(CharStreams.toString(new InputStreamReader(uploadedInputStream, Charsets.UTF_8)));
     }
 
+    static Set<String> missingIcons = MutableSet.of();
+    
     @Override
     public Response create(String yaml) {
         CatalogItem<?,?> item;
@@ -202,8 +207,23 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
             log.debug("Loading and returning "+url+" as icon for "+result);
             
             MediaType mime = WebResourceUtils.getImageMediaTypeFromExtension(Files.getFileExtension(url));
-            Object content = ResourceUtils.create(result.newClassLoadingContext(mgmt())).getResourceFromUrl(url);
-            return Response.ok(content, mime).build();
+            try {
+                Object content = ResourceUtils.create(result.newClassLoadingContext(mgmt())).getResourceFromUrl(url);
+                return Response.ok(content, mime).build();
+            } catch (Exception e) {
+                Exceptions.propagateIfFatal(e);
+                synchronized (missingIcons) {
+                    if (missingIcons.add(url)) {
+                        // note: this can be quite common when running from an IDE, as resources may not be copied;
+                        // a mvn build should sort it out (the IDE will then find the resources, until you clean or maybe refresh...)
+                        log.warn("Missing icon data for "+itemId+", expected at: "+url+" (subsequent messages will log debug only)");
+                        log.debug("Trace for missing icon data at "+url+": "+e, e);
+                    } else {
+                        log.debug("Missing icon data for "+itemId+", expected at: "+url+" (already logged WARN and error details)");
+                    }
+                }
+                throw WebResourceUtils.notFound("Icon unavailable for %s", itemId);
+            }
         }
         
         log.debug("Returning redirect to "+url+" as icon for "+result);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/fa8cdb4c/usage/rest-server/src/main/java/brooklyn/rest/util/WebResourceUtils.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/WebResourceUtils.java b/usage/rest-server/src/main/java/brooklyn/rest/util/WebResourceUtils.java
index 61e4217..6c1c2c1 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/util/WebResourceUtils.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/WebResourceUtils.java
@@ -59,7 +59,7 @@ public class WebResourceUtils {
     /** @throws WebApplicationException With code 404 not found */
     public static WebApplicationException notFound(String format, Object... args) {
         String msg = String.format(format, args);
-        if (log.isDebugEnabled()) log.debug("returning 404 notFound("+msg+") - may be a stale browser session");
+        if (log.isDebugEnabled()) log.debug("returning 404 notFound("+msg+")");
         throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND)
                 .type(MediaType.APPLICATION_JSON_TYPE)
                 .entity(ApiError.builder().message(msg).build()).build());


[06/12] git commit: prevent warning of entitlement context on forwarded requests (eg /) and improve detail for logging REST info

Posted by al...@apache.org.
prevent warning of entitlement context on forwarded requests (eg /) and improve detail for logging REST info


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

Branch: refs/heads/master
Commit: 9d616595b75416682e9dede1bbd045b22cc1a9d4
Parents: fa8cdb4
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 14:08:47 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 .../management/entitlement/Entitlements.java    |  1 +
 .../entitlement/WebEntitlementContext.java      |  9 +++--
 .../entitlement/AcmeEntitlementManagerTest.java |  8 ++---
 .../BrooklynPropertiesSecurityFilter.java       | 37 +++++++++++++++++---
 4 files changed, 45 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9d616595/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
index 21b6b90..f9e188e 100644
--- a/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
+++ b/core/src/main/java/brooklyn/management/entitlement/Entitlements.java
@@ -228,6 +228,7 @@ public class Entitlements {
         EntitlementContext oldContext = PerThreadEntitlementContextHolder.perThreadEntitlementsContextHolder.get();
         if (oldContext!=null && context!=null) {
             log.warn("Changing entitlement context from "+oldContext+" to "+context+"; context should have been reset or extended, not replaced");
+            log.debug("Trace for entitlement context duplicate overwrite", new Throwable("Trace for entitlement context overwrite"));
         }
         PerThreadEntitlementContextHolder.perThreadEntitlementsContextHolder.set(context);
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9d616595/core/src/main/java/brooklyn/management/entitlement/WebEntitlementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/entitlement/WebEntitlementContext.java b/core/src/main/java/brooklyn/management/entitlement/WebEntitlementContext.java
index 657df22..0ae3d90 100644
--- a/core/src/main/java/brooklyn/management/entitlement/WebEntitlementContext.java
+++ b/core/src/main/java/brooklyn/management/entitlement/WebEntitlementContext.java
@@ -28,18 +28,23 @@ public class WebEntitlementContext implements EntitlementContext {
     final String sourceIp;
     final String requestUri;
     
-    public WebEntitlementContext(String user, String sourceIp, String requestUri) {
+    /** a mostly-unique identifier for the inbound request, to distinguish between duplicate requests and for cross-referencing with URI's */
+    final String requestUniqueIdentifier;
+    
+    public WebEntitlementContext(String user, String sourceIp, String requestUri, String requestUniqueIdentifier) {
         this.user = user;
         this.sourceIp = sourceIp;
         this.requestUri = requestUri;
+        this.requestUniqueIdentifier = requestUniqueIdentifier;
     }
     
     @Override public String user() { return user; }
     public String sourceIp() { return sourceIp; }
     public String requestUri() { return requestUri; }
+    public String requestUniqueIdentifier() { return requestUniqueIdentifier; }
 
     @Override
     public String toString() {
-        return JavaClassNames.simpleClassName(getClass())+"["+user+"@"+sourceIp+":"+requestUri+"]";
+        return JavaClassNames.simpleClassName(getClass())+"["+user+"@"+sourceIp+":"+requestUniqueIdentifier+"]";
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9d616595/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
index 2dc2caa..de9efbb 100644
--- a/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
+++ b/core/src/test/java/brooklyn/management/entitlement/AcmeEntitlementManagerTest.java
@@ -68,7 +68,7 @@ public class AcmeEntitlementManagerTest {
     @Test
     public void testUserWithMinimal() {
         setup(configBag);
-        WebEntitlementContext entitlementContext = new WebEntitlementContext("hacker", "127.0.0.1", URI.create("/applications").toString());
+        WebEntitlementContext entitlementContext = new WebEntitlementContext("hacker", "127.0.0.1", URI.create("/applications").toString(), "H");
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
@@ -81,7 +81,7 @@ public class AcmeEntitlementManagerTest {
     @Test
     public void testUserWithReadOnly() {
         setup(configBag);
-        WebEntitlementContext entitlementContext = new WebEntitlementContext("bob", "127.0.0.1", URI.create("/applications").toString());
+        WebEntitlementContext entitlementContext = new WebEntitlementContext("bob", "127.0.0.1", URI.create("/applications").toString(), "B");
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertFalse(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
@@ -94,7 +94,7 @@ public class AcmeEntitlementManagerTest {
     @Test
     public void testUserWithAllPermissions() {
         setup(configBag);
-        WebEntitlementContext entitlementContext = new WebEntitlementContext("alice", "127.0.0.1", URI.create("/applications").toString());
+        WebEntitlementContext entitlementContext = new WebEntitlementContext("alice", "127.0.0.1", URI.create("/applications").toString(), "A");
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));
@@ -107,7 +107,7 @@ public class AcmeEntitlementManagerTest {
     @Test
     public void testNullHasAllPermissions() {
         setup(configBag);
-        WebEntitlementContext entitlementContext = new WebEntitlementContext(null, "127.0.0.1", URI.create("/applications").toString());
+        WebEntitlementContext entitlementContext = new WebEntitlementContext(null, "127.0.0.1", URI.create("/applications").toString(), "X");
         Entitlements.setEntitlementContext(entitlementContext);
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.ROOT, null));
         Assert.assertTrue(Entitlements.isEntitled(mgmt.getEntitlementManager(), Entitlements.SEE_ENTITY, app));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9d616595/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
index 1097d8c..74ab303 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/security/BrooklynPropertiesSecurityFilter.java
@@ -57,6 +57,8 @@ public class BrooklynPropertiesSecurityFilter implements Filter {
     
     protected ManagementContext mgmt;
     protected DelegatingSecurityProvider provider;
+    
+    private static ThreadLocal<String> originalRequest = new ThreadLocal<String>();
 
     @Override
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
@@ -73,18 +75,45 @@ public class BrooklynPropertiesSecurityFilter implements Filter {
                 // do nothing here, fall through to below
             } else {
                 WebEntitlementContext entitlementContext = null;
+                String uri = ((HttpServletRequest)request).getRequestURI();
                 try {
-                    entitlementContext = new WebEntitlementContext(user, ((HttpServletRequest)request).getRemoteAddr(), ((HttpServletRequest)request).getRequestURI());
+                    String uid = Integer.toHexString(hashCode());
+                    entitlementContext = new WebEntitlementContext(user, ((HttpServletRequest)request).getRemoteAddr(), uri, uid);
+                    if (originalRequest.get()==null) {
+                        // initial filter application
+                        originalRequest.set(uri);
+                    } else {
+                        // this filter is being applied *again*, probably due to forwarding (e.g. from '/' to '/index.html')
+                        log.debug("REST request {} being forwarded from {} to {}", new Object[] { uid, originalRequest.get(), uri });
+                        // clear the entitlement context before setting to avoid warnings
+                        Entitlements.clearEntitlementContext();
+                    }
                     Entitlements.setEntitlementContext(entitlementContext);
-                    log.debug("REST starting processing request {}", entitlementContext);
+                    
+                    log.debug("REST starting processing request {} with {}", uri, entitlementContext);
+                    if (!((HttpServletRequest)request).getParameterMap().isEmpty()) {
+                        log.debug("  REST req {} parameters: {}", uid, ((HttpServletRequest)request).getParameterMap());
+                    }
+                    if (((HttpServletRequest)request).getContentLength()>0) {
+                        log.debug("  REST req {} upload content type {}", uid, ((HttpServletRequest)request).getContentType()+" length "+((HttpServletRequest)request).getContentLength());
+                    }
+                    
                     chain.doFilter(request, response);
-                    log.debug("REST completed processing request {}", entitlementContext);
+                    
+                    log.debug("REST completed, code {}, processing request {} with {}", 
+                        new Object[] { ((HttpServletResponse)response).getStatus(), uri, entitlementContext } );
                     return;
+                    
                 } catch (Throwable e) {
+                    // NB errors are typically already caught at this point
                     if (log.isDebugEnabled())
-                        log.debug("REST failed processing request "+entitlementContext+": "+e, e);
+                        log.debug("REST` failed processing request "+uri+" with "+entitlementContext+": "+e, e);
+                    
+                    log.warn("REST` failed processing request "+uri+" with "+entitlementContext+": "+e, e);
                     throw Exceptions.propagate(e);
+                    
                 } finally {
+                    originalRequest.remove();
                     Entitlements.clearEntitlementContext();
                 }
             }


[08/12] git commit: move some many-times test to integration group so build runs faster

Posted by al...@apache.org.
move some many-times test to integration group so build runs faster


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

Branch: refs/heads/master
Commit: 01d6136a6255a86c4ddb36c9840dfc62083478b6
Parents: b15a471
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Fri Jul 18 02:02:50 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:18 2014 -0400

----------------------------------------------------------------------
 core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java    | 2 +-
 .../management/ha/HighAvailabilityManagerSplitBrainTest.java       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/01d6136a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
index d16bea6..1292dea 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindEntityTest.java
@@ -194,7 +194,7 @@ public class RebindEntityTest extends RebindTestFixtureWithApp {
     
     // Saw this fail during development (fixed now); but want at least one of these tests to be run 
     // many times for stress testing purposes
-    @Test(invocationCount=100, groups="Integeration")
+    @Test(invocationCount=100, groups="Integration")
     public void testRestoresEntityIdAndDisplayNameManyTimes() throws Exception {
         testRestoresEntityIdAndDisplayName();
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/01d6136a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
index 26627d6..ddf6b73 100644
--- a/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
+++ b/core/src/test/java/brooklyn/management/ha/HighAvailabilityManagerSplitBrainTest.java
@@ -274,7 +274,7 @@ public class HighAvailabilityManagerSplitBrainTest {
         assertEquals(n2.mgmt.getApplications().size(), 1);
     }
     
-    @Test(invocationCount=50)
+    @Test(invocationCount=50, groups="Integration")
     public void testIfNodeStopsBeingAbleToWriteManyTimes() throws Exception {
         testIfNodeStopsBeingAbleToWrite();
     }


[05/12] git commit: demote dull log messages to 'trace'

Posted by al...@apache.org.
demote dull log messages to 'trace'


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

Branch: refs/heads/master
Commit: 920a0928445799d01aef6d88654553125837803e
Parents: e8f7283
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 16:06:58 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 .../brooklyn/entity/basic/EntityDynamicType.java    | 16 ++++++++--------
 .../management/internal/LocalUsageManager.java      | 11 ++++++-----
 2 files changed, 14 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/920a0928/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java b/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
index 2d298d7..468e538 100644
--- a/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
+++ b/core/src/main/java/brooklyn/entity/basic/EntityDynamicType.java
@@ -300,7 +300,7 @@ public class EntityDynamicType {
                     Effector<?> overwritten = result.put(eff.getName(), eff);
                     Field overwrittenFieldSource = fieldSources.put(eff.getName(), f);
                     if (overwritten!=null && !Effectors.sameInstance(overwritten, eff)) {
-                        LOG.debug("multiple definitions for effector {} on {}; preferring {} from {} to {} from {}", new Object[] {
+                        LOG.trace("multiple definitions for effector {} on {}; preferring {} from {} to {} from {}", new Object[] {
                                 eff.getName(), (optionalEntity != null ? optionalEntity : clazz), eff, f, overwritten, 
                                 overwrittenFieldSource});
                     }
@@ -326,7 +326,7 @@ public class EntityDynamicType {
                         result.put(eff.getName(), eff);
                         Method overwrittenMethodSource = methodSources.put(eff.getName(), m);
                         Field overwrittenFieldSource = fieldSources.remove(eff.getName());
-                        LOG.debug("multiple definitions for effector {} on {}; preferring {} from {} to {} from {}", new Object[] {
+                        LOG.trace("multiple definitions for effector {} on {}; preferring {} from {} to {} from {}", new Object[] {
                                 eff.getName(), (optionalEntity != null ? optionalEntity : clazz), eff, m, overwritten, 
                                 (overwrittenMethodSource != null ? overwrittenMethodSource : overwrittenFieldSource)});
                     }
@@ -359,8 +359,8 @@ public class EntityDynamicType {
                     Field source = sources.put(sens.getName(), f);
                     if (overwritten!=null && overwritten != sens) {
                         if (sens instanceof HasConfigKey) {
-                            // probably overriding defaults, just log as debug (there will be add'l logging in config key section)
-                            LOG.debug("multiple definitions for config sensor {} on {}; preferring {} from {} to {} from {}", new Object[] {
+                            // probably overriding defaults, just log low level (there will be add'l logging in config key section)
+                            LOG.trace("multiple definitions for config sensor {} on {}; preferring {} from {} to {} from {}", new Object[] {
                                     sens.getName(), optionalEntity!=null ? optionalEntity : clazz, sens, f, overwritten, source});
                         } else {
                             LOG.warn("multiple definitions for sensor {} on {}; preferring {} from {} to {} from {}", new Object[] {
@@ -441,8 +441,8 @@ public class EntityDynamicType {
                     ConfigKey<? extends Object> lowerV = lower==null ? null : lower.equals(k.field) ? k.value : best.value;
                     if (best.value == k.value) {
                         // same value doesn't matter which we take (but take lower if there is one)
-                        if (LOG.isDebugEnabled()) 
-                            LOG.debug("multiple definitions for config key {} on {}; same value {}; " +
+                        if (LOG.isTraceEnabled()) 
+                            LOG.trace("multiple definitions for config key {} on {}; same value {}; " +
                                     "from {} and {}, preferring {}", 
                                     new Object[] {
                                     best.value.getName(), optionalEntity!=null ? optionalEntity : clazz,
@@ -451,8 +451,8 @@ public class EntityDynamicType {
                         best = new FieldAndValue<ConfigKey<?>>(lower!=null ? lower : best.field, best.value);
                     } else if (lower!=null) {
                         // different value, but one clearly lower (in type hierarchy)
-                        if (LOG.isDebugEnabled()) 
-                            LOG.debug("multiple definitions for config key {} on {}; " +
+                        if (LOG.isTraceEnabled()) 
+                            LOG.trace("multiple definitions for config key {} on {}; " +
                                     "from {} and {}, preferring lower {}, value {}", 
                                     new Object[] {
                                     best.value.getName(), optionalEntity!=null ? optionalEntity : clazz,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/920a0928/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java b/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
index f825bc3..65efe44 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalUsageManager.java
@@ -69,7 +69,7 @@ public class LocalUsageManager implements UsageManager {
 
     @Override
     public void recordApplicationEvent(Application app, Lifecycle state) {
-        log.debug("Storing location lifecycle event: application {} in state {};", new Object[] {app, state});
+        log.debug("Storing application lifecycle usage event: application {} in state {}", new Object[] {app, state});
         ConcurrentMap<String, ApplicationUsage> eventMap = managementContext.getStorage().getMap(APPLICATION_USAGE_KEY);
         synchronized (mutex) {
             ApplicationUsage usage = eventMap.get(app.getId());
@@ -100,18 +100,18 @@ public class LocalUsageManager implements UsageManager {
         checkNotNull(loc, "location");
         checkNotNull(state, "state of location %s", loc);
         if (loc.getId() == null) {
-            log.error("Ignoring location lifecycle event for {} (state {}), because location has no id", loc, state);
+            log.error("Ignoring location lifecycle usage event for {} (state {}), because location has no id", loc, state);
             return;
         }
         if (managementContext.getStorage() == null) {
-            log.warn("Cannot store location lifecycle event for {} (state {}), because storage not available", loc, state);
+            log.warn("Cannot store location lifecycle usage event for {} (state {}), because storage not available", loc, state);
             return;
         }
         
         Object callerContext = loc.getConfig(LocationConfigKeys.CALLER_CONTEXT);
         
         if (callerContext != null && callerContext instanceof Entity) {
-            log.debug("Storing location lifecycle event: location {} in state {}; caller context {}", new Object[] {loc, state, callerContext});
+            log.debug("Storing location lifecycle usage event: location {} in state {}; caller context {}", new Object[] {loc, state, callerContext});
             
             Entity caller = (Entity) callerContext;
             String entityTypeName = caller.getEntityType().getName();
@@ -128,7 +128,8 @@ public class LocalUsageManager implements UsageManager {
                 usageMap.put(loc.getId(), usage);
             }
         } else {
-            log.debug("Not recording location-event for {} in state {}, because no caller context", new Object[] {loc, state});
+            // normal for high-level locations
+            log.trace("Not recording location lifecycle usage event for {} in state {}, because no caller context", new Object[] {loc, state});
         }
     }
 


[02/12] git commit: allow a CREATE_UNMANAGED mode for locations, used when peeking, so that we don't get lots of logging on the frequent location listings from REST API

Posted by al...@apache.org.
allow a CREATE_UNMANAGED mode for locations, used when peeking, so that we don't get lots of logging on the frequent location listings from REST API


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

Branch: refs/heads/master
Commit: 965a3d1f92e878ad52f3cce389ad0dbad017bfc0
Parents: 920a092
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Thu Jul 17 16:07:59 2014 -0400
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Fri Jul 18 09:15:17 2014 -0400

----------------------------------------------------------------------
 .../java/brooklyn/location/LocationRegistry.java   |  2 +-
 .../main/java/brooklyn/location/LocationSpec.java  |  7 ++++++-
 .../java/brooklyn/management/LocationManager.java  |  6 +++++-
 .../location/basic/BasicLocationRegistry.java      | 10 ++++++----
 .../management/internal/LocalLocationManager.java  | 17 ++++++++++++++++-
 .../main/java/brooklyn/util/config/ConfigBag.java  | 15 ++++++++++-----
 6 files changed, 44 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/965a3d1f/api/src/main/java/brooklyn/location/LocationRegistry.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationRegistry.java b/api/src/main/java/brooklyn/location/LocationRegistry.java
index 34a1637..e9db3f2 100644
--- a/api/src/main/java/brooklyn/location/LocationRegistry.java
+++ b/api/src/main/java/brooklyn/location/LocationRegistry.java
@@ -58,7 +58,7 @@ public interface LocationRegistry {
      * but callers should prefer this when they don't wish to create a new location which will be managed in perpetuity!
      * 
      * @since 0.7.0, but beta and likely to change as the semantics of this class are tuned */
-    @Beta
+    @Beta   // see impl for notes
     public Location resolveForPeeking(LocationDefinition l);
 
     /** returns fully populated (config etc) location from the given definition */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/965a3d1f/api/src/main/java/brooklyn/location/LocationSpec.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/location/LocationSpec.java b/api/src/main/java/brooklyn/location/LocationSpec.java
index d9027b5..32bf7c2 100644
--- a/api/src/main/java/brooklyn/location/LocationSpec.java
+++ b/api/src/main/java/brooklyn/location/LocationSpec.java
@@ -150,11 +150,16 @@ public class LocationSpec<T extends Location> implements Serializable {
         return this;
     }
 
+    public <V> LocationSpec<T> removeConfig(ConfigKey<V> key) {
+        config.remove( checkNotNull(key, "key") );
+        return this;
+    }
+
     public <E> LocationSpec<T> extension(Class<E> extensionType, E extension) {
         extensions.put(checkNotNull(extensionType, "extensionType"), checkNotNull(extension, "extension"));
         return this;
     }
-
+    
     /**
      * @return The type of the location
      */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/965a3d1f/api/src/main/java/brooklyn/management/LocationManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/management/LocationManager.java b/api/src/main/java/brooklyn/management/LocationManager.java
index ef6f990..4708474 100644
--- a/api/src/main/java/brooklyn/management/LocationManager.java
+++ b/api/src/main/java/brooklyn/management/LocationManager.java
@@ -21,7 +21,10 @@ package brooklyn.management;
 import java.util.Collection;
 import java.util.Map;
 
+import javax.annotation.Nullable;
+
 import brooklyn.location.Location;
+import brooklyn.location.LocationDefinition;
 import brooklyn.location.LocationSpec;
 
 /**
@@ -35,7 +38,7 @@ public interface LocationManager {
      * @param spec
      */
     <T extends Location> T createLocation(LocationSpec<T> spec);
-    
+
     /**
      * Convenience (particularly for groovy code) to create a location.
      * Equivalent to {@code createLocation(LocationSpec.create(type).configure(config))}
@@ -83,4 +86,5 @@ public interface LocationManager {
      * (though it may be logged so duplicate calls are best avoided).
      */
     void unmanage(Location loc);
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/965a3d1f/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
index b3b5d03..2c7cf36 100644
--- a/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
+++ b/core/src/main/java/brooklyn/location/basic/BasicLocationRegistry.java
@@ -42,6 +42,7 @@ import brooklyn.location.LocationRegistry;
 import brooklyn.location.LocationResolver;
 import brooklyn.location.LocationResolver.EnableableLocationResolver;
 import brooklyn.management.ManagementContext;
+import brooklyn.management.internal.LocalLocationManager;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.javalang.JavaClassNames;
@@ -333,10 +334,11 @@ public class BasicLocationRegistry implements LocationRegistry {
 
     @Override
     public Location resolveForPeeking(LocationDefinition ld) {
-        // TODO actually look it up
-        Location l = resolve(ld, Collections.emptyMap());
-        mgmt.getLocationManager().unmanage(l);
-        return l;
+        // TODO should clean up how locations are stored, figuring out whether they are shared or not;
+        // or maybe better, the API calls to this might just want to get the LocationSpec objects back
+        
+        // for now we use a 'CREATE_UNMANGED' flag to prevent management (leaks and logging)
+        return resolve(ld, ConfigBag.newInstance().configure(LocalLocationManager.CREATE_UNMANAGED, true).getAllConfig());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/965a3d1f/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
index 72372bb..6c59f3b 100644
--- a/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
+++ b/core/src/main/java/brooklyn/management/internal/LocalLocationManager.java
@@ -26,6 +26,8 @@ import java.util.Map;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.ConfigKeys;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.proxying.InternalLocationFactory;
 import brooklyn.internal.storage.BrooklynStorage;
@@ -35,6 +37,7 @@ import brooklyn.location.basic.AbstractLocation;
 import brooklyn.location.basic.LocationInternal;
 import brooklyn.management.AccessController;
 import brooklyn.management.LocationManager;
+import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.exceptions.RuntimeInterruptedException;
 
@@ -44,6 +47,9 @@ import com.google.common.collect.Maps;
 
 public class LocalLocationManager implements LocationManager {
 
+    public static final ConfigKey<Boolean> CREATE_UNMANAGED = ConfigKeys.newBooleanConfigKey("brooklyn.internal.location.createUnmanaged",
+        "If set on a location or spec, causes the manager to create it in an unmanaged state (for peeking)", false);
+    
     private static final Logger log = LoggerFactory.getLogger(LocalLocationManager.class);
 
     private final LocalManagementContext managementContext;
@@ -71,8 +77,17 @@ public class LocalLocationManager implements LocationManager {
     @Override
     public <T extends Location> T createLocation(LocationSpec<T> spec) {
         try {
+            boolean createUnmanaged = ConfigBag.coerceFirstNonNullKeyValue(CREATE_UNMANAGED, 
+                spec.getConfig().get(CREATE_UNMANAGED), spec.getFlags().get(CREATE_UNMANAGED.getName()));
+            if (createUnmanaged) {
+                spec.removeConfig(CREATE_UNMANAGED);
+            }
+            
             T loc = locationFactory.createLocation(spec);
-            manage(loc);
+            if (!createUnmanaged) {
+                manage(loc);
+            }
+            
             return loc;
         } catch (Throwable e) {
             log.warn("Failed to create location using spec "+spec+" (rethrowing)", e);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/965a3d1f/core/src/main/java/brooklyn/util/config/ConfigBag.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/config/ConfigBag.java b/core/src/main/java/brooklyn/util/config/ConfigBag.java
index 575c8e2..d35fb78 100644
--- a/core/src/main/java/brooklyn/util/config/ConfigBag.java
+++ b/core/src/main/java/brooklyn/util/config/ConfigBag.java
@@ -399,12 +399,17 @@ public class ConfigBag {
     protected <T> T get(ConfigKey<T> key, boolean remove) {
         // TODO for now, no evaluation -- closure content / smart (self-extracting) keys are NOT supported
         // (need a clean way to inject that behaviour, as well as desired TypeCoercions)
-        Object value;
         if (config.containsKey(key.getName()))
-            value = getStringKey(key.getName(), remove);
-        else
-            value = key.getDefaultValue();
-        return TypeCoercions.coerce(value, key.getTypeToken());
+            return coerceFirstNonNullKeyValue(key, getStringKey(key.getName(), remove));
+        
+        return coerceFirstNonNullKeyValue(key);
+    }
+
+    /** returns the first non-null value to be the type indicated by the key, or the keys default value if no non-null values are supplied */
+    public static <T> T coerceFirstNonNullKeyValue(ConfigKey<T> key, Object ...values) {
+        for (Object o: values)
+            if (o!=null) return TypeCoercions.coerce(o, key.getTypeToken());
+        return TypeCoercions.coerce(key.getDefaultValue(), key.getTypeToken());
     }
 
     protected Object getStringKey(String key, boolean markUsed) {


[12/12] git commit: This closes #77

Posted by al...@apache.org.
This closes #77


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

Branch: refs/heads/master
Commit: f0b8f296d0211ef57df933ec8c0e2da5ddcc879d
Parents: 935236e 3fc4370
Author: Aled Sage <al...@gmail.com>
Authored: Fri Jul 18 14:41:48 2014 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Fri Jul 18 14:41:48 2014 +0100

----------------------------------------------------------------------
 .../brooklyn/location/LocationRegistry.java     |   2 +-
 .../java/brooklyn/location/LocationSpec.java    |   7 +-
 .../brooklyn/management/LocationManager.java    |   6 +-
 .../catalog/internal/BasicBrooklynCatalog.java  |   3 +-
 .../brooklyn/catalog/internal/CatalogDto.java   |  25 ++-
 .../catalog/internal/CatalogDtoUtils.java       |   5 +-
 .../entity/basic/ApplicationBuilder.java        |   6 +
 .../entity/basic/EntityDynamicType.java         |  16 +-
 .../location/basic/BasicLocationRegistry.java   |  10 +-
 .../management/entitlement/Entitlements.java    |   1 +
 .../entitlement/WebEntitlementContext.java      |   9 +-
 .../internal/AbstractManagementContext.java     |   4 +-
 .../internal/LocalLocationManager.java          |  19 ++-
 .../management/internal/LocalUsageManager.java  |  11 +-
 .../java/brooklyn/util/config/ConfigBag.java    |  15 +-
 .../catalog/internal/CatalogDtoTest.java        |   9 +-
 ...stomAggregatingEnricherDeprecatedTest.groovy |   3 +-
 .../TransformingEnricherDeprecatedTest.groovy   |   2 +-
 .../entity/EffectorSayHiGroovyTest.groovy       |   3 +-
 .../entity/basic/AbstractEntityLegacyTest.java  |   4 +-
 .../entity/basic/ConfigMapGroovyTest.groovy     |   2 +-
 .../entity/basic/EntitySubscriptionTest.groovy  |   2 +-
 ...apListAndOtherStructuredConfigKeyTest.groovy |   2 +-
 .../java/brooklyn/entity/group/GroupTest.java   |   3 +-
 .../entity/rebind/RebindEntityTest.java         |   2 +-
 .../entity/rebind/RebindManagerSorterTest.java  |   4 +-
 ...regatingMachineProvisioningLocationTest.java |   3 +-
 .../basic/TestPortSupplierLocation.groovy       |   3 +-
 .../entitlement/AcmeEntitlementManagerTest.java |   8 +-
 .../HighAvailabilityManagerSplitBrainTest.java  |   2 +-
 .../policy/basic/PolicySubscriptionTest.groovy  |   2 +-
 .../brooklyn/test/entity/TestApplication.java   |   8 +-
 .../enricher/HttpLatencyDetectorTest.java       |   2 +-
 .../enricher/TimeFractionDeltaEnricherTest.java |   2 +-
 .../brooklyn/policy/ha/ServiceReplacerTest.java |   3 +-
 .../entity/brooklynnode/BrooklynNodeTest.java   |   4 +-
 .../brooklyn/entity/java/EntityPollingTest.java |   2 +-
 .../entity/java/VanillaJavaAppTest.java         |   8 +-
 .../camp/brooklyn/JavaWebAppsMatchingTest.java  |   4 +-
 usage/cli/src/main/java/brooklyn/cli/Main.java  |   4 +-
 .../brooklyn/launcher/WebAppRunnerTest.groovy   | 163 -------------------
 .../brooklyn/launcher/WebAppRunnerTest.java     | 160 ++++++++++++++++++
 .../java/brooklyn/rest/domain/ApiError.java     |  24 +++
 .../fixtures/api-error-no-details.json          |   3 +-
 .../rest/resources/CatalogResource.java         |  24 ++-
 .../brooklyn/rest/resources/UsageResource.java  |   5 +-
 .../BrooklynPropertiesSecurityFilter.java       |  44 ++++-
 .../rest/util/DefaultExceptionMapper.java       |  57 ++++---
 .../brooklyn/rest/util/WebResourceUtils.java    |   2 +-
 .../brooklyn/rest/domain/SensorSummaryTest.java |   3 +-
 .../rest/resources/UsageResourceTest.java       |   2 +-
 .../brooklyn/util/exceptions/Exceptions.java    |  21 +--
 .../util/exceptions/FatalRuntimeException.java  |   2 +-
 .../util/exceptions/UserFacingException.java    |  39 +++++
 54 files changed, 487 insertions(+), 292 deletions(-)
----------------------------------------------------------------------