Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id A093C200C78 for ; Thu, 18 May 2017 11:48:48 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 9F0DA160BC4; Thu, 18 May 2017 09:48:48 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 7053E160BB0 for ; Thu, 18 May 2017 11:48:47 +0200 (CEST) Received: (qmail 96240 invoked by uid 500); 18 May 2017 09:48:46 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 96230 invoked by uid 99); 18 May 2017 09:48:45 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 18 May 2017 09:48:45 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id A6EB6DFCBE; Thu, 18 May 2017 09:48:45 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: adoroszlai@apache.org To: commits@ambari.apache.org Message-Id: <8a575b16d5c54f37873cb7abaf3f9be5@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-21026. Integrate BlueprintService with Swagger (Balazs Bence Sari via adoroszlai) Date: Thu, 18 May 2017 09:48:45 +0000 (UTC) archived-at: Thu, 18 May 2017 09:48:48 -0000 Repository: ambari Updated Branches: refs/heads/ambari-rest-api-explorer 9763993c7 -> f67879461 AMBARI-21026. Integrate BlueprintService 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/f6787946 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f6787946 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f6787946 Branch: refs/heads/ambari-rest-api-explorer Commit: f678794617f6e221bd63b8abd9b1c54618680831 Parents: 9763993 Author: Balazs Bence Sari Authored: Thu May 18 11:42:38 2017 +0200 Committer: Attila Doroszlai Committed: Thu May 18 11:42:38 2017 +0200 ---------------------------------------------------------------------- .../ambari/server/api/services/BaseService.java | 4 +- .../server/api/services/BlueprintService.java | 105 +++++++++++++++++-- .../server/controller/BlueprintSwagger.java | 91 ++++++++++++++++ 3 files changed, 188 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f6787946/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 5f6474c..ce668ee 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 @@ -76,6 +76,9 @@ public abstract class BaseService { static final String QUERY_TO_DESCRIPTION = "The ending page resource (inclusive). \"end\" is also accepted."; static final String QUERY_TO_TYPE = "integer"; static final String QUERY_TO_VALUES = "range[1, infinity]"; + static final String QUERY_PREDICATE = "{predicate}"; + static final String QUERY_PREDICATE_DESCRIPTION = "The predicate to filter resources by. Omitting the predicate will " + + "match all resources."; static final String RESPONSE_CONTAINER_LIST = "List"; @@ -85,7 +88,6 @@ public abstract class BaseService { static final String PARAM_TYPE_QUERY = "query"; static final String PARAM_TYPE_BODY = "body"; - static final String FIELDS_SEPARATOR = ", "; /** http://git-wip-us.apache.org/repos/asf/ambari/blob/f6787946/ambari-server/src/main/java/org/apache/ambari/server/api/services/BlueprintService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BlueprintService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BlueprintService.java index 8159ea4..b23752f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/BlueprintService.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/BlueprintService.java @@ -28,11 +28,22 @@ 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.BlueprintSwagger; 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 handling REST requests for the /blueprints endpoint. @@ -41,8 +52,10 @@ import org.apache.ambari.server.controller.spi.Resource; * immutable. */ @Path("/blueprints/") +@Api(value = "Blueprints", description = "Endpoint for blueprint specific operations") public class BlueprintService extends BaseService { + public static final String BLUEPRINT_REQUEST_TYPE = "org.apache.ambari.server.controller.BlueprintSwagger"; /** * Handles: GET /blueprints * Get all blueprints. @@ -52,7 +65,27 @@ public class BlueprintService extends BaseService { * @return blueprint collection resource representation */ @GET - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get all blueprints", + nickname = "BlueprintService#getBlueprints", + response = BlueprintSwagger.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "Blueprints/blueprint_name", + dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY), + @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION, + defaultValue = "Blueprints/blueprint_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 getBlueprints(String body, @Context HttpHeaders headers, @Context UriInfo ui) { return handleRequest(headers, body, ui, Request.Type.GET, createBlueprintResource(null)); } @@ -68,11 +101,25 @@ public class BlueprintService extends BaseService { */ @GET @Path("{blueprintName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Get the details of a blueprint", + nickname = "BlueprintService#getBlueprint", + response = BlueprintSwagger.class, + responseContainer = RESPONSE_CONTAINER_LIST) + @ApiImplicitParams({ + @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, + defaultValue = "Blueprints/*", + 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_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED), + @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR) + }) public Response getBlueprint(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("blueprintName") String blueprintName) { - - return handleRequest(headers, body, ui, Request.Type.GET, createBlueprintResource(blueprintName)); + @ApiParam @PathParam("blueprintName") String blueprintName) { + return handleRequest(headers, body, ui, Request.Type.GET, createBlueprintResource(blueprintName)); } /** @@ -86,9 +133,25 @@ public class BlueprintService extends BaseService { */ @POST @Path("{blueprintName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Creates a blueprint", + nickname = "BlueprintService#createBlueprint" + ) + @ApiImplicitParams({ + @ApiImplicitParam(dataType = BLUEPRINT_REQUEST_TYPE, paramType = PARAM_TYPE_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_RESOURCE_NOT_FOUND), + @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 createBlueprint(String body, @Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("blueprintName") String blueprintName) { + @ApiParam @PathParam("blueprintName") String blueprintName) { return handleRequest(headers, body, ui, Request.Type.POST, createBlueprintResource(blueprintName)); } @@ -104,10 +167,19 @@ public class BlueprintService extends BaseService { */ @DELETE @Path("{blueprintName}") - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Deletes a blueprint", + nickname = "BlueprintService#deleteBlueprint" + ) + @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 deleteBlueprint(@Context HttpHeaders headers, @Context UriInfo ui, - @PathParam("blueprintName") String blueprintName) { - + @ApiParam @PathParam("blueprintName") String blueprintName) { return handleRequest(headers, null, ui, Request.Type.DELETE, createBlueprintResource(blueprintName)); } @@ -120,7 +192,18 @@ public class BlueprintService extends BaseService { * @return information regarding the deleted blueprint */ @DELETE - @Produces("text/plain") + @Produces(MediaType.TEXT_PLAIN) + @ApiOperation(value = "Deletes multiple blueprints that match the predicate. Omitting the predicate will delete all " + + "blueprints.", + nickname = "BlueprintService#deleteBlueprints" + ) + @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 deleteBlueprints(@Context HttpHeaders headers, @Context UriInfo ui) { return handleRequest(headers, null, ui, Request.Type.DELETE, createBlueprintResource(null)); } http://git-wip-us.apache.org/repos/asf/ambari/blob/f6787946/ambari-server/src/main/java/org/apache/ambari/server/controller/BlueprintSwagger.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/BlueprintSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/BlueprintSwagger.java new file mode 100644 index 0000000..69bd192 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/BlueprintSwagger.java @@ -0,0 +1,91 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.server.controller; + +import java.util.List; +import java.util.Map; + +import org.apache.ambari.server.state.SecurityType; + +import io.swagger.annotations.ApiModelProperty; + +/** + * Request / response schema for blueprint API Swagger documentation generation. The interface only serves documentation + * generation purposes, it is not meant to be implemented. + */ +public interface BlueprintSwagger extends ApiModel { + + @ApiModelProperty(name = "Blueprints") + BlueprintInfo getBlueprintInfo(); + + @ApiModelProperty(name = "configurations") + List> getConfigurations(); + + @ApiModelProperty(name = "host_groups") + List getHostGroups(); + + interface BlueprintInfo { + @ApiModelProperty(name = "blueprint_name") + String getBlueprintName(); + + @ApiModelProperty(name = "stack_name") + String getStackName(); + + @ApiModelProperty(name = "stack_version") + String getStackVersion(); + + @ApiModelProperty(name = "security") + SecurityInfo getSecurity(); + } + + interface SecurityInfo { + @ApiModelProperty(name = "security_type") + SecurityType getSecurityType(); + + @ApiModelProperty(name = "kerberos_descriptor") + Map getKerberosDescriptor(); + + @ApiModelProperty(name = "kerberos_descriptor_reference") + String getKerberosDescriptorReference(); + } + + interface HostGroupInfo { + @ApiModelProperty(name = "name") + String getHostGroupName(); + + @ApiModelProperty(name = "cardinality") + int getCardinality(); + + @ApiModelProperty(name = "components") + List getComponents(); + + @ApiModelProperty(name = "configurations") + List> getConfigurations(); + + } + + interface ComponentInfo { + @ApiModelProperty(name = "name") + String getComponentName(); + + @ApiModelProperty(name = "provision_action") + String getProvisionAction(); + } + +}