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 2015/03/19 15:07:19 UTC

[01/19] incubator-brooklyn git commit: Improve documentation for STOP effector parameters

Repository: incubator-brooklyn
Updated Branches:
  refs/heads/master 78072b294 -> 3d73c9324


Improve documentation for STOP effector parameters


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

Branch: refs/heads/master
Commit: e583aa371f86ce2eb72a3cfcb8f260b161437dd7
Parents: de5b8d5
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Feb 27 13:19:48 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:28 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/entity/basic/SoftwareProcess.java  | 28 ++++++++++++--------
 1 file changed, 17 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e583aa37/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 9219e69..3958e67 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -260,27 +260,33 @@ public interface SoftwareProcess extends Entity, Startable {
 
     @Beta
     public static class StopSoftwareParameters {
-        /** @since 0.7.0 semantics of parameters to restart being explored
-         *  @deprecated since 0.7.0 use  {@link #STOP_MACHINE_MODE} instead */
-        @Beta
-        @Deprecated
-        public static final ConfigKey<Boolean> STOP_MACHINE = ConfigKeys.newBooleanConfigKey("stopMachine",
-                "Whether to stop the machine provisioned for this entity:  'true', or 'false' are supported, "
-                        + "with the default being 'true'", true);
-
         //IF_NOT_STOPPED includes STARTING, STOPPING, RUNNING
         public enum StopMode { ALWAYS, IF_NOT_STOPPED, NEVER };
 
         @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", StopMode.IF_NOT_STOPPED);
+                "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);
 
         @Beta /** @since 0.7.0 semantics of parameters to restart being explored */
         public static final ConfigKey<StopMode> STOP_MACHINE_MODE = ConfigKeys.newConfigKey(StopMode.class, "stopMachineMode",
                 "When to stop the machine with regard to the entity state. " +
-                "ALWAYS will try to stop the machine even if the entity is already stopped, " +
-                "IF_NOT_STOPPED stops the machine only if the entity is not already stopped, " +
+                "ALWAYS will try to stop the machine even if the entity is marked as stopped, " +
+                "IF_NOT_STOPPED stops the machine only if the entity is not marked as stopped, " +
                 "NEVER doesn't stop the machine.", StopMode.IF_NOT_STOPPED);
+
+        /** @since 0.7.0 semantics of parameters to restart being explored
+         *  @deprecated since 0.7.0 use  {@link #STOP_MACHINE_MODE} instead */
+        @Beta
+        @Deprecated
+        public static final ConfigKey<Boolean> STOP_MACHINE = ConfigKeys.newBooleanConfigKey("stopMachine",
+                "Whether to stop the machine provisioned for this entity:  'true', or 'false' are supported, " +
+                "with the default being 'true'." +
+                " 'true' is equivalent to " + STOP_MACHINE_MODE.getName() + " = " + StopMode.IF_NOT_STOPPED.name() + "." +
+                " 'false' is equivalent to " + STOP_MACHINE_MODE.getName() + " = " + StopMode.NEVER.name() + ".", true);
+
     }
     
     // NB: the START, STOP, and RESTART effectors themselves are (re)defined by MachineLifecycleEffectorTasks


[13/19] incubator-brooklyn git commit: Test for force flag in HA resource filter

Posted by al...@apache.org.
Test for force flag in HA resource filter


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

Branch: refs/heads/master
Commit: 8d425905af5a94e5d6f802779a284645f41e3bad
Parents: 95e48b9
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Mar 6 15:42:10 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../rest/filter/HaMasterCheckFilter.java        |  2 +-
 .../test/java/brooklyn/rest/HaHotCheckTest.java | 44 ++++++++++++++++++--
 2 files changed, 42 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8d425905/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
index 5267aba..bb0663f 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
@@ -42,7 +42,7 @@ import brooklyn.management.ha.ManagementNodeState;
  */
 public class HaMasterCheckFilter implements Filter {
 
-    protected static final String SKIP_CHECK_HEADER = "Brooklyn-Allow-Non-Master-Access";
+    public static final String SKIP_CHECK_HEADER = "Brooklyn-Allow-Non-Master-Access";
     private static final Set<String> SAFE_STANDBY_METHODS = Sets.newHashSet("GET", "HEAD");
 
     protected ManagementContext mgmt;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8d425905/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
index 345e51b..8692325 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
@@ -28,6 +28,7 @@ import org.testng.annotations.Test;
 import brooklyn.management.ha.HighAvailabilityManager;
 import brooklyn.management.ha.ManagementNodeState;
 import brooklyn.rest.filter.HaHotCheckResourceFilter;
+import brooklyn.rest.filter.HaMasterCheckFilter;
 import brooklyn.rest.testing.BrooklynRestResourceTest;
 import brooklyn.rest.testing.mocks.ManagementContextMock;
 import brooklyn.rest.util.HaHotStateCheckClassResource;
@@ -35,6 +36,7 @@ import brooklyn.rest.util.HaHotStateCheckResource;
 import brooklyn.rest.util.ManagementContextProvider;
 
 import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource.Builder;
 import com.sun.jersey.api.core.ResourceConfig;
 
 public class HaHotCheckTest extends BrooklynRestResourceTest {
@@ -80,9 +82,45 @@ public class HaHotCheckTest extends BrooklynRestResourceTest {
         testResourceFetch("/ha/class/fail", 200);
     }
 
-    private void testResourceFetch(String resource, int code) {
-        ClientResponse response = client().resource(resource)
-                .accept(MediaType.APPLICATION_JSON_TYPE)
+    @Test
+    public void testHaCheckForce() {
+        HighAvailabilityManager ha = mgmtMock.getHighAvailabilityManager();
+        assertEquals(ha.getNodeState(), ManagementNodeState.MASTER);
+        testResourceForcedFetch("/ha/method/ok", 200);
+        testResourceForcedFetch("/ha/method/fail", 200);
+        testResourceForcedFetch("/ha/class/fail", 200);
+
+        mgmtMock.setState(ManagementNodeState.STANDBY);
+        assertEquals(ha.getNodeState(), ManagementNodeState.STANDBY);
+
+        testResourceForcedFetch("/ha/method/ok", 200);
+        testResourceForcedFetch("/ha/method/fail", 200);
+        testResourceForcedFetch("/ha/class/fail", 200);
+
+        //forces isRunning = false
+        mgmtMock.setState(ManagementNodeState.TERMINATED);
+        assertEquals(ha.getNodeState(), ManagementNodeState.TERMINATED);
+
+        testResourceForcedFetch("/ha/method/ok", 200);
+        testResourceForcedFetch("/ha/method/fail", 200);
+        testResourceForcedFetch("/ha/class/fail", 200);
+    }
+
+    private void testResourceFetch(String resourcePath, int code) {
+        testResourceFetch(resourcePath, false, code);
+    }
+
+    private void testResourceForcedFetch(String resourcePath, int code) {
+        testResourceFetch(resourcePath, true, code);
+    }
+
+    private void testResourceFetch(String resourcePath, boolean force, int code) {
+        Builder resource = client().resource(resourcePath)
+                .accept(MediaType.APPLICATION_JSON_TYPE);
+        if (force) {
+            resource.header(HaMasterCheckFilter.SKIP_CHECK_HEADER, "true");
+        }
+        ClientResponse response = resource
                 .get(ClientResponse.class);
         assertEquals(response.getStatus(), code);
     }


[02/19] incubator-brooklyn git commit: Shutdown BrooklynNode gracefully on restart

Posted by al...@apache.org.
Shutdown BrooklynNode gracefully on restart


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

Branch: refs/heads/master
Commit: de5b8d5afbe842857976886ee47489e0b69110ad
Parents: d3beb51
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Feb 27 12:54:21 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:28 2015 +0200

----------------------------------------------------------------------
 .../entity/brooklynnode/BrooklynNodeImpl.java     | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/de5b8d5a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 20dc032..3827971 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -40,6 +40,7 @@ import brooklyn.entity.basic.Entities;
 import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.ServiceStateLogic.ServiceNotUpLogic;
+import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 import brooklyn.entity.basic.SoftwareProcessImpl;
 import brooklyn.entity.brooklynnode.effector.BrooklynNodeUpgradeEffectorBody;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
@@ -154,17 +155,30 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     @Override
     protected void preStop() {
         super.preStop();
+        shutdownGracefully();
+    }
+
+    @Override
+    protected void preRestart() {
+        super.preRestart();
+        shutdownGracefully();
+        DynamicTasks.queue("post-shutdown", new Runnable() { public void run() {
+            //set by shutdown - clear it so the entity starts cleanly. Does the indicator bring any value at all?
+            ServiceNotUpLogic.clearNotUpIndicator(BrooklynNodeImpl.this, SHUTDOWN.getName());
+        }});
+    }
 
+    private void shutdownGracefully() {
         // Shutdown only if accessible: any of stop_* could have already been called.
         // Don't check serviceUp=true because stop() will already have set serviceUp=false && expectedState=stopping
         if (Boolean.TRUE.equals(getAttribute(BrooklynNode.WEB_CONSOLE_ACCESSIBLE))) {
             queueShutdownTask();
             queueWaitExitTask();
         } else {
-            log.info("Skipping children.isEmpty check and shutdown call, because web-console not up for {}", this);
+            log.info("Skipping graceful shutdown call, because web-console not up for {}", this);
         }
     }
-    
+
     private void queueWaitExitTask() {
         //give time to the process to die gracefully after closing the shutdown call
         DynamicTasks.queue(Tasks.builder().name("wait for graceful stop").body(new Runnable() {


[10/19] incubator-brooklyn git commit: Tests for the HA HOT state check for resource access

Posted by al...@apache.org.
Tests for the HA HOT state check for resource access


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

Branch: refs/heads/master
Commit: cc95fa72092dd5d1be622bcac4769c9934821239
Parents: f2460a6
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Mar 5 15:07:53 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/launcher/BrooklynWebServer.java    |   7 +-
 .../rest/filter/HaStateCheckResourceFilter.java |   3 -
 .../rest/util/ManagementContextProvider.java    |  33 ++++
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |   4 +
 .../brooklyn/rest/resources/HaHotCheckTest.java |  82 ++++++++
 .../mocks/HighAvailabilityManagerMock.java      | 121 ++++++++++++
 .../testing/mocks/ManagementContextMock.java    | 189 +++++++++++++++++++
 .../rest/util/HaHotStateCheckClassResource.java |  38 ++++
 .../rest/util/HaHotStateCheckResource.java      |  44 +++++
 9 files changed, 517 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
index d469152..aaac004 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
@@ -60,9 +60,11 @@ import brooklyn.rest.BrooklynRestApi;
 import brooklyn.rest.BrooklynWebConfig;
 import brooklyn.rest.filter.BrooklynPropertiesSecurityFilter;
 import brooklyn.rest.filter.HaMasterCheckFilter;
+import brooklyn.rest.filter.HaStateCheckResourceFilter;
 import brooklyn.rest.filter.LoggingFilter;
 import brooklyn.rest.filter.NoCacheFilter;
 import brooklyn.rest.filter.RequestTaggingFilter;
+import brooklyn.rest.util.ManagementContextProvider;
 import brooklyn.util.BrooklynNetworkUtils;
 import brooklyn.util.ResourceUtils;
 import brooklyn.util.collections.MutableMap;
@@ -322,7 +324,7 @@ public class BrooklynWebServer {
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, GZIPContentEncodingFilter.class.getName());
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, ImmutableList.of(GZIPContentEncodingFilter.class, NoCacheFilter.class));
         // Checks if appropriate request given HA status
-        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, brooklyn.rest.filter.HaStateCheckResourceFilter.class.getName());
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, HaStateCheckResourceFilter.class.getName());
         // configure to match empty path, or any thing which looks like a file path with /assets/ and extension html, css, js, or png
         // and treat that as static content
         config.getProperties().put(ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX, "(/?|[^?]*/assets/[^?]+\\.[A-Za-z0-9_]+)");
@@ -332,6 +334,9 @@ public class BrooklynWebServer {
         FilterHolder filterHolder = new FilterHolder(new ServletContainer(config));
 
         context.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class));
+
+        ManagementContext mgmt = (ManagementContext) context.getAttribute(BrooklynServiceAttributes.BROOKLYN_MANAGEMENT_CONTEXT);
+        config.getSingletons().add(new ManagementContextProvider(mgmt));
     }
 
     ContextHandlerCollectionHotSwappable handlers = new ContextHandlerCollectionHotSwappable();

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
index d894252..86a5b9b 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
@@ -22,13 +22,11 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
-import javax.servlet.ServletContext;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
-import brooklyn.config.BrooklynServiceAttributes;
 import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.ha.ManagementNodeState;
@@ -110,7 +108,6 @@ public class HaStateCheckResourceFilter implements ResourceFilterFactory {
 
     @Override
     public List<ResourceFilter> create(AbstractMethod am) {
-        ManagementContext mgmt = (ManagementContext)servletContext.getAttribute(BrooklynServiceAttributes.BROOKLYN_MANAGEMENT_CONTEXT);
         return Collections.<ResourceFilter>singletonList(new MethodFilter(am, mgmt));
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/main/java/brooklyn/rest/util/ManagementContextProvider.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/util/ManagementContextProvider.java b/usage/rest-server/src/main/java/brooklyn/rest/util/ManagementContextProvider.java
new file mode 100644
index 0000000..f964000
--- /dev/null
+++ b/usage/rest-server/src/main/java/brooklyn/rest/util/ManagementContextProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest.util;
+
+import javax.ws.rs.core.Context;
+
+import brooklyn.management.ManagementContext;
+
+import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
+
+public class ManagementContextProvider extends SingletonTypeInjectableProvider<Context, ManagementContext> {
+
+    public ManagementContextProvider(ManagementContext instance) {
+        super(ManagementContext.class, instance);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
index 102f7dd..db54b40 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -54,6 +54,7 @@ import brooklyn.rest.filter.NoCacheFilter;
 import brooklyn.rest.filter.RequestTaggingFilter;
 import brooklyn.rest.security.provider.AnyoneSecurityProvider;
 import brooklyn.rest.security.provider.SecurityProvider;
+import brooklyn.rest.util.ManagementContextProvider;
 import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.net.Networking;
 import brooklyn.util.text.WildcardGlobs;
@@ -339,6 +340,9 @@ public class BrooklynRestApiLauncher {
         // finally create this as a _filter_ which falls through to a web app or something (optionally)
         FilterHolder filterHolder = new FilterHolder(new ServletContainer(config));
         context.addFilter(filterHolder, "/*", EnumSet.allOf(DispatcherType.class));
+
+        ManagementContext mgmt = (ManagementContext) context.getAttribute(BrooklynServiceAttributes.BROOKLYN_MANAGEMENT_CONTEXT);
+        config.getSingletons().add(new ManagementContextProvider(mgmt));
     }
 
     private static void installBrooklynFilters(ServletContextHandler context, List<Class<? extends Filter>> filters) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java
new file mode 100644
index 0000000..b8e54ef
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest.resources;
+
+import static org.testng.Assert.assertEquals;
+
+import javax.ws.rs.core.MediaType;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.management.ha.HighAvailabilityManager;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.rest.filter.HaHotCheckResourceFilter;
+import brooklyn.rest.testing.BrooklynRestResourceTest;
+import brooklyn.rest.testing.mocks.ManagementContextMock;
+import brooklyn.rest.util.HaHotStateCheckClassResource;
+import brooklyn.rest.util.HaHotStateCheckResource;
+import brooklyn.rest.util.ManagementContextProvider;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.core.ResourceConfig;
+
+public class HaHotCheckTest extends BrooklynRestResourceTest {
+
+    private ManagementContextMock mgmtMock;
+
+    @Override
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() throws Exception {
+        mgmtMock = new ManagementContextMock();
+        super.setUp();
+    }
+
+    @Override
+    protected void addBrooklynResources() {
+        config.getSingletons().add(new ManagementContextProvider(mgmtMock));
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, HaHotCheckResourceFilter.class.getName());
+        addResource(new HaHotStateCheckResource());
+        addResource(new HaHotStateCheckClassResource());
+    }
+
+    @Test
+    public void testHaCheck() throws Exception {
+        HighAvailabilityManager ha = mgmtMock.getHighAvailabilityManager();
+        assertEquals(ha.getNodeState(), ManagementNodeState.MASTER);
+        testResourceFetch("/ha/method/ok", 200);
+        testResourceFetch("/ha/method/fail", 200);
+        testResourceFetch("/ha/class/fail", 200);
+
+        mgmtMock.setState(ManagementNodeState.STANDBY);
+        assertEquals(ha.getNodeState(), ManagementNodeState.STANDBY);
+
+        testResourceFetch("/ha/method/ok", 200);
+        testResourceFetch("/ha/method/fail", 403);
+        testResourceFetch("/ha/class/fail", 403);
+    }
+
+    private void testResourceFetch(String resource, int code) {
+        ClientResponse response = client().resource(resource)
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(ClientResponse.class);
+        assertEquals(response.getStatus(), code);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
new file mode 100644
index 0000000..abc8e00
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.rest.testing.mocks;
+
+import java.util.Map;
+
+import brooklyn.management.ha.HighAvailabilityManager;
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.management.ha.ManagementPlaneSyncRecord;
+import brooklyn.management.ha.ManagementPlaneSyncRecordPersister;
+
+public class HighAvailabilityManagerMock implements HighAvailabilityManager {
+
+    private ManagementNodeState state = ManagementNodeState.MASTER;
+
+    public void setState(ManagementNodeState state) {
+        this.state = state;
+    }
+
+    private static RuntimeException fail() {
+        throw new UnsupportedOperationException("Mocked method not implemented");
+    }
+
+    @Override
+    public ManagementNodeState getNodeState() {
+        return state;
+    }
+
+    @Override
+    public long getLastStateChange() {
+        return 0;
+    }
+
+    @Override
+    public HighAvailabilityManager setPersister(ManagementPlaneSyncRecordPersister persister) {
+        throw fail();
+    }
+
+    @Override
+    public void disabled() {
+        throw fail();
+    }
+
+    @Override
+    public boolean isRunning() {
+        throw fail();
+    }
+
+    @Override
+    public void start(HighAvailabilityMode startMode) {
+        throw fail();
+    }
+
+    @Override
+    public void stop() {
+        throw fail();
+    }
+
+    @Override
+    public void changeMode(HighAvailabilityMode mode) {
+        throw fail();
+    }
+
+    @Override
+    public void setPriority(long priority) {
+        throw fail();
+    }
+
+    @Override
+    public long getPriority() {
+        throw fail();
+    }
+
+    @Override
+    public void publishClearNonMaster() {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecord getLastManagementPlaneSyncRecord() {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecord getManagementPlaneSyncState() {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecord loadManagementPlaneSyncRecord(boolean useLocalKnowledgeForThisNode) {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecordPersister getPersister() {
+        throw fail();
+    }
+
+    @Override
+    public Map<String, Object> getMetrics() {
+        throw fail();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
new file mode 100644
index 0000000..6a29fed
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest.testing.mocks;
+
+import java.net.URI;
+import java.util.Collection;
+
+import brooklyn.basic.BrooklynObject;
+import brooklyn.catalog.BrooklynCatalog;
+import brooklyn.config.StringConfigMap;
+import brooklyn.entity.Application;
+import brooklyn.entity.Entity;
+import brooklyn.entity.drivers.EntityDriverManager;
+import brooklyn.entity.drivers.downloads.DownloadResolverManager;
+import brooklyn.entity.rebind.RebindManager;
+import brooklyn.location.LocationRegistry;
+import brooklyn.management.AccessController;
+import brooklyn.management.EntityManager;
+import brooklyn.management.ExecutionContext;
+import brooklyn.management.ExecutionManager;
+import brooklyn.management.LocationManager;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.SubscriptionContext;
+import brooklyn.management.SubscriptionManager;
+import brooklyn.management.entitlement.EntitlementManager;
+import brooklyn.management.ha.HighAvailabilityManager;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.util.guava.Maybe;
+
+public class ManagementContextMock implements ManagementContext {
+    private HighAvailabilityManagerMock haMock = new HighAvailabilityManagerMock();
+
+    public void setState(ManagementNodeState state) {
+        haMock.setState(state);
+    }
+
+    private static RuntimeException fail() {
+        throw new UnsupportedOperationException("Mocked method not implemented");
+    }
+
+    @Override
+    public HighAvailabilityManager getHighAvailabilityManager() {
+        return haMock;
+    }
+
+    @Override
+    public String getManagementPlaneId() {
+        throw fail();
+    }
+
+    @Override
+    public String getManagementNodeId() {
+        throw fail();
+    }
+
+    @Override
+    public Maybe<URI> getManagementNodeUri() {
+        throw fail();
+    }
+
+    @Override
+    public Collection<Application> getApplications() {
+        throw fail();
+    }
+
+    @Override
+    public EntityManager getEntityManager() {
+        throw fail();
+    }
+
+    @Override
+    public ExecutionManager getExecutionManager() {
+        throw fail();
+    }
+
+    @Override
+    public ExecutionContext getServerExecutionContext() {
+        throw fail();
+    }
+
+    @Override
+    public EntityDriverManager getEntityDriverManager() {
+        throw fail();
+    }
+
+    @Override
+    public DownloadResolverManager getEntityDownloadsManager() {
+        throw fail();
+    }
+
+    @Override
+    public SubscriptionManager getSubscriptionManager() {
+        throw fail();
+    }
+
+    @Override
+    public ExecutionContext getExecutionContext(Entity entity) {
+        throw fail();
+    }
+
+    @Override
+    public SubscriptionContext getSubscriptionContext(Entity entity) {
+        throw fail();
+    }
+
+    @Override
+    public RebindManager getRebindManager() {
+        throw fail();
+    }
+
+    @Override
+    public StringConfigMap getConfig() {
+        throw fail();
+    }
+
+    @Override
+    public boolean isRunning() {
+        throw fail();
+    }
+
+    @Override
+    public LocationRegistry getLocationRegistry() {
+        throw fail();
+    }
+
+    @Override
+    public BrooklynCatalog getCatalog() {
+        throw fail();
+    }
+
+    @Override
+    public LocationManager getLocationManager() {
+        throw fail();
+    }
+
+    @Override
+    public AccessController getAccessController() {
+        throw fail();
+    }
+
+    @Override
+    public void reloadBrooklynProperties() {
+        throw fail();
+
+    }
+
+    @Override
+    public void addPropertiesReloadListener(PropertiesReloadListener listener) {
+        throw fail();
+
+    }
+
+    @Override
+    public void removePropertiesReloadListener(PropertiesReloadListener listener) {
+        throw fail();
+    }
+
+    @Override
+    public EntitlementManager getEntitlementManager() {
+        throw fail();
+    }
+
+    @Override
+    public BrooklynObject lookup(String id) {
+        throw fail();
+    }
+
+    @Override
+    public <T extends BrooklynObject> T lookup(String id, Class<T> type) {
+        throw fail();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckClassResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckClassResource.java b/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckClassResource.java
new file mode 100644
index 0000000..0a288a5
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckClassResource.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.rest.util;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import brooklyn.rest.filter.HaHotStateRequired;
+
+@Path("/ha/class")
+@Produces(MediaType.APPLICATION_JSON)
+@HaHotStateRequired
+public class HaHotStateCheckClassResource {
+
+    @GET
+    @Path("fail")
+    public String fail() {
+        return "FAIL";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cc95fa72/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckResource.java b/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckResource.java
new file mode 100644
index 0000000..86a8ee3
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/util/HaHotStateCheckResource.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest.util;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+import brooklyn.rest.filter.HaHotStateRequired;
+
+@Path("/ha/method")
+@Produces(MediaType.APPLICATION_JSON)
+public class HaHotStateCheckResource {
+
+    @GET
+    @Path("ok")
+    public String ok() {
+        return "OK";
+    }
+
+    @GET
+    @Path("fail")
+    @HaHotStateRequired
+    public String fail() {
+        return "FAIL";
+    }
+}


[07/19] incubator-brooklyn git commit: Don't shutdown BrooklynNode if STOP_PROCESS_MODE says so.

Posted by al...@apache.org.
Don't shutdown BrooklynNode if STOP_PROCESS_MODE says so.


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

Branch: refs/heads/master
Commit: 92951dc3dadbeea66928a84b08e76d8ff0399ae2
Parents: e583aa3
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Feb 27 17:08:35 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../entity/brooklynnode/BrooklynNodeImpl.java        | 14 +++++++++++++-
 .../software/MachineLifecycleEffectorTasks.java      | 15 +++++++++------
 .../software/MachineLifecycleEffectorTasksTest.java  |  8 +++++++-
 3 files changed, 29 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/92951dc3/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 3827971..2ac59de 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -47,6 +47,7 @@ import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPriorityEffectorBody;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.Effectors;
+import brooklyn.entity.software.MachineLifecycleEffectorTasks;
 import brooklyn.entity.trait.Startable;
 import brooklyn.event.feed.ConfigToAttributes;
 import brooklyn.event.feed.http.HttpFeed;
@@ -155,7 +156,18 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     @Override
     protected void preStop() {
         super.preStop();
-        shutdownGracefully();
+        if (MachineLifecycleEffectorTasks.canStop(getStopProcessModeParam(), this)) {
+            shutdownGracefully();
+        }
+    }
+
+    private StopMode getStopProcessModeParam() {
+        ConfigBag parameters = BrooklynTaskTags.getCurrentEffectorParameters();
+        if (parameters != null) {
+            return parameters.get(StopSoftwareParameters.STOP_PROCESS_MODE);
+        } else {
+            return StopSoftwareParameters.STOP_PROCESS_MODE.getDefaultValue();
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/92951dc3/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index 0edd488..e64e078 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -45,8 +45,8 @@ import brooklyn.entity.basic.Lifecycle;
 import brooklyn.entity.basic.ServiceStateLogic;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters;
-import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters;
 import brooklyn.entity.basic.SoftwareProcess.RestartSoftwareParameters.RestartMachineMode;
+import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters;
 import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 import brooklyn.entity.effector.EffectorBody;
 import brooklyn.entity.effector.Effectors;
@@ -571,8 +571,6 @@ public abstract class MachineLifecycleEffectorTasks {
             }
         }
 
-        boolean isEntityStopped = entity().getAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL)==Lifecycle.STOPPED;
-
         DynamicTasks.queue("pre-stop", new Callable<String>() { public String call() {
             if (entity().getAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL)==Lifecycle.STOPPED) {
                 log.debug("Skipping stop of entity "+entity()+" when already stopped");
@@ -586,7 +584,7 @@ public abstract class MachineLifecycleEffectorTasks {
 
         Maybe<SshMachineLocation> sshMachine = Machines.findUniqueSshMachineLocation(entity().getLocations());
         Task<String> stoppingProcess = null;
-        if (canStop(stopProcessMode, isEntityStopped)) {
+        if (canStop(stopProcessMode, entity())) {
             stoppingProcess = DynamicTasks.queue("stopping (process)", new Callable<String>() { public String call() {
                 DynamicTasks.markInessential();
                 stopProcessesAtMachine();
@@ -652,9 +650,14 @@ public abstract class MachineLifecycleEffectorTasks {
         if (log.isDebugEnabled()) log.debug("Stopped software process entity "+entity());
     }
 
-    protected static boolean canStop(StopMode stopMode, boolean isTargetStopped) {
+    public static boolean canStop(StopMode stopMode, Entity entity) {
+        boolean isEntityStopped = entity.getAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL)==Lifecycle.STOPPED;
+        return canStop(stopMode, isEntityStopped);
+    }
+
+    protected static boolean canStop(StopMode stopMode, boolean isStopped) {
         return stopMode == StopMode.ALWAYS ||
-                stopMode == StopMode.IF_NOT_STOPPED && !isTargetStopped;
+                stopMode == StopMode.IF_NOT_STOPPED && !isStopped;
     }
 
     private void checkCompatibleMachineModes(Boolean isStopMachine, boolean hasStopMachineMode, StopMode stopMachineMode) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/92951dc3/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java b/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
index 223d00b..2e73ca7 100644
--- a/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
+++ b/software/base/src/test/java/brooklyn/entity/software/MachineLifecycleEffectorTasksTest.java
@@ -23,11 +23,17 @@ import static org.testng.Assert.assertEquals;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import brooklyn.entity.basic.BasicEntityImpl;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 
 public class MachineLifecycleEffectorTasksTest {
     public static boolean canStop(StopMode stopMode, boolean isEntityStopped) {
-        return MachineLifecycleEffectorTasks.canStop(stopMode, isEntityStopped);
+        BasicEntityImpl entity = new BasicEntityImpl();
+        Lifecycle state = isEntityStopped ? Lifecycle.STOPPED : Lifecycle.RUNNING;
+        entity.setAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL, state);
+        return MachineLifecycleEffectorTasks.canStop(stopMode, entity);
     }
     
     @DataProvider(name = "canStopStates")


[05/19] incubator-brooklyn git commit: Don't deny requests if HA is stopped

Posted by al...@apache.org.
Don't deny requests if HA is stopped


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

Branch: refs/heads/master
Commit: 95e48b9fcea72789db7b2441bfaca058de2bbbf8
Parents: 5a75775
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Mar 6 15:37:24 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../rest/filter/HaHotCheckResourceFilter.java   |  5 +-
 .../test/java/brooklyn/rest/HaHotCheckTest.java |  8 +++
 .../brooklyn/rest/HaMasterCheckFilterTest.java  | 61 ++++++++++----------
 .../mocks/HighAvailabilityManagerMock.java      | 10 ++--
 4 files changed, 45 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/95e48b9f/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
index 55f5467..8b1d67f 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
@@ -81,7 +81,7 @@ public class HaHotCheckResourceFilter implements ResourceFilterFactory {
         }
 
         private boolean isStateLoaded() {
-            return isHaHotStatus() && !RebindTracker.isRebinding() && !recentlySwitchedState();
+            return isHaHotStatusOrDisabled() && !RebindTracker.isRebinding() && !recentlySwitchedState();
         }
 
         // Ideally there will be a separate state to indicate that we switched state
@@ -99,7 +99,8 @@ public class HaHotCheckResourceFilter implements ResourceFilterFactory {
                     am.getResource().getAnnotation(HaHotStateRequired.class) != null);
         }
 
-        private boolean isHaHotStatus() {
+        private boolean isHaHotStatusOrDisabled() {
+            if (!mgmt.getHighAvailabilityManager().isRunning()) return true;
             ManagementNodeState state = mgmt.getHighAvailabilityManager().getNodeState();
             return HOT_STATES.contains(state);
         }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/95e48b9f/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
index 224cda6..345e51b 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
@@ -70,6 +70,14 @@ public class HaHotCheckTest extends BrooklynRestResourceTest {
         testResourceFetch("/ha/method/ok", 200);
         testResourceFetch("/ha/method/fail", 403);
         testResourceFetch("/ha/class/fail", 403);
+
+        //forces isRunning = false
+        mgmtMock.setState(ManagementNodeState.TERMINATED);
+        assertEquals(ha.getNodeState(), ManagementNodeState.TERMINATED);
+
+        testResourceFetch("/ha/method/ok", 200);
+        testResourceFetch("/ha/method/fail", 200);
+        testResourceFetch("/ha/class/fail", 200);
     }
 
     private void testResourceFetch(String resource, int code) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/95e48b9f/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
index 55452c8..671a6b2 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
@@ -19,7 +19,6 @@
 package brooklyn.rest;
 
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertTrue;
 import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
 
 import java.io.File;
@@ -27,10 +26,9 @@ import java.net.URI;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 
+import org.apache.http.HttpStatus;
 import org.apache.http.client.HttpClient;
 import org.eclipse.jetty.server.Server;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.Test;
 
@@ -55,7 +53,6 @@ import com.google.common.base.Supplier;
 import com.google.common.collect.ImmutableMap;
 
 public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture {
-    private static final Logger LOG = LoggerFactory.getLogger(HaMasterCheckFilterTest.class);
     private static final Duration TIMEOUT = Duration.THIRTY_SECONDS;
 
     private File mementoDir;
@@ -74,6 +71,13 @@ public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture
     }
 
     @Test(groups = "Integration")
+    public void testEntitiesExistOnDisabledHA() throws Exception {
+        initHaCluster(HighAvailabilityMode.DISABLED, HighAvailabilityMode.DISABLED);
+        assertReadIsMaster();
+        assertEntityExists(new ReturnCodeCheck());
+    }
+
+    @Test(groups = "Integration")
     public void testEntitiesExistOnMasterPromotion() throws Exception {
         initHaCluster(HighAvailabilityMode.AUTO, HighAvailabilityMode.AUTO);
         stopWriteNode();
@@ -129,7 +133,11 @@ public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture
                 .emptyCatalog(true)
                 .buildUnstarted();
 
-        mgmt.getHighAvailabilityManager().start(mode);
+        if (mode == HighAvailabilityMode.DISABLED) {
+            mgmt.getHighAvailabilityManager().disabled();
+        } else {
+            mgmt.getHighAvailabilityManager().start(mode);
+        }
 
         new BrooklynCampPlatformLauncherNoServer()
             .useManagementContext(mgmt)
@@ -145,7 +153,12 @@ public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture
         appId = createApp(writeMgmt);
         writeMgmt.getRebindManager().getPersister().waitForWritesCompleted(TIMEOUT);
 
-        readMgmt = createManagementContext(mementoDir, readMode);
+        if (readMode == HighAvailabilityMode.DISABLED) {
+            //no HA, one node only
+            readMgmt = writeMgmt;
+        } else {
+            readMgmt = createManagementContext(mementoDir, readMode);
+        }
 
         server = useServerForTest(BrooklynRestApiLauncher.launcher()
                 .managementContext(readMgmt)
@@ -157,12 +170,11 @@ public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture
         client = getClient(server);
     }
 
-    private void assertEntityExists(Callable<Boolean> c) {
-        assertTrue(Asserts.succeedsEventually(c), "Unexpected code returned");
+    private void assertEntityExists(Callable<Integer> c) {
+        assertEquals((int)Asserts.succeedsEventually(c), 200);
     }
 
     private void assertReadIsMaster() {
-//        Asserts.eventually(new NodeStateSupplier(readMgmt), Predicates.equalTo(ManagementNodeState.MASTER));
         assertEquals(readMgmt.getHighAvailabilityManager().getNodeState(), ManagementNodeState.MASTER);
     }
 
@@ -170,26 +182,23 @@ public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture
         writeMgmt.getHighAvailabilityManager().stop();
     }
 
-    private class ReturnCodeCheck implements Callable<Boolean> {
+    private class ReturnCodeCheck implements Callable<Integer> {
         @Override
-        public Boolean call() {
+        public Integer call() {
             int retCode = getAppResponseCode();
-            if (retCode == 200) {
-                return true;
-            } else if (retCode == 403) {
-                throw new RuntimeException("Not ready, response " + retCode);
+            if (retCode == 403) {
+                throw new RuntimeException("Not ready, retry. Response - " + retCode);
             } else {
-                LOG.error("Unexpected return code " + retCode);
-                return false;
+                return retCode;
             }
         }
     }
 
     private class ReturnCodeAndNodeState extends ReturnCodeCheck {
         @Override
-        public Boolean call() {
-            Boolean ret = super.call();
-            if (ret) {
+        public Integer call() {
+            Integer ret = super.call();
+            if (ret == HttpStatus.SC_OK) {
                 ManagementNodeState state = readMgmt.getHighAvailabilityManager().getNodeState();
                 if (state != ManagementNodeState.MASTER) {
                     throw new RuntimeException("Not master yet " + state);
@@ -206,16 +215,4 @@ public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture
         }
     }
 
-    private static class NodeStateSupplier implements Supplier<ManagementNodeState> {
-        private ManagementContext node;
-        public NodeStateSupplier(ManagementContext node) {
-            this.node = node;
-        }
-
-        @Override
-        public ManagementNodeState get() {
-            return node.getHighAvailabilityManager().getNodeState();
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/95e48b9f/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
index abc8e00..5c99183 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
@@ -39,6 +39,11 @@ public class HighAvailabilityManagerMock implements HighAvailabilityManager {
     }
 
     @Override
+    public boolean isRunning() {
+        return state != ManagementNodeState.TERMINATED;
+    }
+
+    @Override
     public ManagementNodeState getNodeState() {
         return state;
     }
@@ -59,11 +64,6 @@ public class HighAvailabilityManagerMock implements HighAvailabilityManager {
     }
 
     @Override
-    public boolean isRunning() {
-        throw fail();
-    }
-
-    @Override
     public void start(HighAvailabilityMode startMode) {
         throw fail();
     }


[14/19] incubator-brooklyn git commit: Integration tests for resource accessibility with regard to the HA state

Posted by al...@apache.org.
Integration tests for resource accessibility with regard to the HA state


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

Branch: refs/heads/master
Commit: 5a757750783b1f6f79068e8d6f6ebb7d1121ee83
Parents: 86cf35f
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Mar 6 14:02:31 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |  12 +-
 .../test/java/brooklyn/rest/HaHotCheckTest.java |  82 +++++++
 .../brooklyn/rest/HaMasterCheckFilterTest.java  | 221 +++++++++++++++++++
 .../brooklyn/rest/resources/HaHotCheckTest.java |  82 -------
 4 files changed, 312 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5a757750/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
index 5baf2d2..cb7b29d 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -104,6 +104,7 @@ public class BrooklynRestApiLauncher {
     private ManagementContext mgmt;
     private ContextHandler customContext;
     private boolean deployJsgui = true;
+    private boolean disableHighAvailability = true;
 
     protected BrooklynRestApiLauncher() {}
 
@@ -151,6 +152,11 @@ public class BrooklynRestApiLauncher {
         this.deployJsgui = false;
         return this;
     }
+    
+    public BrooklynRestApiLauncher disableHighAvailability(boolean value) {
+        this.disableHighAvailability = value;
+        return this;
+    }
 
     public Server start() {
         if (this.mgmt == null) {
@@ -198,7 +204,7 @@ public class BrooklynRestApiLauncher {
             ((LocalManagementContext) mgmt).setBaseClassPathForScanning(ClasspathHelper.forJavaClassPath());
         }
 
-        return startServer(mgmt, context, summary);
+        return startServer(mgmt, context, summary, disableHighAvailability);
     }
 
     private ContextHandler filterContextHandler(ManagementContext mgmt) {
@@ -254,7 +260,7 @@ public class BrooklynRestApiLauncher {
 
     /** starts a server, on all NICs if security is configured,
      * otherwise (no security) only on loopback interface */
-    public static Server startServer(ManagementContext mgmt, ContextHandler context, String summary) {
+    public static Server startServer(ManagementContext mgmt, ContextHandler context, String summary, boolean disableHighAvailability) {
         // TODO this repeats code in BrooklynLauncher / WebServer. should merge the two paths.
         boolean secure = mgmt != null && !BrooklynWebConfig.hasNoSecurityOptions(mgmt.getConfig());
         if (secure) {
@@ -266,7 +272,7 @@ public class BrooklynRestApiLauncher {
                 ((BrooklynProperties)mgmt.getConfig()).put(BrooklynWebConfig.SECURITY_PROVIDER_CLASSNAME, AnyoneSecurityProvider.class.getName());
             }
         }
-        if (mgmt != null)
+        if (mgmt != null && disableHighAvailability)
             mgmt.getHighAvailabilityManager().disabled();
         InetSocketAddress bindLocation = new InetSocketAddress(
                 secure ? Networking.ANY_NIC : Networking.LOOPBACK,

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5a757750/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
new file mode 100644
index 0000000..224cda6
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest;
+
+import static org.testng.Assert.assertEquals;
+
+import javax.ws.rs.core.MediaType;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.management.ha.HighAvailabilityManager;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.rest.filter.HaHotCheckResourceFilter;
+import brooklyn.rest.testing.BrooklynRestResourceTest;
+import brooklyn.rest.testing.mocks.ManagementContextMock;
+import brooklyn.rest.util.HaHotStateCheckClassResource;
+import brooklyn.rest.util.HaHotStateCheckResource;
+import brooklyn.rest.util.ManagementContextProvider;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.core.ResourceConfig;
+
+public class HaHotCheckTest extends BrooklynRestResourceTest {
+
+    private ManagementContextMock mgmtMock;
+
+    @Override
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() throws Exception {
+        mgmtMock = new ManagementContextMock();
+        super.setUp();
+    }
+
+    @Override
+    protected void addBrooklynResources() {
+        config.getSingletons().add(new ManagementContextProvider(mgmtMock));
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, HaHotCheckResourceFilter.class.getName());
+        addResource(new HaHotStateCheckResource());
+        addResource(new HaHotStateCheckClassResource());
+    }
+
+    @Test
+    public void testHaCheck() {
+        HighAvailabilityManager ha = mgmtMock.getHighAvailabilityManager();
+        assertEquals(ha.getNodeState(), ManagementNodeState.MASTER);
+        testResourceFetch("/ha/method/ok", 200);
+        testResourceFetch("/ha/method/fail", 200);
+        testResourceFetch("/ha/class/fail", 200);
+
+        mgmtMock.setState(ManagementNodeState.STANDBY);
+        assertEquals(ha.getNodeState(), ManagementNodeState.STANDBY);
+
+        testResourceFetch("/ha/method/ok", 200);
+        testResourceFetch("/ha/method/fail", 403);
+        testResourceFetch("/ha/class/fail", 403);
+    }
+
+    private void testResourceFetch(String resource, int code) {
+        ClientResponse response = client().resource(resource)
+                .accept(MediaType.APPLICATION_JSON_TYPE)
+                .get(ClientResponse.class);
+        assertEquals(response.getStatus(), code);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5a757750/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
new file mode 100644
index 0000000..55452c8
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaMasterCheckFilterTest.java
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import io.brooklyn.camp.brooklyn.BrooklynCampPlatformLauncherNoServer;
+
+import java.io.File;
+import java.net.URI;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.http.client.HttpClient;
+import org.eclipse.jetty.server.Server;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BasicApplication;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.rebind.RebindTestUtils;
+import brooklyn.management.EntityManager;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.rest.security.provider.AnyoneSecurityProvider;
+import brooklyn.test.Asserts;
+import brooklyn.util.http.HttpTool;
+import brooklyn.util.http.HttpToolResponse;
+import brooklyn.util.os.Os;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableMap;
+
+public class HaMasterCheckFilterTest extends BrooklynRestApiLauncherTestFixture {
+    private static final Logger LOG = LoggerFactory.getLogger(HaMasterCheckFilterTest.class);
+    private static final Duration TIMEOUT = Duration.THIRTY_SECONDS;
+
+    private File mementoDir;
+    private ManagementContext writeMgmt;
+    private ManagementContext readMgmt;
+    private String appId;
+    private Server server;
+    private HttpClient client;
+
+    @AfterMethod(alwaysRun=true)
+    public void tearDown() throws Exception {
+        server.stop();
+        Entities.destroyAll(writeMgmt);
+        Entities.destroyAll(readMgmt);
+        Os.deleteRecursively(mementoDir);
+    }
+
+    @Test(groups = "Integration")
+    public void testEntitiesExistOnMasterPromotion() throws Exception {
+        initHaCluster(HighAvailabilityMode.AUTO, HighAvailabilityMode.AUTO);
+        stopWriteNode();
+        assertEntityExists(new ReturnCodeCheck());
+        assertReadIsMaster();
+    }
+
+    @Test(groups = "Integration")
+    public void testEntitiesExistOnHotStandbyAndPromotion() throws Exception {
+        initHaCluster(HighAvailabilityMode.AUTO, HighAvailabilityMode.HOT_STANDBY);
+        assertEntityExists(new ReturnCodeCheck());
+        stopWriteNode();
+        assertEntityExists(new ReturnCodeAndNodeState());
+        assertReadIsMaster();
+    }
+
+    @Test(groups = "Integration")
+    public void testEntitiesExistOnHotBackup() throws Exception {
+        initHaCluster(HighAvailabilityMode.AUTO, HighAvailabilityMode.HOT_BACKUP);
+        Asserts.continually(
+                ImmutableMap.<String,Object>of(
+                        "timeout", Duration.THIRTY_SECONDS,
+                        "period", Duration.ZERO),
+                new ReturnCodeSupplier(),
+                Predicates.or(Predicates.equalTo(200), Predicates.equalTo(403)));
+    }
+
+    private HttpClient getClient(Server server) {
+        HttpClient client = HttpTool.httpClientBuilder()
+                .uri(getBaseUri(server))
+                .build();
+        return client;
+    }
+
+    private int getAppResponseCode() {
+        HttpToolResponse response = HttpTool.httpGet(
+                client, URI.create(getBaseUri(server) + "/v1/applications/" + appId),
+                ImmutableMap.<String,String>of());
+        return response.getResponseCode();
+    }
+
+    private String createApp(ManagementContext mgmt) {
+        EntityManager entityMgr = mgmt.getEntityManager();
+        Entity app = entityMgr.createEntity(EntitySpec.create(BasicApplication.class));
+        entityMgr.manage(app);
+        return app.getId();
+    }
+
+    private ManagementContext createManagementContext(File mementoDir, HighAvailabilityMode mode) {
+        ManagementContext mgmt = RebindTestUtils.managementContextBuilder(mementoDir, getClass().getClassLoader())
+                .persistPeriodMillis(1)
+                .forLive(false)
+                .emptyCatalog(true)
+                .buildUnstarted();
+
+        mgmt.getHighAvailabilityManager().start(mode);
+
+        new BrooklynCampPlatformLauncherNoServer()
+            .useManagementContext(mgmt)
+            .launch();
+
+        return mgmt;
+    }
+
+    private void initHaCluster(HighAvailabilityMode writeMode, HighAvailabilityMode readMode) throws InterruptedException, TimeoutException {
+        mementoDir = Os.newTempDir(getClass());
+
+        writeMgmt = createManagementContext(mementoDir, writeMode);
+        appId = createApp(writeMgmt);
+        writeMgmt.getRebindManager().getPersister().waitForWritesCompleted(TIMEOUT);
+
+        readMgmt = createManagementContext(mementoDir, readMode);
+
+        server = useServerForTest(BrooklynRestApiLauncher.launcher()
+                .managementContext(readMgmt)
+                .securityProvider(AnyoneSecurityProvider.class)
+                .forceUseOfDefaultCatalogWithJavaClassPath(true)
+                .withoutJsgui()
+                .disableHighAvailability(false)
+                .start());
+        client = getClient(server);
+    }
+
+    private void assertEntityExists(Callable<Boolean> c) {
+        assertTrue(Asserts.succeedsEventually(c), "Unexpected code returned");
+    }
+
+    private void assertReadIsMaster() {
+//        Asserts.eventually(new NodeStateSupplier(readMgmt), Predicates.equalTo(ManagementNodeState.MASTER));
+        assertEquals(readMgmt.getHighAvailabilityManager().getNodeState(), ManagementNodeState.MASTER);
+    }
+
+    private void stopWriteNode() {
+        writeMgmt.getHighAvailabilityManager().stop();
+    }
+
+    private class ReturnCodeCheck implements Callable<Boolean> {
+        @Override
+        public Boolean call() {
+            int retCode = getAppResponseCode();
+            if (retCode == 200) {
+                return true;
+            } else if (retCode == 403) {
+                throw new RuntimeException("Not ready, response " + retCode);
+            } else {
+                LOG.error("Unexpected return code " + retCode);
+                return false;
+            }
+        }
+    }
+
+    private class ReturnCodeAndNodeState extends ReturnCodeCheck {
+        @Override
+        public Boolean call() {
+            Boolean ret = super.call();
+            if (ret) {
+                ManagementNodeState state = readMgmt.getHighAvailabilityManager().getNodeState();
+                if (state != ManagementNodeState.MASTER) {
+                    throw new RuntimeException("Not master yet " + state);
+                }
+            }
+            return ret;
+        }
+    }
+
+    private class ReturnCodeSupplier implements Supplier<Integer> {
+        @Override
+        public Integer get() {
+            return getAppResponseCode();
+        }
+    }
+
+    private static class NodeStateSupplier implements Supplier<ManagementNodeState> {
+        private ManagementContext node;
+        public NodeStateSupplier(ManagementContext node) {
+            this.node = node;
+        }
+
+        @Override
+        public ManagementNodeState get() {
+            return node.getHighAvailabilityManager().getNodeState();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/5a757750/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java
deleted file mode 100644
index b8e54ef..0000000
--- a/usage/rest-server/src/test/java/brooklyn/rest/resources/HaHotCheckTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.resources;
-
-import static org.testng.Assert.assertEquals;
-
-import javax.ws.rs.core.MediaType;
-
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.management.ha.HighAvailabilityManager;
-import brooklyn.management.ha.ManagementNodeState;
-import brooklyn.rest.filter.HaHotCheckResourceFilter;
-import brooklyn.rest.testing.BrooklynRestResourceTest;
-import brooklyn.rest.testing.mocks.ManagementContextMock;
-import brooklyn.rest.util.HaHotStateCheckClassResource;
-import brooklyn.rest.util.HaHotStateCheckResource;
-import brooklyn.rest.util.ManagementContextProvider;
-
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.core.ResourceConfig;
-
-public class HaHotCheckTest extends BrooklynRestResourceTest {
-
-    private ManagementContextMock mgmtMock;
-
-    @Override
-    @BeforeMethod(alwaysRun = true)
-    public void setUp() throws Exception {
-        mgmtMock = new ManagementContextMock();
-        super.setUp();
-    }
-
-    @Override
-    protected void addBrooklynResources() {
-        config.getSingletons().add(new ManagementContextProvider(mgmtMock));
-        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, HaHotCheckResourceFilter.class.getName());
-        addResource(new HaHotStateCheckResource());
-        addResource(new HaHotStateCheckClassResource());
-    }
-
-    @Test
-    public void testHaCheck() throws Exception {
-        HighAvailabilityManager ha = mgmtMock.getHighAvailabilityManager();
-        assertEquals(ha.getNodeState(), ManagementNodeState.MASTER);
-        testResourceFetch("/ha/method/ok", 200);
-        testResourceFetch("/ha/method/fail", 200);
-        testResourceFetch("/ha/class/fail", 200);
-
-        mgmtMock.setState(ManagementNodeState.STANDBY);
-        assertEquals(ha.getNodeState(), ManagementNodeState.STANDBY);
-
-        testResourceFetch("/ha/method/ok", 200);
-        testResourceFetch("/ha/method/fail", 403);
-        testResourceFetch("/ha/class/fail", 403);
-    }
-
-    private void testResourceFetch(String resource, int code) {
-        ClientResponse response = client().resource(resource)
-                .accept(MediaType.APPLICATION_JSON_TYPE)
-                .get(ClientResponse.class);
-        assertEquals(response.getStatus(), code);
-    }
-
-}


[04/19] incubator-brooklyn git commit: Replace usage of STOP_MACHINE=true with STOP_MACHINE_MODE=IF_NOT_STOPPED

Posted by al...@apache.org.
Replace usage of STOP_MACHINE=true with STOP_MACHINE_MODE=IF_NOT_STOPPED


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

Branch: refs/heads/master
Commit: db5111ac66ccb0e1fcb7518e6a186be1dfa51d8c
Parents: 78072b2
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Feb 27 12:52:29 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:28 2015 +0200

----------------------------------------------------------------------
 .../src/main/java/brooklyn/entity/basic/SoftwareProcess.java | 5 ++++-
 .../java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java  | 8 ++++++--
 .../effector/BrooklynNodeUpgradeEffectorBody.java            | 5 +++--
 .../entity/software/MachineLifecycleEffectorTasks.java       | 6 ++++--
 4 files changed, 17 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/db5111ac/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 2b27a47..9219e69 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcess.java
@@ -260,7 +260,10 @@ public interface SoftwareProcess extends Entity, Startable {
 
     @Beta
     public static class StopSoftwareParameters {
-        @Beta /** @since 0.7.0 semantics of parameters to restart being explored */
+        /** @since 0.7.0 semantics of parameters to restart being explored
+         *  @deprecated since 0.7.0 use  {@link #STOP_MACHINE_MODE} instead */
+        @Beta
+        @Deprecated
         public static final ConfigKey<Boolean> STOP_MACHINE = ConfigKeys.newBooleanConfigKey("stopMachine",
                 "Whether to stop the machine provisioned for this entity:  'true', or 'false' are supported, "
                         + "with the default being 'true'", true);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/db5111ac/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 224215a..20dc032 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -192,8 +192,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     protected void postStop() {
         super.postStop();
         ConfigBag stopParameters = BrooklynTaskTags.getCurrentEffectorParameters();
-        //unmanage only if stopping the machine
-        if (stopParameters == null || stopParameters.get(StopSoftwareParameters.STOP_MACHINE)) {
+        if (isStopMachine(stopParameters)) {
             // Don't unmanage in entity's task context as it will self-cancel the task. Wait for the stop effector to complete.
             // If this is not enough (still getting Caused by: java.util.concurrent.CancellationException: null) then
             // we could search for the top most task with entity context == this and wait on it. Even stronger would be
@@ -203,6 +202,11 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
         }
     }
 
+    private boolean isStopMachine(ConfigBag stopParameters) {
+        return stopParameters == null ||
+                stopParameters.get(StopSoftwareParameters.STOP_MACHINE_MODE) != StopMode.NEVER;
+    }
+
     private void queueShutdownTask() {
         ConfigBag stopParameters = BrooklynTaskTags.getCurrentEffectorParameters();
         ConfigBag shutdownParameters;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/db5111ac/software/base/src/main/java/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
index c939378..d4575a4 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/effector/BrooklynNodeUpgradeEffectorBody.java
@@ -32,6 +32,7 @@ import brooklyn.entity.basic.EntityInternal;
 import brooklyn.entity.basic.EntityTasks;
 import brooklyn.entity.basic.SoftwareProcess;
 import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters;
+import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 import brooklyn.entity.brooklynnode.BrooklynCluster;
 import brooklyn.entity.brooklynnode.BrooklynNode;
 import brooklyn.entity.brooklynnode.BrooklynNodeDriver;
@@ -118,7 +119,7 @@ public class BrooklynNodeUpgradeEffectorBody extends EffectorBody<Void> {
         
         // Stop running instance
         DynamicTasks.queue(Tasks.builder().name("shutdown node")
-                .add(Effectors.invocation(entity(), BrooklynNode.STOP_NODE_BUT_LEAVE_APPS, ImmutableMap.of(StopSoftwareParameters.STOP_MACHINE, Boolean.FALSE)))
+                .add(Effectors.invocation(entity(), BrooklynNode.STOP_NODE_BUT_LEAVE_APPS, ImmutableMap.of(StopSoftwareParameters.STOP_MACHINE_MODE, StopMode.NEVER)))
                 .build());
 
         // backup old files
@@ -192,7 +193,7 @@ public class BrooklynNodeUpgradeEffectorBody extends EffectorBody<Void> {
 
         // 3 stop new version
         DynamicTasks.queue(Tasks.builder().name("shutdown transient node")
-            .add(Effectors.invocation(dryRunChild, BrooklynNode.STOP_NODE_BUT_LEAVE_APPS, ImmutableMap.of(StopSoftwareParameters.STOP_MACHINE, Boolean.FALSE)))
+            .add(Effectors.invocation(dryRunChild, BrooklynNode.STOP_NODE_BUT_LEAVE_APPS, ImmutableMap.of(StopSoftwareParameters.STOP_MACHINE_MODE, StopMode.NEVER)))
             .build());
 
         DynamicTasks.queue(Tasks.<Void>builder().name("remove transient node").body(

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/db5111ac/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index f1b0a67..8a1279c 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -487,10 +487,10 @@ public abstract class MachineLifecycleEffectorTasks {
         } else {
             DynamicTasks.queue("stopping (machine)", new Callable<String>() { public String call() {
                 DynamicTasks.markInessential();
-                stop(ConfigBag.newInstance().configure(StopSoftwareParameters.STOP_MACHINE, true));
+                stop(ConfigBag.newInstance().configure(StopSoftwareParameters.STOP_MACHINE_MODE, StopMode.IF_NOT_STOPPED));
                 DynamicTasks.waitForLast();
                 return "Stop of machine completed with no errors.";
-            }});            
+            }});
         }
 
         DynamicTasks.queue("starting", new Runnable() { public void run() {
@@ -541,7 +541,9 @@ public abstract class MachineLifecycleEffectorTasks {
 
         log.info("Stopping {} in {}", entity(), entity().getLocations());
 
+        @SuppressWarnings("deprecation")
         final boolean hasStopMachine = parameters.containsKey(StopSoftwareParameters.STOP_MACHINE);
+        @SuppressWarnings("deprecation")
         final Boolean isStopMachine = parameters.get(StopSoftwareParameters.STOP_MACHINE);
 
         final StopMode stopProcessMode = parameters.get(StopSoftwareParameters.STOP_PROCESS_MODE);


[09/19] incubator-brooklyn git commit: Decline requests for resources relying on rebinded state in non HOT states

Posted by al...@apache.org.
Decline requests for resources relying on rebinded state in non HOT states

No point in asking for applications when HA state is STANDBY. For example 404 response should mean that the resource doesn't exist, not that it's not loaded yet.


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

Branch: refs/heads/master
Commit: 35e6c3a513ccad9f37425627214d8157f9480b04
Parents: 8343385
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Mar 4 16:50:00 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 usage/jsgui/src/main/webapp/assets/js/router.js |  7 +-
 .../brooklyn/launcher/BrooklynWebServer.java    |  2 +
 .../rest/filter/HaHotStateRequired.java         | 28 ++++++
 .../rest/filter/HaMasterCheckFilter.java        |  2 +-
 .../rest/filter/HaStateCheckResourceFilter.java | 98 ++++++++++++++++++++
 .../rest/resources/ApplicationResource.java     |  2 +
 .../rest/resources/CatalogResource.java         |  2 +
 .../rest/resources/EffectorResource.java        |  2 +
 .../rest/resources/EntityConfigResource.java    |  2 +
 .../brooklyn/rest/resources/EntityResource.java |  2 +
 .../rest/resources/LocationResource.java        |  2 +
 .../rest/resources/PolicyConfigResource.java    |  2 +
 .../brooklyn/rest/resources/PolicyResource.java |  2 +
 .../brooklyn/rest/resources/SensorResource.java |  2 +
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |  2 +
 15 files changed, 154 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/jsgui/src/main/webapp/assets/js/router.js
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/main/webapp/assets/js/router.js b/usage/jsgui/src/main/webapp/assets/js/router.js
index 485af82..3e38841 100644
--- a/usage/jsgui/src/main/webapp/assets/js/router.js
+++ b/usage/jsgui/src/main/webapp/assets/js/router.js
@@ -89,7 +89,7 @@ define([
         homePage:function (trail) {
             var that = this;
             // render the page after we fetch the collection -- no rendering on error
-            this.applications.fetch({success:function () {
+            function render() {
                 var homeView = new HomeView({
                     collection:that.applications,
                     locations:that.locations,
@@ -97,6 +97,9 @@ define([
                 });
                 var veryFirstViewLoad = !that.currentView;
                 that.showView("#application-content", homeView);
+            }
+            this.applications.fetch({success:function () {
+                render();
                 // show add application wizard if none already exist and this is the first page load
                 if ((veryFirstViewLoad && trail=='auto' && that.applications.isEmpty()) ||
                      (trail=='add_application') ) {
@@ -106,7 +109,7 @@ define([
                         }
                     });
                 }
-            }})
+            }, error: render});
         },
         applicationsPage:function (app, trail, tab) {
             if (trail === undefined) trail = app

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
index 8c9c9e3..d469152 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
@@ -321,6 +321,8 @@ public class BrooklynWebServer {
         // Accept gzipped requests and responses, disable caching for dynamic content
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, GZIPContentEncodingFilter.class.getName());
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, ImmutableList.of(GZIPContentEncodingFilter.class, NoCacheFilter.class));
+        // Checks if appropriate request given HA status
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, brooklyn.rest.filter.HaStateCheckResourceFilter.class.getName());
         // configure to match empty path, or any thing which looks like a file path with /assets/ and extension html, css, js, or png
         // and treat that as static content
         config.getProperties().put(ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX, "(/?|[^?]*/assets/[^?]+\\.[A-Za-z0-9_]+)");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
new file mode 100644
index 0000000..271da8f
--- /dev/null
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.rest.filter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface HaHotStateRequired {}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
index 2f40377..5267aba 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaMasterCheckFilter.java
@@ -42,7 +42,7 @@ import brooklyn.management.ha.ManagementNodeState;
  */
 public class HaMasterCheckFilter implements Filter {
 
-    private static final String SKIP_CHECK_HEADER = "Brooklyn-Allow-Non-Master-Access";
+    protected static final String SKIP_CHECK_HEADER = "Brooklyn-Allow-Non-Master-Access";
     private static final Set<String> SAFE_STANDBY_METHODS = Sets.newHashSet("GET", "HEAD");
 
     protected ManagementContext mgmt;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
new file mode 100644
index 0000000..44f1d1a
--- /dev/null
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES 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.rest.filter;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import brooklyn.config.BrooklynServiceAttributes;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ha.ManagementNodeState;
+
+import com.google.common.collect.ImmutableSet;
+import com.sun.jersey.api.model.AbstractMethod;
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+import com.sun.jersey.spi.container.ResourceFilter;
+import com.sun.jersey.spi.container.ResourceFilterFactory;
+
+public class HaStateCheckResourceFilter implements ResourceFilterFactory {
+    private static final Set<ManagementNodeState> HOT_STATES = ImmutableSet.of(
+            ManagementNodeState.MASTER, ManagementNodeState.HOT_STANDBY, ManagementNodeState.HOT_BACKUP);
+
+    @Context
+    private ServletContext servletContext;
+
+    private static class MethodFilter implements ResourceFilter, ContainerRequestFilter {
+        private AbstractMethod am;
+        private ManagementContext mgmt;
+
+        public MethodFilter(AbstractMethod am, ManagementContext mgmt) {
+            this.am = am;
+            this.mgmt = mgmt;
+        }
+
+        @Override
+        public ContainerRequestFilter getRequestFilter() {
+            return this;
+        }
+
+        @Override
+        public ContainerResponseFilter getResponseFilter() {
+            return null;
+        }
+
+        @Override
+        public ContainerRequest filter(ContainerRequest request) {
+            boolean isHot = isHaHotStatus();
+            boolean isOverriden = "true".equalsIgnoreCase(request.getHeaderValue(HaMasterCheckFilter.SKIP_CHECK_HEADER));
+            if (!isHot && !isOverriden &&
+                    (am.getAnnotation(HaHotStateRequired.class) != null ||
+                    am.getResource().getAnnotation(HaHotStateRequired.class) != null)) {
+                Response response = Response.status(Response.Status.FORBIDDEN)
+                        .type(MediaType.APPLICATION_JSON)
+                        .entity("{\"error\":403,\"message\":\"Requests should be made to the master Brooklyn server\"}")
+                        .build();
+                throw new WebApplicationException(response);
+            }
+            return request;
+        }
+
+        private boolean isHaHotStatus() {
+            ManagementNodeState state = mgmt.getHighAvailabilityManager().getNodeState();
+            return HOT_STATES.contains(state);
+        }
+
+    }
+
+    @Override
+    public List<ResourceFilter> create(AbstractMethod am) {
+        ManagementContext mgmt = (ManagementContext)servletContext.getAttribute(BrooklynServiceAttributes.BROOKLYN_MANAGEMENT_CONTEXT);
+        return Collections.<ResourceFilter>singletonList(new MethodFilter(am, mgmt));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
index c9f42ae..fbee750 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/ApplicationResource.java
@@ -69,6 +69,7 @@ import brooklyn.rest.domain.ApplicationSummary;
 import brooklyn.rest.domain.EntitySpec;
 import brooklyn.rest.domain.EntitySummary;
 import brooklyn.rest.domain.TaskSummary;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.ApplicationTransformer;
 import brooklyn.rest.transform.EntityTransformer;
 import brooklyn.rest.transform.TaskTransformer;
@@ -82,6 +83,7 @@ import com.google.common.base.Throwables;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Iterables;
 
+@HaHotStateRequired
 public class ApplicationResource extends AbstractBrooklynRestResource implements ApplicationApi {
 
     private static final Logger log = LoggerFactory.getLogger(ApplicationResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/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 baf25b7..7040f13 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
@@ -51,6 +51,7 @@ import brooklyn.rest.api.CatalogApi;
 import brooklyn.rest.domain.ApiError;
 import brooklyn.rest.domain.CatalogEntitySummary;
 import brooklyn.rest.domain.CatalogItemSummary;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.CatalogTransformer;
 import brooklyn.rest.util.WebResourceUtils;
 import brooklyn.util.ResourceUtils;
@@ -70,6 +71,7 @@ import com.google.common.io.Files;
 import com.sun.jersey.core.header.FormDataContentDisposition;
 import com.wordnik.swagger.core.ApiParam;
 
+@HaHotStateRequired
 public class CatalogResource extends AbstractBrooklynRestResource implements CatalogApi {
 
     private static final Logger log = LoggerFactory.getLogger(CatalogResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
index 1ee4cf4..2cfd8f6 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EffectorResource.java
@@ -42,6 +42,7 @@ import brooklyn.management.internal.EffectorUtils;
 import brooklyn.rest.api.EffectorApi;
 import brooklyn.rest.domain.EffectorSummary;
 import brooklyn.rest.domain.SummaryComparators;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.EffectorTransformer;
 import brooklyn.rest.transform.TaskTransformer;
 import brooklyn.rest.util.WebResourceUtils;
@@ -49,6 +50,7 @@ import brooklyn.util.exceptions.Exceptions;
 import brooklyn.util.guava.Maybe;
 import brooklyn.util.time.Time;
 
+@HaHotStateRequired
 public class EffectorResource extends AbstractBrooklynRestResource implements EffectorApi {
 
     private static final Logger log = LoggerFactory.getLogger(EffectorResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
index 8af5ab7..2c3ceb6 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityConfigResource.java
@@ -36,6 +36,7 @@ import brooklyn.event.basic.BasicConfigKey;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.rest.api.EntityConfigApi;
 import brooklyn.rest.domain.EntityConfigSummary;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.EntityTransformer;
 import brooklyn.rest.util.WebResourceUtils;
 import brooklyn.util.flags.TypeCoercions;
@@ -46,6 +47,7 @@ import com.google.common.base.Predicates;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+@HaHotStateRequired
 public class EntityConfigResource extends AbstractBrooklynRestResource implements EntityConfigApi {
 
     private static final Logger LOG = LoggerFactory.getLogger(EntityConfigResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
index 239139f..5572121 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/EntityResource.java
@@ -53,6 +53,7 @@ import brooklyn.rest.api.EntityApi;
 import brooklyn.rest.domain.EntitySummary;
 import brooklyn.rest.domain.LocationSummary;
 import brooklyn.rest.domain.TaskSummary;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.EntityTransformer;
 import brooklyn.rest.transform.LocationTransformer;
 import brooklyn.rest.transform.LocationTransformer.LocationDetailLevel;
@@ -68,6 +69,7 @@ import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.io.Files;
 
+@HaHotStateRequired
 public class EntityResource extends AbstractBrooklynRestResource implements EntityApi {
 
     private static final Logger log = LoggerFactory.getLogger(EntityResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
index aa73215..8d7e3f6 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java
@@ -37,6 +37,7 @@ import brooklyn.rest.api.LocationApi;
 import brooklyn.rest.domain.LocationSpec;
 import brooklyn.rest.domain.LocationSummary;
 import brooklyn.rest.domain.SummaryComparators;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.LocationTransformer;
 import brooklyn.rest.transform.LocationTransformer.LocationDetailLevel;
 import brooklyn.rest.util.EntityLocationUtils;
@@ -50,6 +51,7 @@ import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
 
+@HaHotStateRequired
 public class LocationResource extends AbstractBrooklynRestResource implements LocationApi {
 
     private static final Logger log = LoggerFactory.getLogger(LocationResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java
index 842be53..f9493ea 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java
@@ -31,6 +31,7 @@ import brooklyn.management.entitlement.Entitlements;
 import brooklyn.policy.Policy;
 import brooklyn.rest.api.PolicyConfigApi;
 import brooklyn.rest.domain.PolicyConfigSummary;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.PolicyTransformer;
 import brooklyn.rest.util.BrooklynRestResourceUtils;
 import brooklyn.rest.util.WebResourceUtils;
@@ -39,6 +40,7 @@ import brooklyn.util.flags.TypeCoercions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+@HaHotStateRequired
 public class PolicyConfigResource extends AbstractBrooklynRestResource implements PolicyConfigApi {
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java
index 06e283d..c677bf5 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java
@@ -35,6 +35,7 @@ import brooklyn.rest.api.PolicyApi;
 import brooklyn.rest.domain.PolicySummary;
 import brooklyn.rest.domain.Status;
 import brooklyn.rest.domain.SummaryComparators;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.ApplicationTransformer;
 import brooklyn.rest.transform.PolicyTransformer;
 import brooklyn.rest.util.WebResourceUtils;
@@ -44,6 +45,7 @@ import com.google.common.base.Function;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.Maps;
 
+@HaHotStateRequired
 public class PolicyResource extends AbstractBrooklynRestResource implements PolicyApi {
 
     private static final Logger log = LoggerFactory.getLogger(PolicyResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
index 8c6f3f3..708685d 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java
@@ -36,6 +36,7 @@ import brooklyn.event.basic.BasicAttributeSensor;
 import brooklyn.management.entitlement.Entitlements;
 import brooklyn.rest.api.SensorApi;
 import brooklyn.rest.domain.SensorSummary;
+import brooklyn.rest.filter.HaHotStateRequired;
 import brooklyn.rest.transform.SensorTransformer;
 import brooklyn.rest.util.WebResourceUtils;
 import brooklyn.util.text.Strings;
@@ -44,6 +45,7 @@ import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+@HaHotStateRequired
 public class SensorResource extends AbstractBrooklynRestResource implements SensorApi {
 
     private static final Logger log = LoggerFactory.getLogger(SensorResource.class);

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/35e6c3a5/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
index 7120d49..102f7dd 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -329,6 +329,8 @@ public class BrooklynRestApiLauncher {
 
         // disable caching for dynamic content
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, NoCacheFilter.class.getName());
+        // Checks if appropriate request given HA status
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, brooklyn.rest.filter.HaStateCheckResourceFilter.class.getName());
         // configure to match empty path, or any thing which looks like a file path with /assets/ and extension html, css, js, or png
         // and treat that as static content
         config.getProperties().put(ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX, "(/?|[^?]*/assets/[^?]+\\.[A-Za-z0-9_]+)");


[12/19] incubator-brooklyn git commit: Rename filter to follow naming convention

Posted by al...@apache.org.
Rename filter to follow naming convention


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

Branch: refs/heads/master
Commit: 86cf35f1062ff8e71c843572b8a05b7035dd6586
Parents: cc95fa7
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Mar 5 15:11:07 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../brooklyn/launcher/BrooklynWebServer.java    |   4 +-
 .../rest/filter/HaHotCheckResourceFilter.java   | 114 +++++++++++++++++++
 .../rest/filter/HaStateCheckResourceFilter.java | 114 -------------------
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |   2 +-
 4 files changed, 117 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/86cf35f1/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
----------------------------------------------------------------------
diff --git a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
index aaac004..56df07a 100644
--- a/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
+++ b/usage/launcher/src/main/java/brooklyn/launcher/BrooklynWebServer.java
@@ -60,7 +60,7 @@ import brooklyn.rest.BrooklynRestApi;
 import brooklyn.rest.BrooklynWebConfig;
 import brooklyn.rest.filter.BrooklynPropertiesSecurityFilter;
 import brooklyn.rest.filter.HaMasterCheckFilter;
-import brooklyn.rest.filter.HaStateCheckResourceFilter;
+import brooklyn.rest.filter.HaHotCheckResourceFilter;
 import brooklyn.rest.filter.LoggingFilter;
 import brooklyn.rest.filter.NoCacheFilter;
 import brooklyn.rest.filter.RequestTaggingFilter;
@@ -324,7 +324,7 @@ public class BrooklynWebServer {
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, GZIPContentEncodingFilter.class.getName());
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, ImmutableList.of(GZIPContentEncodingFilter.class, NoCacheFilter.class));
         // Checks if appropriate request given HA status
-        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, HaStateCheckResourceFilter.class.getName());
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, HaHotCheckResourceFilter.class.getName());
         // configure to match empty path, or any thing which looks like a file path with /assets/ and extension html, css, js, or png
         // and treat that as static content
         config.getProperties().put(ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX, "(/?|[^?]*/assets/[^?]+\\.[A-Za-z0-9_]+)");

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/86cf35f1/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
new file mode 100644
index 0000000..55f5467
--- /dev/null
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.rest.filter;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
+import brooklyn.management.ManagementContext;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.util.time.Duration;
+
+import com.google.common.collect.ImmutableSet;
+import com.sun.jersey.api.model.AbstractMethod;
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+import com.sun.jersey.spi.container.ResourceFilter;
+import com.sun.jersey.spi.container.ResourceFilterFactory;
+
+public class HaHotCheckResourceFilter implements ResourceFilterFactory {
+    private static final Set<ManagementNodeState> HOT_STATES = ImmutableSet.of(
+            ManagementNodeState.MASTER, ManagementNodeState.HOT_STANDBY, ManagementNodeState.HOT_BACKUP);
+    private static final long STATE_CHANGE_SETTLE_OFFSET = Duration.seconds(10).toMilliseconds();
+
+    @Context
+    private ManagementContext mgmt;
+
+    private static class MethodFilter implements ResourceFilter, ContainerRequestFilter {
+
+        private AbstractMethod am;
+        private ManagementContext mgmt;
+
+        public MethodFilter(AbstractMethod am, ManagementContext mgmt) {
+            this.am = am;
+            this.mgmt = mgmt;
+        }
+
+        @Override
+        public ContainerRequestFilter getRequestFilter() {
+            return this;
+        }
+
+        @Override
+        public ContainerResponseFilter getResponseFilter() {
+            return null;
+        }
+
+        @Override
+        public ContainerRequest filter(ContainerRequest request) {
+            if (!isStateLoaded() && isUnsafe(request)) {
+                Response response = Response.status(Response.Status.FORBIDDEN)
+                        .type(MediaType.APPLICATION_JSON)
+                        .entity("{\"error\":403,\"message\":\"Requests should be made to the master Brooklyn server\"}")
+                        .build();
+                throw new WebApplicationException(response);
+            }
+            return request;
+        }
+
+        private boolean isStateLoaded() {
+            return isHaHotStatus() && !RebindTracker.isRebinding() && !recentlySwitchedState();
+        }
+
+        // Ideally there will be a separate state to indicate that we switched state
+        // but still haven't finished rebinding. There's a gap between changing the state
+        // and starting rebind so add a time offset just to be sure.
+        private boolean recentlySwitchedState() {
+            long lastStateChange = mgmt.getHighAvailabilityManager().getLastStateChange();
+            return System.currentTimeMillis() - lastStateChange < STATE_CHANGE_SETTLE_OFFSET;
+        }
+
+        private boolean isUnsafe(ContainerRequest request) {
+            boolean isOverriden = "true".equalsIgnoreCase(request.getHeaderValue(HaMasterCheckFilter.SKIP_CHECK_HEADER));
+            return !isOverriden &&
+                    (am.getAnnotation(HaHotStateRequired.class) != null ||
+                    am.getResource().getAnnotation(HaHotStateRequired.class) != null);
+        }
+
+        private boolean isHaHotStatus() {
+            ManagementNodeState state = mgmt.getHighAvailabilityManager().getNodeState();
+            return HOT_STATES.contains(state);
+        }
+
+    }
+
+    @Override
+    public List<ResourceFilter> create(AbstractMethod am) {
+        return Collections.<ResourceFilter>singletonList(new MethodFilter(am, mgmt));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/86cf35f1/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
deleted file mode 100644
index 86a5b9b..0000000
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.filter;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
-import brooklyn.management.ManagementContext;
-import brooklyn.management.ha.ManagementNodeState;
-import brooklyn.util.time.Duration;
-
-import com.google.common.collect.ImmutableSet;
-import com.sun.jersey.api.model.AbstractMethod;
-import com.sun.jersey.spi.container.ContainerRequest;
-import com.sun.jersey.spi.container.ContainerRequestFilter;
-import com.sun.jersey.spi.container.ContainerResponseFilter;
-import com.sun.jersey.spi.container.ResourceFilter;
-import com.sun.jersey.spi.container.ResourceFilterFactory;
-
-public class HaStateCheckResourceFilter implements ResourceFilterFactory {
-    private static final Set<ManagementNodeState> HOT_STATES = ImmutableSet.of(
-            ManagementNodeState.MASTER, ManagementNodeState.HOT_STANDBY, ManagementNodeState.HOT_BACKUP);
-    private static final long STATE_CHANGE_SETTLE_OFFSET = Duration.seconds(10).toMilliseconds();
-
-    @Context
-    private ManagementContext mgmt;
-
-    private static class MethodFilter implements ResourceFilter, ContainerRequestFilter {
-
-        private AbstractMethod am;
-        private ManagementContext mgmt;
-
-        public MethodFilter(AbstractMethod am, ManagementContext mgmt) {
-            this.am = am;
-            this.mgmt = mgmt;
-        }
-
-        @Override
-        public ContainerRequestFilter getRequestFilter() {
-            return this;
-        }
-
-        @Override
-        public ContainerResponseFilter getResponseFilter() {
-            return null;
-        }
-
-        @Override
-        public ContainerRequest filter(ContainerRequest request) {
-            if (!isStateLoaded() && isUnsafe(request)) {
-                Response response = Response.status(Response.Status.FORBIDDEN)
-                        .type(MediaType.APPLICATION_JSON)
-                        .entity("{\"error\":403,\"message\":\"Requests should be made to the master Brooklyn server\"}")
-                        .build();
-                throw new WebApplicationException(response);
-            }
-            return request;
-        }
-
-        private boolean isStateLoaded() {
-            return isHaHotStatus() && !RebindTracker.isRebinding() && !recentlySwitchedState();
-        }
-
-        // Ideally there will be a separate state to indicate that we switched state
-        // but still haven't finished rebinding. There's a gap between changing the state
-        // and starting rebind so add a time offset just to be sure.
-        private boolean recentlySwitchedState() {
-            long lastStateChange = mgmt.getHighAvailabilityManager().getLastStateChange();
-            return System.currentTimeMillis() - lastStateChange < STATE_CHANGE_SETTLE_OFFSET;
-        }
-
-        private boolean isUnsafe(ContainerRequest request) {
-            boolean isOverriden = "true".equalsIgnoreCase(request.getHeaderValue(HaMasterCheckFilter.SKIP_CHECK_HEADER));
-            return !isOverriden &&
-                    (am.getAnnotation(HaHotStateRequired.class) != null ||
-                    am.getResource().getAnnotation(HaHotStateRequired.class) != null);
-        }
-
-        private boolean isHaHotStatus() {
-            ManagementNodeState state = mgmt.getHighAvailabilityManager().getNodeState();
-            return HOT_STATES.contains(state);
-        }
-
-    }
-
-    @Override
-    public List<ResourceFilter> create(AbstractMethod am) {
-        return Collections.<ResourceFilter>singletonList(new MethodFilter(am, mgmt));
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/86cf35f1/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
index db54b40..5baf2d2 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -331,7 +331,7 @@ public class BrooklynRestApiLauncher {
         // disable caching for dynamic content
         config.getProperties().put(ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS, NoCacheFilter.class.getName());
         // Checks if appropriate request given HA status
-        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, brooklyn.rest.filter.HaStateCheckResourceFilter.class.getName());
+        config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, brooklyn.rest.filter.HaHotCheckResourceFilter.class.getName());
         // configure to match empty path, or any thing which looks like a file path with /assets/ and extension html, css, js, or png
         // and treat that as static content
         config.getProperties().put(ServletContainer.PROPERTY_WEB_PAGE_CONTENT_REGEX, "(/?|[^?]*/assets/[^?]+\\.[A-Za-z0-9_]+)");


[03/19] incubator-brooklyn git commit: Add {pre, post}RestartCustom hooks

Posted by al...@apache.org.
Add {pre,post}RestartCustom hooks

Can't rely on {pre,post}Stop/Start hooks being called on restart.


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

Branch: refs/heads/master
Commit: d3beb51ca7c766abf6903044d1f1ec0f4c655e94
Parents: db5111a
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Feb 27 12:54:00 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:28 2015 +0200

----------------------------------------------------------------------
 ...twareProcessDriverLifecycleEffectorTasks.java | 19 +++++++++++++++++++
 .../entity/basic/SoftwareProcessImpl.java        |  6 ++++++
 .../software/MachineLifecycleEffectorTasks.java  | 19 +++++++++++++++++++
 3 files changed, 44 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d3beb51c/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
index 158817e..df706fd 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessDriverLifecycleEffectorTasks.java
@@ -60,6 +60,10 @@ public class SoftwareProcessDriverLifecycleEffectorTasks extends MachineLifecycl
             return;
         }
         
+        DynamicTasks.queue("pre-restart", new Runnable() { public void run() {
+            preRestartCustom();
+        }});
+
         log.debug("restart of "+entity()+" appears to have driver and hostname - doing driver-level restart");
         entity().getDriver().restart();
         
@@ -67,6 +71,7 @@ public class SoftwareProcessDriverLifecycleEffectorTasks extends MachineLifecycl
         
         DynamicTasks.queue("post-restart", new Runnable() { public void run() {
             postStartCustom();
+            postRestartCustom();
             ServiceStateLogic.setExpectedState(entity(), Lifecycle.RUNNING);
         }});
     }
@@ -176,6 +181,20 @@ public class SoftwareProcessDriverLifecycleEffectorTasks extends MachineLifecycl
     }
 
     @Override
+    protected void preRestartCustom() {
+        super.preRestartCustom();
+        
+        entity().preRestart();
+    }
+
+    @Override
+    protected void postRestartCustom() {
+        super.postRestartCustom();
+        
+        entity().postRestart();
+    }
+
+    @Override
     protected String stopProcessesAtMachine() {
         String result;
         

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d3beb51c/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 4b876ea..f05d0fb 100644
--- a/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/basic/SoftwareProcessImpl.java
@@ -271,6 +271,12 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
     protected void postStop() {
     }
 
+    protected void preRestart() {
+    }
+
+    protected void postRestart() {
+    }
+
     /**
      * For disconnecting from the running app. Will be called on stop.
      */

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/d3beb51c/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index 8a1279c..0edd488 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -477,6 +477,13 @@ public abstract class MachineLifecycleEffectorTasks {
         if (isRestartMachine==RestartMachineMode.AUTO) 
             isRestartMachine = getDefaultRestartStopsMachine() ? RestartMachineMode.TRUE : RestartMachineMode.FALSE; 
 
+        DynamicTasks.queue("pre-restart", new Runnable() { public void run() {
+            //Calling preStopCustom without a corresponding postStopCustom invocation
+            //doesn't look right so use a separate callback pair; Also depending on the arguments
+            //stop() could be called which will call the {pre,post}StopCustom on its own.
+            preRestartCustom();
+        }});
+
         if (isRestartMachine==RestartMachineMode.FALSE) {
             DynamicTasks.queue("stopping (process)", new Callable<String>() { public String call() {
                 DynamicTasks.markInessential();
@@ -502,6 +509,10 @@ public abstract class MachineLifecycleEffectorTasks {
         
         restartChildren(parameters);
 
+        DynamicTasks.queue("post-restart", new Runnable() { public void run() {
+            postRestartCustom();
+        }});
+
         DynamicTasks.waitForLast();
         ServiceStateLogic.setExpectedState(entity(), Lifecycle.RUNNING);
     }
@@ -673,6 +684,14 @@ public abstract class MachineLifecycleEffectorTasks {
         // nothing needed here
     }
 
+    protected void preRestartCustom() {
+        // nothing needed here
+    }
+
+    protected void postRestartCustom() {
+        // nothing needed here
+    }
+
     public static class StopMachineDetails<T> implements Serializable {
         private static final long serialVersionUID = 3256747214315895431L;
         final String message;


[11/19] incubator-brooklyn git commit: Wait for the HA state to stabilize before letting requests in

Posted by al...@apache.org.
Wait for the HA state to stabilize before letting requests in

There is a period of time when the state is MASTER, but the context is not fully initialized.


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

Branch: refs/heads/master
Commit: f2460a6971f3328ebfb4410399ed9b1546f4d062
Parents: 3b99a96
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Thu Mar 5 15:06:20 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../management/ha/HighAvailabilityManager.java       |  5 ++++-
 .../management/ha/HighAvailabilityManagerImpl.java   |  9 +++++++++
 .../internal/NonDeploymentManagementContext.java     |  4 ++++
 .../rest/filter/HaStateCheckResourceFilter.java      | 15 +++++++++++++--
 4 files changed, 30 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2460a69/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java b/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
index 04079bb..2a1af9a 100644
--- a/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
+++ b/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
@@ -44,6 +44,9 @@ public interface HighAvailabilityManager {
 
     ManagementNodeState getNodeState();
     
+    /** The time in milliseconds when the state was last changed */
+    long getLastStateChange();
+    
     /**
      * @param persister
      * @return self
@@ -128,5 +131,5 @@ public interface HighAvailabilityManager {
 
     /** Returns a collection of metrics */
     Map<String,Object> getMetrics();
-    
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2460a69/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java b/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
index bc5c398..b2af52a 100644
--- a/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
+++ b/core/src/main/java/brooklyn/management/ha/HighAvailabilityManagerImpl.java
@@ -1077,4 +1077,13 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
         return result;
     }
     
+    @Override
+    public long getLastStateChange() {
+        if (nodeStateHistory.size() > 0) {
+            return (Long)nodeStateHistory.get(0).get("timestamp");
+        } else {
+            return 0;
+        }
+    }
+    
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2460a69/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java b/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
index ea4ec2b..0972871 100644
--- a/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
+++ b/core/src/main/java/brooklyn/management/internal/NonDeploymentManagementContext.java
@@ -603,5 +603,9 @@ public class NonDeploymentManagementContext implements ManagementContextInternal
         public void publishClearNonMaster() {
             throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
         }
+        @Override
+        public long getLastStateChange() {
+            throw new IllegalStateException("Non-deployment context "+NonDeploymentManagementContext.this+" is not valid for this operation.");
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/f2460a69/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
index 9da0766..d894252 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
@@ -32,6 +32,7 @@ import brooklyn.config.BrooklynServiceAttributes;
 import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.util.time.Duration;
 
 import com.google.common.collect.ImmutableSet;
 import com.sun.jersey.api.model.AbstractMethod;
@@ -44,11 +45,13 @@ import com.sun.jersey.spi.container.ResourceFilterFactory;
 public class HaStateCheckResourceFilter implements ResourceFilterFactory {
     private static final Set<ManagementNodeState> HOT_STATES = ImmutableSet.of(
             ManagementNodeState.MASTER, ManagementNodeState.HOT_STANDBY, ManagementNodeState.HOT_BACKUP);
+    private static final long STATE_CHANGE_SETTLE_OFFSET = Duration.seconds(10).toMilliseconds();
 
     @Context
-    private ServletContext servletContext;
+    private ManagementContext mgmt;
 
     private static class MethodFilter implements ResourceFilter, ContainerRequestFilter {
+
         private AbstractMethod am;
         private ManagementContext mgmt;
 
@@ -80,7 +83,15 @@ public class HaStateCheckResourceFilter implements ResourceFilterFactory {
         }
 
         private boolean isStateLoaded() {
-            return isHaHotStatus() && !RebindTracker.isRebinding();
+            return isHaHotStatus() && !RebindTracker.isRebinding() && !recentlySwitchedState();
+        }
+
+        // Ideally there will be a separate state to indicate that we switched state
+        // but still haven't finished rebinding. There's a gap between changing the state
+        // and starting rebind so add a time offset just to be sure.
+        private boolean recentlySwitchedState() {
+            long lastStateChange = mgmt.getHighAvailabilityManager().getLastStateChange();
+            return System.currentTimeMillis() - lastStateChange < STATE_CHANGE_SETTLE_OFFSET;
         }
 
         private boolean isUnsafe(ContainerRequest request) {


[06/19] incubator-brooklyn git commit: Umanage BrooklynNode only if machine is released.

Posted by al...@apache.org.
Umanage BrooklynNode only if machine is released.

Previous logic of looking at the effector paramaters wasn't working in all cases as IF_NOT_STOPPED depends on external factors. Instead check if the SshMachineLocation is still around.


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

Branch: refs/heads/master
Commit: 8343385f257d21021896db52fbbfe35c5f0e7243
Parents: 92951dc
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Feb 27 17:08:46 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../entity/brooklynnode/BrooklynNodeImpl.java         | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8343385f/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 2ac59de..952d32b 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -25,6 +25,7 @@ import java.util.concurrent.Callable;
 
 import javax.annotation.Nullable;
 
+import brooklyn.location.basic.Locations;
 import org.apache.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -217,8 +218,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     @Override
     protected void postStop() {
         super.postStop();
-        ConfigBag stopParameters = BrooklynTaskTags.getCurrentEffectorParameters();
-        if (isStopMachine(stopParameters)) {
+        if (isStopMachine()) {
             // Don't unmanage in entity's task context as it will self-cancel the task. Wait for the stop effector to complete.
             // If this is not enough (still getting Caused by: java.util.concurrent.CancellationException: null) then
             // we could search for the top most task with entity context == this and wait on it. Even stronger would be
@@ -228,9 +228,13 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
         }
     }
 
-    private boolean isStopMachine(ConfigBag stopParameters) {
-        return stopParameters == null ||
-                stopParameters.get(StopSoftwareParameters.STOP_MACHINE_MODE) != StopMode.NEVER;
+    private boolean isStopMachine() {
+        // Don't rely on effector parameters, check if there is still a machine running.
+        // If the entity was previously stopped with STOP_MACHINE_MODE=StopMode.NEVER
+        // and a second time with STOP_MACHINE_MODE=StopMode.IF_NOT_STOPPED, then the
+        // machine is still running, but there is no deterministic way to infer this from
+        // the parameters alone.
+        return Locations.findUniqueSshMachineLocation(this.getLocations()).isAbsent();
     }
 
     private void queueShutdownTask() {


[08/19] incubator-brooklyn git commit: Deny resource requests during rebind

Posted by al...@apache.org.
Deny resource requests during rebind


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

Branch: refs/heads/master
Commit: 3b99a96fd3f7fce9ba8b4f396c7bc696ecac6e9d
Parents: 35e6c3a
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Mar 4 17:05:56 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:01:29 2015 +0200

----------------------------------------------------------------------
 .../rest/filter/HaStateCheckResourceFilter.java   | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/3b99a96f/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
index 44f1d1a..9da0766 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaStateCheckResourceFilter.java
@@ -29,6 +29,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
 import brooklyn.config.BrooklynServiceAttributes;
+import brooklyn.entity.rebind.RebindManagerImpl.RebindTracker;
 import brooklyn.management.ManagementContext;
 import brooklyn.management.ha.ManagementNodeState;
 
@@ -68,11 +69,7 @@ public class HaStateCheckResourceFilter implements ResourceFilterFactory {
 
         @Override
         public ContainerRequest filter(ContainerRequest request) {
-            boolean isHot = isHaHotStatus();
-            boolean isOverriden = "true".equalsIgnoreCase(request.getHeaderValue(HaMasterCheckFilter.SKIP_CHECK_HEADER));
-            if (!isHot && !isOverriden &&
-                    (am.getAnnotation(HaHotStateRequired.class) != null ||
-                    am.getResource().getAnnotation(HaHotStateRequired.class) != null)) {
+            if (!isStateLoaded() && isUnsafe(request)) {
                 Response response = Response.status(Response.Status.FORBIDDEN)
                         .type(MediaType.APPLICATION_JSON)
                         .entity("{\"error\":403,\"message\":\"Requests should be made to the master Brooklyn server\"}")
@@ -82,6 +79,17 @@ public class HaStateCheckResourceFilter implements ResourceFilterFactory {
             return request;
         }
 
+        private boolean isStateLoaded() {
+            return isHaHotStatus() && !RebindTracker.isRebinding();
+        }
+
+        private boolean isUnsafe(ContainerRequest request) {
+            boolean isOverriden = "true".equalsIgnoreCase(request.getHeaderValue(HaMasterCheckFilter.SKIP_CHECK_HEADER));
+            return !isOverriden &&
+                    (am.getAnnotation(HaHotStateRequired.class) != null ||
+                    am.getResource().getAnnotation(HaHotStateRequired.class) != null);
+        }
+
         private boolean isHaHotStatus() {
             ManagementNodeState state = mgmt.getHighAvailabilityManager().getNodeState();
             return HOT_STATES.contains(state);


[15/19] incubator-brooklyn git commit: Adds test for BrooklynNode restart

Posted by al...@apache.org.
Adds test for BrooklynNode restart


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

Branch: refs/heads/master
Commit: 9bafb46df9f1f1ac7e8104ae7ab2e90d2b552f19
Parents: 363989b
Author: Aled Sage <al...@gmail.com>
Authored: Tue Mar 10 13:46:54 2015 +0000
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:03:08 2015 +0200

----------------------------------------------------------------------
 .../BrooklynNodeIntegrationTest.java            | 55 +++++++++++++++-----
 1 file changed, 43 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/9bafb46d/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
index 065996d..717eb68 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/BrooklynNodeIntegrationTest.java
@@ -41,26 +41,25 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import brooklyn.config.BrooklynProperties;
+import brooklyn.entity.BrooklynAppUnitTestSupport;
 import brooklyn.entity.Effector;
 import brooklyn.entity.Entity;
 import brooklyn.entity.basic.BasicApplication;
 import brooklyn.entity.basic.BasicApplicationImpl;
 import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.SoftwareProcess.StopSoftwareParameters.StopMode;
 import brooklyn.entity.brooklynnode.BrooklynNode.DeployBlueprintEffector;
 import brooklyn.entity.brooklynnode.BrooklynNode.ExistingFileBehaviour;
 import brooklyn.entity.brooklynnode.BrooklynNode.StopNodeAndKillAppsEffector;
 import brooklyn.entity.proxying.EntityProxyImpl;
 import brooklyn.entity.proxying.EntitySpec;
 import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.location.LocationSpec;
 import brooklyn.location.basic.LocalhostMachineProvisioningLocation;
 import brooklyn.location.basic.Locations;
 import brooklyn.location.basic.PortRanges;
 import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.management.ManagementContext;
 import brooklyn.test.EntityTestUtils;
 import brooklyn.test.HttpTestUtils;
-import brooklyn.test.entity.TestApplication;
 import brooklyn.util.collections.MutableMap;
 import brooklyn.util.config.ConfigBag;
 import brooklyn.util.exceptions.Exceptions;
@@ -102,36 +101,40 @@ import com.google.common.io.Files;
  * rm -rf /tmp/brooklyn-`whoami`/installs/BrooklynNode*
  * </code>
  */
-public class BrooklynNodeIntegrationTest {
+public class BrooklynNodeIntegrationTest extends BrooklynAppUnitTestSupport {
 
     private static final Logger log = LoggerFactory.getLogger(BrooklynNodeIntegrationTest.class);
     
     private File pseudoBrooklynPropertiesFile;
     private File pseudoBrooklynCatalogFile;
+    private File persistenceDir;
     private LocalhostMachineProvisioningLocation loc;
     private List<LocalhostMachineProvisioningLocation> locs;
-    private TestApplication app;
-    private ManagementContext mgmt;
 
     @BeforeMethod(alwaysRun=true)
+    @Override
     public void setUp() throws Exception {
+        super.setUp();
         pseudoBrooklynPropertiesFile = Os.newTempFile("brooklynnode-test", ".properties");
         pseudoBrooklynPropertiesFile.delete();
 
         pseudoBrooklynCatalogFile = Os.newTempFile("brooklynnode-test", ".catalog");
         pseudoBrooklynCatalogFile.delete();
 
-        app = TestApplication.Factory.newManagedInstanceForTests();
-        mgmt = app.getManagementContext();
-        loc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+        loc = app.newLocalhostProvisioningLocation();
         locs = ImmutableList.of(loc);
     }
 
     @AfterMethod(alwaysRun=true)
+    @Override
     public void tearDown() throws Exception {
-        if (mgmt != null) Entities.destroyAll(mgmt);
-        if (pseudoBrooklynPropertiesFile != null) pseudoBrooklynPropertiesFile.delete();
-        if (pseudoBrooklynCatalogFile != null) pseudoBrooklynCatalogFile.delete();
+        try {
+            super.tearDown();
+        } finally {
+            if (pseudoBrooklynPropertiesFile != null) pseudoBrooklynPropertiesFile.delete();
+            if (pseudoBrooklynCatalogFile != null) pseudoBrooklynCatalogFile.delete();
+            if (persistenceDir != null) Os.deleteRecursively(persistenceDir);
+        }
     }
 
     protected EntitySpec<BrooklynNode> newBrooklynNodeSpecForTest() {
@@ -471,6 +474,34 @@ services:
     public void testStopButLeaveAppsEffector() throws Exception {
         createNodeAndExecStopEffector(BrooklynNode.STOP_NODE_BUT_LEAVE_APPS);
     }
+    
+    @Test(groups="Integration")
+    public void testStopAndRestartProcess() throws Exception {
+        persistenceDir = Files.createTempDir();
+        BrooklynNode brooklynNode = app.createAndManageChild(newBrooklynNodeSpecForTest()
+                .configure(BrooklynNode.EXTRA_LAUNCH_PARAMETERS, "--persist auto --persistenceDir "+persistenceDir.getAbsolutePath())
+                .configure(BrooklynNode.APP, BasicApplicationImpl.class.getName()));
+        app.start(locs);
+        log.info("started "+app+" containing "+brooklynNode+" for "+JavaClassNames.niceClassAndMethod());
+        File pidFile = new File(getDriver(brooklynNode).getPidFile());
+        URI webConsoleUri = brooklynNode.getAttribute(BrooklynNode.WEB_CONSOLE_URI);
+
+        // Stop just the process; will not have unmanaged entity unless machine was being terminated 
+        brooklynNode.invoke(BrooklynNode.STOP, ImmutableMap.<String, Object>of(
+                BrooklynNode.StopSoftwareParameters.STOP_MACHINE_MODE.getName(), StopMode.NEVER,
+                BrooklynNode.StopSoftwareParameters.STOP_PROCESS_MODE.getName(), StopMode.ALWAYS)).getUnchecked();
+
+        assertTrue(Entities.isManaged(brooklynNode));
+        assertFalse(isPidRunning(pidFile), "pid in "+pidFile+" still running");
+        
+        // Restart the process; expect persisted state to have been restored, so apps still known about
+        brooklynNode.invoke(BrooklynNode.RESTART, ImmutableMap.<String, Object>of(
+                BrooklynNode.RestartSoftwareParameters.RESTART_MACHINE.getName(), "false")).getUnchecked();
+
+        String apps = HttpTestUtils.getContent(webConsoleUri.toString()+"/v1/applications");
+        List<String> appType = parseJsonList(apps, ImmutableList.of("spec", "type"), String.class);
+        assertEquals(appType, ImmutableList.of(BasicApplication.class.getName()));
+    }
 
     private void createNodeAndExecStopEffector(Effector<?> eff) throws Exception {
         BrooklynNode brooklynNode = setUpBrooklynNodeWithApp();


[17/19] incubator-brooklyn git commit: Deploy blueprint must retry if remote denies with 403 response

Posted by al...@apache.org.
Deploy blueprint must retry if remote denies with 403 response

It means the server hasn't started properly yet.


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

Branch: refs/heads/master
Commit: 884f107db1d13e4515a46d2869128cf899b8d03f
Parents: 8d42590
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Mar 6 16:16:10 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:03:08 2015 +0200

----------------------------------------------------------------------
 .../entity/brooklynnode/BrooklynNodeImpl.java   | 35 ++++++++++++++++----
 1 file changed, 28 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/884f107d/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 952d32b..7856b8f 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -22,10 +22,10 @@ import java.net.URI;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.annotation.Nullable;
 
-import brooklyn.location.basic.Locations;
 import org.apache.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,6 +56,7 @@ import brooklyn.event.feed.http.HttpPollConfig;
 import brooklyn.event.feed.http.HttpValueFunctions;
 import brooklyn.event.feed.http.JsonFunctions;
 import brooklyn.location.access.BrooklynAccessUtils;
+import brooklyn.location.basic.Locations;
 import brooklyn.management.Task;
 import brooklyn.management.TaskAdaptable;
 import brooklyn.management.ha.ManagementNodeState;
@@ -80,6 +81,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.net.HostAndPort;
+import com.google.common.util.concurrent.Runnables;
 import com.google.gson.Gson;
 
 public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNode {
@@ -313,12 +315,31 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
         @VisibleForTesting
         // Integration test for this in BrooklynNodeIntegrationTest in this project doesn't use this method,
         // but a Unit test for this does, in DeployBlueprintTest -- but in the REST server project (since it runs against local) 
-        public String submitPlan(String plan) {
-            MutableMap<String, String> headers = MutableMap.of(com.google.common.net.HttpHeaders.CONTENT_TYPE, "application/yaml");
-            HttpToolResponse result = ((BrooklynNode)entity()).http()
-                    .post("/v1/applications", headers, plan.getBytes());
-            byte[] content = result.getContent();
-            return (String)new Gson().fromJson(new String(content), Map.class).get("entityId");
+        public String submitPlan(final String plan) {
+            final MutableMap<String, String> headers = MutableMap.of(com.google.common.net.HttpHeaders.CONTENT_TYPE, "application/yaml");
+            final AtomicReference<byte[]> response = new AtomicReference<byte[]>();
+            Repeater.create()
+                .every(Duration.ONE_SECOND)
+                .backoffTo(Duration.FIVE_SECONDS)
+                .limitTimeTo(Duration.minutes(5))
+                .repeat(Runnables.doNothing())
+                .until(new Callable<Boolean>() {
+                    public Boolean call() {
+                        HttpToolResponse result = ((BrooklynNode)entity()).http()
+                                .post("/v1/applications", headers, plan.getBytes());
+                        if (result.getResponseCode() == HttpStatus.SC_FORBIDDEN) {
+                            log.debug("Remote is not ready to accept requests, response is " + result.getResponseCode());
+                            return false;
+                        } else {
+                            //will fail on non-2xx response
+                            byte[] content = result.getContent();
+                            response.set(content);
+                            return true;
+                        }
+                    }
+                })
+                .runRequiringTrue();
+            return (String)new Gson().fromJson(new String(response.get()), Map.class).get("entityId");
         }
     }
 


[19/19] incubator-brooklyn git commit: This closes #542

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


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

Branch: refs/heads/master
Commit: 3d73c9324420b86c59c250de1fbd6b2a2fb0a44c
Parents: 78072b2 9bafb46
Author: Aled Sage <al...@gmail.com>
Authored: Thu Mar 19 14:07:04 2015 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Thu Mar 19 14:07:04 2015 +0000

----------------------------------------------------------------------
 .../management/ha/HighAvailabilityManager.java  |   5 +-
 .../ha/HighAvailabilityManagerImpl.java         |   9 +
 .../NonDeploymentManagementContext.java         |   4 +
 .../brooklyn/entity/basic/SoftwareProcess.java  |  25 ++-
 ...wareProcessDriverLifecycleEffectorTasks.java |  19 ++
 .../entity/basic/SoftwareProcessImpl.java       |   6 +
 .../entity/brooklynnode/BrooklynNodeImpl.java   |  78 ++++++-
 .../BrooklynNodeUpgradeEffectorBody.java        |   5 +-
 .../software/MachineLifecycleEffectorTasks.java |  78 ++++---
 .../BrooklynNodeIntegrationTest.java            |  55 ++++-
 .../entity/brooklynnode/MockBrooklynNode.java   |   2 -
 .../MachineLifecycleEffectorTasksTest.java      |   8 +-
 usage/jsgui/src/main/webapp/assets/js/router.js |   7 +-
 .../BrooklynJavascriptGuiLauncherTest.java      |   7 +-
 .../brooklyn/launcher/BrooklynWebServer.java    |   7 +
 .../rest/filter/HaHotCheckResourceFilter.java   | 116 ++++++++++
 .../rest/filter/HaHotStateRequired.java         |  36 +++
 .../rest/filter/HaMasterCheckFilter.java        |   2 +-
 .../rest/resources/ApplicationResource.java     |   2 +
 .../rest/resources/CatalogResource.java         |   2 +
 .../rest/resources/EffectorResource.java        |   2 +
 .../rest/resources/EntityConfigResource.java    |   2 +
 .../brooklyn/rest/resources/EntityResource.java |   2 +
 .../rest/resources/LocationResource.java        |   2 +
 .../rest/resources/PolicyConfigResource.java    |   2 +
 .../brooklyn/rest/resources/PolicyResource.java |   2 +
 .../brooklyn/rest/resources/SensorResource.java |   2 +
 .../rest/util/ManagementContextProvider.java    |  33 +++
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |  18 +-
 .../rest/BrooklynRestApiLauncherTest.java       |  25 ++-
 .../test/java/brooklyn/rest/HaHotCheckTest.java | 141 ++++++++++++
 .../brooklyn/rest/HaMasterCheckFilterTest.java  | 218 +++++++++++++++++++
 .../mocks/HighAvailabilityManagerStub.java      | 121 ++++++++++
 .../testing/mocks/ManagementContextMock.java    | 189 ++++++++++++++++
 .../rest/util/HaHotStateCheckClassResource.java |  38 ++++
 .../rest/util/HaHotStateCheckResource.java      |  44 ++++
 36 files changed, 1240 insertions(+), 74 deletions(-)
----------------------------------------------------------------------



[18/19] incubator-brooklyn git commit: Fix failing tests after changes to return 403 response code

Posted by al...@apache.org.
Fix failing tests after changes to return 403 response code


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

Branch: refs/heads/master
Commit: a8a27f86e856ffd5c6f6b39ab15170826d8e9d86
Parents: 884f107
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Fri Mar 6 16:16:57 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:03:08 2015 +0200

----------------------------------------------------------------------
 .../entity/brooklynnode/MockBrooklynNode.java   |  2 --
 .../BrooklynJavascriptGuiLauncherTest.java      | 12 ++++++++--
 .../rest/BrooklynRestApiLauncherTest.java       | 25 ++++++++++++++++----
 .../test/java/brooklyn/rest/HaHotCheckTest.java | 16 ++++++++++++-
 4 files changed, 46 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a8a27f86/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
index c75131e..e20f493 100644
--- a/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
+++ b/software/base/src/test/java/brooklyn/entity/brooklynnode/MockBrooklynNode.java
@@ -23,8 +23,6 @@ import java.util.Collection;
 import brooklyn.config.ConfigKey;
 import brooklyn.entity.basic.AbstractEntity;
 import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.brooklynnode.BrooklynNode;
-import brooklyn.entity.brooklynnode.EntityHttpClient;
 import brooklyn.entity.brooklynnode.CallbackEntityHttpClient.Request;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityModeEffectorBody;
 import brooklyn.entity.brooklynnode.effector.SetHighAvailabilityPriorityEffectorBody;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a8a27f86/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java b/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
index ca82ee1..ab55d66 100644
--- a/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
+++ b/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
@@ -27,6 +27,7 @@ import brooklyn.config.BrooklynServiceAttributes;
 import brooklyn.entity.basic.Entities;
 import brooklyn.management.ManagementContext;
 import brooklyn.rest.BrooklynRestApiLauncherTestFixture;
+import brooklyn.test.Asserts;
 import brooklyn.test.HttpTestUtils;
 
 /** Convenience and demo for launching programmatically. */
@@ -60,8 +61,15 @@ public class BrooklynJavascriptGuiLauncherTest {
         checkUrlContains("/v1/catalog/entities", "Tomcat");
     }
 
-    protected void checkUrlContains(String path, String text) {
-        HttpTestUtils.assertContentContainsText(rootUrl()+path, text);
+    protected void checkUrlContains(final String path, final String text) {
+        //Server may return 403 until it loads completely, wait a bit
+        //until it stabilizes.
+        Asserts.succeedsEventually(new Runnable() {
+            @Override
+            public void run() {
+                HttpTestUtils.assertContentContainsText(rootUrl()+path, text);
+            }
+        });
     }
 
     protected void checkEventuallyHealthy() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a8a27f86/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncherTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncherTest.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncherTest.java
index da44a69..0412118 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncherTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncherTest.java
@@ -18,12 +18,19 @@
  */
 package brooklyn.rest;
 
-import static brooklyn.rest.BrooklynRestApiLauncher.StartMode.*;
+import static brooklyn.rest.BrooklynRestApiLauncher.StartMode.FILTER;
+import static brooklyn.rest.BrooklynRestApiLauncher.StartMode.SERVLET;
+import static brooklyn.rest.BrooklynRestApiLauncher.StartMode.WEB_XML;
+
+import java.util.concurrent.Callable;
+
+import org.apache.http.HttpStatus;
 import org.eclipse.jetty.server.Server;
 import org.testng.annotations.Test;
 
 import brooklyn.rest.security.provider.AnyoneSecurityProvider;
 import brooklyn.rest.util.BrooklynRestResourceUtilsTest.SampleNoOpApplication;
+import brooklyn.test.Asserts;
 import brooklyn.test.HttpTestUtils;
 
 public class BrooklynRestApiLauncherTest extends BrooklynRestApiLauncherTestFixture {
@@ -50,9 +57,19 @@ public class BrooklynRestApiLauncherTest extends BrooklynRestApiLauncherTestFixt
     }
     
     private static void checkRestCatalogApplications(Server server) throws Exception {
-        String rootUrl = "http://localhost:"+server.getConnectors()[0].getLocalPort();
-        HttpTestUtils.assertHealthyStatusCode(
-                HttpTestUtils.getHttpStatusCode(rootUrl+"/v1/catalog/applications"));
+        final String rootUrl = "http://localhost:"+server.getConnectors()[0].getLocalPort();
+        int code = Asserts.succeedsEventually(new Callable<Integer>() {
+            @Override
+            public Integer call() throws Exception {
+                int code = HttpTestUtils.getHttpStatusCode(rootUrl+"/v1/catalog/applications");
+                if (code == HttpStatus.SC_FORBIDDEN) {
+                    throw new RuntimeException("Retry request");
+                } else {
+                    return code;
+                }
+            }
+        });
+        HttpTestUtils.assertHealthyStatusCode(code);
         HttpTestUtils.assertContentContainsText(rootUrl+"/v1/catalog/applications", SampleNoOpApplication.class.getSimpleName());
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a8a27f86/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
index 8692325..8f28728 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
@@ -22,6 +22,9 @@ import static org.testng.Assert.assertEquals;
 
 import javax.ws.rs.core.MediaType;
 
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -43,13 +46,24 @@ public class HaHotCheckTest extends BrooklynRestResourceTest {
 
     private ManagementContextMock mgmtMock;
 
-    @Override
+    //Treat before/after class methods as before/after method
+    //otherwise they should be static.
+    @BeforeClass(alwaysRun=true)
+    public void setUpClass() {}
+    @AfterClass(alwaysRun=true)
+    public void tearDownClass() {}
+
     @BeforeMethod(alwaysRun = true)
     public void setUp() throws Exception {
         mgmtMock = new ManagementContextMock();
         super.setUp();
     }
 
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
     @Override
     protected void addBrooklynResources() {
         config.getSingletons().add(new ManagementContextProvider(mgmtMock));


[16/19] incubator-brooklyn git commit: Addressed PR#542 comments

Posted by al...@apache.org.
Addressed PR#542 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/363989b9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/363989b9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/363989b9

Branch: refs/heads/master
Commit: 363989b95ad20a51148f8140a5dae9cdef9a5434
Parents: a8a27f8
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Mar 17 23:36:05 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu Mar 19 16:03:08 2015 +0200

----------------------------------------------------------------------
 .../management/ha/HighAvailabilityManager.java  |   2 +-
 .../entity/brooklynnode/BrooklynNodeImpl.java   |   7 +-
 .../software/MachineLifecycleEffectorTasks.java |  42 ++++---
 .../BrooklynJavascriptGuiLauncherTest.java      |   7 +-
 .../rest/filter/HaHotCheckResourceFilter.java   |   1 +
 .../rest/filter/HaHotStateRequired.java         |   8 ++
 .../brooklyn/rest/BrooklynRestApiLauncher.java  |   2 +-
 .../test/java/brooklyn/rest/HaHotCheckTest.java |  19 ++-
 .../mocks/HighAvailabilityManagerMock.java      | 121 -------------------
 .../mocks/HighAvailabilityManagerStub.java      | 121 +++++++++++++++++++
 .../testing/mocks/ManagementContextMock.java    |   2 +-
 11 files changed, 170 insertions(+), 162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
----------------------------------------------------------------------
diff --git a/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java b/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
index 2a1af9a..c530116 100644
--- a/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
+++ b/api/src/main/java/brooklyn/management/ha/HighAvailabilityManager.java
@@ -44,7 +44,7 @@ public interface HighAvailabilityManager {
 
     ManagementNodeState getNodeState();
     
-    /** The time in milliseconds when the state was last changed */
+    /** The time in milliseconds when the state was last changed. -1 if no state transition has occurred yet.*/
     long getLastStateChange();
     
     /**

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
index 7856b8f..d4b4992 100644
--- a/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
+++ b/software/base/src/main/java/brooklyn/entity/brooklynnode/BrooklynNodeImpl.java
@@ -176,8 +176,9 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     @Override
     protected void preRestart() {
         super.preRestart();
+        //restart will kill the process, try to shut down before that
         shutdownGracefully();
-        DynamicTasks.queue("post-shutdown", new Runnable() { public void run() {
+        DynamicTasks.queue("pre-restart", new Runnable() { public void run() {
             //set by shutdown - clear it so the entity starts cleanly. Does the indicator bring any value at all?
             ServiceNotUpLogic.clearNotUpIndicator(BrooklynNodeImpl.this, SHUTDOWN.getName());
         }});
@@ -220,7 +221,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
     @Override
     protected void postStop() {
         super.postStop();
-        if (isStopMachine()) {
+        if (isMachineStopped()) {
             // Don't unmanage in entity's task context as it will self-cancel the task. Wait for the stop effector to complete.
             // If this is not enough (still getting Caused by: java.util.concurrent.CancellationException: null) then
             // we could search for the top most task with entity context == this and wait on it. Even stronger would be
@@ -230,7 +231,7 @@ public class BrooklynNodeImpl extends SoftwareProcessImpl implements BrooklynNod
         }
     }
 
-    private boolean isStopMachine() {
+    private boolean isMachineStopped() {
         // Don't rely on effector parameters, check if there is still a machine running.
         // If the entity was previously stopped with STOP_MACHINE_MODE=StopMode.NEVER
         // and a second time with STOP_MACHINE_MODE=StopMode.IF_NOT_STOPPED, then the

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
index e64e078..4fd6b09 100644
--- a/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/brooklyn/entity/software/MachineLifecycleEffectorTasks.java
@@ -552,24 +552,8 @@ public abstract class MachineLifecycleEffectorTasks {
 
         log.info("Stopping {} in {}", entity(), entity().getLocations());
 
-        @SuppressWarnings("deprecation")
-        final boolean hasStopMachine = parameters.containsKey(StopSoftwareParameters.STOP_MACHINE);
-        @SuppressWarnings("deprecation")
-        final Boolean isStopMachine = parameters.get(StopSoftwareParameters.STOP_MACHINE);
-
-        final StopMode stopProcessMode = parameters.get(StopSoftwareParameters.STOP_PROCESS_MODE);
-
-        final boolean hasStopMachineMode = parameters.containsKey(StopSoftwareParameters.STOP_MACHINE_MODE);
-        StopMode stopMachineMode = parameters.get(StopSoftwareParameters.STOP_MACHINE_MODE);
-
-        if (hasStopMachine && isStopMachine != null) {
-            checkCompatibleMachineModes(isStopMachine, hasStopMachineMode, stopMachineMode);
-            if (isStopMachine) {
-                stopMachineMode = StopMode.IF_NOT_STOPPED;
-            } else {
-                stopMachineMode = StopMode.NEVER;
-            }
-        }
+        StopMode stopMachineMode = getStopMachineMode(parameters);
+        StopMode stopProcessMode = parameters.get(StopSoftwareParameters.STOP_PROCESS_MODE);
 
         DynamicTasks.queue("pre-stop", new Callable<String>() { public String call() {
             if (entity().getAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL)==Lifecycle.STOPPED) {
@@ -650,6 +634,26 @@ public abstract class MachineLifecycleEffectorTasks {
         if (log.isDebugEnabled()) log.debug("Stopped software process entity "+entity());
     }
 
+    public static StopMode getStopMachineMode(ConfigBag parameters) {
+        @SuppressWarnings("deprecation")
+        final boolean hasStopMachine = parameters.containsKey(StopSoftwareParameters.STOP_MACHINE);
+        @SuppressWarnings("deprecation")
+        final Boolean isStopMachine = parameters.get(StopSoftwareParameters.STOP_MACHINE);
+
+        final boolean hasStopMachineMode = parameters.containsKey(StopSoftwareParameters.STOP_MACHINE_MODE);
+        final StopMode stopMachineMode = parameters.get(StopSoftwareParameters.STOP_MACHINE_MODE);
+
+        if (hasStopMachine && isStopMachine != null) {
+            checkCompatibleMachineModes(isStopMachine, hasStopMachineMode, stopMachineMode);
+            if (isStopMachine) {
+                return StopMode.IF_NOT_STOPPED;
+            } else {
+                return StopMode.NEVER;
+            }
+        }
+        return stopMachineMode;
+    }
+
     public static boolean canStop(StopMode stopMode, Entity entity) {
         boolean isEntityStopped = entity.getAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL)==Lifecycle.STOPPED;
         return canStop(stopMode, isEntityStopped);
@@ -660,7 +664,7 @@ public abstract class MachineLifecycleEffectorTasks {
                 stopMode == StopMode.IF_NOT_STOPPED && !isStopped;
     }
 
-    private void checkCompatibleMachineModes(Boolean isStopMachine, boolean hasStopMachineMode, StopMode stopMachineMode) {
+    private static void checkCompatibleMachineModes(Boolean isStopMachine, boolean hasStopMachineMode, StopMode stopMachineMode) {
         if (hasStopMachineMode &&
                 (isStopMachine && stopMachineMode != StopMode.IF_NOT_STOPPED ||
                  !isStopMachine && stopMachineMode != StopMode.NEVER)) {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
----------------------------------------------------------------------
diff --git a/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java b/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
index ab55d66..9ebb40b 100644
--- a/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
+++ b/usage/jsgui/src/test/java/brooklyn/rest/jsgui/BrooklynJavascriptGuiLauncherTest.java
@@ -64,12 +64,7 @@ public class BrooklynJavascriptGuiLauncherTest {
     protected void checkUrlContains(final String path, final String text) {
         //Server may return 403 until it loads completely, wait a bit
         //until it stabilizes.
-        Asserts.succeedsEventually(new Runnable() {
-            @Override
-            public void run() {
-                HttpTestUtils.assertContentContainsText(rootUrl()+path, text);
-            }
-        });
+        HttpTestUtils.assertContentEventuallyContainsText(rootUrl()+path, text);
     }
 
     protected void checkEventuallyHealthy() {

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
index 8b1d67f..5367439 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotCheckResourceFilter.java
@@ -89,6 +89,7 @@ public class HaHotCheckResourceFilter implements ResourceFilterFactory {
         // and starting rebind so add a time offset just to be sure.
         private boolean recentlySwitchedState() {
             long lastStateChange = mgmt.getHighAvailabilityManager().getLastStateChange();
+            if (lastStateChange == -1) return false;
             return System.currentTimeMillis() - lastStateChange < STATE_CHANGE_SETTLE_OFFSET;
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
index 271da8f..09eea5f 100644
--- a/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
+++ b/usage/rest-server/src/main/java/brooklyn/rest/filter/HaHotStateRequired.java
@@ -23,6 +23,14 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * When a REST method (or its containing class) is marked with this annotation
+ * requests to it will fail with a 403 response if the instance is not in MASTER
+ * mode (or has recently switched or is still rebinding). Guards the method so
+ * that when it returns the caller can be certain of the response. For example
+ * if the response is 404, then the resource doesn't exist as opposed to
+ * not being loaded from persistence store yet.
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD, ElementType.TYPE})
 public @interface HaHotStateRequired {}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
index cb7b29d..5643614 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/BrooklynRestApiLauncher.java
@@ -152,7 +152,7 @@ public class BrooklynRestApiLauncher {
         this.deployJsgui = false;
         return this;
     }
-    
+
     public BrooklynRestApiLauncher disableHighAvailability(boolean value) {
         this.disableHighAvailability = value;
         return this;

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
index 8f28728..58a9e6b 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/HaHotCheckTest.java
@@ -23,7 +23,6 @@ import static org.testng.Assert.assertEquals;
 import javax.ws.rs.core.MediaType;
 
 import org.testng.annotations.AfterClass;
-import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -46,24 +45,24 @@ public class HaHotCheckTest extends BrooklynRestResourceTest {
 
     private ManagementContextMock mgmtMock;
 
-    //Treat before/after class methods as before/after method
-    //otherwise they should be static.
-    @BeforeClass(alwaysRun=true)
-    public void setUpClass() {}
-    @AfterClass(alwaysRun=true)
-    public void tearDownClass() {}
-
-    @BeforeMethod(alwaysRun = true)
+    @Override
+    @BeforeClass(alwaysRun = true)
     public void setUp() throws Exception {
         mgmtMock = new ManagementContextMock();
         super.setUp();
     }
 
-    @AfterMethod(alwaysRun = true)
+    @Override
+    @AfterClass(alwaysRun = true)
     public void tearDown() throws Exception {
         super.tearDown();
     }
 
+    @BeforeMethod(alwaysRun = true)
+    public void setUpMethod() {
+        mgmtMock.setState(ManagementNodeState.MASTER);
+    }
+
     @Override
     protected void addBrooklynResources() {
         config.getSingletons().add(new ManagementContextProvider(mgmtMock));

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
deleted file mode 100644
index 5c99183..0000000
--- a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerMock.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package brooklyn.rest.testing.mocks;
-
-import java.util.Map;
-
-import brooklyn.management.ha.HighAvailabilityManager;
-import brooklyn.management.ha.HighAvailabilityMode;
-import brooklyn.management.ha.ManagementNodeState;
-import brooklyn.management.ha.ManagementPlaneSyncRecord;
-import brooklyn.management.ha.ManagementPlaneSyncRecordPersister;
-
-public class HighAvailabilityManagerMock implements HighAvailabilityManager {
-
-    private ManagementNodeState state = ManagementNodeState.MASTER;
-
-    public void setState(ManagementNodeState state) {
-        this.state = state;
-    }
-
-    private static RuntimeException fail() {
-        throw new UnsupportedOperationException("Mocked method not implemented");
-    }
-
-    @Override
-    public boolean isRunning() {
-        return state != ManagementNodeState.TERMINATED;
-    }
-
-    @Override
-    public ManagementNodeState getNodeState() {
-        return state;
-    }
-
-    @Override
-    public long getLastStateChange() {
-        return 0;
-    }
-
-    @Override
-    public HighAvailabilityManager setPersister(ManagementPlaneSyncRecordPersister persister) {
-        throw fail();
-    }
-
-    @Override
-    public void disabled() {
-        throw fail();
-    }
-
-    @Override
-    public void start(HighAvailabilityMode startMode) {
-        throw fail();
-    }
-
-    @Override
-    public void stop() {
-        throw fail();
-    }
-
-    @Override
-    public void changeMode(HighAvailabilityMode mode) {
-        throw fail();
-    }
-
-    @Override
-    public void setPriority(long priority) {
-        throw fail();
-    }
-
-    @Override
-    public long getPriority() {
-        throw fail();
-    }
-
-    @Override
-    public void publishClearNonMaster() {
-        throw fail();
-    }
-
-    @Override
-    public ManagementPlaneSyncRecord getLastManagementPlaneSyncRecord() {
-        throw fail();
-    }
-
-    @Override
-    public ManagementPlaneSyncRecord getManagementPlaneSyncState() {
-        throw fail();
-    }
-
-    @Override
-    public ManagementPlaneSyncRecord loadManagementPlaneSyncRecord(boolean useLocalKnowledgeForThisNode) {
-        throw fail();
-    }
-
-    @Override
-    public ManagementPlaneSyncRecordPersister getPersister() {
-        throw fail();
-    }
-
-    @Override
-    public Map<String, Object> getMetrics() {
-        throw fail();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerStub.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerStub.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerStub.java
new file mode 100644
index 0000000..98fb8d5
--- /dev/null
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/HighAvailabilityManagerStub.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package brooklyn.rest.testing.mocks;
+
+import java.util.Map;
+
+import brooklyn.management.ha.HighAvailabilityManager;
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.management.ha.ManagementPlaneSyncRecord;
+import brooklyn.management.ha.ManagementPlaneSyncRecordPersister;
+
+public class HighAvailabilityManagerStub implements HighAvailabilityManager {
+
+    private ManagementNodeState state = ManagementNodeState.MASTER;
+
+    public void setState(ManagementNodeState state) {
+        this.state = state;
+    }
+
+    private static RuntimeException fail() {
+        throw new UnsupportedOperationException("Mocked method not implemented");
+    }
+
+    @Override
+    public boolean isRunning() {
+        return state != ManagementNodeState.TERMINATED;
+    }
+
+    @Override
+    public ManagementNodeState getNodeState() {
+        return state;
+    }
+
+    @Override
+    public long getLastStateChange() {
+        return 0;
+    }
+
+    @Override
+    public HighAvailabilityManager setPersister(ManagementPlaneSyncRecordPersister persister) {
+        throw fail();
+    }
+
+    @Override
+    public void disabled() {
+        throw fail();
+    }
+
+    @Override
+    public void start(HighAvailabilityMode startMode) {
+        throw fail();
+    }
+
+    @Override
+    public void stop() {
+        throw fail();
+    }
+
+    @Override
+    public void changeMode(HighAvailabilityMode mode) {
+        throw fail();
+    }
+
+    @Override
+    public void setPriority(long priority) {
+        throw fail();
+    }
+
+    @Override
+    public long getPriority() {
+        throw fail();
+    }
+
+    @Override
+    public void publishClearNonMaster() {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecord getLastManagementPlaneSyncRecord() {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecord getManagementPlaneSyncState() {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecord loadManagementPlaneSyncRecord(boolean useLocalKnowledgeForThisNode) {
+        throw fail();
+    }
+
+    @Override
+    public ManagementPlaneSyncRecordPersister getPersister() {
+        throw fail();
+    }
+
+    @Override
+    public Map<String, Object> getMetrics() {
+        throw fail();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/363989b9/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
----------------------------------------------------------------------
diff --git a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
index 6a29fed..90edf1e 100644
--- a/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
+++ b/usage/rest-server/src/test/java/brooklyn/rest/testing/mocks/ManagementContextMock.java
@@ -44,7 +44,7 @@ import brooklyn.management.ha.ManagementNodeState;
 import brooklyn.util.guava.Maybe;
 
 public class ManagementContextMock implements ManagementContext {
-    private HighAvailabilityManagerMock haMock = new HighAvailabilityManagerMock();
+    private HighAvailabilityManagerStub haMock = new HighAvailabilityManagerStub();
 
     public void setState(ManagementNodeState state) {
         haMock.setState(state);