This is an automated email from the ASF dual-hosted git repository.

ztang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git


The following commit(s) were added to refs/heads/master by this push:
     new 56dd1a8  SUBMARINE-481. Use Swagger to submarine RESTful APIs
56dd1a8 is described below

commit 56dd1a8b5888aafa4d051a49c996b8c53beff79c
Author: pingsutw <[email protected]>
AuthorDate: Thu May 7 09:22:58 2020 +0800

    SUBMARINE-481. Use Swagger to submarine RESTful APIs
    
    ### What is this PR for?
    Use swagger annotation to generate API document
    https://gist.github.com/pingsutw/4d96afb54d4c767304f74844b432585c
    1. Build Submarine source code
    2. start submarine server
    3. open localhost:8080/v2/swagger.json
    
    ### What type of PR is it?
    [Improvement]
    
    ### Todos
    * [ ] - Task
    
    ### What is the Jira issue?
    https://issues.apache.org/jira/browse/SUBMARINE-481
    
    ### How should this be tested?
    https://travis-ci.org/github/pingsutw/hadoop-submarine/builds/680491536
    
    ### Screenshots (if appropriate)
    
    ### Questions:
    * Does the licenses files need update? No
    * Is there breaking changes for older versions? No
    * Does this needs documentation? No
    
    Author: pingsutw <[email protected]>
    
    Closes #271 from pingsutw/SUBMARINE-481 and squashes the following commits:
    
    a80b90b [pingsutw] Add License
    76c3887 [pingsutw] update
    c2a8e17 [pingsutw] SUBMARINE-481. Use Swagger to describe and document 
submarine RESTful APIs
---
 pom.xml                                            |  1 +
 submarine-server/server-core/pom.xml               | 33 ++++++++++
 .../org/apache/submarine/server/Bootstrap.java     | 75 ++++++++++++++++++++++
 .../submarine/server/rest/JobManagerRestApi.java   | 38 +++++++++++
 .../workbench-web-ng/src/WEB-INF/web.xml           | 25 +++++++-
 5 files changed, 171 insertions(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index d16b378..f7aa8ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -89,6 +89,7 @@
     <node.version>v10.12.0</node.version>
     <yarn.version>v1.10.1</yarn.version>
     <npm.version>6.4.1</npm.version>
+    <io.swagger.version>2.1.2</io.swagger.version>
 
     
<hadoop.common.build.dir>${basedir}/../hadoop-common-project/hadoop-common/target</hadoop.common.build.dir>
     <slf4j.version>1.7.25</slf4j.version>
diff --git a/submarine-server/server-core/pom.xml 
b/submarine-server/server-core/pom.xml
index 8dcfc36..0917f48 100644
--- a/submarine-server/server-core/pom.xml
+++ b/submarine-server/server-core/pom.xml
@@ -45,6 +45,39 @@
     </dependency>
 
     <dependency>
+      <groupId>io.swagger.core.v3</groupId>
+      <artifactId>swagger-jaxrs2</artifactId>
+      <version>${io.swagger.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>com.fasterxml.jackson.core</groupId>
+          <artifactId>jackson-databind</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>io.github.classgraph</groupId>
+          <artifactId>classgraph</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.fasterxml.jackson.jaxrs</groupId>
+          <artifactId>jackson-jaxrs-json-provider</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.fasterxml.jackson.module</groupId>
+          <artifactId>jackson-module-jaxb-annotations</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.javassist</groupId>
+               <artifactId>javassist</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>io.swagger.core.v3</groupId>
+      <artifactId>swagger-jaxrs2-servlet-initializer-v2</artifactId>
+      <version>${io.swagger.version}</version>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.submarine</groupId>
       <artifactId>submarine-commons-metastore</artifactId>
       <version>${project.version}</version>
diff --git 
a/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java
 
b/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java
new file mode 100644
index 0000000..c4bee19
--- /dev/null
+++ 
b/submarine-server/server-core/src/main/java/org/apache/submarine/server/Bootstrap.java
@@ -0,0 +1,75 @@
+/*
+ * 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.submarine.server;
+
+import io.swagger.v3.jaxrs2.integration.JaxrsOpenApiContextBuilder;
+import io.swagger.v3.oas.integration.SwaggerConfiguration;
+import io.swagger.v3.oas.integration.OpenApiConfigurationException;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.info.Contact;
+import io.swagger.v3.oas.models.info.Info;
+import io.swagger.v3.oas.models.info.License;
+import io.swagger.v3.oas.models.servers.Server;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class Bootstrap extends HttpServlet {
+  @Override
+  public void init(ServletConfig config) throws ServletException {
+
+    OpenAPI oas = new OpenAPI();
+    Info info = new Info()
+             .title("Submarine Experiment API")
+             .description("The Submarine REST API allows you to create, list, 
and get experiments. The" +
+                     "API is hosted under the /v1/jobs route on the Submarine 
server. For example," +
+                     "to list experiments on a server hosted at 
http://localhost:8080, access" +
+                     "http://localhost:8080/api/v1/jobs/";)
+             .termsOfService("http://swagger.io/terms/";)
+             .contact(new Contact()
+             .email("[email protected]"))
+             .version("0.4.0-SNAPSHOT")
+             .license(new License()
+             .name("Apache 2.0")
+             .url("http://www.apache.org/licenses/LICENSE-2.0.html";));
+
+    oas.info(info);
+    List<Server> servers = new ArrayList<>();
+    servers.add(new Server().url("/api"));
+    oas.servers(servers);
+    SwaggerConfiguration oasConfig = new SwaggerConfiguration()
+            .openAPI(oas)
+            
.resourcePackages(Stream.of("org.apache.submarine.server.rest").collect(Collectors.toSet()));
+
+    try {
+      new JaxrsOpenApiContextBuilder()
+              .servletConfig(config)
+              .openApiConfiguration(oasConfig)
+              .buildContext(true);
+    } catch (OpenApiConfigurationException e) {
+      throw new ServletException(e.getMessage(), e);
+    }
+  }
+}
+
diff --git 
a/submarine-server/server-core/src/main/java/org/apache/submarine/server/rest/JobManagerRestApi.java
 
b/submarine-server/server-core/src/main/java/org/apache/submarine/server/rest/JobManagerRestApi.java
index ef26e40..14e7ca9 100644
--- 
a/submarine-server/server-core/src/main/java/org/apache/submarine/server/rest/JobManagerRestApi.java
+++ 
b/submarine-server/server-core/src/main/java/org/apache/submarine/server/rest/JobManagerRestApi.java
@@ -32,6 +32,11 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import java.util.List;
 
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+
 import org.apache.submarine.commons.utils.exception.SubmarineRuntimeException;
 import org.apache.submarine.server.job.JobManager;
 import org.apache.submarine.server.api.job.Job;
@@ -53,6 +58,11 @@ public class JobManagerRestApi {
   @GET
   @Path(RestConstants.PING)
   @Consumes(MediaType.APPLICATION_JSON)
+  @Operation(summary = "Ping submarine server",
+          tags = {"jobs"},
+          description = "Return the Pong message for test the connectivity",
+          responses = {
+                  @ApiResponse(responseCode = "200", description = "successful 
operation")})
   public Response ping() {
     return new JsonResponse.Builder<String>(Response.Status.OK)
         .success(true).result("Pong").build();
@@ -65,6 +75,11 @@ public class JobManagerRestApi {
    */
   @POST
   @Consumes({RestConstants.MEDIA_TYPE_YAML, MediaType.APPLICATION_JSON})
+  @Operation(summary = "Create a job",
+          tags = {"jobs"},
+          responses = {
+                  @ApiResponse(description = "successful operation", content = 
@Content(
+                          schema = @Schema(implementation = Job.class)))})
   public Response createJob(JobSpec spec) {
     try {
       Job job = jobManager.createJob(spec);
@@ -79,6 +94,11 @@ public class JobManagerRestApi {
    * @return job list
    */
   @GET
+  @Operation(summary = "List jobs",
+          tags = {"jobs"},
+          responses = {
+                  @ApiResponse(description = "successful operation", content = 
@Content(
+                          schema = @Schema(implementation = Job.class)))})
   public Response listJob(@QueryParam("status") String status) {
     try {
       List<Job> jobList = jobManager.listJobsByStatus(status);
@@ -95,6 +115,12 @@ public class JobManagerRestApi {
    */
   @GET
   @Path("/{id}")
+  @Operation(summary = "Find job by id",
+          tags = {"jobs"},
+          responses = {
+                  @ApiResponse(description = "successful operation", content = 
@Content(
+                          schema = @Schema(implementation = Job.class))),
+                  @ApiResponse(responseCode = "404", description = "Job not 
found")})
   public Response getJob(@PathParam(RestConstants.JOB_ID) String id) {
     try {
       Job job = jobManager.getJob(id);
@@ -107,6 +133,12 @@ public class JobManagerRestApi {
   @PATCH
   @Path("/{id}")
   @Consumes({RestConstants.MEDIA_TYPE_YAML, MediaType.APPLICATION_JSON})
+  @Operation(summary = "Update the job in the submarine server with job spec",
+          tags = {"jobs"},
+          responses = {
+                  @ApiResponse(description = "successful operation", content = 
@Content(
+                          schema = @Schema(implementation = Job.class))),
+                  @ApiResponse(responseCode = "404", description = "Job not 
found")})
   public Response patchJob(@PathParam(RestConstants.JOB_ID) String id, JobSpec 
spec) {
     try {
       Job job = jobManager.patchJob(id, spec);
@@ -124,6 +156,12 @@ public class JobManagerRestApi {
    */
   @DELETE
   @Path("/{id}")
+  @Operation(summary = "Delete the job",
+          tags = {"jobs"},
+          responses = {
+                  @ApiResponse(description = "successful operation", content = 
@Content(
+                          schema = @Schema(implementation = Job.class))),
+                  @ApiResponse(responseCode = "404", description = "Job not 
found")})
   public Response deleteJob(@PathParam(RestConstants.JOB_ID) String id) {
     try {
       Job job = jobManager.deleteJob(id);
diff --git a/submarine-workbench/workbench-web-ng/src/WEB-INF/web.xml 
b/submarine-workbench/workbench-web-ng/src/WEB-INF/web.xml
index c7b7a29..677ece1 100644
--- a/submarine-workbench/workbench-web-ng/src/WEB-INF/web.xml
+++ b/submarine-workbench/workbench-web-ng/src/WEB-INF/web.xml
@@ -28,7 +28,19 @@
     
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
     <init-param>
       <param-name>jersey.config.server.provider.packages</param-name>
-      <param-value>org.apache.submarine.server.rest</param-value>
+      
<param-value>io.swagger.v3.jaxrs2.integration.resources,org.apache.submarine.server.rest</param-value>
+    </init-param>
+    <init-param>
+      <param-name>openApi.configuration.resourceClasses</param-name>
+      
<param-value>org.apache.submarine.server.rest.JobManagerRestApi</param-value>
+    </init-param>
+    <init-param>
+      <param-name>openApi.configuration.scannerClass</param-name>
+      
<param-value>io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner</param-value>
+    </init-param>
+    <init-param>
+      <param-name>openApi.configuration.prettyPrint</param-name>
+      <param-value>true</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
   </servlet>
@@ -36,6 +48,17 @@
     <param-name>configuration</param-name>
     <param-value>deployment</param-value>
   </context-param>
+  
+  <servlet-mapping>
+    <servlet-name>default</servlet-name>
+    <url-pattern>/v1/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet>
+    <servlet-name>Bootstrap</servlet-name>
+    <servlet-class>org.apache.submarine.server.Bootstrap</servlet-class>
+    <load-on-startup>2</load-on-startup>
+  </servlet>
 
   <session-config>
     <cookie-config>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to