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(); +}
