IOT-3143
[iotivity.git] / cloud / resourcedirectory / src / main / java / org / iotivity / cloud / rdserver / db / MongoDB.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.rdserver.db;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.Map.Entry;
29 import java.util.Set;
30
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33 import org.bson.Document;
34
35 import com.mongodb.MongoClient;
36 import com.mongodb.client.MongoCollection;
37 import com.mongodb.client.MongoCursor;
38 import com.mongodb.client.MongoDatabase;
39 import com.mongodb.client.model.IndexOptions;
40
41 /**
42  *
43  * This class provides a set of APIs to use MongoDB APIs.
44  *
45  */
46 public class MongoDB {
47     private final static Logger Log   = LoggerFactory.getLogger(MongoDB.class);
48     private MongoClient   mongoClient = null;
49     private MongoDatabase db          = null;
50
51     /**
52      * API creating MongoClient and initializing MongoDatabase
53      *
54      * @param host
55      *            host of MongoDatabase
56      * @param dbname
57      *            database name to create MongoDatabase
58      * @throws Exception
59      */
60     public MongoDB(String host, String dbname) throws Exception {
61         mongoClient = new MongoClient(host);
62         db = mongoClient.getDatabase(dbname);
63     }
64
65     /**
66      * API for creating collection
67      *
68      * @param tableName
69      *            collection name
70      */
71     public void createTable(String tableName) {
72         if (!collectionExists(tableName))
73             db.createCollection(tableName);
74     }
75
76     private boolean collectionExists(String tableName ) {
77         return db.listCollectionNames().into(new ArrayList<>()).contains(tableName);
78     }
79
80     /**
81      * API for dropping collection
82      *
83      * @param tableName
84      *            collection name
85      */
86     public void dropTable(String tableName) {
87         if (collectionExists(tableName))
88             db.getCollection(tableName).drop();
89     }
90
91     /**
92      * API for creating index
93      *
94      * @param tableName
95      *            collection name
96      * @param keys
97      *            key fields of collection
98      */
99     public void createIndex(String tablename, ArrayList<String> keys) {
100
101         Document doc = new Document();
102
103         for (String key : keys) {
104
105             doc.append(key, 1);
106         }
107
108         IndexOptions options = new IndexOptions();
109         options.unique(true);
110
111         db.getCollection(tablename).createIndex(doc, options);
112     }
113
114     /**
115      * API for deleting collection
116      *
117      * @param tableName
118      *            collection name
119      */
120     public void deleteTable(String tableName) {
121
122         db.getCollection(tableName).drop();
123     }
124
125     /**
126      * API for getting database object
127      *
128      */
129     public MongoDatabase getMongoDatabase() {
130
131         return db;
132     }
133
134     /**
135      * API for inserting a record into DB table. the record will not be inserted
136      * if duplicated one.
137      * 
138      * @param tableName
139      *            table name to be inserted
140      * @param doc
141      *            document to be inserted
142      */
143     public Boolean insertRecord(String tableName, Document doc) {
144
145         if (tableName == null || doc == null)
146             return false;
147
148         MongoCollection<Document> collection = db.getCollection(tableName);
149
150         try {
151
152             if (collection.find(doc).first() == null) {
153
154                 collection.insertOne(doc);
155
156             } else {
157
158                 Log.warn("DB insert failed due to duplecated one.");
159                 return false;
160             }
161
162         } catch (Exception e) {
163
164             e.printStackTrace();
165             return false;
166         }
167
168         showRecord(tableName);
169
170         return true;
171     }
172
173     /**
174      * API for inserting a record into DB table. the record will be replaced if
175      * duplicated one.
176      * 
177      * @param tableName
178      *            table name to be inserted
179      * @param filter
180      *            document filter
181      * @param doc
182      *            document to be inserted
183      * @return returns true if the record is inserted and replaced successfully,
184      *         or returns false
185      */
186     public Boolean insertAndReplaceRecord(String tableName, Document filter,
187             Document doc) {
188
189         if (tableName == null || filter == null || doc == null)
190             return false;
191
192         MongoCollection<Document> collection = db.getCollection(tableName);
193
194         try {
195
196             if (collection.findOneAndReplace(filter, doc) == null) {
197
198                 collection.insertOne(doc);
199             }
200
201         } catch (Exception e) {
202
203             e.printStackTrace();
204             return false;
205         }
206
207         showRecord(tableName);
208
209         return true;
210     }
211
212     /**
213      * API for updating a record into DB table.
214      * 
215      * @param tableName
216      *            table name to be updated
217      * @param filter
218      *            document filter
219      * @param record
220      *            record to be updated
221      * @return returns true if the record is updated successfully, or returns
222      *         false
223      */
224     public Boolean updateRecord(String tableName, Document filter,
225             Document record) {
226
227         if (tableName == null || filter == null || record == null)
228             return false;
229
230         MongoCollection<Document> collection = db.getCollection(tableName);
231
232         if (collection.findOneAndReplace(filter, record) == null) {
233
234             Log.warn("DB update failed due to no matched record!");
235             return false;
236         }
237
238         showRecord(tableName);
239
240         return true;
241     }
242
243     /**
244      * API for deleting records from DB table.
245      * 
246      * @param tableName
247      *            table name for the record to be deleted
248      * @param record
249      *            record filter to be deleted
250      * @return returns true if the record is deleted successfully, or returns
251      *         false
252      */
253     public Boolean deleteRecord(String tableName, Document record) {
254
255         if (tableName == null || record == null)
256             return false;
257
258         MongoCollection<Document> collection = db.getCollection(tableName);
259
260         try {
261
262             collection.deleteMany(record);
263
264         } catch (Exception e) {
265
266             e.printStackTrace();
267             return false;
268         }
269
270         showRecord(tableName);
271
272         return true;
273     }
274
275     /**
276      * API for selecting records from DB table.
277      * 
278      * @param tableName
279      *            table name for the record to be selected
280      * @param doc
281      *            document filter to be selected
282      * @return record list according to the filter document
283      */
284     public ArrayList<HashMap<String, Object>> selectRecord(String tableName,
285             Document doc) {
286
287         if (tableName == null || doc == null)
288             return new ArrayList<>();
289
290         MongoCollection<Document> collection = db.getCollection(tableName);
291         MongoCursor<Document> cursor = collection.find(doc).iterator();
292
293         ArrayList<HashMap<String, Object>> recordList = new ArrayList<>();
294
295         try {
296
297             while (cursor.hasNext()) {
298                 Document selectedDoc = cursor.next();
299                 recordList.add(convertDocumentToHashMap(selectedDoc));
300             }
301
302         } finally {
303
304             cursor.close();
305         }
306
307         return recordList;
308     }
309
310     private HashMap<String, Object> convertDocumentToHashMap(Document doc) {
311         HashMap<String, Object> resourceMap = new HashMap<>();
312
313         Set<Entry<String, Object>> entrySet = doc.entrySet();
314         Iterator<Entry<String, Object>> entryIter = entrySet.iterator();
315
316         while (entryIter.hasNext()) {
317
318             Map.Entry<String, Object> entry = (Map.Entry<String, Object>) entryIter
319                     .next();
320
321             String entryKey = entry.getKey();
322
323             // remove a mongoDB index
324             if (entry.getValue() != null && !entryKey.equals("_id")) {
325
326                 resourceMap.put(entry.getKey(), entry.getValue());
327             }
328         }
329
330         return resourceMap;
331     }
332
333     private void showRecord(String tableName) {
334
335         MongoCollection<Document> collection = db.getCollection(tableName);
336         MongoCursor<Document> cursor = collection.find().iterator();
337
338         Log.info("<" + tableName + ">");
339
340         HashMap<String, Object> records = null;
341         int index = 0;
342         while (cursor.hasNext()) {
343
344             Document doc = cursor.next();
345             records = convertDocumentToHashMap(doc);
346
347             Log.info("[" + index + "] " + records.toString());
348             index++;
349         }
350
351         cursor.close();
352     }
353 }