Repository: ambari Updated Branches: refs/heads/ambari-rest-api-explorer 54983ee3b -> 580067f99
AMBARI-20995. Integrate ServiceService 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/fea1aaec Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fea1aaec Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fea1aaec Branch: refs/heads/ambari-rest-api-explorer Commit: fea1aaec8a5ff5b6c2fae8cf38f9ca3b789e1ab9 Parents: 54983ee Author: Balazs Bence Sari <[email protected]> Authored: Tue May 16 09:09:07 2017 +0200 Committer: Attila Doroszlai <[email protected]> Committed: Tue May 16 09:09:07 2017 +0200 ---------------------------------------------------------------------- .../ambari/server/api/services/BaseService.java | 3 + .../server/api/services/ServiceService.java | 291 +++++++++++++++++-- .../ClusterServiceArtifactRequest.java | 26 ++ .../ClusterServiceArtifactResponse.java | 49 ++++ .../server/controller/ServiceRequest.java | 8 + .../controller/ServiceRequestSwagger.java | 31 ++ .../server/controller/ServiceResponse.java | 19 +- 7 files changed, 394 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/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 0b2afd1..964fb59 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 @@ -57,6 +57,7 @@ public abstract class BaseService { static final String MSG_NOT_AUTHENTICATED = "Not authenticated"; static final String MSG_PERMISSION_DENIED = "Not permitted to perform the operation"; static final String MSG_SERVER_ERROR = "Internal server error"; + static final String MSG_RESOURCE_ALREADY_EXISTS = "The requested resource already exists."; static final String MSG_RESOURCE_NOT_FOUND = "The requested resource doesn't exist."; static final String QUERY_FIELDS = "fields"; @@ -81,6 +82,8 @@ public abstract class BaseService { static final String DATA_TYPE_STRING = "string"; static final String PARAM_TYPE_QUERY = "query"; + static final String PARAM_TYPE_BODY = "body"; + /** * Logger instance. http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java index 52871f2..27de0b4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java @@ -30,16 +30,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.ClusterServiceArtifactResponse; +import org.apache.ambari.server.controller.ServiceResponse; 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 services resource requests. */ +@Api(value = "Services", description = "Endpoint for service specific operations") public class ServiceService extends BaseService { + private static final String SERVICE_REQUEST_TYPE = "org.apache.ambari.server.controller.ServiceRequestSwagger"; + private static final String ARTIFACT_REQUEST_TYPE = "org.apache.ambari.server.controller.ClusterServiceArtifactRequest"; + /** * Parent cluster name. */ @@ -65,9 +81,23 @@ public class ServiceService extends BaseService { */ @GET @Path("{serviceName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get the details of a service", + nickname = "ServiceService#getService", + notes = "Returns the details of a service.", + response = ServiceResponse.ServiceResponseSwagger.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "ServiceInfo/*", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY) + }) + @ApiResponses(value = { + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getService(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName) { + @ApiParam @PathParam("serviceName") String serviceName) { return handleRequest(headers, body, ui, Request.Type.GET, createServiceResource(m_clusterName, serviceName)); @@ -82,7 +112,27 @@ public class ServiceService extends BaseService { * @return service collection resource representation */ @GET - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get all services", + nickname = "ServiceService#getServices", + notes = "Returns all services.", + response = ServiceResponse.ServiceResponseSwagger.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "ServiceInfo/service_name, ServiceInfo/cluster_name", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, + defaultValue = "ServiceInfo/service_name.asc, ServiceInfo/cluster_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_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) { return handleRequest(headers, body, ui, Request.Type.GET, createServiceResource(m_clusterName, null)); @@ -100,10 +150,25 @@ public class ServiceService extends BaseService { */ @POST @Path("{serviceName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Creates a service", + nickname = "ServiceService#createServices" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = SERVICE_REQUEST_TYPE, paramType = "body", allowMultiple = false) + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS), + @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 createService(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName) { - + @ApiParam @PathParam("serviceName") String serviceName) { return handleRequest(headers, body, ui, Request.Type.POST, createServiceResource(m_clusterName, serviceName)); } @@ -118,7 +183,23 @@ public class ServiceService extends BaseService { * @return information regarding the created services */ @POST - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Creates a service", + nickname = "ServiceService#createService" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = SERVICE_REQUEST_TYPE, paramType = "body", allowMultiple = true) + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS), + @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 createServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) { return handleRequest(headers, body, ui, Request.Type.POST, @@ -137,10 +218,24 @@ public class ServiceService extends BaseService { */ @PUT @Path("{serviceName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Updates a service", + nickname = "ServiceService#updateService" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = SERVICE_REQUEST_TYPE, paramType = "body") + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @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 updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName) { - + @ApiParam @PathParam("serviceName") String serviceName) { return handleRequest(headers, body, ui, Request.Type.PUT, createServiceResource(m_clusterName, serviceName)); } @@ -154,7 +249,22 @@ public class ServiceService extends BaseService { * @return information regarding the updated service */ @PUT - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Updates multiple services", + nickname = "ServiceService#updateServices" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = SERVICE_REQUEST_TYPE, paramType = "body") + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @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 updateServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) { return handleRequest(headers, body, ui, Request.Type.PUT, createServiceResource(m_clusterName, null)); @@ -171,10 +281,19 @@ public class ServiceService extends BaseService { */ @DELETE @Path("{serviceName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Deletes a service", + nickname = "ServiceService#deleteService" + ) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @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 deleteService(@Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName) { - + @ApiParam(required = true) @PathParam("serviceName") String serviceName) { return handleRequest(headers, null, ui, Request.Type.DELETE, createServiceResource(m_clusterName, serviceName)); } @@ -185,6 +304,7 @@ public class ServiceService extends BaseService { * @return the components service */ @Path("{serviceName}/components") + // TODO: find a way to handle this with Swagger (refactor or custom annotation?) public ComponentService getComponentHandler(@PathParam("serviceName") String serviceName) { return new ComponentService(m_clusterName, serviceName); @@ -194,6 +314,7 @@ public class ServiceService extends BaseService { * Gets the alerts sub-resource. */ @Path("{serviceName}/alerts") + // TODO: find a way to handle this with Swagger (refactor or custom annotation?) public AlertService getAlertHandler( @PathParam("serviceName") String serviceName) { return new AlertService(m_clusterName, serviceName, null); @@ -213,12 +334,28 @@ public class ServiceService extends BaseService { */ @POST @Path("{serviceName}/artifacts/{artifactName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Creates a service artifact", + nickname = "ServiceService#createArtifact" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = ARTIFACT_REQUEST_TYPE, paramType = "body", allowMultiple = false) + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS), + @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 createArtifact(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName, - @PathParam("artifactName") String artifactName) { + @ApiParam @PathParam("serviceName") String serviceName, + @ApiParam @PathParam("artifactName") String artifactName) { return handleRequest(headers, body, ui, Request.Type.POST, createArtifactResource(m_clusterName, serviceName, artifactName)); @@ -237,7 +374,27 @@ public class ServiceService extends BaseService { */ @GET @Path("{serviceName}/artifacts") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get all service artifacts", + nickname = "ServiceService#getArtifacts", + response = ClusterServiceArtifactResponse.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "Artifacts/artifact_name", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, + defaultValue = "Artifacts/artifact_name", + 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_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getArtifacts(String body, @Context HttpHeaders headers, @Context UriInfo ui, @@ -261,13 +418,32 @@ public class ServiceService extends BaseService { */ @GET @Path("{serviceName}/artifacts/{artifactName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get the detais of a service artifact", + nickname = "ServiceService#getArtifact", + response = ClusterServiceArtifactResponse.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "Artifacts/artifact_name", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, + defaultValue = "Artifacts/artifact_name", + 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_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getArtifact(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName, - @PathParam("artifactName") String artifactName) { - + @ApiParam @PathParam("serviceName") String serviceName, + @ApiParam @PathParam("artifactName") String artifactName) { return handleRequest(headers, body, ui, Request.Type.GET, createArtifactResource(m_clusterName, serviceName, artifactName)); } @@ -284,11 +460,26 @@ public class ServiceService extends BaseService { */ @PUT @Path("{serviceName}/artifacts") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Updates multiple artifacts", + nickname = "ServiceService#updateArtifacts" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = ARTIFACT_REQUEST_TYPE, paramType = "body") + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @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 updateArtifacts(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName) { + @ApiParam @PathParam("serviceName") String serviceName) { return handleRequest(headers, body, ui, Request.Type.PUT, createArtifactResource(m_clusterName, serviceName, null)); @@ -307,12 +498,27 @@ public class ServiceService extends BaseService { */ @PUT @Path("{serviceName}/artifacts/{artifactName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Updates a single artifact", + nickname = "ServiceService#updateArtifact" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = ARTIFACT_REQUEST_TYPE, paramType = "body") + }) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED), + @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS), + @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 updateArtifact(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName, - @PathParam("artifactName") String artifactName) { + @ApiParam(required = true) @PathParam("serviceName") String serviceName, + @ApiParam(required = true) @PathParam("artifactName") String artifactName) { return handleRequest(headers, body, ui, Request.Type.PUT, createArtifactResource(m_clusterName, serviceName, artifactName)); @@ -330,11 +536,21 @@ public class ServiceService extends BaseService { */ @DELETE @Path("{serviceName}/artifacts") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Deletes all artifacts of a service that match the provided predicate", + nickname = "ServiceService#deleteArtifacts" + ) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @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 deleteArtifacts(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName) { + @ApiParam(required = true) @PathParam("serviceName") String serviceName) { return handleRequest(headers, body, ui, Request.Type.DELETE, createArtifactResource(m_clusterName, serviceName, null)); @@ -353,12 +569,22 @@ public class ServiceService extends BaseService { */ @DELETE @Path("{serviceName}/artifacts/{artifactName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Deletes a single service artifact", + nickname = "ServiceService#deleteArtifact" + ) + @ApiResponses({ + @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION), + @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 deleteArtifact(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("serviceName") String serviceName, - @PathParam("artifactName") String artifactName) { + @ApiParam(required = true) @PathParam("serviceName") String serviceName, + @ApiParam(required = true) @PathParam("artifactName") String artifactName) { return handleRequest(headers, body, ui, Request.Type.DELETE, createArtifactResource(m_clusterName, serviceName, artifactName)); @@ -375,6 +601,7 @@ public class ServiceService extends BaseService { * @return the alert history service */ @Path("{serviceName}/alert_history") + // TODO: find a way to handle this with Swagger (refactor or custom annotation?) public AlertHistoryService getAlertHistoryService( @Context javax.ws.rs.core.Request request, @PathParam("serviceName") String serviceName) { http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactRequest.java new file mode 100644 index 0000000..ac37c0f --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactRequest.java @@ -0,0 +1,26 @@ +package org.apache.ambari.server.controller; + +import java.util.Map; + +import io.swagger.annotations.ApiModelProperty; + +/** + * Request schema for endpoint {@link org.apache.ambari.server.api.services.ServiceService#createArtifact(String, + * javax.ws.rs.core.HttpHeaders, javax.ws.rs.core.UriInfo, String, String)} + * + * The interface is not actually implemented, it only carries swagger annotations. + */ +public interface ClusterServiceArtifactRequest extends ApiModel { + + @ApiModelProperty(name = "Artifacts") + public ClusterServiceArtifactRequestInfo getClusterServiceArtifactRequestInfo(); + + @ApiModelProperty(name = "artifact_data") + public Map<String, Object> getArtifactData(); + + public interface ClusterServiceArtifactRequestInfo { + @ApiModelProperty(name = "artifact_name") + public String getArtifactName(); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactResponse.java new file mode 100644 index 0000000..29b8c94 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ClusterServiceArtifactResponse.java @@ -0,0 +1,49 @@ +/** + * 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 + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * 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 java.util.Map; + +import io.swagger.annotations.ApiModelProperty; + +/** + * Response schema for endpoint {@link org.apache.ambari.server.api.services.ServiceService#getArtifact} + * + * The interface is not actually implemented, it only carries swagger annotations. + */ +public interface ClusterServiceArtifactResponse { + + @ApiModelProperty(name = "Artifacts") + public ClusterServiceArtifactResponseInfo getClusterServiceArtifactResponseInfo(); + + @ApiModelProperty(name = "artifact_data") + public Map<String, Object> getArtifactData(); + + public interface ClusterServiceArtifactResponseInfo { + @ApiModelProperty(name = "artifact_name") + public String getArtifactName(); + + @ApiModelProperty(name = "cluster_name") + public String getClusterName(); + + @ApiModelProperty(name = "service_name") + public String getServiceName(); + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java index 6c0d4ea..5ac6251 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequest.java @@ -18,6 +18,7 @@ package org.apache.ambari.server.controller; +import io.swagger.annotations.ApiModelProperty; public class ServiceRequest { @@ -48,6 +49,7 @@ public class ServiceRequest { /** * @return the serviceName */ + @ApiModelProperty(name = "service_name") public String getServiceName() { return serviceName; } @@ -62,6 +64,7 @@ public class ServiceRequest { /** * @return the desiredState */ + @ApiModelProperty(name = "state") public String getDesiredState() { return desiredState; } @@ -76,6 +79,7 @@ public class ServiceRequest { /** * @return the clusterName */ + @ApiModelProperty(name = "cluster_name") public String getClusterName() { return clusterName; } @@ -97,6 +101,7 @@ public class ServiceRequest { /** * @return the maintenance state */ + @ApiModelProperty(name = "maintenance_state") public String getMaintenanceState() { return maintenanceState; } @@ -104,6 +109,7 @@ public class ServiceRequest { /** * @return credential store enabled */ + @ApiModelProperty(name = "credential_store_enabled") public String getCredentialStoreEnabled() { return credentialStoreEnabled; } @@ -126,6 +132,7 @@ public class ServiceRequest { /** * @param credentialStoreSupported the new credential store supported */ + @ApiModelProperty(name = "credential_store_supporteds") public void setCredentialStoreSupported(String credentialStoreSupported) { this.credentialStoreSupported = credentialStoreSupported; } @@ -139,4 +146,5 @@ public class ServiceRequest { .append(", credentialStoreSupported=").append(credentialStoreSupported); return sb.toString(); } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequestSwagger.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequestSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequestSwagger.java new file mode 100644 index 0000000..475ad41 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceRequestSwagger.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.ServiceService#createService(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 ServiceRequestSwagger extends ApiModel { + @ApiModelProperty(name = "ServiceInfo") + public ServiceRequest getServiceRequest(); +} http://git-wip-us.apache.org/repos/asf/ambari/blob/fea1aaec/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java index 3e35c0c..44bdfc7 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java @@ -19,6 +19,8 @@ package org.apache.ambari.server.controller; +import io.swagger.annotations.ApiModelProperty; + public class ServiceResponse { private Long clusterId; @@ -48,6 +50,7 @@ public class ServiceResponse { /** * @return the serviceName */ + @ApiModelProperty(name = "service_name") public String getServiceName() { return serviceName; } @@ -62,6 +65,7 @@ public class ServiceResponse { /** * @return the clusterId */ + @ApiModelProperty(hidden = true) public Long getClusterId() { return clusterId; } @@ -76,6 +80,7 @@ public class ServiceResponse { /** * @return the clusterName */ + @ApiModelProperty(name = "cluster_name") public String getClusterName() { return clusterName; } @@ -90,6 +95,7 @@ public class ServiceResponse { /** * @return the desiredState */ + @ApiModelProperty(name = "state") public String getDesiredState() { return desiredState; } @@ -104,6 +110,7 @@ public class ServiceResponse { /** * @return the desiredStackVersion */ + @ApiModelProperty(hidden = true) public String getDesiredStackVersion() { return desiredStackVersion; } @@ -141,7 +148,8 @@ public class ServiceResponse { public void setMaintenanceState(String state) { maintenanceState = state; } - + + @ApiModelProperty(name = "maintenance_state") public String getMaintenanceState() { return maintenanceState; } @@ -152,6 +160,7 @@ public class ServiceResponse { * * @return true or false */ + @ApiModelProperty(name = "credential_store_supported") public boolean isCredentialStoreSupported() { return credentialStoreSupported; } @@ -172,6 +181,7 @@ public class ServiceResponse { * * @return true or false */ + @ApiModelProperty(name = "credential_store_enabled") public boolean isCredentialStoreEnabled() { return credentialStoreEnabled; } @@ -194,4 +204,11 @@ public class ServiceResponse { return result; } + /** + * Interface to help correct Swagger documentation generation + */ + public interface ServiceResponseSwagger extends ApiModel { + @ApiModelProperty(name = "ServiceInfo") + ServiceResponse getServiceResponse(); + } }
