brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hadr...@apache.org
Subject [22/28] incubator-brooklyn git commit: brooklyn-rest-api: add org.apache package prefix
Date Sun, 09 Aug 2015 02:55:29 GMT
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
new file mode 100644
index 0000000..d2e86b0
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/CatalogApi.java
@@ -0,0 +1,325 @@
+/*
+ * 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.api;
+
+import java.io.InputStream;
+import java.util.List;
+
+import javax.validation.Valid;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.CatalogEntitySummary;
+import org.apache.brooklyn.rest.domain.CatalogItemSummary;
+import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
+import org.apache.brooklyn.rest.domain.CatalogPolicySummary;
+
+import com.sun.jersey.core.header.FormDataContentDisposition;
+import com.sun.jersey.multipart.FormDataParam;
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+@Path("/v1/catalog")
+@Apidoc("Catalog")
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public interface CatalogApi {
+
+    @POST
+    @ApiOperation(value = "Add a catalog item (e.g. new type of entity, policy or location) by uploading YAML descriptor from browser using multipart/form-data",
+        responseClass = "String")
+    @Consumes(MediaType.MULTIPART_FORM_DATA)
+    public Response createFromMultipart(
+        @ApiParam(name = "yaml", value = "multipart/form-data file input field")
+        @FormDataParam("yaml") InputStream uploadedInputStream,
+        @FormDataParam("yaml") FormDataContentDisposition fileDetail);
+
+    @Consumes
+    @POST
+    @ApiOperation(value = "Add a catalog item (e.g. new type of entity, policy or location) by uploading YAML descriptor "
+        + "Return value is map of ID to CatalogItemSummary, with code 201 CREATED.", responseClass = "Response")
+    public Response create(
+            @ApiParam(name = "yaml", value = "YAML descriptor of catalog item", required = true)
+            @Valid String yaml);
+
+    @POST
+    @Consumes(MediaType.APPLICATION_XML)
+    @Path("/reset")
+    @ApiOperation(value = "Resets the catalog to the given (XML) format")
+    public Response resetXml(
+            @ApiParam(name = "xml", value = "XML descriptor of the entire catalog to install", required = true)
+            @Valid String xml,
+            @ApiParam(name ="ignoreErrors", value ="Don't fail on invalid bundles, log the errors only")
+            @QueryParam("ignoreErrors")  @DefaultValue("false")
+            boolean ignoreErrors);
+
+    /** @deprecated since 0.7.0 use {@link #deleteEntity(String, String)} */
+    @Deprecated
+    @DELETE
+    @Path("/entities/{entityId}")
+    @ApiOperation(value = "Deletes a specific version of an entity's definition from the catalog")
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public void deleteEntity(
+        @ApiParam(name = "entityId", value = "The ID of the entity or template to delete", required = true)
+        @PathParam("entityId") String entityId) throws Exception;
+
+    @DELETE
+    @Path("/applications/{symbolicName}/{version}")
+    @ApiOperation(value = "Deletes a specific version of an application's definition from the catalog")
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public void deleteApplication(
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the application or template to delete", required = true)
+        @PathParam("symbolicName") String symbolicName,
+
+        @ApiParam(name = "version", value = "The version identifier of the application or template to delete", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    @DELETE
+    @Path("/entities/{symbolicName}/{version}")
+    @ApiOperation(value = "Deletes a specific version of an entity's definition from the catalog")
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public void deleteEntity(
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the entity or template to delete", required = true)
+        @PathParam("symbolicName") String symbolicName,
+
+        @ApiParam(name = "version", value = "The version identifier of the entity or template to delete", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    @DELETE
+    @Path("/policies/{policyId}/{version}")
+    @ApiOperation(value = "Deletes a specific version of an policy's definition from the catalog")
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Policy not found")
+    })
+    public void deletePolicy(
+        @ApiParam(name = "policyId", value = "The ID of the policy to delete", required = true)
+        @PathParam("policyId") String policyId,
+
+        @ApiParam(name = "version", value = "The version identifier of the policy to delete", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    @DELETE
+    @Path("/locations/{locationId}/{version}")
+    @ApiOperation(value = "Deletes a specific version of an location's definition from the catalog")
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Location not found")
+    })
+    public void deleteLocation(
+        @ApiParam(name = "locationId", value = "The ID of the location to delete", required = true)
+        @PathParam("locationId") String locationId,
+
+        @ApiParam(name = "version", value = "The version identifier of the location to delete", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    @GET
+    @Path("/entities")
+    @ApiOperation(value = "List available entity types optionally matching a query", responseClass = "CatalogItemSummary", multiValueResponse = true)
+    public List<CatalogEntitySummary> listEntities(
+        @ApiParam(name = "regex", value = "Regular expression to search for")
+        @QueryParam("regex") @DefaultValue("") String regex,
+        @ApiParam(name = "fragment", value = "Substring case-insensitive to search for")
+        @QueryParam("fragment") @DefaultValue("") String fragment,
+        @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)")
+        @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions);
+
+    @GET
+    @Path("/applications")
+    @ApiOperation(value = "Fetch a list of application templates optionally matching a query", responseClass = "CatalogItemSummary", multiValueResponse = true)
+    public List<CatalogItemSummary> listApplications(
+            @ApiParam(name = "regex", value = "Regular expression to search for")
+            @QueryParam("regex") @DefaultValue("") String regex,
+            @ApiParam(name = "fragment", value = "Substring case-insensitive to search for")
+            @QueryParam("fragment") @DefaultValue("") String fragment,
+            @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)")
+            @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions);
+
+    /** @deprecated since 0.7.0 use {@link #getEntity(String, String)} */
+    @Deprecated
+    @GET
+    @Path("/entities/{entityId}")
+    @ApiOperation(value = "Fetch an entity's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogEntitySummary getEntity(
+        @ApiParam(name = "entityId", value = "The ID of the entity or template to retrieve", required = true)
+        @PathParam("entityId") String entityId) throws Exception;
+
+    @GET
+    @Path("/entities/{symbolicName}/{version}")
+    @ApiOperation(value = "Fetch a specific version of an entity's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogEntitySummary getEntity(
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the entity or template to retrieve", required = true)
+        @PathParam("symbolicName") String symbolicName,
+
+        @ApiParam(name = "version", value = "The version identifier of the entity or template to retrieve", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    /** @deprecated since 0.7.0 use {@link #getEntity(String, String)} */
+    @Deprecated
+    @GET
+    @Path("/applications/{applicationId}")
+    @ApiOperation(value = "Fetch a specific version of an application's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogEntitySummary getApplication(
+        @ApiParam(name = "applicationId", value = "The ID of the application to retrieve", required = true)
+        @PathParam("applicationId") String applicationId) throws Exception;
+
+    @GET
+    @Path("/applications/{symbolicName}/{version}")
+    @ApiOperation(value = "Fetch a specific version of an application's definition from the catalog", responseClass = "CatalogEntitySummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogEntitySummary getApplication(
+        @ApiParam(name = "symbolicName", value = "The symbolic name of the application to retrieve", required = true)
+        @PathParam("symbolicName") String symbolicName,
+
+        @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    @GET
+    @Path("/policies")
+    @ApiOperation(value = "List available policies optionally matching a query", responseClass = "CatalogPolicySummary", multiValueResponse = true)
+    public List<CatalogPolicySummary> listPolicies(
+            @ApiParam(name = "regex", value = "Regular expression to search for")
+            @QueryParam("regex") @DefaultValue("") String regex,
+            @ApiParam(name = "fragment", value = "Substring case-insensitive to search for")
+            @QueryParam("fragment") @DefaultValue("") String fragment,
+            @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)")
+            @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions);
+
+    /** @deprecated since 0.7.0 use {@link #getPolicy(String, String)} */
+    @Deprecated
+    @GET
+    @Path("/policies/{policyId}")
+    @ApiOperation(value = "Fetch a policy's definition from the catalog", responseClass = "CatalogItemSummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogItemSummary getPolicy(
+        @ApiParam(name = "policyId", value = "The ID of the policy to retrieve", required = true)
+        @PathParam("policyId") String policyId) throws Exception;
+
+    @GET
+    @Path("/policies/{policyId}/{version}")
+    @ApiOperation(value = "Fetch a policy's definition from the catalog", responseClass = "CatalogItemSummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogItemSummary getPolicy(
+        @ApiParam(name = "policyId", value = "The ID of the policy to retrieve", required = true)
+        @PathParam("policyId") String policyId,
+        @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    @GET
+    @Path("/locations")
+    @ApiOperation(value = "List available locations optionally matching a query", responseClass = "CatalogLocationSummary", multiValueResponse = true)
+    public List<CatalogLocationSummary> listLocations(
+            @ApiParam(name = "regex", value = "Regular expression to search for")
+            @QueryParam("regex") @DefaultValue("") String regex,
+            @ApiParam(name = "fragment", value = "Substring case-insensitive to search for")
+            @QueryParam("fragment") @DefaultValue("") String fragment,
+            @ApiParam(name = "allVersions", value = "Include all versions (defaults false, only returning the best version)")
+            @QueryParam("allVersions") @DefaultValue("false") boolean includeAllVersions);
+
+    /** @deprecated since 0.7.0 use {@link #getLocation(String, String)} */
+    @Deprecated
+    @GET
+    @Path("/locations/{locationId}")
+    @ApiOperation(value = "Fetch a location's definition from the catalog", responseClass = "CatalogItemSummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogItemSummary getLocation(
+        @ApiParam(name = "locationId", value = "The ID of the location to retrieve", required = true)
+        @PathParam("locationId") String locationId) throws Exception;
+
+    @GET
+    @Path("/locations/{locationId}/{version}")
+    @ApiOperation(value = "Fetch a location's definition from the catalog", responseClass = "CatalogItemSummary", multiValueResponse = true)
+    @ApiErrors(value = {
+        @ApiError(code = 404, reason = "Entity not found")
+    })
+    public CatalogItemSummary getLocation(
+        @ApiParam(name = "locationId", value = "The ID of the location to retrieve", required = true)
+        @PathParam("locationId") String locationId,
+        @ApiParam(name = "version", value = "The version identifier of the application to retrieve", required = true)
+        @PathParam("version") String version) throws Exception;
+
+    /** @deprecated since 0.7.0 use {@link #getIcon(String, String)} */
+    @Deprecated
+    @GET
+    @Path("/icon/{itemId}")
+    @ApiOperation(value = "Return the icon for a given catalog entry (application/image or HTTP redirect)")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Item not found")
+        })
+    @Produces("application/image")
+    public Response getIcon(
+        @ApiParam(name = "itemId", value = "ID of catalog item (application, entity, policy, location)")
+        @PathParam("itemId") @DefaultValue("") String itemId);
+
+    @GET
+    @Path("/icon/{itemId}/{version}")
+    @ApiOperation(value = "Return the icon for a given catalog entry (application/image or HTTP redirect)")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Item not found")
+        })
+    @Produces("application/image")
+    public Response getIcon(
+        @ApiParam(name = "itemId", value = "ID of catalog item (application, entity, policy, location)", required=true)
+        @PathParam("itemId") String itemId,
+
+        @ApiParam(name = "version", value = "version identifier of catalog item (application, entity, policy, location)", required=true)
+        @PathParam("version") String version);
+
+    @POST
+    @Path("/entities/{itemId}/deprecated/{deprecated}")
+    public void setDeprecated(
+        @ApiParam(name = "itemId", value = "The ID of the catalog item to be deprecated", required = true)
+        @PathParam("itemId") String itemId,
+        @ApiParam(name = "deprecated", value = "Whether or not the catalog item is deprecated", required = true)
+        @PathParam("deprecated") boolean deprecated);
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EffectorApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EffectorApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EffectorApi.java
new file mode 100644
index 0000000..79a5e66
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EffectorApi.java
@@ -0,0 +1,85 @@
+/*
+ * 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.api;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.EffectorSummary;
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+import javax.validation.Valid;
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Map;
+
+@Path("/v1/applications/{application}/entities/{entity}/effectors")
+@Apidoc("Entity Effectors")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface EffectorApi {
+
+    @GET
+    @ApiOperation(value = "Fetch the list of effectors",
+            responseClass = "org.apache.brooklyn.rest.domain.EffectorSummary",
+            multiValueResponse = true)
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    public List<EffectorSummary> list(
+            @ApiParam(name = "application", value = "Application name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(name = "entity", value = "Entity name", required = true)
+            @PathParam("entity") final String entityToken);
+
+    @POST
+    @Path("/{effector}")
+    @ApiOperation(value = "Trigger an effector",
+            notes="Returns the return value (status 200) if it completes, or an activity task ID (status 202) if it times out")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or effector")
+    })
+    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_FORM_URLENCODED})
+    public Response invoke(
+            @ApiParam(name = "application", value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            
+            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            
+            @ApiParam(name = "effector", value = "Name of the effector to trigger", required = true)
+            @PathParam("effector") String effectorName,
+            
+            // TODO test timeout; and should it be header, form, or what?
+            @ApiParam(name = "timeout", value = "Delay before server should respond with activity task ID rather than result (in millis if no unit specified): " +
+                    "'never' (blocking) is default; " +
+                    "'0' means 'always' return task activity ID; " +
+                    "and e.g. '1000' or '1s' will return a result if available within one second otherwise status 202 and the activity task ID", 
+                    required = false, defaultValue = "never")
+            @QueryParam("timeout")
+            String timeout,
+            
+            @ApiParam(/* FIXME: giving a `name` in swagger @ApiParam seems wrong as this object is the body, not a named argument */ name = "parameters",
+                    value = "Effector parameters (as key value pairs)", required = false)
+            @Valid 
+            Map<String, Object> parameters);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
new file mode 100644
index 0000000..431ffec
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityApi.java
@@ -0,0 +1,235 @@
+/*
+ * 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.api;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.EntitySummary;
+import org.apache.brooklyn.rest.domain.LocationSummary;
+import org.apache.brooklyn.rest.domain.TaskSummary;
+
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import java.util.List;
+import java.util.Map;
+
+@Path("/v1/applications/{application}/entities")
+@Apidoc("Entities")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface EntityApi {
+
+    @GET
+    @ApiOperation(value = "Fetch the list of entities for a given application",
+            responseClass = "org.apache.brooklyn.rest.domain.EntitySummary",
+            multiValueResponse = true)
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application not found")
+    })
+    public List<EntitySummary> list(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application) ;
+
+    @GET
+    @Path("/{entity}")
+    @ApiOperation(value = "Fetch details about a specific application entity",
+            responseClass = "org.apache.brooklyn.rest.domain.EntitySummary")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application or entity missing")
+    })
+    public EntitySummary get(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entity);
+
+    // TODO rename as "/children" ?
+    @GET
+    @ApiOperation(value = "Fetch details about a specific application entity's children",
+            responseClass = "org.apache.brooklyn.rest.domain.EntitySummary")
+    @Path("/{entity}/children")
+    public List<EntitySummary> getChildren(
+            @PathParam("application") final String application,
+            @PathParam("entity") final String entity);
+
+    /** @deprecated since 0.7.0 use /children */
+    @Deprecated
+    @Path("/{entity}/entities")
+    public List<EntitySummary> getChildrenOld(
+            @PathParam("application") final String application,
+            @PathParam("entity") final String entity);
+
+    @POST
+    @ApiOperation(value = "Add a child or children to this entity given a YAML spec",
+            responseClass = "org.apache.brooklyn.rest.domain.TaskSummary")
+    @Consumes({"application/x-yaml",
+            // see http://stackoverflow.com/questions/332129/yaml-mime-type
+            "text/yaml", "text/x-yaml", "application/yaml", MediaType.APPLICATION_JSON})
+    @Path("/{entity}/children")
+    public Response addChildren(
+            @PathParam("application") final String application,
+            @PathParam("entity") final String entity,
+
+            @ApiParam(
+                    name = "start",
+                    value = "Whether to automatically start this child; if omitted, true for Startable entities")
+            @QueryParam("start") final Boolean start,
+
+            @ApiParam(name = "timeout", value = "Delay before server should respond with incomplete activity task, rather than completed task: " +
+                    "'never' means block until complete; " +
+                    "'0' means return task immediately; " +
+                    "and e.g. '20ms' (the default) will wait 20ms for completed task information to be available", 
+                    required = false, defaultValue = "20ms")
+            @QueryParam("timeout") final String timeout,
+
+            @ApiParam(
+                    name = "childrenSpec",
+                    value = "Entity spec in CAMP YAML format (including 'services' root element)",
+                    required = true)
+            String yaml);
+
+    @GET
+    @Path("/{entity}/activities")
+    @ApiOperation(value = "Fetch list of tasks for this entity")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    public List<TaskSummary> listTasks(
+            @ApiParam(value = "Entity ID or name", required = true) @PathParam("application") String applicationId,
+            @ApiParam(value = "Application ID or name", required = true) @PathParam("entity") String entityId);
+
+    @GET
+    @Path("/{entity}/activities/{task}")
+    @ApiOperation(value = "Fetch task details", responseClass = "org.apache.brooklyn.rest.domain.TaskSummary")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or task")
+    })
+    @Produces("text/json")
+    public TaskSummary getTask(
+            @ApiParam(value = "Application ID or name", required = true) @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true) @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Task ID", required = true) @PathParam("task") String taskId);
+
+    @GET
+    @ApiOperation(value = "Returns an icon for the entity, if defined")
+    @Path("/{entity}/icon")
+    public Response getIcon(
+            @PathParam("application") final String application,
+            @PathParam("entity") final String entity);
+
+    @GET
+    @Path("/{entity}/tags")
+    @ApiOperation(value = "Fetch list of tags on this entity")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    public List<Object> listTags(
+            @ApiParam(value = "Entity ID or name", required = true) @PathParam("application") String applicationId,
+            @ApiParam(value = "Application ID or name", required = true) @PathParam("entity") String entityId);
+
+    @POST
+    @ApiOperation(
+            value = "Rename an entity"
+    )
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Undefined application or entity")
+    })
+    @Path("/{entity}/name")
+    public Response rename(
+            @ApiParam(value = "Application ID or name", required = true) @PathParam("application") final String applicationId, 
+            @ApiParam(value = "Entity ID or name", required = true) @PathParam("entity") final String entityId, 
+            @ApiParam(value = "New name for this entity", required = true) @QueryParam("name") final String name);
+
+    @POST
+    @ApiOperation(
+            value = "Expunge an entity",
+            responseClass = "org.apache.brooklyn.rest.domain.TaskSummary"
+    )
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Undefined application or entity")
+    })
+    @Path("/{entity}/expunge")
+    public Response expunge(
+            @ApiParam(value = "Application ID or name", required = true) @PathParam("application") final String applicationId, 
+            @ApiParam(value = "Entity ID or name", required = true) @PathParam("entity") final String entityId, 
+            @ApiParam(value = "Whether to gracefully release all resources", required = true) @QueryParam("release") final boolean release);
+
+    @GET
+    @Path("/{entity}/descendants")
+    @ApiOperation(value = "Fetch entity info for all (or filtered) descendants",
+            responseClass = "org.apache.brooklyn.rest.domain.EntitySummary")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application or entity missing")
+    })
+    public List<EntitySummary> getDescendants(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entity,
+            @ApiParam(value="Regular expression for an entity type which must be matched", required=false)
+            @DefaultValue(".*")
+            @QueryParam("typeRegex") String typeRegex);
+
+    @GET
+    @Path("/{entity}/descendants/sensor/{sensor}")
+    @ApiOperation(value = "Fetch values of a given sensor for all (or filtered) descendants")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application or entity missing")
+    })
+    public Map<String,Object> getDescendantsSensor(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entity,
+            @ApiParam(value = "Sensor name", required = true)
+            @PathParam("sensor") String sensor,
+            @ApiParam(value="Regular expression applied to filter descendant entities based on their type", required=false)
+            @DefaultValue(".*")
+            @QueryParam("typeRegex") String typeRegex);
+
+    @GET
+    @Path("/{entity}/locations")
+    @ApiOperation(value = "List the locations set on the entity")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application or entity missing")
+    })
+    public List<LocationSummary> getLocations(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entity);
+
+    @GET
+    @Path("/{entity}/spec")
+    @ApiOperation(value = "Get the YAML spec used to create the entity, if available")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application or entity missing")
+    })
+    public String getSpec(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entity);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
new file mode 100644
index 0000000..b74ea28
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/EntityConfigApi.java
@@ -0,0 +1,145 @@
+/*
+ * 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.api;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.EntityConfigSummary;
+
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+@Path("/v1/applications/{application}/entities/{entity}/config")
+@Apidoc("Entity Config")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface EntityConfigApi {
+
+    @GET
+    @ApiOperation(value = "Fetch the config keys for a specific application entity",
+            responseClass = "org.apache.brooklyn.rest.domain.ConfigSummary",
+            multiValueResponse = true)
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    public List<EntityConfigSummary> list(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken);
+
+    // TODO support parameters  ?show=value,summary&name=xxx &format={string,json,xml}
+    // (and in sensors class)
+    @GET
+    @Path("/current-state")
+    @ApiOperation(value = "Fetch config key values in batch", notes="Returns a map of config name to value")
+    public Map<String, Object> batchConfigRead(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Return raw config data instead of display values", required = false)
+            @QueryParam("raw") @DefaultValue("false") final Boolean raw);
+
+    //To call this endpoint set the Accept request field e.g curl -H "Accept: application/json" ...
+    @GET
+    @Path("/{config}")
+    @ApiOperation(value = "Fetch config value (json)", responseClass = "Object")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or config key")
+    })
+    @Produces(MediaType.APPLICATION_JSON)
+    public Object get(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Config key ID", required = true)
+            @PathParam("config") String configKeyName,
+            @ApiParam(value = "Return raw config data instead of display values", required = false)
+            @QueryParam("raw") @DefaultValue("false") final Boolean raw);
+
+    // if user requests plain value we skip some json post-processing
+    @GET
+    @Path("/{config}")
+    @ApiOperation(value = "Fetch config value (text/plain)", responseClass = "Object")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or config key")
+    })
+    @Produces(MediaType.TEXT_PLAIN)
+    public String getPlain(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Config key ID", required = true)
+            @PathParam("config") String configKeyName,
+            @ApiParam(value = "Return raw config data instead of display values", required = false)
+            @QueryParam("raw") @DefaultValue("false") final Boolean raw);
+
+    @POST
+    @ApiOperation(value = "Manually set multiple config values")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    @SuppressWarnings("rawtypes")
+    public void setFromMap(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Apply the config to all pre-existing descendants", required = false)
+            @QueryParam("recurse") @DefaultValue("false") final Boolean recurse,
+            @ApiParam(value = "Map of config key names to values", required = true)
+            Map newValues);
+
+    @POST
+    @Path("/{config}")
+    @ApiOperation(value = "Manually set a config value")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or config key")
+    })
+    public void set(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Config key name", required = true)
+            @PathParam("config") String configName,
+            @ApiParam(value = "Apply the config to all pre-existing descendants", required = false)
+            @QueryParam("recurse") @DefaultValue("false") final Boolean recurse,
+            @ApiParam(value = "Value to set")
+            Object newValue);
+
+    // deletion of config is not supported; you can set it null
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/LocationApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/LocationApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/LocationApi.java
new file mode 100644
index 0000000..d41d0a2
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/LocationApi.java
@@ -0,0 +1,101 @@
+/*
+ * 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.api;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.validation.Valid;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.LocationSpec;
+import org.apache.brooklyn.rest.domain.LocationSummary;
+
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+@SuppressWarnings("deprecation")
+@Path("/v1/locations")
+@Apidoc("Locations")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface LocationApi {
+
+    /**
+     * @deprecated since 0.7.0; use {@link CatalogApi#listLocations(String, String)}
+     */
+    @GET
+    @ApiOperation(value = "Fetch the list of location definitions",
+            responseClass = "org.apache.brooklyn.rest.domain.LocationSummary",
+            multiValueResponse = true)
+    @Deprecated
+    public List<LocationSummary> list();
+
+    // this is here to support the web GUI's circles
+    @GET
+    @Path("/usage/LocatedLocations")
+    @ApiOperation(value = "Return a summary of all usage", notes="interim API, expected to change")
+    public Map<String,Map<String,Object>> getLocatedLocations();
+
+    /**
+     * WARNING: behaviour will change in a future release; this will only return location instances.
+     * See {@link CatalogApi#getLocation(String, String)} for retrieving location definitions.
+     */
+    @GET
+    @Path("/{locationId}")
+    @ApiOperation(value = "Fetch details about a location instance, or a location definition",
+            responseClass = "org.apache.brooklyn.rest.domain.LocationSummary",
+            multiValueResponse = true)
+    public LocationSummary get(
+            @ApiParam(value = "Location id to fetch", required = true)
+            @PathParam("locationId") String locationId,
+            @ApiParam(value = "Whether full (inherited) config should be compiled", required = false)
+            @DefaultValue("false")
+            @QueryParam("full") String fullConfig);
+
+    /** @deprecated since 0.7.0 use {@link CatalogApi#create(String)} with a location definition */
+    @POST
+    @ApiOperation(value = "Create a new location definition", responseClass = "String")
+    @Deprecated
+    public Response create(
+            @ApiParam(name = "locationSpec", value = "Location specification object", required = true)
+            @Valid LocationSpec locationSpec);
+
+    /**
+     * @deprecated since 0.7.0; use {@link CatalogApi#deleteLocation(String, String)}
+     */
+    @DELETE
+    @Path("/{locationId}")
+    @ApiOperation(value = "Deletes a location definition by id")
+    @Deprecated
+    public void delete(
+            @ApiParam(value = "Location id to delete", required = true)
+            @PathParam("locationId") String locationId);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
new file mode 100644
index 0000000..8c9713b
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyApi.java
@@ -0,0 +1,151 @@
+/*
+ * 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.api;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.PolicySummary;
+import org.apache.brooklyn.rest.domain.Status;
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Map;
+
+@Path("/v1/applications/{application}/entities/{entity}/policies")
+@Apidoc("Entity Policies")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface PolicyApi {
+    
+    @GET
+    @ApiOperation(value = "Fetch the policies attached to a specific application entity",
+            responseClass = "org.apache.brooklyn.rest.domain.PolicySummary",
+            multiValueResponse = true)
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    public List<PolicySummary> list(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken);
+
+    // TODO support parameters  ?show=value,summary&name=xxx
+    // (and in sensors class)
+    @GET
+    @Path("/current-state")
+    @ApiOperation(value = "Fetch policy states in batch", notes="Returns a map of policy ID to whether it is active")
+    // FIXME method name -- this is nothing to do with config!
+    public Map<String, Boolean> batchConfigRead(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken) ;
+
+    @POST
+    @ApiOperation(value = "Add a policy", notes = "Returns a summary of the new policy")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity"),
+            @ApiError(code = 400, reason = "Type is not a class implementing Policy")
+    })
+    public PolicySummary addPolicy(
+            @ApiParam(name = "application", value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+
+            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+
+            @ApiParam(name = "policyType", value = "Class of policy to add", required = true)
+            @QueryParam("type")
+            String policyTypeName,
+
+            // TODO would like to make this optional but jersey complains if we do
+            @ApiParam(name = "config", value = "Configuration for the policy (as key value pairs)", required = true)
+            Map<String, String> config);
+
+    @GET
+    @Path("/{policy}")
+    @ApiOperation(value = "Gets status of a policy (RUNNING / SUSPENDED)")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or policy")
+    })
+    public Status getStatus(
+            @ApiParam(name = "application", value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+
+            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+
+            @ApiParam(name = "policy", value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyId);
+
+    @POST
+    @Path("/{policy}/start")
+    @ApiOperation(value = "Start or resume a policy")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or policy")
+    })
+    public Response start(
+            @ApiParam(name = "application", value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+
+            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+
+            @ApiParam(name = "policy", value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyId);
+
+    @POST
+    @Path("/{policy}/stop")
+    @ApiOperation(value = "Suspends a policy")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or policy")
+    })
+    public Response stop(
+            @ApiParam(name = "application", value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+
+            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+
+            @ApiParam(name = "policy", value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyId);
+
+    // TODO: Should be DELETE /policy, not POST /policy/destroy
+    @POST
+    @Path("/{policy}/destroy")
+    @ApiOperation(value = "Destroy a policy", notes="Removes a policy from being associated with the entity and destroys it (stopping first if running)")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or policy")
+    })
+    public Response destroy(
+            @ApiParam(name = "application", value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+
+            @ApiParam(name = "entity", value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+
+            @ApiParam(name = "policy", value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyToken);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
new file mode 100644
index 0000000..e7fcabf
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/PolicyConfigApi.java
@@ -0,0 +1,120 @@
+/*
+ * 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.api;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.PolicyConfigSummary;
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.List;
+import java.util.Map;
+
+@Path("/v1/applications/{application}/entities/{entity}/policies/{policy}/config")
+@Apidoc("Entity Policy Config")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface PolicyConfigApi {
+
+    @GET
+    @ApiOperation(value = "Fetch the config keys for a specific policy",
+            responseClass = "org.apache.brooklyn.rest.domain.ConfigSummary",
+            multiValueResponse = true)
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity or policy")
+    })
+    public List<PolicyConfigSummary> list(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Policy ID or name", required = true)
+            @PathParam("policy") final String policyToken);
+
+    // TODO support parameters  ?show=value,summary&name=xxx &format={string,json,xml}
+    // (and in sensors class)
+    @GET
+    @Path("/current-state")
+    @ApiOperation(value = "Fetch config key values in batch", notes="Returns a map of config name to value")
+    public Map<String, Object> batchConfigRead(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyToken) ;
+
+    @GET
+    @Path("/{config}")
+    @ApiOperation(value = "Fetch config value", responseClass = "Object")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity, policy or config key")
+    })
+    public String get(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyToken,
+            @ApiParam(value = "Config key ID", required = true)
+            @PathParam("config") String configKeyName);
+
+    /** @deprecated since 0.7.0 use set with object*/ @Deprecated
+    @POST
+    @Path("/{config}/set")
+    @ApiOperation(value = "Sets the given config on this policy")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity, policy or config key")
+    })
+    public Response set(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyToken,
+            @ApiParam(value = "Config key ID", required = true)
+            @PathParam("config") String configKeyName,
+            @ApiParam(name = "value", value = "New value for the configuration", required = true)
+            @QueryParam("value") String value);
+
+    @POST
+    @Path("/{config}")
+    @ApiOperation(value = "Sets the given config on this policy")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity, policy or config key")
+    })
+    public Response set(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") String entityToken,
+            @ApiParam(value = "Policy ID or name", required = true)
+            @PathParam("policy") String policyToken,
+            @ApiParam(value = "Config key ID", required = true)
+            @PathParam("config") String configKeyName,
+            @ApiParam(name = "value", value = "New value for the configuration", required = true)
+            Object value);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ScriptApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ScriptApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ScriptApi.java
new file mode 100644
index 0000000..1fd6d56
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ScriptApi.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.rest.api;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.ScriptExecutionSummary;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+
+@Path("/v1/script")
+@Apidoc(value="Scripting")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface ScriptApi {
+    
+    public static final String USER_DATA_MAP_SESSION_ATTRIBUTE = "brooklyn.script.groovy.user.data";
+    public static final String USER_LAST_VALUE_SESSION_ATTRIBUTE = "brooklyn.script.groovy.user.last";
+    
+    @POST
+    @Path("/groovy")
+    @Consumes("application/text")
+    @ApiOperation(value = "Execute a groovy script",
+            responseClass = "org.apache.brooklyn.rest.domain.SensorSummary")
+    public ScriptExecutionSummary groovy(
+            @Context HttpServletRequest request,
+            @ApiParam(name = "script", value = "Groovy script to execute", required = true)
+            String script);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/SensorApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/SensorApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/SensorApi.java
new file mode 100644
index 0000000..13db60f
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/SensorApi.java
@@ -0,0 +1,150 @@
+/*
+ * 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.api;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.SensorSummary;
+
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+@Path("/v1/applications/{application}/entities/{entity}/sensors")
+@Apidoc("Entity Sensors")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface SensorApi {
+
+    @GET
+    @ApiOperation(value = "Fetch the sensor list for a specific application entity",
+            responseClass = "org.apache.brooklyn.rest.domain.SensorSummary",
+            multiValueResponse = true)
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    public List<SensorSummary> list(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken);
+
+    @GET
+    @Path("/current-state")
+    @ApiOperation(value = "Fetch sensor values in batch", notes="Returns a map of sensor name to value")
+    public Map<String, Object> batchSensorRead(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Return raw sensor data instead of display values", required = false)
+            @QueryParam("raw") @DefaultValue("false") final Boolean raw);
+
+    @GET
+    @Path("/{sensor}")
+    @ApiOperation(value = "Fetch sensor value (json)", responseClass = "Object")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or sensor")
+    })
+    public Object get(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Sensor name", required = true)
+            @PathParam("sensor") String sensorName,
+            @ApiParam(value = "Return raw sensor data instead of display values", required = false)
+            @QueryParam("raw") @DefaultValue("false") final Boolean raw);
+
+    // this method is used if user has requested plain (ie not converting to json)
+    @GET
+    @Path("/{sensor}")
+    @ApiOperation(value = "Fetch sensor value (text/plain)", responseClass = "String")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or sensor")
+    })
+    @Produces(MediaType.TEXT_PLAIN)
+    public String getPlain(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Sensor name", required = true)
+            @PathParam("sensor") String sensorName,
+            @ApiParam(value = "Return raw sensor data instead of display values", required = false)
+            @QueryParam("raw") @DefaultValue("false") final Boolean raw);
+
+    @POST
+    @ApiOperation(value = "Manually set multiple sensor values")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application or entity")
+    })
+    @SuppressWarnings("rawtypes")
+    public void setFromMap(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Map of sensor names to values", required = true)
+            Map newValues);
+
+    @POST
+    @Path("/{sensor}")
+    @ApiOperation(value = "Manually set a sensor value")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or sensor")
+    })
+    public void set(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Sensor name", required = true)
+            @PathParam("sensor") String sensorName,
+            @ApiParam(value = "Value to set")
+            Object newValue);
+
+    @DELETE
+    @Path("/{sensor}")
+    @ApiOperation(value = "Manually clear a sensor value")
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Could not find application, entity or sensor")
+    })
+    public void delete(
+            @ApiParam(value = "Application ID or name", required = true)
+            @PathParam("application") final String application,
+            @ApiParam(value = "Entity ID or name", required = true)
+            @PathParam("entity") final String entityToken,
+            @ApiParam(value = "Sensor name", required = true)
+            @PathParam("sensor") String sensorName);
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ServerApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ServerApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ServerApi.java
new file mode 100644
index 0000000..faaca97
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/ServerApi.java
@@ -0,0 +1,203 @@
+/*
+ * 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.api;
+
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.FormParam;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import brooklyn.management.ha.HighAvailabilityMode;
+import brooklyn.management.ha.ManagementNodeState;
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.HighAvailabilitySummary;
+import org.apache.brooklyn.rest.domain.VersionSummary;
+
+import com.google.common.annotations.Beta;
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+@Path("/v1/server")
+@Apidoc("Server")
+@Produces(MediaType.APPLICATION_JSON)
+@Beta
+public interface ServerApi {
+
+    public final String MIME_TYPE_ZIP = "applicaiton/zip";
+    // TODO support TGZ, and check mime type
+    public final String MIME_TYPE_TGZ = "applicaiton/gzip";
+    
+    @POST
+    @Path("/properties/reload")
+    @ApiOperation(value = "Reload brooklyn.properties")
+    public void reloadBrooklynProperties();
+
+    @POST
+    @Path("/shutdown")
+    @ApiOperation(value = "Terminate this Brooklyn server instance")
+    @Consumes({MediaType.APPLICATION_FORM_URLENCODED})
+    public void shutdown(
+            @ApiParam(name = "stopAppsFirst", value = "Whether to stop running applications before shutting down")
+            @FormParam("stopAppsFirst") @DefaultValue("false") boolean stopAppsFirst,
+            @ApiParam(name = "forceShutdownOnError", value ="Force shutdown if apps fail to stop or timeout")
+            @FormParam("forceShutdownOnError") @DefaultValue("false") boolean forceShutdownOnError,
+            @ApiParam(name = "shutdownTimeout", value = "A maximum delay to wait for apps to gracefully stop before giving up or forcibly exiting, 0 to wait infinitely")
+            @FormParam("shutdownTimeout") @DefaultValue("20s") String shutdownTimeout,
+            @ApiParam(name = "requestTimeout", value = "Maximum time to block the request for the shutdown to finish, 0 to wait infinitely")
+            @FormParam("requestTimeout") @DefaultValue("20s") String requestTimeout,
+            @ApiParam(name = "delayForHttpReturn", value = "The delay before exiting the process, to permit the REST response to be returned")
+            @FormParam("delayForHttpReturn") @DefaultValue("5s") String delayForHttpReturn,
+            @ApiParam(name = "delayMillis", value = "Deprecated, analogous to delayForHttpReturn")
+            @FormParam("delayMillis") Long delayMillis);
+
+    @GET
+    @Path("/version")
+    @ApiOperation(value = "Return version identifier information for this Brooklyn instance", responseClass = "String", multiValueResponse = false)
+    public VersionSummary getVersion();
+
+    @GET
+    @Path("/up")
+    @ApiOperation(value = "Returns whether this server is up - fully started, and not stopping, though it may have errors")
+    public boolean isUp();
+    
+    @GET
+    @Path("/shuttingDown")
+    @ApiOperation(value = "Returns whether this server is shutting down")
+    public boolean isShuttingDown();
+    
+    @GET
+    @Path("/healthy")
+    @ApiOperation(value = "Returns whether this node is healthy - fully started, not stopping, and no errors")
+    public boolean isHealthy();
+    
+    @Deprecated /** @deprecated since 0.7.0 use /ha/node (which returns correct JSON) */
+    @GET
+    @Path("/status")
+    @ApiOperation(value = "Returns the status of this Brooklyn instance [DEPRECATED; see ../ha/state]",
+            responseClass = "String",
+            multiValueResponse = false)
+    public String getStatus();
+
+    @GET
+    @Path("/up/extended")
+    @ApiOperation(value = "Returns extended server-up information, a map including up (/up), shuttingDown (/shuttingDown), healthy (/healthy), and ha (/ha/states) (qv)")
+    public Map<String,Object> getUpExtended();
+
+    @GET
+    @Path("/config/{configKey}")
+    @ApiOperation(value = "Get the value of the specified config key from brooklyn properties")
+    @ApiErrors(value = {
+            // TODO: This should probably return a 404 if the key is not present, and should return a predictable
+            // value if the value is not set. Behaviour should be consistent with EntityConfigApi.get()
+            @ApiError(code = 204, reason = "Could not find config key")
+    })
+    public String getConfig(
+            @ApiParam(value = "Config key ID", required = true)
+            @PathParam("configKey") String configKey);
+
+    @Deprecated /** @deprecated since 0.7.0 use /ha/states */
+    @GET
+    @Path("/highAvailability")
+    @ApiOperation(value = "Returns the status of all Brooklyn instances in the management plane [DEPRECATED; see ../ha/states]",
+            responseClass = "org.apache.brooklyn.rest.domain.HighAvailabilitySummary")
+    public HighAvailabilitySummary getHighAvailability();
+    
+    @GET
+    @Path("/ha/state")
+    @ApiOperation(value = "Returns the HA state of this management node")
+    public ManagementNodeState getHighAvailabilityNodeState();
+    
+    @GET
+    @Path("/ha/metrics")
+    @ApiOperation(value = "Returns a collection of HA metrics")
+    public Map<String,Object> getHighAvailabilityMetrics();
+    
+    @POST
+    @Path("/ha/state")
+    @ApiOperation(value = "Changes the HA state of this management node")
+    public ManagementNodeState setHighAvailabilityNodeState(
+            @ApiParam(name = "mode", value = "The state to change to")
+            @FormParam("mode") HighAvailabilityMode mode);
+
+    @GET
+    @Path("/ha/states")
+    @ApiOperation(value = "Returns the HA states and detail for all nodes in this management plane",
+            responseClass = "org.apache.brooklyn.rest.domain.HighAvailabilitySummary")
+    public HighAvailabilitySummary getHighAvailabilityPlaneStates();
+
+    @POST
+    @Path("/ha/states/clear")
+    @ApiOperation(value = "Clears HA node information for non-master nodes; active nodes will repopulate and other records will be erased")
+    public Response clearHighAvailabilityPlaneStates();
+    
+    @GET
+    @Path("/ha/priority")
+    @ApiOperation(value = "Returns the HA node priority for MASTER failover")
+    public long getHighAvailabitlityPriority();
+    
+    @POST
+    @Path("/ha/priority")
+    @ApiOperation(value = "Sets the HA node priority for MASTER failover")
+    public long setHighAvailabilityPriority(
+            @ApiParam(name = "priority", value = "The priority to be set")
+            @FormParam("priority") long priority);
+    
+    @GET
+    @Produces(MIME_TYPE_ZIP)
+    @Path("/ha/persist/export")
+    @ApiOperation(value = "Retrieves the persistence store data, as an archive")
+    public Response exportPersistenceData(
+        @ApiParam(name = "origin", value = "Whether to take from LOCAL or REMOTE state; default to AUTO detect, "
+                + "using LOCAL as master and REMOTE for other notes")
+        @QueryParam("origin") @DefaultValue("AUTO") String origin);
+
+    // TODO would be nice to allow setting, as a means to recover / control more easily than messing with persistent stores
+//    @POST
+//    @Consumes({MediaType.APPLICATION_FORM_URLENCODED})
+//    @Path("/ha/persist/import")
+//    @ApiOperation(value = "Causes the supplied persistence data (tgz) to be imported and added "
+//        + "(fails if the node is not master), optionally removing any items not referenced")
+//    public Response importPersistenceData(
+//          // question: do we want the MementoCopyMode, cf export above?
+//        @ApiParam(name = "clearOthers", value = "Whether to clear all existing items before adding these", required = false, defaultValue = "false")
+//        @FormParam("clearOthers") Boolean clearOthers,
+//        @ApiParam(name = "data",
+//        value = "TGZ contents of a persistent directory to be imported", required = true)
+//    @Valid String dataTgz);
+
+    // TODO /ha/persist/backup set of endpoints, to list and retrieve specific backups
+
+    @GET
+    @Path("/user")
+    @ApiOperation(value = "Return user information for this Brooklyn instance", 
+            responseClass = "String", multiValueResponse = false)
+    public String getUser(); 
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/UsageApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/UsageApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/UsageApi.java
new file mode 100644
index 0000000..e44475c
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/UsageApi.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.api;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+
+import brooklyn.rest.apidoc.Apidoc;
+import org.apache.brooklyn.rest.domain.UsageStatistics;
+
+import com.wordnik.swagger.core.ApiError;
+import com.wordnik.swagger.core.ApiErrors;
+import com.wordnik.swagger.core.ApiOperation;
+import com.wordnik.swagger.core.ApiParam;
+
+@Path("/v1/usage")
+@Apidoc("Usage")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public interface UsageApi {
+
+    // TODO should `/applications?start=...` only return those applications matching the constraint?
+    // Or return all applications, but with empty statistics for some?
+    // Currently it returns only those applications that match.
+    
+    @GET
+    @Path("/applications")
+    @ApiOperation(
+            value = "Retrieve usage information about all applications",
+            responseClass = "org.apache.brooklyn.rest.domain.UsageStatistics"
+    )
+    @ApiErrors(value = {})
+    public List<UsageStatistics> listApplicationsUsage(
+            @ApiParam(
+                    name = "start",
+                    value = "timestamp of start marker for usage reporting, in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("start") String startDate,
+            @ApiParam(
+                    name = "end",
+                    value = "timestamp of end marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("end") String endDate) ;
+
+    @GET
+    @Path("/applications/{application}")
+    @ApiOperation(
+            value = "Retrieve usage information about a specified application",
+            responseClass = "org.apache.brooklyn.rest.domain.UsageStatistics"
+    )
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application not found")
+    })
+    public UsageStatistics getApplicationUsage(
+            @ApiParam(
+                    name = "application",
+                    value = "Application id",
+                    required = true
+            )
+            @PathParam("application") String applicationId,
+            @ApiParam(
+                    name = "start",
+                    value = "timestamp of start marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("start") String startDate,
+            @ApiParam(
+                    name = "end",
+                    value = "timestamp of end marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("end") String endDate) ;
+
+    @GET
+    @Path("/machines")
+    @ApiOperation(
+            value = "Retrieve usage information about all machine locations, optionally filtering for a specific application and/or time range",
+            responseClass = "org.apache.brooklyn.rest.domain.UsageStatistics"
+    )
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Application not found")
+    })
+    public List<UsageStatistics> listMachinesUsage(
+            @ApiParam(
+                    name = "application",
+                    value = "Application id",
+                    required = false
+            )
+            @QueryParam("application") String application,
+            @ApiParam(
+                    name = "start",
+                    value = "timestamp of start marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("start") String startDate,
+            @ApiParam(
+                    name = "end",
+                    value = "timestamp of end marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("end") String endDate) ;
+
+    @GET
+    @Path("/machines/{machine}")
+    @ApiOperation(
+            value = "Retrieve usage information about a specific machine location",
+            responseClass = "org.apache.brooklyn.rest.domain.UsageStatistics"
+    )
+    @ApiErrors(value = {
+            @ApiError(code = 404, reason = "Machine not found")
+    })
+    public UsageStatistics getMachineUsage(
+            @ApiParam(
+                    name = "machine",
+                    value = "Machine id",
+                    required = true
+            )
+            @PathParam("machine") String machine,
+            @ApiParam(
+                    name = "start",
+                    value = "timestamp of start marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("start") String startDate,
+            @ApiParam(
+                    name = "end",
+                    value = "timestamp of end marker for usage reporting in format UTC millis or yyyy-MM-dd'T'HH:mm:ssZ",
+                    required = false
+            )
+            @QueryParam("end") String endDate) ;
+}

http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/4c98f111/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/VersionApi.java
----------------------------------------------------------------------
diff --git a/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/VersionApi.java b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/VersionApi.java
new file mode 100644
index 0000000..ca928f0
--- /dev/null
+++ b/usage/rest-api/src/main/java/org/apache/brooklyn/rest/api/VersionApi.java
@@ -0,0 +1,42 @@
+/*
+ * 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.api;
+
+import brooklyn.rest.apidoc.Apidoc;
+import com.wordnik.swagger.core.ApiOperation;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("/v1/version")
+@Apidoc("Version")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+/** @deprecated since 0.7.0; use /v1/server/version */
+@Deprecated
+public interface VersionApi {
+
+  @GET
+  @ApiOperation(value = "Return version identifier information for this Brooklyn instance; deprecated, use /server/version", 
+          responseClass = "String", multiValueResponse = false)
+  public String getVersion();
+}


Mime
View raw message