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