AMBARI-21009. Integrate ActionService resource with Swagger (Balazs Bence Sari via adoroszlai)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/580067f9 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/580067f9 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/580067f9 Branch: refs/heads/trunk Commit: 580067f9965060a80ed99fb9f803ff5aae504fc0 Parents: fea1aae Author: Balazs Bence Sari <[email protected]> Authored: Tue May 16 09:11:01 2017 +0200 Committer: Attila Doroszlai <[email protected]> Committed: Tue May 16 09:11:01 2017 +0200 ---------------------------------------------------------------------- .../server/api/services/ActionService.java | 98 ++++++++++++++++++-- .../ambari/server/api/services/BaseService.java | 1 + .../ambari/server/controller/ActionRequest.java | 19 ++++ .../server/controller/ActionRequestSwagger.java | 31 +++++++ .../server/controller/ActionResponse.java | 20 +++- 5 files changed, 159 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/580067f9/ambari-server/src/main/java/org/apache/ambari/server/api/services/ActionService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ActionService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ActionService.java index 0290151..cd74867 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ActionService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ActionService.java @@ -29,19 +29,32 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.apache.ambari.server.api.resources.ResourceInstance; +import org.apache.ambari.server.controller.ActionResponse; import org.apache.ambari.server.controller.spi.Resource; +import org.apache.http.HttpStatus; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.annotations.ApiResponse; +import io.swagger.annotations.ApiResponses; /** * Service responsible for action definition resource requests. */ @Path("/actions/") +@Api(value = "Actions", description = "Endpoint for action definition specific operations") public class ActionService extends BaseService { + private static final String ACTION_REQUEST_TYPE = "org.apache.ambari.server.controller.ActionRequestSwagger"; + /** * Handles: GET /actions/{actionName} * Get a specific action definition. @@ -53,9 +66,23 @@ public class ActionService extends BaseService { */ @GET @Path("{actionName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get the details of an action definition", + nickname = "ActionService#getActionDefinition", + response = ActionResponse.ActionResponseSwagger.class) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "Actions/*", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) + }) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getActionDefinition(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("actionName") String actionName) { + @ApiParam(required = true) @PathParam("actionName") String actionName) { return handleRequest(headers, body, ui, Request.Type.GET, createActionDefinitionResource(actionName)); } @@ -69,7 +96,27 @@ public class ActionService extends BaseService { * @return action definition collection resource representation */ @GET - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get all action definitions", + nickname = "ActionService#getActionDefinitions", + response = ActionResponse.ActionResponseSwagger.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "Actions/action_name", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, + defaultValue = "Actions/action_name.asc", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) + }) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getActionDefinitions(String body, @Context HttpHeaders headers, @Context UriInfo ui) { return handleRequest(headers, body, ui, Request.Type.GET, createActionDefinitionResource(null)); } @@ -85,9 +132,21 @@ public class ActionService extends BaseService { */ @POST @Path("{actionName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Creates an action definition - Currently Not Supported", + nickname = "ActionService#createActionDefinition" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = ACTION_REQUEST_TYPE, paramType = "body", allowMultiple = false) + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_REQUEST), + @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR), + }) public Response createActionDefinition(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("actionName") String actionName) { + @ApiParam(required = true) @PathParam("actionName") String actionName) { return handleRequest(headers, body, ui, Request.Type.POST, createActionDefinitionResource(actionName)); } @@ -103,9 +162,21 @@ public class ActionService extends BaseService { */ @PUT @Path("{actionName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Updates an action definition - Currently Not Supported", + nickname = "ActionService#updateActionDefinition" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = ACTION_REQUEST_TYPE, paramType = "body") + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_REQUEST), + @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR), + }) public Response updateActionDefinition(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("actionName") String actionName) { + @ApiParam(required = true) @PathParam("actionName") String actionName) { return handleRequest(headers, body, ui, Request.Type.PUT, createActionDefinitionResource(actionName)); } @@ -121,9 +192,18 @@ public class ActionService extends BaseService { */ @DELETE @Path("{actionName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Deletes an action definition - Currently Not Supported", + nickname = "ActionService#deleteActionDefinition" + ) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR), + }) public Response deleteActionDefinition(@Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("actionName") String actionName) { + @ApiParam(required = true) @PathParam("actionName") String actionName) { return handleRequest(headers, null, ui, Request.Type.DELETE, createActionDefinitionResource(actionName)); } http://git-wip-us.apache.org/repos/asf/ambari/blob/580067f9/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java index 964fb59..2808911 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BaseService.java @@ -52,6 +52,7 @@ public abstract class BaseService { static final String MSG_SUCCESSFUL_OPERATION = "Successful operation"; static final String MSG_REQUEST_ACCEPTED = "Request is accepted, but not completely processed yet"; static final String MSG_INVALID_ARGUMENTS = "Invalid arguments"; + static final String MSG_INVALID_REQUEST = "Invalid request"; static final String MSG_CLUSTER_NOT_FOUND = "Cluster not found"; static final String MSG_CLUSTER_OR_HOST_NOT_FOUND = "Cluster or host not found"; static final String MSG_NOT_AUTHENTICATED = "Not authenticated"; http://git-wip-us.apache.org/repos/asf/ambari/blob/580067f9/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequest.java index 7a4fd36..499f28c 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequest.java @@ -18,11 +18,22 @@ package org.apache.ambari.server.controller; +import io.swagger.annotations.ApiModelProperty; + /** * Used to perform CRUD operations of Action */ public class ActionRequest { + static final String ACTION_NAME = "action_name"; + static final String ACTION_TYPE = "action_type"; + static final String INPUTS = "inputs"; + static final String TARGET_SERVICE = "target_service"; + static final String TARGET_COMPONENT = "target_component"; + static final String DESCRIPTION = "description"; + static final String TARGET_TYPE = "target_type"; + static final String DEFAULT_TIMEOUT = "default_timeout"; + private String actionName; //CRUD private String actionType; //C private String inputs; //C @@ -55,6 +66,7 @@ public class ActionRequest { return new ActionRequest(null, null, null, null, null, null, null, null); } + @ApiModelProperty(name = ACTION_NAME) public String getActionName() { return actionName; } @@ -63,6 +75,7 @@ public class ActionRequest { this.actionName = actionName; } + @ApiModelProperty(name = ACTION_TYPE) public String getActionType() { return actionType; } @@ -71,6 +84,7 @@ public class ActionRequest { this.actionType = actionType; } + @ApiModelProperty(name = INPUTS) public String getInputs() { return inputs; } @@ -79,6 +93,7 @@ public class ActionRequest { this.inputs = inputs; } + @ApiModelProperty(name = TARGET_SERVICE) public String getTargetService() { return targetService; } @@ -87,6 +102,7 @@ public class ActionRequest { this.targetService = targetService; } + @ApiModelProperty(name = TARGET_COMPONENT) public String getTargetComponent() { return targetComponent; } @@ -95,6 +111,7 @@ public class ActionRequest { this.targetComponent = targetComponent; } + @ApiModelProperty(name = DESCRIPTION) public String getDescription() { return description; } @@ -103,6 +120,7 @@ public class ActionRequest { this.description = description; } + @ApiModelProperty(name = TARGET_TYPE) public String getTargetType() { return targetType; } @@ -111,6 +129,7 @@ public class ActionRequest { this.targetType = targetType; } + @ApiModelProperty(name = DEFAULT_TIMEOUT) public String getDefaultTimeout() { return defaultTimeout; } http://git-wip-us.apache.org/repos/asf/ambari/blob/580067f9/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequestSwagger.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequestSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequestSwagger.java new file mode 100644 index 0000000..65b96fd --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionRequestSwagger.java @@ -0,0 +1,31 @@ +/** + * 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.ambari.server.controller; + +import io.swagger.annotations.ApiModelProperty; + +/** + * Request schema for endpoint {@link org.apache.ambari.server.api.services.ActionService#createActionDefinition(String, + * javax.ws.rs.core.HttpHeaders, javax.ws.rs.core.UriInfo, String)} + * + * The interface is not actually implemented, it only carries swagger annotations. + */ +public interface ActionRequestSwagger { + @ApiModelProperty(name = "Actions") + public ActionRequest getActionRequest(); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/580067f9/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java index e7edafb..3373d6d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ActionResponse.java @@ -18,6 +18,8 @@ package org.apache.ambari.server.controller; +import io.swagger.annotations.ApiModelProperty; + /** * Used to respond to GET requests for actions */ @@ -45,6 +47,7 @@ public class ActionResponse { setDefaultTimeout(defaultTimeout); } + @ApiModelProperty(name = ActionRequest.ACTION_NAME) public String getActionName() { return actionName; } @@ -53,6 +56,7 @@ public class ActionResponse { this.actionName = actionName; } + @ApiModelProperty(name = ActionRequest.ACTION_TYPE) public String getActionType() { return actionType; } @@ -61,6 +65,7 @@ public class ActionResponse { this.actionType = actionType; } + @ApiModelProperty(name = ActionRequest.INPUTS) public String getInputs() { return inputs; } @@ -69,6 +74,7 @@ public class ActionResponse { this.inputs = inputs; } + @ApiModelProperty(name = ActionRequest.TARGET_SERVICE) public String getTargetService() { return targetService; } @@ -77,6 +83,7 @@ public class ActionResponse { this.targetService = targetService; } + @ApiModelProperty(name = ActionRequest.TARGET_COMPONENT) public String getTargetComponent() { return targetComponent; } @@ -84,7 +91,8 @@ public class ActionResponse { public void setTargetComponent(String targetComponent) { this.targetComponent = targetComponent; } - + + @ApiModelProperty(name = ActionRequest.DESCRIPTION) public String getDescription() { return description; } @@ -93,6 +101,7 @@ public class ActionResponse { this.description = description; } + @ApiModelProperty(name = ActionRequest.TARGET_TYPE) public String getTargetType() { return targetType; } @@ -101,6 +110,7 @@ public class ActionResponse { this.targetType = targetType; } + @ApiModelProperty(name = ActionRequest.DEFAULT_TIMEOUT) public String getDefaultTimeout() { return defaultTimeout; } @@ -172,4 +182,12 @@ public class ActionResponse { result = result + (defaultTimeout != null ? defaultTimeout.hashCode() : 0); return result; } + + /** + * Interface to help correct Swagger documentation generation + */ + public interface ActionResponseSwagger { + @ApiModelProperty(name = "Actions") + ActionResponse getActionResponse(); + } }
