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