Integrate Swagger for REST API 76/84576/1
authorGuobiao Mo <guobiaomo@chinamobile.com>
Mon, 8 Apr 2019 23:59:14 +0000 (16:59 -0700)
committerGuobiao Mo <guobiaomo@chinamobile.com>
Mon, 8 Apr 2019 23:59:14 +0000 (16:59 -0700)
Issue-ID: DCAEGEN2-1400
Change-Id: Idd68e1f50b6572dcd4c2e17291628810f3813dba
Signed-off-by: Guobiao Mo <guobiaomo@chinamobile.com>
components/datalake-handler/feeder/pom.xml
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/Application.java
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/config/SwaggerConfig.java [new file with mode: 0644]
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/DbController.java
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/FeederController.java
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/TopicController.java
components/datalake-handler/feeder/src/test/java/org/onap/datalake/feeder/config/SwaggerConfigTest.java [new file with mode: 0644]

index 5b47a24..d6b5078 100644 (file)
 
 
        <dependencies>
-       
+
                <dependency>
-               <groupId>org.mariadb.jdbc</groupId>
-               <artifactId>mariadb-java-client</artifactId>
+                       <groupId>org.mariadb.jdbc</groupId>
+                       <artifactId>mariadb-java-client</artifactId>
                </dependency>
-       
+
                <dependency>
                        <groupId>org.json</groupId>
                        <artifactId>json</artifactId>
                </dependency>
-       
+
                <dependency>
                        <groupId>org.apache.httpcomponents</groupId>
                        <artifactId>httpclient</artifactId>
-                       <version>4.5.6</version>
-               </dependency>
+                       </dependency>
 
                <dependency>
                        <groupId>org.apache.kafka</groupId>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-actuator</artifactId>
                </dependency>
-        
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-jpa</artifactId>
-        </dependency>
-        
+
+               <dependency>
+                       <groupId>org.springframework.boot</groupId>
+                       <artifactId>spring-boot-starter-data-jpa</artifactId>
+               </dependency>
+
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-data-couchbase</artifactId>
                        <version>6.0.10.Final</version>
                </dependency>
 
+               <dependency>
+                       <groupId>io.springfox</groupId>
+                       <artifactId>springfox-swagger2</artifactId>
+                       <version>2.9.2</version>
+                       <scope>compile</scope>
+               </dependency>
+
+               <dependency>
+                       <groupId>io.springfox</groupId>
+                       <artifactId>springfox-swagger-ui</artifactId>
+                       <version>2.9.2</version>
+                       <scope>compile</scope>
+               </dependency>
+
        </dependencies>
 
        <build>
index 8f17937..83f56b1 100644 (file)
@@ -26,6 +26,8 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.Bean;
 
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
 /**
  * Entry point of the DataLake feeder application
  * 
@@ -34,6 +36,7 @@ import org.springframework.context.annotation.Bean;
  */
 
 @SpringBootApplication
+@EnableSwagger2
 public class Application {
        public static void main(String[] args) {
                SpringApplication.run(Application.class, args);
diff --git a/components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/config/SwaggerConfig.java b/components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/config/SwaggerConfig.java
new file mode 100644 (file)
index 0000000..dcf00a9
--- /dev/null
@@ -0,0 +1,60 @@
+/*\r
+* ============LICENSE_START=======================================================\r
+* ONAP : DATALAKE\r
+* ================================================================================\r
+* Copyright 2019 China Mobile\r
+*=================================================================================\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+*     http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ============LICENSE_END=========================================================\r
+*/\r
+\r
+package org.onap.datalake.feeder.config;\r
+\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.context.annotation.Configuration;\r
+import com.google.common.base.Predicate;\r
+import com.google.common.base.Predicates;\r
+import springfox.documentation.builders.ApiInfoBuilder;\r
+import springfox.documentation.builders.PathSelectors;\r
+import springfox.documentation.builders.RequestHandlerSelectors;\r
+import springfox.documentation.service.ApiInfo;\r
+import springfox.documentation.spi.DocumentationType;\r
+import springfox.documentation.spring.web.plugins.Docket;\r
+import springfox.documentation.swagger2.annotations.EnableSwagger2;\r
+\r
+/**\r
+ * For Swagger integration\r
+ * \r
+ * @author Guobiao Mo\r
+ *\r
+ */\r
+\r
+@Configuration\r
+@EnableSwagger2\r
+public class SwaggerConfig {\r
+       @Bean\r
+       public Docket produceApi() {\r
+               return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("org.onap.datalake.feeder")).paths(paths()).build();\r
+       }\r
+\r
+       // Describe your apis\r
+       private ApiInfo apiInfo() {\r
+               return new ApiInfoBuilder().title("DataLake Rest APIs").description("This page lists all the rest apis for DataLake.").version("1.0.0-SNAPSHOT").build();\r
+       }\r
+\r
+       // Only select apis that matches the given Predicates.\r
+       private Predicate<String> paths() {\r
+               // Match all paths except /error\r
+               return Predicates.or(PathSelectors.regex("/dbs.*"), PathSelectors.regex("/topics.*"), PathSelectors.regex("/feeder.*"));\r
+       }\r
+}
\ No newline at end of file
index c34befc..c4288d9 100644 (file)
@@ -42,8 +42,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
 /**
- * This controller manages the big data storage settings. All the settings are saved in database. 
+ * This controller manages the big data storage settings. All the settings are
+ * saved in database.
  * 
  * @author Guobiao Mo
  *
@@ -51,19 +57,21 @@ import org.springframework.web.bind.annotation.RestController;
 
 @RestController
 @RequestMapping(value = "/dbs", produces = { MediaType.APPLICATION_JSON_VALUE })
+//@Api(value = "db", consumes = "application/json", produces = "application/json")
 public class DbController {
 
        private final Logger log = LoggerFactory.getLogger(this.getClass());
 
        @Autowired
        private DbRepository dbRepository;
-       
+
        @Autowired
        private DbService dbService;
 
        //list all dbs 
        @GetMapping("/")
        @ResponseBody
+       @ApiOperation(value="Get all databases' details.")
        public Iterable<Db> list() throws IOException {
                Iterable<Db> ret = dbRepository.findAll();
                return ret;
@@ -71,18 +79,23 @@ public class DbController {
 
        //Read a db
        //the topics are missing in the return, since in we use @JsonBackReference on Db's topics 
-       //need to the the following method to retrieve the topic list
-       @GetMapping("/{name}")
+       //need to the the following method to retrieve the topic list 
+       @GetMapping("/{dbName}")
        @ResponseBody
-       public Db getDb(@PathVariable("name") String dbName) throws IOException {
+       @ApiOperation(value="Get a database's details.")
+       public Db getDb(@PathVariable("dbName") String dbName, HttpServletResponse response) throws IOException {
                Db db = dbService.getDb(dbName);
+               if (db == null) {
+                       sendError(response, 404, "Db not found: " + dbName);
+               }
                return db;
        }
 
        //Read topics in a DB 
-       @GetMapping("/{name}/topics")
+       @GetMapping("/{dbName}/topics")
        @ResponseBody
-       public Set<Topic> getDbTopics(@PathVariable("name") String dbName) throws IOException {
+       @ApiOperation(value="Get a database's all topics.")
+       public Set<Topic> getDbTopics(@PathVariable("dbName") String dbName) throws IOException {
                Db db = dbService.getDb(dbName);
                Set<Topic> topics = db.getTopics();
                return topics;
@@ -91,45 +104,46 @@ public class DbController {
        //Update Db
        @PutMapping("/")
        @ResponseBody
+       @ApiOperation(value="Update a database.")
        public Db updateDb(@RequestBody Db db, BindingResult result, HttpServletResponse response) throws IOException {
 
                if (result.hasErrors()) {
-                       sendError(response, 400, "Error parsing DB: "+result.toString());
-                       return null; 
+                       sendError(response, 400, "Error parsing DB: " + result.toString());
+                       return null;
                }
 
-               Db oldDb = getDb(db.getName());
+               Db oldDb = dbService.getDb(db.getName());
                if (oldDb == null) {
-                       sendError(response, 404, "Db not found: "+db.getName());
-                       return null; 
+                       sendError(response, 404, "Db not found: " + db.getName());
+                       return null;
                } else {
-                       dbRepository.save(db);                  
+                       dbRepository.save(db);
                        return db;
                }
        }
 
-       //create a new Db  
        @PostMapping("/")
        @ResponseBody
+       @ApiOperation(value="Create a new database.")
        public Db createDb(@RequestBody Db db, BindingResult result, HttpServletResponse response) throws IOException {
 
                if (result.hasErrors()) {
-                       sendError(response, 400, "Error parsing DB: "+result.toString());
+                       sendError(response, 400, "Error parsing DB: " + result.toString());
                        return null;
                }
 
-               Db oldDb = getDb(db.getName());
+               Db oldDb = dbService.getDb(db.getName());
                if (oldDb != null) {
-                       sendError(response, 400, "Db already exists: "+db.getName());
+                       sendError(response, 400, "Db already exists: " + db.getName());
                        return null;
                } else {
-                       dbRepository.save(db);                  
+                       dbRepository.save(db);
                        return db;
                }
        }
 
        private void sendError(HttpServletResponse response, int sc, String msg) throws IOException {
                log.info(msg);
-               response.sendError(sc, msg);            
+               response.sendError(sc, msg);
        }
 }
index 2e13e1a..3d296d5 100644 (file)
@@ -30,6 +30,8 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.annotations.ApiOperation;
+
 /**
  * This controller controls DL data feeder.
  * 
@@ -51,6 +53,7 @@ public class FeederController {
      * @throws IOException 
      */
     @GetMapping("/start")
+       @ApiOperation(value="Start pulling data.")
     public String start() throws IOException {
        log.info("DataLake feeder starting to pull data from DMaaP...");
        pullService.start();
@@ -61,6 +64,7 @@ public class FeederController {
      * @return message that application stop process is triggered
      */
     @GetMapping("/stop")
+       @ApiOperation(value="Stop pulling data.")
     public String stop() {     
        pullService.shutdown();
        log.info("DataLake feeder is stopped.");
@@ -70,6 +74,7 @@ public class FeederController {
      * @return feeder status
      */
     @GetMapping("/status")
+       @ApiOperation(value="Retrieve feeder status.")
     public String status() {           
        String status = "Feeder is running: "+pullService.isRunning();
        log.info("senting feeder status ...");//TODO we can send what topics are monitored, how many messages are sent, etc. 
index c4aec14..bf9e417 100644 (file)
@@ -46,6 +46,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
+import io.swagger.annotations.ApiOperation;
+
 /**
  * This controller manages topic settings. 
  * 
@@ -75,43 +77,43 @@ public class TopicController {
        @Autowired
        private DbService dbService;
        
-       //list all topics in DMaaP
        @GetMapping("/dmaap/")
        @ResponseBody
+       @ApiOperation(value="List all topics in DMaaP.")
        public List<String> listDmaapTopics() throws IOException {
                return dmaapService.getTopics();
        }
 
-       //list all topics 
        @GetMapping("/")
        @ResponseBody
+       @ApiOperation(value="List all topics' details.")
        public Iterable<Topic> list() throws IOException {
                Iterable<Topic> ret = topicRepository.findAll();
                return ret;
        }
 
-       //Read a topic
-       @GetMapping("/{topicname}")
+       @GetMapping("/{topicName}")
        @ResponseBody
-       public Topic getTopic(@PathVariable("topicname") String topicName) throws IOException {
+       @ApiOperation(value="Get a topic's details.")
+       public Topic getTopic(@PathVariable("topicName") String topicName) throws IOException {
                Topic topic = topicService.getTopic(topicName);
                return topic;
        }
 
-       //Read DBs in a topic 
-       @GetMapping("/{topicname}/dbs")
+       @GetMapping("/{topicName}/dbs")
        @ResponseBody
-       public Set<Db> getTopicDbs(@PathVariable("topicname") String topicName) throws IOException {
+       @ApiOperation(value="Get all DBs in a topic.")
+       public Set<Db> getTopicDbs(@PathVariable("topicName") String topicName) throws IOException {
                Topic topic = topicService.getTopic(topicName);
                Set<Db> dbs = topic.getDbs();
                return dbs;
        }
 
-       //Update Topic
-       //This is not a partial update: old topic is wiped out, and new topic is created base on the input json. 
+       //This is not a partial update: old topic is wiped out, and new topic is created based on the input json. 
        //One exception is that old DBs are kept
        @PutMapping("/")
        @ResponseBody
+       @ApiOperation(value="Update a topic.")
        public Topic updateTopic(@RequestBody Topic topic, BindingResult result, HttpServletResponse response) throws IOException {
 
                if (result.hasErrors()) {
@@ -134,10 +136,10 @@ public class TopicController {
                        return topic;
                }
        }
-
-       //create a new Topic  
        @PostMapping("/")
        @ResponseBody
+       @ApiOperation(value="Create a new topic.")
        public Topic createTopic(@RequestBody Topic topic, BindingResult result, HttpServletResponse response) throws IOException {
                
                if (result.hasErrors()) {
@@ -160,10 +162,10 @@ public class TopicController {
                }
        }
 
-       //delete a db from the topic
-       @DeleteMapping("/{topicname}/db/{dbname}")
+       @DeleteMapping("/{topicName}/db/{dbName}")
        @ResponseBody
-       public Set<Db> deleteDb(@PathVariable("topicname") String topicName, @PathVariable("dbname") String dbName, HttpServletResponse response) throws IOException {
+       @ApiOperation(value="Delete a DB from a topic.")
+       public Set<Db> deleteDb(@PathVariable("topicName") String topicName, @PathVariable("dbName") String dbName, HttpServletResponse response) throws IOException {
                Topic topic = topicService.getTopic(topicName);
                Set<Db> dbs = topic.getDbs();
                dbs.remove(new Db(dbName));
@@ -172,10 +174,10 @@ public class TopicController {
                return topic.getDbs();           
        }
 
-       //add a db to the topic
-       @PutMapping("/{topicname}/db/{dbname}")
+       @PutMapping("/{topicName}/db/{dbName}")
        @ResponseBody
-       public Set<Db> addDb(@PathVariable("topicname") String topicName, @PathVariable("dbname") String dbName, HttpServletResponse response) throws IOException {
+       @ApiOperation(value="Add a DB to a topic.")
+       public Set<Db> addDb(@PathVariable("topicName") String topicName, @PathVariable("dbName") String dbName, HttpServletResponse response) throws IOException {
                Topic topic = topicService.getTopic(topicName);
                Set<Db> dbs = topic.getDbs();           
 
diff --git a/components/datalake-handler/feeder/src/test/java/org/onap/datalake/feeder/config/SwaggerConfigTest.java b/components/datalake-handler/feeder/src/test/java/org/onap/datalake/feeder/config/SwaggerConfigTest.java
new file mode 100644 (file)
index 0000000..4293c69
--- /dev/null
@@ -0,0 +1,46 @@
+/*\r
+* ============LICENSE_START=======================================================\r
+* ONAP : DATALAKE\r
+* ================================================================================\r
+* Copyright 2019 China Mobile\r
+*=================================================================================\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+*     http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ============LICENSE_END=========================================================\r
+*/\r
+\r
+package org.onap.datalake.feeder.config;\r
+\r
+import static org.junit.Assert.fail;\r
+\r
+import org.junit.Test;\r
+\r
+/**\r
+ * Test Swagger integration\r
+ * \r
+ * @author Guobiao Mo\r
+ *\r
+ */\r
\r
+public class SwaggerConfigTest {\r
+\r
+    @Test\r
+       public void test() {\r
+        try {\r
+               SwaggerConfig config = new SwaggerConfig();\r
+               config.produceApi();\r
+        } catch (Exception e) {\r
+            fail("failed to read configure Swagger.");\r
+        }\r
+       }\r
+\r
+}
\ No newline at end of file