http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/main/webapp/WEB-INF/web.xml 
b/rest/rest-api/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index bab259b..0000000
--- a/rest/rest-api/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    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.
--->
-<!DOCTYPE web-app PUBLIC
- "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
- "http://java.sun.com/dtd/web-app_2_3.dtd"; >
-
-<web-app>
-    <display-name>Brooklyn REST API v1</display-name>
-
-    <filter>
-        <filter-name>Brooklyn Request Tagging Filter</filter-name>
-        
<filter-class>org.apache.brooklyn.rest.filter.RequestTaggingFilter</filter-class>
-    </filter>
-    <filter-mapping>
-        <filter-name>Brooklyn Request Tagging Filter</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-
-    <filter>
-        <filter-name>Brooklyn Properties Authentication Filter</filter-name>
-        
<filter-class>org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter</filter-class>
-    </filter>
-    <filter-mapping>
-        <filter-name>Brooklyn Properties Authentication Filter</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-
-    <filter>
-        <filter-name>Brooklyn Logging Filter</filter-name>
-        
<filter-class>org.apache.brooklyn.rest.filter.LoggingFilter</filter-class>
-    </filter>
-    <filter-mapping>
-        <filter-name>Brooklyn Logging Filter</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-
-    <filter>
-        <filter-name>Brooklyn HA Master Filter</filter-name>
-        
<filter-class>org.apache.brooklyn.rest.filter.HaMasterCheckFilter</filter-class>
-    </filter>
-    <filter-mapping>
-        <filter-name>Brooklyn HA Master Filter</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-    <filter>
-        <filter-name>Brooklyn Swagger Bootstrap</filter-name>
-        
<filter-class>org.apache.brooklyn.rest.filter.SwaggerFilter</filter-class>
-    </filter>
-    <filter-mapping>
-        <filter-name>Brooklyn Swagger Bootstrap</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-
-<!-- Brooklyn REST is usually run as a filter so static content can be placed 
in a webapp
-     to which this is added; to run as a servlet directly, replace the filter 
tags 
-     below (after the comment) with the servlet tags (commented out 
immediately below),
-     (and do the same for the matching tags at the bottom)
-    <servlet>
-        <servlet-name>Brooklyn REST API v1 Servlet</servlet-name>
-        
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
- -->
-    <filter>
-        <filter-name>Brooklyn REST API v1 Filter</filter-name>
-        
<filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class>
-
-        <!-- load our REST API jersey resources -->
-        <init-param>
-            <param-name>com.sun.jersey.config.property.packages</param-name>
-            
<param-value>io.swagger.jaxrs.listing;com.fasterxml.jackson.jaxrs;org.apache.brooklyn.rest.resources;org.apache.brooklyn.rest.util</param-value>
-        </init-param>
-
-        <!-- install Jackson and turn on pojo/json serialization (could add 
org.codehaus.jackson.jaxrs 
-             above but seems cleaner to pull in just the class -->
-        <init-param>  
-            <param-name>com.sun.jersey.config.property.classnames</param-name>
-            
<param-value>com.fasterxml.jackson.jaxrs.JacksonJsonProvider</param-value>
-        </init-param>
-        <init-param>
-            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
-            <param-value>true</param-value>
-        </init-param>
-        
-        <!-- no need for WADL. of course you can turn it back on it you want. 
--> 
-        <init-param>
-            <param-name>com.sun.jersey.config.feature.DisableWADL</param-name>
-            <param-value>true</param-value>
-        </init-param>
-        
-    </filter>
-    <filter-mapping>
-        <filter-name>Brooklyn REST API v1 Filter</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-<!-- Brooklyn REST as a filter above; replace above 5 lines with those 
commented out below,
-     to run it as a servlet (see note above) 
-        <load-on-startup>1</load-on-startup>
-    </servlet>
-    <servlet-mapping>
-        <servlet-name>Brooklyn REST API v1 Servlet</servlet-name>
-        <url-pattern>/*</url-pattern>
-    </servlet-mapping>
--->
-
-</web-app>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
index b2690d6..82bbb43 100644
--- 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
+++ 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java
@@ -33,7 +33,7 @@ public class ApplicationSpecTest extends AbstractDomainTest {
         EntitySpec entitySpec = new EntitySpec("Vanilla Java App", 
"org.apache.brooklyn.entity.java.VanillaJavaApp",
                 ImmutableMap.of("initialSize", "1", "creationScriptUrl", 
"http://my.brooklyn.io/storage/foo.sql";));
         return ApplicationSpec.builder().name("myapp")
-                
.entities(ImmutableSet.of(entitySpec)).locations(ImmutableSet.of("/v1/locations/1"))
+                
.entities(ImmutableSet.of(entitySpec)).locations(ImmutableSet.of("/locations/1"))
                 .build();
     }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
index 71cb64d..f71399c 100644
--- 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
+++ 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java
@@ -38,7 +38,7 @@ public class EffectorSummaryTest extends AbstractDomainTest {
                 ImmutableSet.<EffectorSummary.ParameterSummary<?>>of(),
                 "Effector description",
                 ImmutableMap.of(
-                        "self", 
URI.create("/v1/applications/redis-app/entities/redis-ent/effectors/stop")));
+                        "self", 
URI.create("/applications/redis-app/entities/redis-ent/effectors/stop")));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
index 2d39cc9..6eb38c8 100644
--- 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
+++ 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java
@@ -33,10 +33,10 @@ public class EntitySummaryTest extends AbstractDomainTest {
     @Override
     protected Object getDomainObject() {
         Map<String, URI> links = Maps.newLinkedHashMap();
-        links.put("self", 
URI.create("/v1/applications/tesr/entities/zQsqdXzi"));
-        links.put("catalog", 
URI.create("/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer"));
-        links.put("application", URI.create("/v1/applications/tesr"));
-        links.put("children", 
URI.create("/v1/applications/tesr/entities/zQsqdXzi/children"));
+        links.put("self", URI.create("/applications/tesr/entities/zQsqdXzi"));
+        links.put("catalog", 
URI.create("/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer"));
+        links.put("application", URI.create("/applications/tesr"));
+        links.put("children", 
URI.create("/applications/tesr/entities/zQsqdXzi/children"));
         links.put("effectors", 
URI.create("fixtures/effector-summary-list.json"));
         links.put("sensors", URI.create("fixtures/sensor-summary-list.json"));
         links.put("activities", URI.create("fixtures/task-summary-list.json"));

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java
 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java
index 6279546..8d40e75 100644
--- 
a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java
+++ 
b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java
@@ -33,7 +33,7 @@ public class LocationSummaryTest extends AbstractDomainTest {
     @Override
     protected Object getDomainObject() {
         Map<String, URI> links = Maps.newLinkedHashMap();
-        links.put("self", URI.create("/v1/locations/123"));
+        links.put("self", URI.create("/locations/123"));
 
         return new LocationSummary("123", "localhost", "localhost", null, 
null, links);
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/application-list.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/application-list.json 
b/rest/rest-api/src/test/resources/fixtures/application-list.json
index 029cf68..a4e7980 100644
--- a/rest/rest-api/src/test/resources/fixtures/application-list.json
+++ b/rest/rest-api/src/test/resources/fixtures/application-list.json
@@ -10,12 +10,12 @@
                 }
             ],
             "locations":[
-                "/v1/locations/0"
+                "/locations/0"
             ]
         },
         "status":"STARTING",
         "links":{
-            "self":"/v1/applications/tesr",
+            "self":"/applications/tesr",
             "entities":"fixtures/entity-summary-list.json"
         }
     },
@@ -32,11 +32,11 @@
                     }
                 }
             ],
-            "locations":["/v1/locations/1"]
+            "locations":["/locations/1"]
         },
         "status":"STARTING",
         "links":{
-            "self":"/v1/applications/myapp",
+            "self":"/applications/myapp",
             "entities":"fixtures/entity-summary-list.json"
         }
     }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/application-spec.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/application-spec.json 
b/rest/rest-api/src/test/resources/fixtures/application-spec.json
index 9f042c6..48e9e5f 100644
--- a/rest/rest-api/src/test/resources/fixtures/application-spec.json
+++ b/rest/rest-api/src/test/resources/fixtures/application-spec.json
@@ -11,6 +11,6 @@
         }
     ],
     "locations":[
-        "/v1/locations/1"
+        "/locations/1"
     ]
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/application.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/application.json 
b/rest/rest-api/src/test/resources/fixtures/application.json
index cd6a21a..c7b9aed 100644
--- a/rest/rest-api/src/test/resources/fixtures/application.json
+++ b/rest/rest-api/src/test/resources/fixtures/application.json
@@ -12,11 +12,11 @@
                 }
             }
         ],
-        "locations":["/v1/locations/1"]
+        "locations":["/locations/1"]
     },
     "status":"STARTING",
     "links":{
-        "self":"/v1/applications/myapp",
+        "self":"/applications/myapp",
         "entities":"fixtures/entity-summary-list.json"
     }
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json
----------------------------------------------------------------------
diff --git 
a/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json 
b/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json
index fe2828c..2b7e7c5 100644
--- a/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json
+++ b/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json
@@ -17,9 +17,9 @@
             }
         ],
         "links":{
-            "self":"/v1/applications/tesr/entities/ZgoDhGQA/effectors/start",
-            "entity":"/v1/applications/tesr/entities/ZgoDhGQA",
-            "application":"/v1/applications/tesr"
+            "self":"/applications/tesr/entities/ZgoDhGQA/effectors/start",
+            "entity":"/applications/tesr/entities/ZgoDhGQA",
+            "application":"/applications/tesr"
         }
     },
     {
@@ -28,9 +28,9 @@
         "returnType":"void",
         "parameters":[ ],
         "links":{
-            "self":"/v1/applications/tesr/entities/ZgoDhGQA/effectors/restart",
-            "entity":"/v1/applications/tesr/entities/ZgoDhGQA",
-            "application":"/v1/applications/tesr"
+            "self":"/applications/tesr/entities/ZgoDhGQA/effectors/restart",
+            "entity":"/applications/tesr/entities/ZgoDhGQA",
+            "application":"/applications/tesr"
         }
     },
     {
@@ -39,9 +39,9 @@
         "returnType":"void",
         "parameters":[ ],
         "links":{
-            "self":"/v1/applications/tesr/entities/ZgoDhGQA/effectors/stop",
-            "entity":"/v1/applications/tesr/entities/ZgoDhGQA",
-            "application":"/v1/applications/tesr"
+            "self":"/applications/tesr/entities/ZgoDhGQA/effectors/stop",
+            "entity":"/applications/tesr/entities/ZgoDhGQA",
+            "application":"/applications/tesr"
         }
     }
 ]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/effector-summary.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/effector-summary.json 
b/rest/rest-api/src/test/resources/fixtures/effector-summary.json
index eda97dd..1ba826d 100644
--- a/rest/rest-api/src/test/resources/fixtures/effector-summary.json
+++ b/rest/rest-api/src/test/resources/fixtures/effector-summary.json
@@ -4,6 +4,6 @@
     "parameters":[],
     "description":"Effector description",
     "links":{
-        "self":"/v1/applications/redis-app/entities/redis-ent/effectors/stop"
+        "self":"/applications/redis-app/entities/redis-ent/effectors/stop"
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json 
b/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json
index 6e2dc4e..bf71c36 100644
--- a/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json
+++ b/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json
@@ -2,10 +2,10 @@
     {
         "type":"org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
         "links":{
-            "self":"/v1/applications/tesr/entities/zQsqdXzi",
-            
"catalog":"/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
-            "application":"/v1/applications/tesr",
-            "children":"/v1/applications/tesr/entities/zQsqdXzi/entities",
+            "self":"/applications/tesr/entities/zQsqdXzi",
+            
"catalog":"/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
+            "application":"/applications/tesr",
+            "children":"/applications/tesr/entities/zQsqdXzi/entities",
             "effectors":"fixtures/effector-summary-list.json",
             "sensors":"fixtures/sensor-summary-list.json",
             "activities":"fixtures/task-summary-list.json"

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/entity-summary.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/entity-summary.json 
b/rest/rest-api/src/test/resources/fixtures/entity-summary.json
index 05d2e8f..fe0343c 100644
--- a/rest/rest-api/src/test/resources/fixtures/entity-summary.json
+++ b/rest/rest-api/src/test/resources/fixtures/entity-summary.json
@@ -2,10 +2,10 @@
  "name":"MyTomcat",
  "type":"org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
  "links":{
-   "self":"/v1/applications/tesr/entities/zQsqdXzi",
-   
"catalog":"/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
-   "application":"/v1/applications/tesr",
-   "children":"/v1/applications/tesr/entities/zQsqdXzi/children",
+   "self":"/applications/tesr/entities/zQsqdXzi",
+   
"catalog":"/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer",
+   "application":"/applications/tesr",
+   "children":"/applications/tesr/entities/zQsqdXzi/children",
    "effectors":"fixtures/effector-summary-list.json",
    "sensors":"fixtures/sensor-summary-list.json",
    "activities":"fixtures/task-summary-list.json"

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/location-list.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/location-list.json 
b/rest/rest-api/src/test/resources/fixtures/location-list.json
index c4e05de..6faa0b9 100644
--- a/rest/rest-api/src/test/resources/fixtures/location-list.json
+++ b/rest/rest-api/src/test/resources/fixtures/location-list.json
@@ -4,7 +4,7 @@
         "name":"localhost",
         "spec":"localhost",
         "links":{
-            "self":"/v1/locations/123"
+            "self":"/locations/123"
         }
     }
 ]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/location-summary.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/location-summary.json 
b/rest/rest-api/src/test/resources/fixtures/location-summary.json
index d1d0573..57749aa 100644
--- a/rest/rest-api/src/test/resources/fixtures/location-summary.json
+++ b/rest/rest-api/src/test/resources/fixtures/location-summary.json
@@ -3,6 +3,6 @@
     "name":"localhost",
     "spec":"localhost",
     "links":{
-        "self":"/v1/locations/123"
+        "self":"/locations/123"
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json 
b/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json
index 6ab457b..10d7ee2 100644
--- a/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json
+++ b/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json
@@ -5,8 +5,8 @@
         "description":"Service lifecycle state",
         "links":{
             "self":"fixtures/service-state.json",
-            "application":"/v1/applications/tesr",
-            "entity":"/v1/applications/tesr/entities/zQsqdXzi"
+            "application":"/applications/tesr",
+            "entity":"/applications/tesr/entities/zQsqdXzi"
         }
     },
     {
@@ -15,8 +15,8 @@
         "description":"JMX context path",
         "links":{
             "self":"fixtures/service-state.json",
-            "application":"/v1/applications/tesr",
-            "entity":"/v1/applications/tesr/entities/zQsqdXzi"
+            "application":"/applications/tesr",
+            "entity":"/applications/tesr/entities/zQsqdXzi"
         }
     },
     {
@@ -25,8 +25,8 @@
         "description":"Suggested shutdown port",
         "links":{
             "self":"fixtures/service-state.json",
-            "application":"/v1/applications/tesr",
-            "entity":"/v1/applications/tesr/entities/zQsqdXzi"
+            "application":"/applications/tesr",
+            "entity":"/applications/tesr/entities/zQsqdXzi"
         }
     },
     {
@@ -35,8 +35,8 @@
         "description":"Service has been started successfully and is running",
         "links":{
             "self":"fixtures/service-state.json",
-            "application":"/v1/applications/tesr",
-            "entity":"/v1/applications/tesr/entities/zQsqdXzi"
+            "application":"/applications/tesr",
+            "entity":"/applications/tesr/entities/zQsqdXzi"
         }
     }
 ]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/sensor-summary.json
----------------------------------------------------------------------
diff --git a/rest/rest-api/src/test/resources/fixtures/sensor-summary.json 
b/rest/rest-api/src/test/resources/fixtures/sensor-summary.json
index 0803b37..0ab6c8e 100644
--- a/rest/rest-api/src/test/resources/fixtures/sensor-summary.json
+++ b/rest/rest-api/src/test/resources/fixtures/sensor-summary.json
@@ -3,6 +3,6 @@
     "type":"Integer",
     "description":"Description",
     "links":{
-        
"self":"/v1/applications/redis-app/entities/redis-ent/sensors/redis.uptime"
+        
"self":"/applications/redis-app/entities/redis-ent/sensors/redis.uptime"
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-client/pom.xml
----------------------------------------------------------------------
diff --git a/rest/rest-client/pom.xml b/rest/rest-client/pom.xml
index d133518..afb9d65 100644
--- a/rest/rest-client/pom.xml
+++ b/rest/rest-client/pom.xml
@@ -133,6 +133,13 @@
         </dependency>
         <dependency>
             <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-rest-resources</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
             <artifactId>brooklyn-rest-server</artifactId>
             <version>${project.version}</version>
             <classifier>tests</classifier>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
 
b/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
index da3966f..adbdeda 100644
--- 
a/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
+++ 
b/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java
@@ -18,7 +18,6 @@
  */
 package org.apache.brooklyn.rest.client;
 
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
@@ -76,7 +75,7 @@ public class BrooklynApiRestClientTest {
                 .securityProvider(TestSecurityProvider.class)
                 .start();
 
-        api = BrooklynApi.newInstance("http://localhost:"; + 
((NetworkConnector)server.getConnectors()[0]).getPort() + "/",
+        api = BrooklynApi.newInstance("http://localhost:"; + 
((NetworkConnector)server.getConnectors()[0]).getPort() + "/v1",
                 TestSecurityProvider.USER, TestSecurityProvider.PASSWORD);
     }
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/pom.xml
----------------------------------------------------------------------
diff --git a/rest/rest-resources/pom.xml b/rest/rest-resources/pom.xml
new file mode 100644
index 0000000..2f171f8
--- /dev/null
+++ b/rest/rest-resources/pom.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>brooklyn-rest-resources</artifactId>
+    <packaging>jar</packaging>
+    <name>Brooklyn REST Resources</name>
+    <description>
+        Brooklyn REST Endpoint (CXF)
+    </description>
+
+    <parent>
+        <groupId>org.apache.brooklyn</groupId>
+        <artifactId>brooklyn-parent</artifactId>
+        <version>0.9.0-SNAPSHOT</version><!-- BROOKLYN_VERSION -->
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-rest-api</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.ws.rs</groupId>
+                    <artifactId>jsr311-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-camp</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn.camp</groupId>
+            <artifactId>camp-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-utils-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-software-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-utils-rest-swagger</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.yaml</groupId>
+            <artifactId>snakeyaml</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.findbugs</groupId>
+            <artifactId>jsr305</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-test-support</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-policy</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-core</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-software-base</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-rest-api</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-locations-jclouds</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.ws.rs</groupId>
+                    <artifactId>jsr311-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-software-nosql</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-software-webapp</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-software-database</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-local</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-transports-http-jetty</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.cxf</groupId>
+            <artifactId>cxf-rt-rs-client</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.brooklyn</groupId>
+            <artifactId>brooklyn-rt-osgi</artifactId>
+            <version>${project.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <!-- Required to set values in build-metadata.properties -->
+                <filtering>true</filtering>
+            </resource>
+            <resource>
+                <directory>${basedir}/src/main/webapp</directory>
+            </resource>
+        </resources>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
new file mode 100644
index 0000000..f42548f
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java
@@ -0,0 +1,91 @@
+/*
+ * 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 org.apache.brooklyn.rest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.brooklyn.rest.resources.AbstractBrooklynRestResource;
+import org.apache.brooklyn.rest.resources.AccessResource;
+import org.apache.brooklyn.rest.resources.ActivityResource;
+import org.apache.brooklyn.rest.resources.ApidocResource;
+import org.apache.brooklyn.rest.resources.ApplicationResource;
+import org.apache.brooklyn.rest.resources.CatalogResource;
+import org.apache.brooklyn.rest.resources.EffectorResource;
+import org.apache.brooklyn.rest.resources.EntityConfigResource;
+import org.apache.brooklyn.rest.resources.EntityResource;
+import org.apache.brooklyn.rest.resources.LocationResource;
+import org.apache.brooklyn.rest.resources.PolicyConfigResource;
+import org.apache.brooklyn.rest.resources.PolicyResource;
+import org.apache.brooklyn.rest.resources.ScriptResource;
+import org.apache.brooklyn.rest.resources.SensorResource;
+import org.apache.brooklyn.rest.resources.ServerResource;
+import org.apache.brooklyn.rest.resources.UsageResource;
+import org.apache.brooklyn.rest.resources.VersionResource;
+import org.apache.brooklyn.rest.util.DefaultExceptionMapper;
+import org.apache.brooklyn.rest.util.FormMapProvider;
+import org.apache.brooklyn.rest.util.json.BrooklynJacksonJsonProvider;
+
+import com.google.common.collect.Iterables;
+
+import io.swagger.jaxrs.listing.SwaggerSerializers;
+
+
+@SuppressWarnings("deprecation")
+public class BrooklynRestApi {
+
+    public static Iterable<AbstractBrooklynRestResource> 
getBrooklynRestResources() {
+        List<AbstractBrooklynRestResource> resources = new ArrayList<>();
+        resources.add(new LocationResource());
+        resources.add(new CatalogResource());
+        resources.add(new ApplicationResource());
+        resources.add(new EntityResource());
+        resources.add(new EntityConfigResource());
+        resources.add(new SensorResource());
+        resources.add(new EffectorResource());
+        resources.add(new PolicyResource());
+        resources.add(new PolicyConfigResource());
+        resources.add(new ActivityResource());
+        resources.add(new AccessResource());
+        resources.add(new ScriptResource());
+        resources.add(new ServerResource());
+        resources.add(new UsageResource());
+        resources.add(new VersionResource());
+        return resources;
+    }
+
+    public static Iterable<Object> getApidocResources() {
+        List<Object> resources = new ArrayList<Object>();
+        resources.add(new SwaggerSerializers());
+        resources.add(new ApidocResource());
+        return resources;
+    }
+
+    public static Iterable<Object> getMiscResources() {
+        List<Object> resources = new ArrayList<Object>();
+        resources.add(new DefaultExceptionMapper());
+        resources.add(new BrooklynJacksonJsonProvider());
+        resources.add(new FormMapProvider());
+        return resources;
+    }
+
+    public static Iterable<Object> getAllResources() {
+        return Iterables.concat(getBrooklynRestResources(), 
getApidocResources(), getMiscResources());
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java
new file mode 100644
index 0000000..419715b
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java
@@ -0,0 +1,56 @@
+/*
+ * 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 org.apache.brooklyn.rest;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
+public class BrooklynRestApp extends Application {
+    private Set<Object> singletons;
+
+    public BrooklynRestApp() {
+        singletons = Sets.newHashSet(BrooklynRestApi.getAllResources());
+    }
+
+    public BrooklynRestApp singleton(Object singleton) {
+        singletons.add(singleton);
+        return this;
+    }
+
+    @Override
+    public Set<Object> getSingletons() {
+        return singletons;
+    }
+
+    //Uncomment after removing jersey dependencies
+    //@Override
+    public Map<String, Object> getProperties() {
+        return ImmutableMap.<String, Object>of(
+                // Makes sure that all exceptions are handled by our custom 
DefaultExceptionMapper
+                "default.wae.mapper.least.specific", Boolean.TRUE);
+    }
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
new file mode 100644
index 0000000..69342a0
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java
@@ -0,0 +1,164 @@
+/*
+ * 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 org.apache.brooklyn.rest;
+
+import org.apache.brooklyn.api.location.PortRange;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.config.ConfigMap;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.ConfigPredicates;
+import org.apache.brooklyn.rest.security.provider.DelegatingSecurityProvider;
+import 
org.apache.brooklyn.rest.security.provider.ExplicitUsersSecurityProvider;
+import org.apache.brooklyn.rest.security.provider.SecurityProvider;
+
+public class BrooklynWebConfig {
+
+    public final static String BASE_NAME = "brooklyn.webconsole";
+    public final static String BASE_NAME_SECURITY = BASE_NAME+".security";
+
+    /**
+     * The session attribute set to indicate the remote address of the HTTP 
request.
+     * Corresponds to {@link 
javax.servlet.http.HttpServletRequest#getRemoteAddr()}.
+     */
+    public static final String REMOTE_ADDRESS_SESSION_ATTRIBUTE = 
"request.remoteAddress";
+
+    /**
+     * The security provider to be loaded by {@link 
DelegatingSecurityProvider}.
+     * e.g. 
<code>brooklyn.webconsole.security.provider=org.apache.brooklyn.rest.security.provider.AnyoneSecurityProvider</code>
+     * will allow anyone to log in.
+     */
+    public final static ConfigKey<String> SECURITY_PROVIDER_CLASSNAME = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME_SECURITY+".provider", "class name of a Brooklyn 
SecurityProvider",
+            ExplicitUsersSecurityProvider.class.getCanonicalName());
+    public final static ConfigKey<SecurityProvider> SECURITY_PROVIDER_INSTANCE 
= ConfigKeys.newConfigKey(SecurityProvider.class,
+            SECURITY_PROVIDER_CLASSNAME.getName()+".internal.instance", 
"instance of a pre-configured security provider");
+    
+    /**
+     * Explicitly set the users/passwords, e.g. in brooklyn.properties:
+     * brooklyn.webconsole.security.users=admin,bob
+     * brooklyn.webconsole.security.user.admin.password=password
+     * brooklyn.webconsole.security.user.bob.password=bobspass
+     */
+    public final static ConfigKey<String> USERS = 
ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY+".users");
+
+    public final static ConfigKey<String> PASSWORD_FOR_USER(String user) {
+        return ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY + ".user." + 
user + ".password");
+    }
+    
+    public final static ConfigKey<String> SALT_FOR_USER(String user) {
+        return ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY + ".user." + 
user + ".salt");
+    }
+    
+    public final static ConfigKey<String> SHA256_FOR_USER(String user) {
+        return ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY + ".user." + 
user + ".sha256");
+    }
+    
+    public final static ConfigKey<String> LDAP_URL = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME_SECURITY+".ldap.url");
+
+    public final static ConfigKey<String> LDAP_REALM = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME_SECURITY+".ldap.realm");
+
+    public final static ConfigKey<String> LDAP_OU = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME_SECURITY+".ldap.ou");
+
+    public final static ConfigKey<Boolean> HTTPS_REQUIRED = 
ConfigKeys.newBooleanConfigKey(
+            BASE_NAME+".security.https.required",
+            "Whether HTTPS is required; false here can be overridden by CLI 
option", false); 
+
+    public final static ConfigKey<PortRange> WEB_CONSOLE_PORT = 
ConfigKeys.newConfigKey(PortRange.class,
+        BASE_NAME+".port",
+        "Port/range for the web console to listen on; can be overridden by CLI 
option");
+
+    public final static ConfigKey<String> KEYSTORE_URL = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME+".security.keystore.url",
+            "Keystore from which to take the certificate to present when 
running HTTPS; "
+            + "note that normally the password is also required, and an alias 
for the certificate if the keystore has more than one");
+
+    public final static ConfigKey<String> KEYSTORE_PASSWORD = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME+".security.keystore.password",
+            "Password for the "+KEYSTORE_URL);
+
+    public final static ConfigKey<String> KEYSTORE_CERTIFICATE_ALIAS = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME+".security.keystore.certificate.alias",
+            "Alias in "+KEYSTORE_URL+" for the certificate to use; defaults to 
the first if not supplied");
+
+    public final static ConfigKey<String> TRANSPORT_PROTOCOLS = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME+".security.transport.protocols",
+            "SSL/TLS protocol versions to use for web console connections",
+            "TLSv1, TLSv1.1, TLSv1.2");
+
+    // https://wiki.mozilla.org/Security/Server_Side_TLS (v3.4)
+    // 
http://stackoverflow.com/questions/19846020/how-to-map-a-openssls-cipher-list-to-java-jsse
+    // list created on 05.05.2015, Intermediate config from first link
+    public final static ConfigKey<String> TRANSPORT_CIPHERS = 
ConfigKeys.newStringConfigKey(
+            BASE_NAME+".security.transport.ciphers",
+            "SSL/TLS cipher suites to use for web console connections",
+            
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,"
 +
+            
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,"
 +
+            
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," +
+            
"TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384," +
+            
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,"
 +
+            
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," +
+            
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,"
 +
+            
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," +
+            
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA," +
+            
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," +
+            
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA," +
+            "TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384," 
+
+            "TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256," 
+
+            "TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA," +
+            
"TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA," +
+            
"TLS_SRP_SHA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA256," +
+            
"TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA," +
+            
"TLS_SRP_SHA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA," +
+            
"TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA," +
+            
"TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA," +
+            
"TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA," +
+            "TLS_RSA_WITH_3DES_EDE_CBC_SHA," +
+            // Same as above but with SSL_ prefix, IBM Java compatibility 
(cipher is independent of protocol)
+            // 
https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.security.component.70.doc/security-component/jsse2Docs/ciphersuites.html
+            
"SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256,SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,"
 +
+            
"SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384,SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,"
 +
+            
"SSL_DHE_RSA_WITH_AES_128_GCM_SHA256,SSL_DHE_DSS_WITH_AES_128_GCM_SHA256," +
+            
"SSL_DHE_DSS_WITH_AES_256_GCM_SHA384,SSL_DHE_RSA_WITH_AES_256_GCM_SHA384," +
+            
"SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256,SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,"
 +
+            
"SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA,SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," +
+            
"SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA384,SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,"
 +
+            
"SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA,SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," +
+            
"SSL_DHE_RSA_WITH_AES_128_CBC_SHA256,SSL_DHE_RSA_WITH_AES_128_CBC_SHA," +
+            
"SSL_DHE_DSS_WITH_AES_128_CBC_SHA256,SSL_DHE_RSA_WITH_AES_256_CBC_SHA256," +
+            
"SSL_DHE_DSS_WITH_AES_256_CBC_SHA,SSL_DHE_RSA_WITH_AES_256_CBC_SHA," +
+            "SSL_RSA_WITH_AES_128_GCM_SHA256,SSL_RSA_WITH_AES_256_GCM_SHA384," 
+
+            "SSL_RSA_WITH_AES_128_CBC_SHA256,SSL_RSA_WITH_AES_256_CBC_SHA256," 
+
+            "SSL_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_256_CBC_SHA," +
+            
"SSL_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,SSL_SRP_SHA_RSA_WITH_AES_256_CBC_SHA," +
+            
"SSL_SRP_SHA_WITH_AES_256_CBC_SHA,SSL_DHE_DSS_WITH_AES_256_CBC_SHA256," +
+            
"SSL_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,SSL_SRP_SHA_RSA_WITH_AES_128_CBC_SHA," +
+            
"SSL_SRP_SHA_WITH_AES_128_CBC_SHA,SSL_DHE_DSS_WITH_AES_128_CBC_SHA," +
+            
"SSL_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,SSL_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA," +
+            
"SSL_RSA_WITH_CAMELLIA_256_CBC_SHA,SSL_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA," +
+            
"SSL_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,SSL_RSA_WITH_CAMELLIA_128_CBC_SHA," +
+            "SSL_RSA_WITH_3DES_EDE_CBC_SHA");
+
+    public final static boolean hasNoSecurityOptions(ConfigMap config) {
+        return 
config.submap(ConfigPredicates.nameStartsWith(BASE_NAME_SECURITY)).isEmpty();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
new file mode 100644
index 0000000..13c5cbf
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java
@@ -0,0 +1,159 @@
+/*
+ * 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 org.apache.brooklyn.rest.filter;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ResourceInfo;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
+import org.apache.brooklyn.rest.domain.ApiError;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableSet;
+
+/** 
+ * Checks that if the method or resource class corresponding to a request
+ * has a {@link HaHotStateRequired} annotation,
+ * that the server is in that state (and up). 
+ * Requests with {@link #SKIP_CHECK_HEADER} set as a header skip this check.
+ * <p>
+ * This follows a different pattern to {@link HaMasterCheckFilter} 
+ * as this needs to know the method being invoked. 
+ */
+@Provider
+public class HaHotCheckResourceFilter implements ContainerRequestFilter {
+    public static final String SKIP_CHECK_HEADER = 
"Brooklyn-Allow-Non-Master-Access";
+    
+    private static final Logger log = 
LoggerFactory.getLogger(HaHotCheckResourceFilter.class);
+    
+    private static final Set<ManagementNodeState> HOT_STATES = ImmutableSet.of(
+            ManagementNodeState.MASTER, ManagementNodeState.HOT_STANDBY, 
ManagementNodeState.HOT_BACKUP);
+
+    // Not quite standards compliant. Should instead be:
+    // @Context Providers providers
+    // ....
+    // ContextResolver<ManagementContext> resolver = 
providers.getContextResolver(ManagementContext.class, MediaType.WILDCARD_TYPE)
+    // ManagementContext engine = resolver.get(ManagementContext.class);
+    @Context
+    private ContextResolver<ManagementContext> mgmt;
+
+    @Context
+    private ResourceInfo resourceInfo;
+    
+    public HaHotCheckResourceFilter() {
+    }
+
+    @VisibleForTesting
+    public HaHotCheckResourceFilter(ContextResolver<ManagementContext> mgmt) {
+        this.mgmt = mgmt;
+    }
+
+    private ManagementContext mgmt() {
+        return mgmt.getContext(ManagementContext.class);
+    }
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws 
IOException {
+        String problem = lookForProblem(requestContext);
+        if (Strings.isNonBlank(problem)) {
+            log.warn("Disallowing web request as "+problem+": 
"+requestContext.getUriInfo()+"/"+resourceInfo.getResourceMethod()+" (caller 
should set '"+SKIP_CHECK_HEADER+"' to force)");
+            requestContext.abortWith(ApiError.builder()
+                .message("This request is only permitted against an active hot 
Brooklyn server")
+                
.errorCode(Response.Status.FORBIDDEN).build().asJsonResponse());
+        }
+    }
+
+    private String lookForProblem(ContainerRequestContext requestContext) {
+        if (isSkipCheckHeaderSet(requestContext)) 
+            return null;
+        
+        if (!isHaHotStateRequired())
+            return null;
+        
+        String problem = lookForProblemIfServerNotRunning(mgmt());
+        if (Strings.isNonBlank(problem)) 
+            return problem;
+        
+        if (!isHaHotStatus())
+            return "server not in required HA hot state";
+        if (isStateNotYetValid())
+            return "server not yet completed loading data for required HA hot 
state";
+        
+        return null;
+    }
+    
+    public static String lookForProblemIfServerNotRunning(ManagementContext 
mgmt) {
+        if (mgmt==null) return "no management context available";
+        if (!mgmt.isRunning()) return "server no longer running";
+        if (!mgmt.isStartupComplete()) return "server not in required 
startup-completed state";
+        return null;
+    }
+    
+    // Maybe there should be a separate state to indicate that we have 
switched state
+    // but still haven't finished rebinding. (Previously there was a time 
delay and an
+    // isRebinding check, but introducing 
RebindManager#isAwaitingInitialRebind() seems cleaner.)
+    private boolean isStateNotYetValid() {
+        return mgmt().getRebindManager().isAwaitingInitialRebind();
+    }
+
+    private boolean isHaHotStateRequired() {
+        // TODO support super annotations
+        Method m = resourceInfo.getResourceMethod();
+        return getAnnotation(m, HaHotStateRequired.class) != null;
+    }
+    
+    private <T extends Annotation> T getAnnotation(Method m, Class<T> 
annotation) {
+        T am = m.getAnnotation(annotation);
+        if (am != null) {
+            return am;
+        }
+        Class<?> superClass = m.getDeclaringClass();
+        T ac = superClass.getAnnotation(annotation);
+        if (ac != null) {
+            return ac;
+        }
+        // TODO could look in super classes but not needed now, we are in 
control of where to put the annotation
+        return null;
+    }
+
+    private boolean isSkipCheckHeaderSet(ContainerRequestContext 
requestContext) {
+        return 
"true".equalsIgnoreCase(requestContext.getHeaderString(SKIP_CHECK_HEADER));
+    }
+
+    private boolean isHaHotStatus() {
+        ManagementNodeState state = 
mgmt().getHighAvailabilityManager().getNodeState();
+        return HOT_STATES.contains(state);
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java
new file mode 100644
index 0000000..babfe43
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.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 org.apache.brooklyn.rest.filter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+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})
+@Inherited
+public @interface HaHotStateRequired {}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
new file mode 100644
index 0000000..97fdda1
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java
@@ -0,0 +1,40 @@
+/*
+ * 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 org.apache.brooklyn.rest.filter;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+public class NoCacheFilter implements ContainerResponseFilter {
+
+    @Override
+    public void filter(ContainerRequestContext request, 
ContainerResponseContext response) {
+        //https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ
+        MultivaluedMap<String, Object> headers = response.getHeaders();
+        headers.putSingle(HttpHeaders.CACHE_CONTROL, "no-cache, no-store");
+        headers.putSingle("Pragma", "no-cache");
+        headers.putSingle(HttpHeaders.EXPIRES, "0");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
new file mode 100644
index 0000000..9882eb3
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java
@@ -0,0 +1,156 @@
+/*
+ * 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 org.apache.brooklyn.rest.resources;
+
+import javax.annotation.Nullable;
+import javax.servlet.ServletContext;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.core.config.render.RendererHints;
+import org.apache.brooklyn.core.mgmt.ManagementContextInjectable;
+import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
+import org.apache.brooklyn.rest.util.OsgiCompat;
+import org.apache.brooklyn.rest.util.WebResourceUtils;
+import org.apache.brooklyn.rest.util.json.BrooklynJacksonJsonProvider;
+import org.apache.brooklyn.util.core.task.Tasks;
+import org.apache.brooklyn.util.guava.Maybe;
+import org.apache.brooklyn.util.time.Duration;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public abstract class AbstractBrooklynRestResource implements 
ManagementContextInjectable {
+
+    // can be injected by jersey when ManagementContext in not injected 
manually
+    // (seems there is no way to make this optional so note it _must_ be 
injected;
+    // most of the time that happens for free, but with test framework it 
doesn't,
+    // so we have set up a NullServletContextProvider in our tests) 
+    private @Context ServletContext servletContext;
+
+    protected @Context UriInfo ui;
+
+    
+    private ManagementContext managementContext;
+    private BrooklynRestResourceUtils brooklynRestResourceUtils;
+    private ObjectMapper mapper;
+
+    public ManagementContext mgmt() {
+        return mgmtMaybe().get();
+    }
+    
+    protected synchronized Maybe<ManagementContext> mgmtMaybe() {
+        if (managementContext!=null) return Maybe.of(managementContext);
+        managementContext = OsgiCompat.getManagementContext(servletContext);
+        if (managementContext!=null) return Maybe.of(managementContext);
+        
+        return Maybe.absent("ManagementContext not available for Brooklyn 
Jersey Resource "+this);
+    }
+    
+    @Override
+    public void setManagementContext(ManagementContext managementContext) {
+        if (this.managementContext!=null) {
+            if (this.managementContext.equals(managementContext)) return;
+            throw new IllegalStateException("ManagementContext cannot be 
changed: specified twice for Brooklyn Jersey Resource "+this);
+        }
+        this.managementContext = managementContext;
+    }
+
+    public synchronized BrooklynRestResourceUtils brooklyn() {
+        if (brooklynRestResourceUtils!=null) return brooklynRestResourceUtils;
+        brooklynRestResourceUtils = new BrooklynRestResourceUtils(mgmt());
+        return brooklynRestResourceUtils;
+    }
+    
+    protected ObjectMapper mapper() {
+        if (mapper==null)
+            mapper = 
BrooklynJacksonJsonProvider.findAnyObjectMapper(servletContext, 
managementContext);
+        return mapper;
+    }
+
+    /** @deprecated since 0.7.0 use {@link #getValueForDisplay(Object, 
boolean, boolean, Boolean, EntityLocal, Duration)} */ @Deprecated
+    protected Object getValueForDisplay(Object value, boolean preferJson, 
boolean isJerseyReturnValue) {
+        return 
resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(isJerseyReturnValue).resolve();
+    }
+
+    protected RestValueResolver resolving(Object v) {
+        return new RestValueResolver(v).mapper(mapper());
+    }
+
+    public static class RestValueResolver {
+        final private Object valueToResolve;
+        private @Nullable ObjectMapper mapper;
+        private boolean preferJson;
+        private boolean isJerseyReturnValue;
+        private @Nullable Boolean raw; 
+        private @Nullable Entity entity;
+        private @Nullable Duration timeout;
+        private @Nullable Object rendererHintSource;
+        
+        public static RestValueResolver resolving(Object v) { return new 
RestValueResolver(v); }
+        
+        private RestValueResolver(Object v) { valueToResolve = v; }
+        
+        public RestValueResolver mapper(ObjectMapper mapper) { this.mapper = 
mapper; return this; }
+        
+        /** whether JSON is the ultimate product; 
+         * main effect here is to give null for null if true, else to give 
empty string 
+         * <p>
+         * conversion to JSON for complex types is done subsequently (often by 
the framework)
+         * <p>
+         * default is true */
+        public RestValueResolver preferJson(boolean preferJson) { 
this.preferJson = preferJson; return this; }
+        /** whether an outermost string must be wrapped in quotes, because a 
String return object is treated as
+         * already JSON-encoded
+         * <p>
+         * default is false */
+        public RestValueResolver asJerseyOutermostReturnValue(boolean 
asJerseyReturnJson) {
+            isJerseyReturnValue = asJerseyReturnJson;
+            return this;
+        }
+        public RestValueResolver raw(Boolean raw) { this.raw = raw; return 
this; }
+        public RestValueResolver context(Entity entity) { this.entity = 
entity; return this; }
+        public RestValueResolver timeout(Duration timeout) { this.timeout = 
timeout; return this; }
+        public RestValueResolver renderAs(Object rendererHintSource) { 
this.rendererHintSource = rendererHintSource; return this; }
+
+        public Object resolve() {
+            Object valueResult = getImmediateValue(valueToResolve, entity, 
timeout);
+            if (valueResult==UNRESOLVED) valueResult = valueToResolve;
+            if (rendererHintSource!=null && Boolean.FALSE.equals(raw)) {
+                valueResult = 
RendererHints.applyDisplayValueHintUnchecked(rendererHintSource, valueResult);
+            }
+            return WebResourceUtils.getValueForDisplay(mapper, valueResult, 
preferJson, isJerseyReturnValue);
+        }
+        
+        private static Object UNRESOLVED = "UNRESOLVED".toCharArray();
+        
+        private static Object getImmediateValue(Object value, @Nullable Entity 
context, @Nullable Duration timeout) {
+            return Tasks.resolving(value)
+                    .as(Object.class)
+                    .defaultValue(UNRESOLVED)
+                    .timeout(timeout)
+                    .context(context)
+                    .swallowExceptions()
+                    .get();
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java
new file mode 100644
index 0000000..bb40edf
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java
@@ -0,0 +1,46 @@
+/*
+ * 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 org.apache.brooklyn.rest.resources;
+
+import javax.ws.rs.core.Response;
+
+import org.apache.brooklyn.core.mgmt.internal.AccessManager;
+import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
+import org.apache.brooklyn.rest.api.AccessApi;
+import org.apache.brooklyn.rest.domain.AccessSummary;
+import org.apache.brooklyn.rest.transform.AccessTransformer;
+
+import com.google.common.annotations.Beta;
+
+@Beta
+public class AccessResource extends AbstractBrooklynRestResource implements 
AccessApi {
+
+    @Override
+    public AccessSummary get() {
+        AccessManager accessManager = ((ManagementContextInternal) 
mgmt()).getAccessManager();
+        return AccessTransformer.accessSummary(accessManager, 
ui.getBaseUriBuilder());
+    }
+
+    @Override
+    public Response locationProvisioningAllowed(boolean allowed) {
+        AccessManager accessManager = ((ManagementContextInternal) 
mgmt()).getAccessManager();
+        accessManager.setLocationProvisioningAllowed(allowed);
+        return Response.status(Response.Status.OK).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java
new file mode 100644
index 0000000..f29827b
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java
@@ -0,0 +1,99 @@
+/*
+ * 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 org.apache.brooklyn.rest.resources;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.mgmt.HasTaskChildren;
+import org.apache.brooklyn.api.mgmt.Task;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
+import org.apache.brooklyn.core.mgmt.BrooklynTaskTags.WrappedStream;
+import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
+import org.apache.brooklyn.rest.api.ActivityApi;
+import org.apache.brooklyn.rest.domain.TaskSummary;
+import org.apache.brooklyn.rest.transform.TaskTransformer;
+import org.apache.brooklyn.rest.util.WebResourceUtils;
+
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Lists;
+
+public class ActivityResource extends AbstractBrooklynRestResource implements 
ActivityApi {
+
+    @Override
+    public TaskSummary get(String taskId) {
+        Task<?> t = mgmt().getExecutionManager().getTask(taskId);
+        if (t == null) {
+            throw WebResourceUtils.notFound("Cannot find task '%s'", taskId);
+        }
+        checkEntityEntitled(t);
+
+        return TaskTransformer.fromTask(ui.getBaseUriBuilder()).apply(t);
+    }
+
+    @Override
+    public List<TaskSummary> children(String taskId) {
+        Task<?> t = mgmt().getExecutionManager().getTask(taskId);
+        if (t == null) {
+            throw WebResourceUtils.notFound("Cannot find task '%s'", taskId);
+        }
+        checkEntityEntitled(t);
+        
+        if (!(t instanceof HasTaskChildren)) {
+            return Collections.emptyList();
+        }
+        return new 
LinkedList<TaskSummary>(Collections2.transform(Lists.newArrayList(((HasTaskChildren)
 t).getChildren()),
+                TaskTransformer.fromTask(ui.getBaseUriBuilder())));
+    }
+
+    @Override
+    public String stream(String taskId, String streamId) {
+        Task<?> t = mgmt().getExecutionManager().getTask(taskId);
+        if (t == null) {
+            throw WebResourceUtils.notFound("Cannot find task '%s'", taskId);
+        }
+        checkEntityEntitled(t);
+        checkStreamEntitled(t, streamId);
+        
+        WrappedStream stream = BrooklynTaskTags.stream(t, streamId);
+        if (stream == null) {
+            throw WebResourceUtils.notFound("Cannot find stream '%s' in task 
'%s'", streamId, taskId);
+        }
+        return stream.streamContents.get();
+    }
+    
+    protected void checkEntityEntitled(Task<?> task) {
+        Entity entity = BrooklynTaskTags.getContextEntity(task);
+        if (entity != null && 
!Entitlements.isEntitled(mgmt().getEntitlementManager(), 
Entitlements.SEE_ENTITY, entity)) {
+            throw WebResourceUtils.forbidden("User '%s' is not authorized to 
see activity of entity '%s'",
+                    Entitlements.getEntitlementContext().user(), entity);
+        }
+    }
+    
+    protected void checkStreamEntitled(Task<?> task, String streamId) {
+        Entity entity = BrooklynTaskTags.getContextEntity(task);
+        Entitlements.TaskAndItem<String> item = new 
Entitlements.TaskAndItem<String>(task, streamId);
+        if (entity != null && 
!Entitlements.isEntitled(mgmt().getEntitlementManager(), 
Entitlements.SEE_ACTIVITY_STREAMS, item)) {
+            throw WebResourceUtils.forbidden("User '%s' is not authorized to 
see activity stream of entity '%s'",
+                    Entitlements.getEntitlementContext().user(), entity);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java
----------------------------------------------------------------------
diff --git 
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java
 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java
new file mode 100644
index 0000000..220e4e3
--- /dev/null
+++ 
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.brooklyn.rest.resources;
+
+
+import javax.ws.rs.Path;
+
+import org.apache.brooklyn.rest.apidoc.ApiListingResource;
+
+import io.swagger.annotations.Api;
+
+/**
+ * @author Ciprian Ciubotariu <cheepe...@gmx.net>
+ */
+@Api("API Documentation")
+@Path("/apidoc")
+public class ApidocResource extends ApiListingResource {
+
+}

Reply via email to