You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2015/07/14 11:35:52 UTC

[01/16] incubator-brooklyn git commit: [BROOKLYN-153] Update the REST API documentation for the catalog endpoints

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master b2d3f336c -> 31b8471f7


[BROOKLYN-153] Update the REST API documentation for the catalog endpoints


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

Branch: refs/heads/master
Commit: 08790a76b28f7e2d560c873118af0379ecb60895
Parents: ea1d6cb
Author: Thomas Bouron <th...@cloudsoftcorp.com>
Authored: Tue Jun 30 15:55:53 2015 +0100
Committer: Thomas Bouron <th...@cloudsoftcorp.com>
Committed: Tue Jun 30 15:55:53 2015 +0100

----------------------------------------------------------------------
 .../main/java/brooklyn/rest/api/CatalogApi.java | 42 ++++++++++----------
 1 file changed, 21 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/08790a76/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
index f757310..fe6de3a 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
@@ -94,27 +94,27 @@ public interface CatalogApi {
         @PathParam("entityId") String entityId) throws Exception;
 
     @DELETE
-    @Path("/applications/{applicationId}/{version}")
+    @Path("/applications/{type}/{version}")
     @ApiOperation(value = "Deletes a specific version of an application's definition from the catalog")
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public void deleteApplication(
-        @ApiParam(name = "applicationId", value = "The ID of the application or template to delete", required = true)
-        @PathParam("applicationId") String entityId,
+        @ApiParam(name = "type", value = "The type identifier of the application or template to delete", required = true)
+        @PathParam("type") String type,
 
         @ApiParam(name = "version", value = "The version identifier of the application or template to delete", required = true)
         @PathParam("version") String version) throws Exception;
 
     @DELETE
-    @Path("/entities/{entityId}/{version}")
+    @Path("/entities/{type}/{version}")
     @ApiOperation(value = "Deletes a specific version of an entity's definition from the catalog")
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public void deleteEntity(
-        @ApiParam(name = "entityId", value = "The ID of the entity or template to delete", required = true)
-        @PathParam("entityId") String entityId,
+        @ApiParam(name = "type", value = "The type identifier of the entity or template to delete", required = true)
+        @PathParam("type") String type,
 
         @ApiParam(name = "version", value = "The version identifier of the entity or template to delete", required = true)
         @PathParam("version") String version) throws Exception;
@@ -180,15 +180,15 @@ public interface CatalogApi {
         @PathParam("entityId") String entityId) throws Exception;
 
     @GET
-    @Path("/entities/{entityId}/{version}")
+    @Path("/entities/{type}/{version}")
     @ApiOperation(value = "Fetch a specific version of an entity's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public CatalogEntitySummary getEntity(
-        @ApiParam(name = "entityId", value = "The ID of the entity or template to retrieve", required = true)
-        @PathParam("entityId") String entityId,
-        
+        @ApiParam(name = "type", value = "The type identifier of the entity or template to retrieve", required = true)
+        @PathParam("type") String type,
+
         @ApiParam(name = "version", value = "The version identifier of the entity or template to retrieve", required = true)
         @PathParam("version") String version) throws Exception;
 
@@ -202,18 +202,18 @@ public interface CatalogApi {
     })
     public CatalogEntitySummary getApplication(
         @ApiParam(name = "applicationId", value = "The ID of the application to retrieve", required = true)
-        @PathParam("applicationId") String entityId) throws Exception;
+        @PathParam("applicationId") String applicationId) throws Exception;
 
     @GET
-    @Path("/applications/{applicationId}/{version}")
+    @Path("/applications/{type}/{version}")
     @ApiOperation(value = "Fetch a specific version of an application's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public CatalogEntitySummary getApplication(
-        @ApiParam(name = "applicationId", value = "The ID of the application to retrieve", required = true)
-        @PathParam("applicationId") String entityId,
-        
+        @ApiParam(name = "type", value = "The type identifier of the application to retrieve", required = true)
+        @PathParam("type") String type,
+
         @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
         @PathParam("version") String version) throws Exception;
 
@@ -227,7 +227,7 @@ public interface CatalogApi {
             @QueryParam("fragment") @DefaultValue("") String fragment,
             @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)")
             @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions);
-    
+
     /** @deprecated since 0.7.0 use {@link #getPolicy(String, String)} */
     @Deprecated
     @GET
@@ -239,7 +239,7 @@ public interface CatalogApi {
     public CatalogItemSummary getPolicy(
         @ApiParam(name = "policyId", value = "The ID of the policy to retrieve", required = true)
         @PathParam("policyId") String policyId) throws Exception;
-    
+
     @GET
     @Path("/policies/{policyId}/{version}")
     @ApiOperation(value = "Fetch a policy's definition from the catalog", responseClass = "CatalogItemSummary", multiValueResponse = true)
@@ -251,7 +251,7 @@ public interface CatalogApi {
         @PathParam("policyId") String policyId,
         @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
         @PathParam("version") String version) throws Exception;
-    
+
     @GET
     @Path("/locations")
     @ApiOperation(value = "List available locations optionally matching a query", responseClass = "CatalogLocationSummary", multiValueResponse = true)
@@ -262,7 +262,7 @@ public interface CatalogApi {
             @QueryParam("fragment") @DefaultValue("") String fragment,
             @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)")
             @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions);
-    
+
     /** @deprecated since 0.7.0 use {@link #getLocation(String, String)} */
     @Deprecated
     @GET
@@ -274,7 +274,7 @@ public interface CatalogApi {
     public CatalogItemSummary getLocation(
         @ApiParam(name = "locationId", value = "The ID of the location to retrieve", required = true)
         @PathParam("locationId") String locationId) throws Exception;
-    
+
     @GET
     @Path("/locations/{locationId}/{version}")
     @ApiOperation(value = "Fetch a location's definition from the catalog", responseClass = "CatalogItemSummary", multiValueResponse = true)
@@ -286,7 +286,7 @@ public interface CatalogApi {
         @PathParam("locationId") String locationId,
         @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
         @PathParam("version") String version) throws Exception;
-    
+
     /** @deprecated since 0.7.0 use {@link #getIcon(String, String)} */
     @Deprecated
     @GET


[08/16] incubator-brooklyn git commit: Test should wait for feeds to start

Posted by sj...@apache.org.
Test should wait for feeds to start

Feeds will take some time to start after creation (in this case on rebind). Update the test to handle it.


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

Branch: refs/heads/master
Commit: c6bb3b8c0ad2f0f907f8e16b0f316618d5501b3a
Parents: 30e6b44
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Jun 12 19:51:47 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 .../brooklyn/entity/rebind/RebindFeedTest.java  | 37 +++++++++++++++-----
 1 file changed, 29 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/c6bb3b8c/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
index 18c1edc..4f5acd1 100644
--- a/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/RebindFeedTest.java
@@ -50,6 +50,7 @@ import brooklyn.location.Location;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.location.basic.SshMachineLocation;
 import brooklyn.management.internal.BrooklynGarbageCollector;
+import brooklyn.test.Asserts;
 import brooklyn.test.EntityTestUtils;
 import brooklyn.test.entity.TestEntity;
 import brooklyn.test.entity.TestEntityImpl.TestEntityWithoutEnrichers;
@@ -62,6 +63,7 @@ import brooklyn.util.time.Duration;
 import brooklyn.util.time.Time;
 
 import com.google.common.base.Function;
+import com.google.common.base.Predicates;
 import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -206,8 +208,8 @@ public class RebindFeedTest extends RebindTestFixtureWithApp {
         int expectedCount = 4;
         assertEquals(currentFeeds.size(), expectedCount);
         knownFeeds.addAll(currentFeeds);
-        assertEquals(countActive(knownFeeds), expectedCount);
-        origEntity.setConfig(MyEntityWithNewFeedsEachTimeImpl.MAKE_NEW, !soakTest);
+        assertActiveFeedsEventually(knownFeeds, expectedCount);
+        origEntity.config().set(MyEntityWithNewFeedsEachTimeImpl.MAKE_NEW, !soakTest);
         
         long usedOriginally = -1;
         
@@ -225,7 +227,7 @@ public class RebindFeedTest extends RebindTestFixtureWithApp {
 
             switchOriginalToNewManagementContext();
             waitForTaskCountToBecome(origManagementContext, expectedCount + SYSTEM_TASK_COUNT);
-            assertEquals(countActive(knownFeeds), expectedCount);
+            assertActiveFeedsEventually(knownFeeds, expectedCount);
             knownFeeds.clear();
             knownFeeds.addAll(currentFeeds);
             
@@ -243,13 +245,32 @@ public class RebindFeedTest extends RebindTestFixtureWithApp {
             }
         }
     }
+
+    // Feeds take a while to start, also they do it asynchronously from the rebind. Wait for them to catch up.
+    private void assertActiveFeedsEventually(List<Feed> knownFeeds, int expectedCount) {
+        Asserts.eventually(new CountActiveSupplier(knownFeeds), Predicates.equalTo(expectedCount));
+    }
     
-    private int countActive(List<Feed> knownFeeds) {
-        int activeCount=0;
-        for (Feed f: knownFeeds) {
-            if (f.isRunning()) activeCount++;
+    private static class CountActiveSupplier implements Supplier<Integer> {
+        private List<Feed> knownFeeds;
+
+        public CountActiveSupplier(List<Feed> knownFeeds) {
+            this.knownFeeds = knownFeeds;
+        }
+
+        @Override
+        public Integer get() {
+            return countActive(knownFeeds);
         }
-        return activeCount;
+        
+        private int countActive(List<Feed> knownFeeds) {
+            int activeCount=0;
+            for (Feed f: knownFeeds) {
+                if (f.isRunning()) activeCount++;
+            }
+            return activeCount;
+        }
+        
     }
 
     public static class MyEntityWithHttpFeedImpl extends TestEntityWithoutEnrichers {


[05/16] incubator-brooklyn git commit: Limit number of threads executed in parallel

Posted by sj...@apache.org.
Limit number of threads executed in parallel

On a single-CPU machines threads will build up in the queue which leads to OutOfMemoryException (can't allocate enough memory for the stacks). Also a problem on 32 bit VMs.


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

Branch: refs/heads/master
Commit: d2d90c273d74f98ed004c54aa82907c468feb86d
Parents: ea1d6cb
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Jun 10 17:21:15 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 .../test/java/brooklyn/entity/basic/AttributeMapTest.java   | 9 +++++----
 .../util/task/BasicTaskExecutionPerformanceTest.java        | 4 +++-
 2 files changed, 8 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d2d90c27/core/src/test/java/brooklyn/entity/basic/AttributeMapTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/basic/AttributeMapTest.java b/core/src/test/java/brooklyn/entity/basic/AttributeMapTest.java
index 3224041..bdbd25e 100644
--- a/core/src/test/java/brooklyn/entity/basic/AttributeMapTest.java
+++ b/core/src/test/java/brooklyn/entity/basic/AttributeMapTest.java
@@ -51,6 +51,7 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 public class AttributeMapTest {
+    final int NUM_TASKS = Math.min(500 * Runtime.getRuntime().availableProcessors(), 1000);
 
     Application app;
     TestEntityImpl entity;
@@ -77,7 +78,7 @@ public class AttributeMapTest {
     public void testConcurrentUpdatesDoNotCauseConcurrentModificationException() throws Exception {
         List<Future<?>> futures = Lists.newArrayList();
         
-        for (int i = 0; i < 1000; i++) {
+        for (int i = 0; i < NUM_TASKS; i++) {
             final AttributeSensor<String> nextSensor = Sensors.newStringSensor("attributeMapTest.exampleSensor"+i, "");
             Future<?> future = executor.submit(newUpdateMapRunnable(map, nextSensor, "a"));
             futures.add(future);
@@ -92,7 +93,7 @@ public class AttributeMapTest {
     public void testConcurrentUpdatesAndGetsDoNotCauseConcurrentModificationException() throws Exception {
         List<Future<?>> futures = Lists.newArrayList();
         
-        for (int i = 0; i < 1000; i++) {
+        for (int i = 0; i < NUM_TASKS; i++) {
             final AttributeSensor<String> nextSensor = Sensors.newStringSensor("attributeMapTest.exampleSensor"+i, "");
             Future<?> future = executor.submit(newUpdateMapRunnable(map, nextSensor, "a"));
             Future<?> future2 = executor.submit(newGetAttributeCallable(map, nextSensor));
@@ -171,7 +172,7 @@ public class AttributeMapTest {
         
         List<Future<?>> futures = Lists.newArrayList();
         
-        for (int i = 0; i < 1000; i++) {
+        for (int i = 0; i < NUM_TASKS; i++) {
             Future<?> future = executor.submit(newModifyAttributeCallable(map, sensor, modifier));
             futures.add(future);
         }
@@ -180,7 +181,7 @@ public class AttributeMapTest {
             future.get();
         }
 
-        assertEquals(map.getValue(sensor), Integer.valueOf(1000));
+        assertEquals(map.getValue(sensor), Integer.valueOf(NUM_TASKS));
     }
     
     @Test

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d2d90c27/core/src/test/java/brooklyn/util/task/BasicTaskExecutionPerformanceTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/util/task/BasicTaskExecutionPerformanceTest.java b/core/src/test/java/brooklyn/util/task/BasicTaskExecutionPerformanceTest.java
index 2788a4c..7fd51dd 100644
--- a/core/src/test/java/brooklyn/util/task/BasicTaskExecutionPerformanceTest.java
+++ b/core/src/test/java/brooklyn/util/task/BasicTaskExecutionPerformanceTest.java
@@ -158,7 +158,9 @@ public class BasicTaskExecutionPerformanceTest {
     // (e.g. 9s for first 1000; 26s for next 1000; 42s for next 1000).
     @Test
     public void testExecutionManagerPerformance() throws Exception {
-        final int NUM_TASKS = 1000;
+        // Was fixed at 1000 tasks, but was running out of virtual memory due to excessive thread creation
+        // on machines which were not able to execute the threads quickly.
+        final int NUM_TASKS = Math.min(500 * Runtime.getRuntime().availableProcessors(), 1000);
         final int NUM_TIMES = 10;
         final int MAX_ACCEPTABLE_TIME = 7500; // saw 5601ms on buildhive
         


[13/16] incubator-brooklyn git commit: This closes #735

Posted by sj...@apache.org.
This closes #735


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

Branch: refs/heads/master
Commit: 344ee5a09d20a2ed48bb3e9409f402073be8be39
Parents: b2d3f33 7dbfb88
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Jul 14 10:27:22 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Tue Jul 14 10:27:22 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/SoftwareProcess.java  | 17 ++++++--
 .../entity/basic/SoftwareProcessImpl.java       | 17 ++++----
 ...ftwareProcessAndChildrenIntegrationTest.java |  6 +--
 .../test/entity/TestJavaWebAppEntity.java       | 41 ++++++++++++++++++++
 .../test/entity/TestJavaWebAppEntityImpl.java   | 35 +----------------
 5 files changed, 68 insertions(+), 48 deletions(-)
----------------------------------------------------------------------



[09/16] incubator-brooklyn git commit: Convert sanity check exception to an error log - no longer fatal after classpath catalog items use YAML.

Posted by sj...@apache.org.
Convert sanity check exception to an error log - no longer fatal after classpath catalog items use YAML.

Catalog items scanned from the classpath (using reflection and annotations) now
get yaml spec rather than a java type. Can't use those when creating apps from
the legacy app spec format. Fall back to direct classpath loading instead.


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

Branch: refs/heads/master
Commit: 807e6d18b418f660ed17abf3650cbc4a007e9985
Parents: d66df91
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Mon Jul 6 17:57:45 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 .../java/brooklyn/catalog/internal/BasicBrooklynCatalog.java   | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/807e6d18/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 37af858..b0a8492 100644
--- a/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
+++ b/core/src/main/java/brooklyn/catalog/internal/BasicBrooklynCatalog.java
@@ -1294,9 +1294,13 @@ public class BasicBrooklynCatalog implements BrooklynCatalog {
                 resultI = catalog.getCatalogItem(typeName, BrooklynCatalog.DEFAULT_VERSION);
                 if (resultI != null) {
                     if (resultI.getJavaType() == null) {
-                        throw new NoSuchElementException("Unable to find catalog item for type "+typeName +
+                        //Catalog items scanned from the classpath (using reflection and annotations) now
+                        //get yaml spec rather than a java type. Can't use those when creating apps from
+                        //the legacy app spec format.
+                        log.warn("Unable to find catalog item for type "+typeName +
                                 ". There is an existing catalog item with ID " + resultI.getId() +
                                 " but it doesn't define a class type.");
+                        return null;
                     }
                 }
             }


[03/16] incubator-brooklyn git commit: Don't try to re-submit DST secondary tasks if already executed

Posted by sj...@apache.org.
Don't try to re-submit DST secondary tasks if already executed

Effectors invoked against an entity will be submitted twice - once in the entity's context and again in the TaskQueueingContext of the caller (see brooklyn.management.internal.LocalManagementContext.runAtEntity(Entity, TaskAdaptable<T>)). Usually it's not a problem because the ExecutionContext will notice it's already submitted and ignore it. But if the entity is unmanaged in the time being then the call to get the entity's ExecutionContext will fail.


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

Branch: refs/heads/master
Commit: 160b3ca0fc6fefd9ef5b6e6929c7d3594436cf09
Parents: 807e6d1
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jul 7 17:24:24 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 .../entity/group/DynamicClusterImpl.java        |  6 +-
 .../util/task/DynamicSequentialTask.java        | 10 ++-
 .../entity/effector/EffectorTaskTest.java       | 79 ++++++++++++++++++++
 3 files changed, 88 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/160b3ca0/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
index 447a4bb..0e2f164 100644
--- a/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
+++ b/core/src/main/java/brooklyn/entity/group/DynamicClusterImpl.java
@@ -874,11 +874,7 @@ public class DynamicClusterImpl extends AbstractGroupImpl implements DynamicClus
         try {
             if (member instanceof Startable) {
                 Task<?> task = member.invoke(Startable.STOP, Collections.<String,Object>emptyMap());
-                try {
-                    task.get();
-                } catch (Exception e) {
-                    throw Exceptions.propagate(e);
-                }
+                task.getUnchecked();
             }
         } finally {
             Entities.unmanage(member);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/160b3ca0/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java b/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
index 967c831..7756388 100644
--- a/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
+++ b/core/src/main/java/brooklyn/util/task/DynamicSequentialTask.java
@@ -209,12 +209,18 @@ public class DynamicSequentialTask<T> extends BasicTask<T> implements HasTaskChi
             throw new IllegalStateException(message);
         }
         synchronized (task) {
-            if (task.isSubmitted() && !task.isDone()) {
+            if (task.isSubmitted()) {
                 if (log.isTraceEnabled()) {
                     log.trace("DST "+this+" skipping submission of child "+task+" because it is already submitted");
                 }
             } else {
-                ec.submit(task);
+                try {
+                    ec.submit(task);
+                } catch (Exception e) {
+                    Exceptions.propagateIfFatal(e);
+                    // Give some context when the submit fails (happens when the target is already unmanaged)
+                    throw new IllegalStateException("Failure submitting task "+task+" in "+this+": "+e.getMessage(), e);
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/160b3ca0/core/src/test/java/brooklyn/entity/effector/EffectorTaskTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/effector/EffectorTaskTest.java b/core/src/test/java/brooklyn/entity/effector/EffectorTaskTest.java
index e9584db..bc7677c 100644
--- a/core/src/test/java/brooklyn/entity/effector/EffectorTaskTest.java
+++ b/core/src/test/java/brooklyn/entity/effector/EffectorTaskTest.java
@@ -19,6 +19,7 @@
 package brooklyn.entity.effector;
 
 import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -28,6 +29,7 @@ import brooklyn.entity.Effector;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.effector.EffectorTasks.EffectorTaskFactory;
 import brooklyn.entity.proxying.EntitySpec;
@@ -37,12 +39,14 @@ import brooklyn.management.Task;
 import brooklyn.test.entity.TestEntity;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
+import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.task.DynamicSequentialTask;
 import brooklyn.util.task.DynamicTasks;
 import brooklyn.util.task.TaskBuilder;
 import brooklyn.util.task.Tasks;
 
 import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
 public class EffectorTaskTest extends BrooklynAppUnitTestSupport {
@@ -53,6 +57,7 @@ public class EffectorTaskTest extends BrooklynAppUnitTestSupport {
             .description("doubles the given number")
             .parameter(Integer.class, "numberToDouble")
             .impl(new EffectorBody<Integer>() {
+                @Override
                 public Integer call(ConfigBag parameters) {
                     // do a sanity check
                     Assert.assertNotNull(entity());
@@ -352,4 +357,78 @@ public class EffectorTaskTest extends BrooklynAppUnitTestSupport {
         
         Assert.assertEquals(doubler.invoke(DoublingEntity.DOUBLE, MutableMap.of("numberToDouble", 3, "numberToStartWith", 3)).get(), (Integer)7);
     }
+    
+    public static final Effector<Void> DUMMY = Effectors.effector(Void.class, "dummy")
+            .impl(new EffectorBody<Void>() {
+                @Override
+                public Void call(ConfigBag parameters) {
+                    return null;
+                }
+            })
+            .build();
+    
+    public static final Effector<Void> STALL = Effectors.effector(Void.class, "stall")
+            .parameter(AtomicBoolean.class, "lock")
+            .impl(new EffectorBody<Void>() {
+                @Override
+                public Void call(ConfigBag parameters) {
+                    AtomicBoolean lock = (AtomicBoolean)parameters.getStringKey("lock");
+                    synchronized(lock) {
+                        if (!lock.get()) {
+                            try {
+                                lock.wait();
+                            } catch (InterruptedException e) {
+                                Exceptions.propagate(e);
+                            }
+                        }
+                    }
+                    return null;
+                }
+            })
+            .build();
+
+    public static final Effector<Void> CONTEXT = Effectors.effector(Void.class, "stall_caller")
+            .parameter(AtomicBoolean.class, "lock")
+            .impl(new EffectorBody<Void>() {
+                @Override
+                public Void call(ConfigBag parameters) {
+                    Entity child = Iterables.getOnlyElement(entity().getChildren());
+                    AtomicBoolean lock = new AtomicBoolean();
+                    Task<Void> dummyTask = null;
+
+                    try {
+                        // Queue a (DST secondary) task which waits until notified, so that tasks queued later will get blocked
+                        queue(Effectors.invocation(entity(), STALL, ImmutableMap.of("lock", lock)));
+    
+                        // Start a new task - submitted directly to child's ExecutionContext, as well as added as a
+                        // DST secondary of the current effector.
+                        dummyTask = child.invoke(DUMMY, ImmutableMap.<String, Object>of());
+                        dummyTask.getUnchecked();
+
+                        // Execution completed in the child's ExecutionContext, but still queued as a secondary.
+                        // Destroy the child entity so that no subsequent tasks can be executed in its context.
+                        Entities.destroy(child);
+                    } finally {
+                        // Let STALL complete
+                        synchronized(lock) {
+                            lock.set(true);
+                            lock.notifyAll();
+                        }
+                        // At this point DUMMY will be unblocked and the DST will try to execute it as a secondary.
+                        // Submission will be ignored because DUMMY already executed.
+                        // If it's not ignored then submission will fail because entity is already unmanaged.
+                    }
+                    return null;
+                }
+            })
+            .build();
+    
+
+    @Test
+    public void testNestedEffectorExecutedAsSecondaryTask() throws Exception {
+        app.createAndManageChild(EntitySpec.create(TestEntity.class));
+        Task<Void> effTask = app.invoke(CONTEXT, ImmutableMap.<String, Object>of());
+        effTask.get();
+    }
+
 }


[10/16] incubator-brooklyn git commit: SoftwareProcess exposes LifecycleEffectorTasks implementation as config

Posted by sj...@apache.org.
SoftwareProcess exposes LifecycleEffectorTasks implementation as config


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

Branch: refs/heads/master
Commit: 0576be63535d83e31d49d84fde1997b70215ff20
Parents: b2d3f33
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Jul 9 14:23:51 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Fri Jul 10 10:33:48 2015 +0100

----------------------------------------------------------------------
 .../brooklyn/entity/basic/SoftwareProcess.java  | 17 ++++++--
 .../entity/basic/SoftwareProcessImpl.java       | 17 ++++----
 .../test/entity/TestJavaWebAppEntity.java       | 41 ++++++++++++++++++++
 .../test/entity/TestJavaWebAppEntityImpl.java   | 35 +----------------
 4 files changed, 65 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0576be63/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
index 75b3573..1de84de 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -214,7 +214,16 @@ public interface SoftwareProcess extends Entity, Startable {
                     "several others. Set to null or to 0 to disable any delay.",
             Duration.TEN_SECONDS);
 
-    /** controls the behavior when starting (stop, restart) {@link Startable} children as part of the start (stop, restart) effector on this entity
+    /**
+     * Sets the object that manages the sequence of calls of the entity's driver.
+     */
+    @Beta
+    @SetFromFlag("lifecycleEffectorTasks")
+    ConfigKey<SoftwareProcessDriverLifecycleEffectorTasks> LIFECYCLE_EFFECTOR_TASKS = ConfigKeys.newConfigKey(SoftwareProcessDriverLifecycleEffectorTasks.class,
+            "softwareProcess.lifecycleTasks", "An object that handles lifecycle of an entity's associated machine.",
+            new SoftwareProcessDriverLifecycleEffectorTasks());
+
+    /** Controls the behavior when starting (stop, restart) {@link Startable} children as part of the start (stop, restart) effector on this entity
      * <p>
      * (NB: restarts are currently not propagated to children in the default {@link SoftwareProcess}
      * due to the various semantics which may be desired; this may change, but if entities have specific requirements for restart,
@@ -258,7 +267,9 @@ public interface SoftwareProcess extends Entity, Startable {
     }
 
     @SetFromFlag("childStartMode")
-    ConfigKey<ChildStartableMode> CHILDREN_STARTABLE_MODE = ConfigKeys.newConfigKey(ChildStartableMode.class, "children.startable.mode");
+    ConfigKey<ChildStartableMode> CHILDREN_STARTABLE_MODE = ConfigKeys.newConfigKey(ChildStartableMode.class,
+            "children.startable.mode", "Controls behaviour when starting Startable children as part of this entity's lifecycle.",
+            ChildStartableMode.NONE);
 
     @SuppressWarnings("rawtypes")
     AttributeSensor<MachineProvisioningLocation> PROVISIONING_LOCATION = Sensors.newSensor(
@@ -301,7 +312,7 @@ public interface SoftwareProcess extends Entity, Startable {
 
         @Beta /** @since 0.7.0 semantics of parameters to restart being explored */
         public static final ConfigKey<StopMode> STOP_PROCESS_MODE = ConfigKeys.newConfigKey(StopMode.class, "stopProcessMode",
-                "When to stop the process with regard to the entity state" +
+                "When to stop the process with regard to the entity state. " +
                 "ALWAYS will try to stop the process even if the entity is marked as stopped, " +
                 "IF_NOT_STOPPED stops the process only if the entity is not marked as stopped, " +
                 "NEVER doesn't stop the process.", StopMode.IF_NOT_STOPPED);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0576be63/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
index 3d5511f..9daed4c 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
@@ -85,9 +85,6 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
     /** @see #connectServiceUpIsRunning() */
     private volatile FunctionFeed serviceProcessIsRunning;
 
-    private static final SoftwareProcessDriverLifecycleEffectorTasks LIFECYCLE_TASKS =
-            new SoftwareProcessDriverLifecycleEffectorTasks();
-
     protected boolean connectedSensors = false;
     
     public SoftwareProcessImpl() {
@@ -129,7 +126,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
     @Override
     public void init() {
         super.init();
-        LIFECYCLE_TASKS.attachLifecycleEffectors(this);
+        getLifecycleEffectorTasks().attachLifecycleEffectors(this);
     }
     
     @Override
@@ -442,7 +439,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
 
     /** returns the ports that this entity wants to use;
      * default implementation returns {@link SoftwareProcess#REQUIRED_OPEN_LOGIN_PORTS} plus first value 
-     * for each {@link PortAttributeSensorAndConfigKey} config key {@link PortRange}
+     * for each {@link brooklyn.event.basic.PortAttributeSensorAndConfigKey} config key {@link PortRange}
      * plus any ports defined with a config keys ending in {@code .port}.
      */
     protected Collection<Integer> getRequiredOpenPorts() {
@@ -614,7 +611,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
      */
     @Deprecated
     protected final void doStart(Collection<? extends Location> locations) {
-        LIFECYCLE_TASKS.start(locations);
+        getLifecycleEffectorTasks().start(locations);
     }
     
     /**
@@ -624,7 +621,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
      */
     @Deprecated
     protected final void doStop() {
-        LIFECYCLE_TASKS.stop();
+        getLifecycleEffectorTasks().stop();
     }
     
     /**
@@ -634,7 +631,7 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
      */
     @Deprecated
     protected final void doRestart(ConfigBag parameters) {
-        LIFECYCLE_TASKS.restart(parameters);
+        getLifecycleEffectorTasks().restart(parameters);
     }
 
     @Deprecated /** @deprecated since 0.7.0 see {@link #doRestart(ConfigBag)} */
@@ -642,4 +639,8 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
         doRestart(ConfigBag.EMPTY);
     }
 
+    protected SoftwareProcessDriverLifecycleEffectorTasks getLifecycleEffectorTasks() {
+        return getConfig(LIFECYCLE_EFFECTOR_TASKS);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0576be63/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java b/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
index 8710d0b..003d81c 100644
--- a/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
+++ b/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntity.java
@@ -18,9 +18,20 @@
  */
 package brooklyn.test.entity;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.basic.ServiceStateLogic;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.basic.SoftwareProcessDriverLifecycleEffectorTasks;
 import brooklyn.entity.java.VanillaJavaApp;
 import brooklyn.entity.proxying.ImplementedBy;
 import brooklyn.entity.webapp.WebAppService;
+import brooklyn.location.Location;
 
 /**
  * Mock web application server entity for testing.
@@ -28,8 +39,38 @@ import brooklyn.entity.webapp.WebAppService;
 @ImplementedBy(TestJavaWebAppEntityImpl.class)
 public interface TestJavaWebAppEntity extends VanillaJavaApp, WebAppService {
 
+    /**
+     * Injects the test entity's customised lifecycle tasks.
+     */
+    ConfigKey<SoftwareProcessDriverLifecycleEffectorTasks> LIFECYCLE_EFFECTOR_TASKS = ConfigKeys.newConfigKeyWithDefault(
+            SoftwareProcess.LIFECYCLE_EFFECTOR_TASKS,
+            new TestJavaWebAppEntityLifecycleTasks());
+
     void spoofRequest();
     int getA();
     int getB();
     int getC();
+
+    static class TestJavaWebAppEntityLifecycleTasks extends SoftwareProcessDriverLifecycleEffectorTasks {
+        private static final Logger LOG = LoggerFactory.getLogger(TestJavaWebAppEntityLifecycleTasks.class);
+
+        @Override
+        public void start(java.util.Collection<? extends Location> locations) {
+            ServiceStateLogic.setExpectedState(entity(), Lifecycle.STARTING);
+            LOG.trace("Starting {}", this);
+            entity().setAttribute(SERVICE_PROCESS_IS_RUNNING, true);
+            entity().setAttribute(Attributes.SERVICE_UP, true);
+            ServiceStateLogic.setExpectedState(entity(), Lifecycle.RUNNING);
+        }
+
+        @Override
+        public void stop() {
+            ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPING);
+            LOG.trace("Stopping {}", this);
+            entity().setAttribute(Attributes.SERVICE_UP, false);
+            entity().setAttribute(SERVICE_PROCESS_IS_RUNNING, false);
+            ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPED);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0576be63/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntityImpl.java b/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntityImpl.java
index 579763d..be7fb8a 100644
--- a/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntityImpl.java
+++ b/software/webapp/src/test/java/brooklyn/test/entity/TestJavaWebAppEntityImpl.java
@@ -20,23 +20,13 @@ package brooklyn.test.entity;
 
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.Lifecycle;
-import brooklyn.entity.basic.ServiceStateLogic;
-import brooklyn.entity.basic.SoftwareProcessDriverLifecycleEffectorTasks;
 import brooklyn.entity.java.VanillaJavaAppImpl;
 import brooklyn.entity.webapp.WebAppServiceConstants;
-import brooklyn.location.Location;
 import brooklyn.util.flags.SetFromFlag;
 
 public class TestJavaWebAppEntityImpl extends VanillaJavaAppImpl implements TestJavaWebAppEntity {
 
-    private static final Logger LOG = LoggerFactory.getLogger(TestJavaWebAppEntity.class);
-
     @SetFromFlag public int a;
     @SetFromFlag public int b;
     @SetFromFlag public int c;
@@ -46,30 +36,6 @@ public class TestJavaWebAppEntityImpl extends VanillaJavaAppImpl implements Test
     // constructor required for use in DynamicCluster.factory
     public TestJavaWebAppEntityImpl(@SuppressWarnings("rawtypes") Map flags, Entity parent) { super(flags, parent); }
 
-    private static final SoftwareProcessDriverLifecycleEffectorTasks LIFECYCLE_TASKS =
-        new SoftwareProcessDriverLifecycleEffectorTasks() {
-        public void start(java.util.Collection<? extends Location> locations) {
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.STARTING);
-            LOG.trace("Starting {}", this);
-            entity().setAttribute(SERVICE_PROCESS_IS_RUNNING, true);
-            entity().setAttribute(Attributes.SERVICE_UP, true);
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.RUNNING);
-        }
-        public void stop() {
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPING);
-            LOG.trace("Stopping {}", this);
-            entity().setAttribute(Attributes.SERVICE_UP, false);
-            entity().setAttribute(SERVICE_PROCESS_IS_RUNNING, false);
-            ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPED);
-        }
-    };
-
-    @Override
-    public void init() {
-        super.init();
-        LIFECYCLE_TASKS.attachLifecycleEffectors(this);
-    }
-
     @Override
     public synchronized void spoofRequest() {
         Integer rc = getAttribute(WebAppServiceConstants.REQUEST_COUNT);
@@ -91,4 +57,5 @@ public class TestJavaWebAppEntityImpl extends VanillaJavaAppImpl implements Test
     public int getC() {
         return c;
     }
+
 }


[12/16] incubator-brooklyn git commit: Ports @aledsage's Troubleshooting blog post to docs

Posted by sj...@apache.org.
Ports @aledsage's Troubleshooting blog post to docs


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

Branch: refs/heads/master
Commit: 6255b203671bb0ac2ba2e107d5e72d3175f4371d
Parents: b2d3f33
Author: Martin Harris <gi...@nakomis.com>
Authored: Fri Jul 10 11:10:35 2015 +0100
Committer: Martin Harris <gi...@nakomis.com>
Committed: Fri Jul 10 11:10:35 2015 +0100

----------------------------------------------------------------------
 docs/guide/dev/index.md                         |   1 +
 .../dev/tips/troubleshooting-connectivity.md    | 143 +++++++++++++++++++
 2 files changed, 144 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6255b203/docs/guide/dev/index.md
----------------------------------------------------------------------
diff --git a/docs/guide/dev/index.md b/docs/guide/dev/index.md
index 0a7acfd..eefd719 100644
--- a/docs/guide/dev/index.md
+++ b/docs/guide/dev/index.md
@@ -14,6 +14,7 @@ children:
 - tips/
 - tips/logging.md
 - tips/debugging-remote-brooklyn.md
+- tips/troubleshooting-connectivity.md
 - rest/rest-api-doc.md
 ---
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6255b203/docs/guide/dev/tips/troubleshooting-connectivity.md
----------------------------------------------------------------------
diff --git a/docs/guide/dev/tips/troubleshooting-connectivity.md b/docs/guide/dev/tips/troubleshooting-connectivity.md
new file mode 100644
index 0000000..ac7575b
--- /dev/null
+++ b/docs/guide/dev/tips/troubleshooting-connectivity.md
@@ -0,0 +1,143 @@
+---
+layout: website-normal
+title: Troubleshooting Server Connectivity Issues in the Cloud
+toc: /guide/toc.json
+---
+
+A common problem when setting up an application in the cloud is getting the basic connectivity right - how
+do I get my service (e.g. a TCP host:port) publicly accessible over the internet?
+
+This varies a lot - e.g. Is the VM public or in a private network? Is the service only accessible through
+a load balancer? Should the service be globally reachable or only to a particular CIDR?
+
+This blog post gives some general tips for debugging connectivity issues, which are applicable to a 
+range of different service types. Choose those that are appropriate for your use-case.
+
+## VM reachable
+If the VM is supposed to be accessible directly (e.g. from the public internet, or if in a private network
+then from a jump host)...
+
+### ping
+Can you `ping` the VM from the machine you are trying to reach it from?
+
+However, ping is over ICMP. If the VM is unreachable, it could be that the firewall forbids ICMP but still
+lets TCP traffic through.
+
+### telnet to TCP port
+You can check if a given TCP port is reachable and listening using `telnet <host> <port>`, such as
+`telnet www.google.com 80`, which gives output like:
+
+```
+    Trying 31.55.163.219...
+    Connected to www.google.com.
+    Escape character is '^]'.
+```
+
+If this is very slow to respond, it can be caused by a firewall blocking access. If it is fast, it could
+be that the server is just not listening on that port.
+
+### DNS and routing
+If using a hostname rather than IP, then is it resolving to a sensible IP?
+
+Is the route to the server sensible? (e.g. one can hit problems with proxy servers in a corporate
+network, or ISPs returning a default result for unknown hosts).
+
+The following commands can be useful:
+
+* `host` is a DNS lookup utility. e.g. `host www.google.com`.
+* `dig` stands for "domain information groper". e.g. `dig www.google.com`.
+* `traceroute` prints the route that packets take to a network host. e.g. `traceroute www.google.com`.
+
+## Service is listening
+
+### Service responds
+Try connecting to the service from the VM itself. For example, `curl http://localhost:8080` for a
+web-service.
+
+On dev/test VMs, don't be afraid to install the utilities you need such as `curl`, `telnet`, `nc`,
+etc. Cloud VMs often have a very cut-down set of packages installed. For example, execute
+`sudo apt-get update; sudo apt-get install -y curl` or `sudo yum install -y curl`.
+
+### Listening on port
+Check that the service is listening on the port, and on the correct NIC(s).
+
+Execute `netstat -antp` (or on OS X `netstat -antp TCP`) to list the TCP ports in use (or use
+`-anup` for UDP). You should expect to see the something like the output below for a service.
+
+```
+Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
+tcp        0      0 :::8080                     :::*                        LISTEN      8276/java           
+```
+
+In this case a Java process with pid 8276 is listening on port 8080. The local address `:::8080`
+format means all NICs (in IPv6 address format). You may also see `0.0.0.0:8080` for IPv4 format.
+If it says 127.0.0.1:8080 then your service will most likely not be reachable externally.
+
+Use `ip addr show` (or the obsolete `ifconfig -a`) to see the network interfaces on your server.
+
+For `netstat`, run with `sudo` to see the pid for all listed ports.
+
+## Firewalls
+On Linux, check if `iptables` is preventing the remote connection. On Windows, check the Windows Firewall.
+
+If it is acceptable (e.g. it is not a server in production), try turning off the firewall temporarily,
+and testing connectivity again. Remember to re-enable it afterwards! On CentOS, this is `sudo service
+iptables stop`. On Ubuntu, use `sudo ufw disable`. On Windows, press the Windows key and type 'Windows
+Firewall with Advanced Security' to open the firewall tools, then click 'Windows Firewall Properties'
+and set the firewall state to 'Off' in the Domain, Public and Private profiles.
+
+If you cannot temporarily turn off the firewall, then look carefully at the firewall settings. For
+example, execute `sudo iptables -n --list` and `iptables -t nat -n --list`.
+
+## Cloud firewalls
+Some clouds offer a firewall service, where ports need to be explicitly listed to be reachable.
+
+For example, [security groups for EC2-classic]
+(http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-network-security.html#ec2-classic-security-groups)
+have rules for the protocols and ports to be reachable from specific CIDRs.
+
+Check these settings via the cloud provider's web-console (or API).
+
+## Quick test of a listener port
+It can be useful to start listening on a given port, and to then check if that port is reachable.
+This is useful for testing basic connectivity when your service is not yet running, or to a
+different port to compare behaviour, or to compare with another VM in the network.
+
+The `nc` netcat tool is useful for this. For example, `nc -l 0.0.0.0 8080` will listen on port
+TCP 8080 on all network interfaces. On another server, you can then run `echo hello from client
+| nc <hostname> 8080`. If all works well, this will send "hello from client" over the TCP port 8080,
+which will be written out by the `nc -l` process before exiting.
+
+Similarly for UDP, you use `-lU`.
+
+You may first have to install `nc`, e.g. with `sudo yum install -y nc` or `sudo apt-get install netcat`.
+
+### Cloud load balancers
+For some use-cases, it is good practice to use the load balancer service offered by the cloud provider
+(e.g. [ELB in AWS](http://aws.amazon.com/elasticloadbalancing/) or the [Cloudstack Load Balancer]
+(http://docs.cloudstack.apache.org/projects/cloudstack-installation/en/latest/network_setup.html#management-server-load-balancing))
+
+The VMs can all be isolated within a private network, with access only through the load balancer service.
+
+Debugging techniques here include ensuring connectivity from another jump server within the private
+network, and careful checking of the load-balancer configuration from the Cloud Provider's web-console.
+
+### DNAT
+Use of DNAT is appropriate for some use-cases, where a particular port on a particular VM is to be
+made available.
+
+Debugging connectivity issues here is similar to the steps for a cloud load balancer. Ensure
+connectivity from another jump server within the private network. Carefully check the NAT rules from
+the Cloud Provider's web-console.
+
+### Guest wifi
+It is common for guest wifi to restrict access to only specific ports (e.g. 80 and 443, restricting
+ssh over port 22 etc).
+
+Normally your best bet is then to abandon the guest wifi (e.g. to tether to a mobile phone instead).
+
+There are some unconventional workarounds such as [configuring sshd to listen on port 80 so you can
+use an ssh tunnel](http://askubuntu.com/questions/107173/is-it-possible-to-ssh-through-port-80).
+However, the firewall may well inspect traffic so sending non-http traffic over port 80 may still fail.
+
+  


[14/16] incubator-brooklyn git commit: This closes #736

Posted by sj...@apache.org.
This closes #736


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

Branch: refs/heads/master
Commit: 98558b8a3841d2b41da072a9223a24174971861e
Parents: 344ee5a 160b3ca
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Jul 14 10:28:24 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Tue Jul 14 10:28:24 2015 +0100

----------------------------------------------------------------------
 .../catalog/internal/BasicBrooklynCatalog.java  |  6 +-
 .../entity/group/DynamicClusterImpl.java        |  6 +-
 .../util/task/DynamicSequentialTask.java        | 10 ++-
 .../brooklyn/entity/basic/AttributeMapTest.java |  9 ++-
 .../entity/effector/EffectorTaskTest.java       | 79 ++++++++++++++++++++
 .../brooklyn/entity/rebind/RebindFeedTest.java  | 37 +++++++--
 ...ntoPersisterInMemorySizeIntegrationTest.java |  4 +-
 .../task/BasicTaskExecutionPerformanceTest.java |  4 +-
 .../usage/ApplicationUsageTrackingTest.java     |  9 +--
 .../src/main/java/brooklyn/util/time/Time.java  |  7 +-
 10 files changed, 140 insertions(+), 31 deletions(-)
----------------------------------------------------------------------



[11/16] incubator-brooklyn git commit: Field name typo

Posted by sj...@apache.org.
Field name typo


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

Branch: refs/heads/master
Commit: 7dbfb88c6547869a9a54fffb5ee66c2e93a1a456
Parents: 0576be6
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Thu Jul 9 14:24:02 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Fri Jul 10 10:33:51 2015 +0100

----------------------------------------------------------------------
 .../VanillaSoftwareProcessAndChildrenIntegrationTest.java      | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/7dbfb88c/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
index 37f569a..ae2ae62 100644
--- a/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/basic/VanillaSoftwareProcessAndChildrenIntegrationTest.java
@@ -56,7 +56,7 @@ public class VanillaSoftwareProcessAndChildrenIntegrationTest {
     private static final int PARENT_TASK_SLEEP_LENGTH_SECS = 10;
     private static final int CHILD_TASK_SLEEP_LENGTH_SECS = 10;
     private static final int CONCURRENT_MAX_ACCEPTABLE_DIFF_SECS = PARENT_TASK_SLEEP_LENGTH_SECS - 1;
-    private static final int SEQUENCTIAL_MIN_ACCEPTABLE_DIFF_SECS = PARENT_TASK_SLEEP_LENGTH_SECS - 1;
+    private static final int SEQUENTIAL_MIN_ACCEPTABLE_DIFF_SECS = PARENT_TASK_SLEEP_LENGTH_SECS - 1;
     private static final int EARLY_RETURN_GRACE_MS = 20;
     
     private TestApplication app;
@@ -102,7 +102,7 @@ public class VanillaSoftwareProcessAndChildrenIntegrationTest {
         long startTime = startApp();
 
         long timediff = timediff();
-        Assert.assertTrue( timediff >= SEQUENCTIAL_MIN_ACCEPTABLE_DIFF_SECS, "should have started later, not with time difference "+timediff+" ("+p1+", "+p2+")" );
+        Assert.assertTrue( timediff >= SEQUENTIAL_MIN_ACCEPTABLE_DIFF_SECS, "should have started later, not with time difference "+timediff+" ("+p1+", "+p2+")" );
         Assert.assertTrue(startTime >= 2*PARENT_TASK_SLEEP_LENGTH_SECS*1000 - EARLY_RETURN_GRACE_MS, "startTime="+Time.makeTimeStringRounded(startTime));
     }
 
@@ -127,7 +127,7 @@ public class VanillaSoftwareProcessAndChildrenIntegrationTest {
         checkChildComesUpSoon();
         
         long timediff = timediff();
-        Assert.assertTrue( Math.abs(timediff) >= SEQUENCTIAL_MIN_ACCEPTABLE_DIFF_SECS, "should have started later, not with time difference "+timediff+" ("+p1+", "+p2+")" );
+        Assert.assertTrue( Math.abs(timediff) >= SEQUENTIAL_MIN_ACCEPTABLE_DIFF_SECS, "should have started later, not with time difference "+timediff+" ("+p1+", "+p2+")" );
         Assert.assertTrue(startTime >= PARENT_TASK_SLEEP_LENGTH_SECS*1000 - EARLY_RETURN_GRACE_MS, "startTime="+Time.makeTimeStringRounded(startTime));
         
         // just to prevent warnings


[16/16] incubator-brooklyn git commit: This closes #729

Posted by sj...@apache.org.
This closes #729


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

Branch: refs/heads/master
Commit: 31b8471f72da3714ec1943964948ccd3d5469397
Parents: d0d8d81 f2f8470
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Jul 14 10:35:24 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Tue Jul 14 10:35:24 2015 +0100

----------------------------------------------------------------------
 .../main/java/brooklyn/rest/api/CatalogApi.java | 42 ++++++++++----------
 .../rest/resources/CatalogResource.java         | 30 +++++++-------
 2 files changed, 36 insertions(+), 36 deletions(-)
----------------------------------------------------------------------



[06/16] incubator-brooklyn git commit: Increase persistence write limit

Posted by sj...@apache.org.
Increase persistence write limit

Sometimes entities will get another round of writes before the test is able to check the size, going above the previous limit. Usually writes are around 15k, but when this happens they go a bit above 20k.


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

Branch: refs/heads/master
Commit: 389acacb6a4fd7374dc4b3df13c0920108472f0c
Parents: d2d90c2
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Jun 11 14:17:12 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 .../BrooklynMementoPersisterInMemorySizeIntegrationTest.java     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/389acacb/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
index ac647c6..14545b4 100644
--- a/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
+++ b/core/src/test/java/brooklyn/entity/rebind/persister/BrooklynMementoPersisterInMemorySizeIntegrationTest.java
@@ -74,8 +74,8 @@ public class BrooklynMementoPersisterInMemorySizeIntegrationTest extends Brookly
         long out1 = recorder.getBytesOut();
         int filesOut1 = recorder.getCountDataOut();
         Assert.assertTrue(out1>512, "should have written at least 0.5k, only wrote "+out1);
-        Assert.assertTrue(out1<20*1000, "should have written less than 20k, wrote "+out1);
-        Assert.assertTrue(filesOut1<20, "should have written fewer than 20 files, wrote "+out1);
+        Assert.assertTrue(out1<30*1000, "should have written less than 30k, wrote "+out1);
+        Assert.assertTrue(filesOut1<30, "should have written fewer than 30 files, wrote "+out1);
         
         ((EntityInternal)app).setAttribute(TestEntity.NAME, "hello world");
         if (forceDelay) Time.sleep(Duration.FIVE_SECONDS);


[07/16] incubator-brooklyn git commit: Locale independent time parsing

Posted by sj...@apache.org.
Locale independent time 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/d66df91e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/d66df91e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/d66df91e

Branch: refs/heads/master
Commit: d66df91e4a0276cf47b79d7b417455a70565ba97
Parents: c6bb3b8
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Jun 16 18:09:33 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 utils/common/src/main/java/brooklyn/util/time/Time.java | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d66df91e/utils/common/src/main/java/brooklyn/util/time/Time.java
----------------------------------------------------------------------
diff --git a/utils/common/src/main/java/brooklyn/util/time/Time.java b/utils/common/src/main/java/brooklyn/util/time/Time.java
index 05bf088..3379d49 100644
--- a/utils/common/src/main/java/brooklyn/util/time/Time.java
+++ b/utils/common/src/main/java/brooklyn/util/time/Time.java
@@ -26,6 +26,7 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.List;
+import java.util.Locale;
 import java.util.SimpleTimeZone;
 import java.util.TimeZone;
 import java.util.concurrent.TimeUnit;
@@ -545,7 +546,7 @@ public class Time {
         // return the error from this method
         Maybe<Calendar> returnResult = result;
 
-        result = parseCalendarFormat(input, new SimpleDateFormat(DATE_FORMAT_OF_DATE_TOSTRING));
+        result = parseCalendarFormat(input, new SimpleDateFormat(DATE_FORMAT_OF_DATE_TOSTRING, Locale.ROOT));
         if (result.isPresent()) return result;
         result = parseCalendarDefaultParse(input);
         if (result.isPresent()) return result;
@@ -750,7 +751,7 @@ public class Time {
                 month = Integer.parseInt(monthS)-1;
             } else {
                 try {
-                    month = new SimpleDateFormat("yyyy-MMM-dd").parse("2015-"+monthS+"-15").getMonth();
+                    month = new SimpleDateFormat("yyyy-MMM-dd", Locale.ROOT).parse("2015-"+monthS+"-15").getMonth();
                 } catch (ParseException e) {
                     return Maybe.absent("Unknown date format '"+input+"': invalid month '"+monthS+"'; try http://yaml.org/type/timestamp.html format e.g. 2015-06-15 16:00:00 +0000");
                 }
@@ -918,7 +919,7 @@ public class Time {
         throw new IllegalArgumentException("Date " + dateString + " cannot be parsed as UTC millis or using format " + format);
     }
     public static Maybe<Calendar> parseCalendarFormat(String dateString, String format) {
-        return parseCalendarFormat(dateString, new SimpleDateFormat(format));
+        return parseCalendarFormat(dateString, new SimpleDateFormat(format, Locale.ROOT));
     }
     public static Maybe<Calendar> parseCalendarFormat(String dateString, DateFormat format) {
         if (dateString == null) { 


[15/16] incubator-brooklyn git commit: This closes #741

Posted by sj...@apache.org.
This closes #741


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

Branch: refs/heads/master
Commit: d0d8d811bbd534a812dc3dd96f66d38e67f92152
Parents: 98558b8 6255b20
Author: Sam Corbett <sa...@cloudsoftcorp.com>
Authored: Tue Jul 14 10:33:14 2015 +0100
Committer: Sam Corbett <sa...@cloudsoftcorp.com>
Committed: Tue Jul 14 10:33:14 2015 +0100

----------------------------------------------------------------------
 docs/guide/dev/index.md                         |   1 +
 .../dev/tips/troubleshooting-connectivity.md    | 143 +++++++++++++++++++
 2 files changed, 144 insertions(+)
----------------------------------------------------------------------



[04/16] incubator-brooklyn git commit: Fix test expectations - apps now unmanage themselves on stop.

Posted by sj...@apache.org.
Fix test expectations - apps now unmanage themselves on stop.


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

Branch: refs/heads/master
Commit: 30e6b4435c813feed48ca5fcadbf49ae6db1baff
Parents: 389acac
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Jun 11 17:43:18 2015 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Jul 7 17:29:16 2015 +0300

----------------------------------------------------------------------
 .../management/usage/ApplicationUsageTrackingTest.java      | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/30e6b443/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java b/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
index 337391f..5f520be 100644
--- a/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
+++ b/software/base/src/test/java/brooklyn/management/usage/ApplicationUsageTrackingTest.java
@@ -19,6 +19,7 @@
 package brooklyn.management.usage;
 
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -190,16 +191,14 @@ public class ApplicationUsageTrackingTest {
         assertApplicationUsage(usage2, app);
         assertApplicationEvent(usage2.getEvents().get(2), Lifecycle.STOPPING, preStop, postStop);
         assertApplicationEvent(usage2.getEvents().get(3), Lifecycle.STOPPED, preStop, postStop);
+        //Apps unmanage themselves on stop
+        assertApplicationEvent(usage2.getEvents().get(4), Lifecycle.DESTROYED, preStop, postStop);
         
-        // Destroy
-        long preDestroy = System.currentTimeMillis();
-        Entities.unmanage(app);
-        long postDestroy = System.currentTimeMillis();
+        assertFalse(mgmt.getEntityManager().isManaged(app), "App should already be unmanaged");
         
         Set<ApplicationUsage> usages3 = mgmt.getUsageManager().getApplicationUsage(Predicates.alwaysTrue());
         ApplicationUsage usage3 = Iterables.getOnlyElement(usages3);
         assertApplicationUsage(usage3, app);
-        assertApplicationEvent(usage3.getEvents().get(4), Lifecycle.DESTROYED, preDestroy, postDestroy);
         
         assertEquals(usage3.getEvents().size(), 5, "usage="+usage3);
     }


[02/16] incubator-brooklyn git commit: [BROOKLYN-153] Rename REST API "type" attribute to "symbolicName" to avoid confusion. Also match the internal representation for a better understanding

Posted by sj...@apache.org.
[BROOKLYN-153] Rename REST API "type" attribute to "symbolicName" to avoid confusion. Also match the internal representation for a better understanding


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

Branch: refs/heads/master
Commit: f2f8470d59232d42787280157ab1ebab1f9cd46c
Parents: 08790a7
Author: Thomas Bouron <th...@cloudsoftcorp.com>
Authored: Thu Jul 2 13:35:16 2015 +0100
Committer: Thomas Bouron <th...@cloudsoftcorp.com>
Committed: Thu Jul 2 13:35:16 2015 +0100

----------------------------------------------------------------------
 .../main/java/brooklyn/rest/api/CatalogApi.java | 24 ++++++++--------
 .../rest/resources/CatalogResource.java         | 30 ++++++++++----------
 2 files changed, 27 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2f8470d/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java b/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
index fe6de3a..09e60a9 100644
--- a/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
+++ b/usage/rest-api/src/main/java/brooklyn/rest/api/CatalogApi.java
@@ -94,27 +94,27 @@ public interface CatalogApi {
         @PathParam("entityId") String entityId) throws Exception;
 
     @DELETE
-    @Path("/applications/{type}/{version}")
+    @Path("/applications/{symbolicName}/{version}")
     @ApiOperation(value = "Deletes a specific version of an application's definition from the catalog")
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public void deleteApplication(
-        @ApiParam(name = "type", value = "The type identifier of the application or template to delete", required = true)
-        @PathParam("type") String type,
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the application or template to delete", required = true)
+        @PathParam("symbolicName") String symbolicName,
 
         @ApiParam(name = "version", value = "The version identifier of the application or template to delete", required = true)
         @PathParam("version") String version) throws Exception;
 
     @DELETE
-    @Path("/entities/{type}/{version}")
+    @Path("/entities/{symbolicName}/{version}")
     @ApiOperation(value = "Deletes a specific version of an entity's definition from the catalog")
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public void deleteEntity(
-        @ApiParam(name = "type", value = "The type identifier of the entity or template to delete", required = true)
-        @PathParam("type") String type,
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the entity or template to delete", required = true)
+        @PathParam("symbolicName") String symbolicName,
 
         @ApiParam(name = "version", value = "The version identifier of the entity or template to delete", required = true)
         @PathParam("version") String version) throws Exception;
@@ -180,14 +180,14 @@ public interface CatalogApi {
         @PathParam("entityId") String entityId) throws Exception;
 
     @GET
-    @Path("/entities/{type}/{version}")
+    @Path("/entities/{symbolicName}/{version}")
     @ApiOperation(value = "Fetch a specific version of an entity's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public CatalogEntitySummary getEntity(
-        @ApiParam(name = "type", value = "The type identifier of the entity or template to retrieve", required = true)
-        @PathParam("type") String type,
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the entity or template to retrieve", required = true)
+        @PathParam("symbolicName") String symbolicName,
 
         @ApiParam(name = "version", value = "The version identifier of the entity or template to retrieve", required = true)
         @PathParam("version") String version) throws Exception;
@@ -205,14 +205,14 @@ public interface CatalogApi {
         @PathParam("applicationId") String applicationId) throws Exception;
 
     @GET
-    @Path("/applications/{type}/{version}")
+    @Path("/applications/{symbolicName}/{version}")
     @ApiOperation(value = "Fetch a specific version of an application's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
     @ApiErrors(value = {
         @ApiError(code = 404, reason = "Entity not found")
     })
     public CatalogEntitySummary getApplication(
-        @ApiParam(name = "type", value = "The type identifier of the application to retrieve", required = true)
-        @PathParam("type") String type,
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the application to retrieve", required = true)
+        @PathParam("symbolicName") String symbolicName,
 
         @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
         @PathParam("version") String version) throws Exception;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2f8470d/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 344e939..3bb14e7 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
@@ -160,22 +160,22 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
     }
 
     @Override
-    public void deleteApplication(String applicationId, String version) throws Exception {
-        deleteEntity(applicationId, version);
+    public void deleteApplication(String symbolicName, String version) throws Exception {
+        deleteEntity(symbolicName, version);
     }
 
     @Override
-    public void deleteEntity(String entityId, String version) throws Exception {
-        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_CATALOG_ITEM, StringAndArgument.of(entityId+(Strings.isBlank(version) ? "" : ":"+version), "delete"))) {
+    public void deleteEntity(String symbolicName, String version) throws Exception {
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_CATALOG_ITEM, StringAndArgument.of(symbolicName+(Strings.isBlank(version) ? "" : ":"+version), "delete"))) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify catalog",
                 Entitlements.getEntitlementContext().user());
         }
         
-        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(entityId, version);
+        CatalogItem<?, ?> item = mgmt().getCatalog().getCatalogItem(symbolicName, version);
         if (item == null) {
-            throw WebResourceUtils.notFound("Entity with id '%s:%s' not found", entityId, version);
+            throw WebResourceUtils.notFound("Entity with id '%s:%s' not found", symbolicName, version);
         } else if (item.getCatalogItemType() != CatalogItemType.ENTITY && item.getCatalogItemType() != CatalogItemType.TEMPLATE) {
-            throw WebResourceUtils.preconditionFailed("Item with id '%s:%s' not an entity", entityId, version);
+            throw WebResourceUtils.preconditionFailed("Item with id '%s:%s' not an entity", symbolicName, version);
         } else {
             brooklyn().getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion());
         }
@@ -248,8 +248,8 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
     }
     
     @Override
-    public CatalogEntitySummary getEntity(String entityId, String version) {
-        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, entityId+(Strings.isBlank(version)?"":":"+version))) {
+    public CatalogEntitySummary getEntity(String symbolicName, String version) {
+        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_CATALOG_ITEM, symbolicName+(Strings.isBlank(version)?"":":"+version))) {
             throw WebResourceUtils.unauthorized("User '%s' is not authorized to see catalog entry",
                 Entitlements.getEntitlementContext().user());
         }
@@ -258,10 +258,10 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
         //Or we could provide asEntity/asPolicy cast methods on the CataloItem doing a safety check internally
         @SuppressWarnings("unchecked")
         CatalogItem<? extends Entity, EntitySpec<?>> result =
-              (CatalogItem<? extends Entity, EntitySpec<?>>) brooklyn().getCatalog().getCatalogItem(entityId, version);
+              (CatalogItem<? extends Entity, EntitySpec<?>>) brooklyn().getCatalog().getCatalogItem(symbolicName, version);
 
         if (result==null) {
-            throw WebResourceUtils.notFound("Entity with id '%s:%s' not found", entityId, version);
+            throw WebResourceUtils.notFound("Entity with id '%s:%s' not found", symbolicName, version);
         }
 
         return CatalogTransformer.catalogEntitySummary(brooklyn(), result);
@@ -269,13 +269,13 @@ public class CatalogResource extends AbstractBrooklynRestResource implements Cat
 
     @Override
     @Deprecated
-    public CatalogEntitySummary getApplication(String entityId) throws Exception {
-        return getEntity(entityId);
+    public CatalogEntitySummary getApplication(String applicationId) throws Exception {
+        return getEntity(applicationId);
     }
 
     @Override
-    public CatalogEntitySummary getApplication(String applicationId, String version) {
-        return getEntity(applicationId, version);
+    public CatalogEntitySummary getApplication(String symbolicName, String version) {
+        return getEntity(symbolicName, version);
     }
 
     @Override