Add REST API calls for DB manipulation. 33/85733/6
authorKate Hsuan <kate.hsuan@qct.io>
Fri, 19 Apr 2019 01:51:05 +0000 (09:51 +0800)
committerKate Hsuan <kate.hsuan@qct.io>
Tue, 23 Apr 2019 02:16:42 +0000 (10:16 +0800)
1. Add the REST APIs for DB configuration.
2. Fix ORM relationship.

Issue-ID: DCAEGEN2-1437

Change-Id: Iae842921aa671419e57f569093ecdd74dea4f8d2
Signed-off-by: Kate Hsuan <kate.hsuan@qct.io>
components/datalake-handler/feeder/src/assembly/scripts/init_db.sql
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/domain/DbConfig.java [new file with mode: 0644]
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/domain/PostReturnBody.java [new file with mode: 0644]
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/domain/Db.java
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/domain/Topic.java
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/repository/DbRepository.java
components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/service/CouchbaseService.java
components/datalake-handler/feeder/src/main/resources/application.properties

index 32b9268..a349d14 100644 (file)
@@ -22,7 +22,7 @@ CREATE TABLE `db` (
   `name` varchar(255) NOT NULL,\r
   `host` varchar(255) DEFAULT NULL,\r
   `port` int(11) DEFAULT NULL,\r
-  `database` varchar(255) DEFAULT NULL,\r
+  `database_name` varchar(255) DEFAULT NULL,\r
   `encrypt` bit(1) DEFAULT NULL,\r
   `login` varchar(255) DEFAULT NULL,\r
   `pass` varchar(255) DEFAULT NULL,\r
@@ -43,10 +43,10 @@ CREATE TABLE `map_db_topic` (
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;\r
 \r
 \r
-insert into db (name,host,login,pass,`database`) values ('Couchbase','dl_couchbase','dl','dl1234','datalake');\r
-insert into db (name,host) values ('Elasticsearch','dl_es');\r
-insert into db (name,host,port,`database`) values ('MongoDB','dl_mongodb',27017,'datalake');\r
-insert into db (name,host) values ('Druid','dl_druid');\r
+insert into db (`name`,`host`,`login`,`pass`,`database`) values ('Couchbase','dl_couchbase','dl','dl1234','datalake');\r
+insert into db (`name`,`host`) values ('Elasticsearch','dl_es');\r
+insert into db (`name`,`host`,`port`,`database`) values ('MongoDB','dl_mongodb',27017,'datalake');\r
+insert into db (`name`,`host`) values ('Druid','dl_druid');\r
 \r
 \r
 -- in production, default enabled should be off\r
index c4288d9..4bfe7aa 100644 (file)
 package org.onap.datalake.feeder.controller;
 
 import java.io.IOException;
-import java.util.Set;
+import java.util.*;
 
 import javax.servlet.http.HttpServletResponse;
 
+import io.swagger.annotations.*;
 import org.onap.datalake.feeder.domain.Db;
 import org.onap.datalake.feeder.domain.Topic;
 import org.onap.datalake.feeder.repository.DbRepository;
+import org.onap.datalake.feeder.repository.TopicRepository;
 import org.onap.datalake.feeder.service.DbService;
+import org.onap.datalake.feeder.controller.domain.DbConfig;
+import org.onap.datalake.feeder.controller.domain.PostReturnBody;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 import org.springframework.validation.BindingResult;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -57,6 +54,7 @@ import io.swagger.annotations.ApiResponses;
 
 @RestController
 @RequestMapping(value = "/dbs", produces = { MediaType.APPLICATION_JSON_VALUE })
+
 //@Api(value = "db", consumes = "application/json", produces = "application/json")
 public class DbController {
 
@@ -65,81 +63,181 @@ public class DbController {
        @Autowired
        private DbRepository dbRepository;
 
+       @Autowired
+       private TopicRepository topicRepository;
+
        @Autowired
        private DbService dbService;
 
        //list all dbs 
-       @GetMapping("/")
+       @GetMapping("")
        @ResponseBody
-       @ApiOperation(value="Get all databases' details.")
-       public Iterable<Db> list() throws IOException {
+       @ApiOperation(value="Gat all databases name")
+       //public Iterable<Db> list() throws IOException {
+       public List<String> list() throws IOException {
                Iterable<Db> ret = dbRepository.findAll();
-               return ret;
+               List<String> retString = new ArrayList<>();
+               for(Db db : ret)
+               {
+                       log.info(db.getName());
+                       retString.add(db.getName());
+
+               }
+               return retString;
        }
 
-       //Read a db
+       //Create a  DB
+       @PostMapping("")
+       @ResponseBody
+       @ApiOperation(value="Create a new database.")
+       public PostReturnBody<DbConfig> createDb(@RequestBody DbConfig dbConfig, BindingResult result, HttpServletResponse response) throws IOException {
+               if (result.hasErrors()) {
+                       sendError(response, 400, "Malformed format of Post body: " + result.toString());
+                       return null;
+               }
+
+               Db oldDb = dbService.getDb(dbConfig.getName());
+               if (oldDb != null) {
+                       sendError(response, 400, "Db already exists: " + dbConfig.getName());
+                       return null;
+               } else {
+                       Db newdb = new Db();
+                       newdb.setName(dbConfig.getName());
+                       newdb.setHost(dbConfig.getHost());
+                       newdb.setPort(dbConfig.getPort());
+                       newdb.setLogin(dbConfig.getLogin());
+                       newdb.setPass(dbConfig.getPassword());
+                       newdb.setEncrypt(false);
+
+                       if(dbConfig.getName().equals("Elecsticsearch") || dbConfig.getName().equals("Druid"))
+                       {
+                               newdb.setDatabase(new String(dbConfig.getDatabase()));
+                       }
+                       dbRepository.save(newdb);
+                       DbConfig retMsg;
+                       PostReturnBody<DbConfig> retBody = new PostReturnBody<>();
+                       retMsg = new DbConfig();
+                       composeRetMessagefromDbConfig(newdb, retMsg);
+                       retBody.setReturnBody(retMsg);
+                       retBody.setStatusCode(200);
+                       return retBody;
+               }
+       }
+
+       //Show 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("/{dbName}")
        @ResponseBody
        @ApiOperation(value="Get a database's details.")
        public Db getDb(@PathVariable("dbName") String dbName, HttpServletResponse response) throws IOException {
-               Db db = dbService.getDb(dbName);
+               /*Db db = dbService.getDb(dbName);
+               if (db == null) {
+                       sendError(response, 404, "Db not found: " + dbName);
+               }*/
+               Db db = dbRepository.findByName(dbName);
                if (db == null) {
                        sendError(response, 404, "Db not found: " + dbName);
                }
                return db;
        }
 
-       //Read topics in a DB 
-       @GetMapping("/{dbName}/topics")
-       @ResponseBody
-       @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;
-       }
 
        //Update Db
-       @PutMapping("/")
+       @PutMapping("/{dbName}")
        @ResponseBody
        @ApiOperation(value="Update a database.")
-       public Db updateDb(@RequestBody Db db, BindingResult result, HttpServletResponse response) throws IOException {
+       public PostReturnBody<DbConfig> updateDb(@PathVariable("dbName") String dbName, @RequestBody DbConfig dbConfig, BindingResult result, HttpServletResponse response) throws IOException {
 
                if (result.hasErrors()) {
                        sendError(response, 400, "Error parsing DB: " + result.toString());
                        return null;
                }
 
-               Db oldDb = dbService.getDb(db.getName());
+               Db oldDb = dbService.getDb(dbConfig.getName());
                if (oldDb == null) {
-                       sendError(response, 404, "Db not found: " + db.getName());
+                       sendError(response, 404, "Db not found: " + dbConfig.getName());
                        return null;
                } else {
-                       dbRepository.save(db);
-                       return db;
+                       oldDb.setName(dbConfig.getName());
+                       oldDb.setHost(dbConfig.getHost());
+                       oldDb.setPort(dbConfig.getPort());
+                       oldDb.setLogin(dbConfig.getLogin());
+                       oldDb.setPass(dbConfig.getPassword());
+                       oldDb.setEncrypt(false);
+
+                       if(oldDb.getName().equals("Elecsticsearch") || oldDb.getName().equals("Druid"))
+                       {
+                               oldDb.setDatabase(dbConfig.getDatabase());
+                       }
+                       dbRepository.save(oldDb);
+                       DbConfig retMsg;
+                       PostReturnBody<DbConfig> retBody = new PostReturnBody<>();
+                       retMsg = new DbConfig();
+                       composeRetMessagefromDbConfig(oldDb, retMsg);
+                       retBody.setReturnBody(retMsg);
+                       retBody.setStatusCode(200);
+                       return retBody;
                }
        }
 
-       @PostMapping("/")
+       //Delete 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
+       @DeleteMapping("/{dbName}")
        @ResponseBody
-       @ApiOperation(value="Create a new database.")
-       public Db createDb(@RequestBody Db db, BindingResult result, HttpServletResponse response) throws IOException {
+       @ApiOperation(value="Delete a database.")
+       public void deleteDb(@PathVariable("dbName") String dbName, HttpServletResponse response) throws IOException {
 
-               if (result.hasErrors()) {
-                       sendError(response, 400, "Error parsing DB: " + result.toString());
-                       return null;
+               Db delDb = dbRepository.findByName(dbName);
+               if (delDb == null) {
+                       sendError(response, 404, "Db not found: " + dbName);
                }
+               Set<Topic> topicRelation = delDb.getTopics();
+               topicRelation.clear();
+               dbRepository.save(delDb);
+               dbRepository.delete(delDb);
+               response.setStatus(204);
+       }
 
-               Db oldDb = dbService.getDb(db.getName());
-               if (oldDb != null) {
-                       sendError(response, 400, "Db already exists: " + db.getName());
+       //Read topics in a DB
+       @GetMapping("/{dbName}/topics")
+       @ResponseBody
+       @ApiOperation(value="Get a database's all topics.")
+       public Set<Topic> getDbTopics(@PathVariable("dbName") String dbName, HttpServletResponse response) throws IOException {
+               //Db db = dbService.getDb(dbName);
+               Set<Topic> topics;
+               try {
+                       Db db = dbRepository.findByName(dbName);
+                       topics = db.getTopics();
+               }catch(Exception ex)
+               {
+                       sendError(response, 404, "DB: " + dbName + " or Topics not found");
                        return null;
-               } else {
-                       dbRepository.save(db);
-                       return db;
+
                }
+               return topics;
+       }
+
+
+       @PostMapping("/verify")
+       @ResponseBody
+       @ApiOperation(value="Database connection verification")
+       public PostReturnBody<DbConfig> verifyDbConnection(@RequestBody DbConfig dbConfig, HttpServletResponse response) throws IOException {
+
+               /*
+                       Not implemented yet.
+                */
+
+               response.setStatus(501);
+               return null;
+       }
+
+       private void composeRetMessagefromDbConfig(Db db, DbConfig dbConfigMsg)
+       {
+               dbConfigMsg.setName(db.getName());
+               dbConfigMsg.setHost(db.getHost());
+               dbConfigMsg.setPort(db.getPort());
        }
 
        private void sendError(HttpServletResponse response, int sc, String msg) throws IOException {
diff --git a/components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/domain/DbConfig.java b/components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/domain/DbConfig.java
new file mode 100644 (file)
index 0000000..63de219
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 2019 QCT
+ *=================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.datalake.feeder.controller.domain;
+
+import java.util.Set;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToMany;
+import javax.persistence.Table;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * JSON request body for DB manipulation.
+ *
+ * @author Kate Hsuan
+ *
+ */
+
+@Getter
+@Setter
+public class DbConfig {
+    private String name;
+    private String host;
+    private String login;
+    private String password;
+    private String database;
+    private int port;
+    private String poperties;
+}
diff --git a/components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/domain/PostReturnBody.java b/components/datalake-handler/feeder/src/main/java/org/onap/datalake/feeder/controller/domain/PostReturnBody.java
new file mode 100644 (file)
index 0000000..107f494
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : DataLake
+ * ================================================================================
+ * Copyright 2019 QCT
+ *=================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.datalake.feeder.controller.domain;
+
+import lombok.Getter;
+import lombok.Setter;
+
+
+/**
+ *   Unified POST return format
+ *   {
+ *       statusCode: int,
+ *       message: {
+ *                   return body ...
+ *       }
+ *   }
+ *
+ *   @author Kate Hsuan
+ *
+ */
+
+@Setter
+@Getter
+public class PostReturnBody<T> {
+    private int statusCode;
+    private T returnBody;
+}
index 3fe14e3..7aaf4e3 100644 (file)
@@ -21,17 +21,19 @@ package org.onap.datalake.feeder.domain;
 
 import java.util.Set;
 
-import javax.persistence.CascadeType;
+import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
 import javax.persistence.Table;
-
 import com.fasterxml.jackson.annotation.JsonBackReference;
-
 import lombok.Getter;
 import lombok.Setter;
 
+
 /**
  * Domain class representing bid data storage
  * 
@@ -44,28 +46,42 @@ import lombok.Setter;
 @Table(name = "db")
 public class Db {
        @Id
+       @Column(name="`name`")
        private String name;
 
+       @Column(name="`host`")
        private String host;
+
+       @Column(name="`port`")
        private Integer port;
+
+       @Column(name="`login`")
        private String login;
+
+       @Column(name="`pass`")
        private String pass;
 
+       @Column(name="`database_name`")
        private String database;
+
+       @Column(name="`encrypt`")
        private Boolean encrypt;
-       
+
+       @Column(name="`property1`")
        private String property1;
+
+       @Column(name="`property2`")
        private String property2;
+
+       @Column(name="`property3`")
        private String property3;
 
        @JsonBackReference
-       @ManyToMany(mappedBy = "dbs", cascade = CascadeType.ALL)
-       /*
-       @ManyToMany(cascade=CascadeType.ALL)//, fetch=FetchType.EAGER) 
+       @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(     name                            = "map_db_topic",
-                               joinColumns             = {  @JoinColumn(name="db_name")  },
-                               inverseJoinColumns      = {  @JoinColumn(name="topic_name")  }
-       ) */
+                       joinColumns             = {  @JoinColumn(name="db_name")  },
+                       inverseJoinColumns      = {  @JoinColumn(name="topic_name")  }
+       )
        protected Set<Topic> topics;
 
        public Db() {
index 6547870..b7f89fc 100644 (file)
@@ -67,7 +67,7 @@ public class Topic {
        //@ManyToMany(mappedBy = "topics", cascade=CascadeType.ALL)
        @JsonBackReference
        //@JsonManagedReference
-       @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+       @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(        name                            = "map_db_topic",
                        joinColumns             = {  @JoinColumn(name="topic_name")  },
                        inverseJoinColumns      = {  @JoinColumn(name="db_name")  }
index 01c908e..a717e10 100644 (file)
@@ -59,21 +59,26 @@ public class CouchbaseService {
        @Autowired
        private DbService dbService;
        
-       Bucket bucket;          
+       Bucket bucket;
+       private boolean isReady = false;
 
        @PostConstruct
        private void init() {
         // Initialize Couchbase Connection
-               
-               Db couchbase = dbService.getCouchbase();
-        Cluster cluster = CouchbaseCluster.create(couchbase.getHost());
-        cluster.authenticate(couchbase.getLogin(), couchbase.getPass());
-        bucket = cluster.openBucket(couchbase.getDatabase());
-
-               log.info("Connect to Couchbase {}", couchbase.getHost());
-               
-        // Create a N1QL Primary Index (but ignore if it exists)
-        bucket.bucketManager().createN1qlPrimaryIndex(true, false);                 
+        try {
+            Db couchbase = dbService.getCouchbase();
+            Cluster cluster = CouchbaseCluster.create(couchbase.getHost());
+            cluster.authenticate(couchbase.getLogin(), couchbase.getPass());
+            bucket = cluster.openBucket(couchbase.getDatabase());
+            log.info("Connect to Couchbase {}", couchbase.getHost());
+            // Create a N1QL Primary Index (but ignore if it exists)
+            bucket.bucketManager().createN1qlPrimaryIndex(true, false);
+        }
+        catch(Exception        ex)
+        {
+            isReady = false;
+        }
+        isReady = true;
        }
 
        @PreDestroy
index 42b1345..842d01b 100644 (file)
@@ -1,6 +1,6 @@
 
 server.port = 1680
-
+server.servlet.context-path = /datalake/v1
 
 # Spring connection to MariaDB for ORM
 #spring.jpa.hibernate.ddl-auto=update