Add DI based resource search through /oic/res
[platform/upstream/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.bson.Document;
32 import org.iotivity.cloud.rdserver.Constants;
33 import org.iotivity.cloud.rdserver.resources.presence.resource.ResPresencePayload;
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.Filters;
40
41 /**
42  *
43  * This class provides a set of APIs to use MongoDB APIs.
44  *
45  */
46 public class MongoDB {
47
48     private MongoClient   mongoClient = null;
49     private MongoDatabase db          = null;
50
51     /**
52      * API creating MongoClient and initializing MongoDatabase
53      *
54      * @param dbname
55      *            database name to create MongoDatabase
56      * @throws Exception
57      */
58     public MongoDB(String dbname) throws Exception {
59         mongoClient = new MongoClient();
60         mongoClient.dropDatabase(dbname);
61         db = mongoClient.getDatabase(dbname);
62     }
63
64     /**
65      * API creating collection
66      *
67      * @param tableName
68      *            collection name
69      */
70     public void createTable(String tableName) {
71         deleteTable(tableName);
72         db.createCollection(tableName);
73     }
74
75     /**
76      * API deleting collection
77      *
78      * @param tableName
79      *            collection name
80      */
81     public void deleteTable(String tableName) {
82         db.getCollection(tableName).drop();
83     }
84
85     private Document createDocument(HashMap<Object, Object> storeRes) {
86
87         Document doc = new Document();
88         Set<Entry<Object, Object>> resEntrySet = storeRes.entrySet();
89         Iterator<Entry<Object, Object>> entryIter = resEntrySet.iterator();
90
91         while (entryIter.hasNext()) {
92             Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) entryIter
93                     .next();
94             doc.append(entry.getKey().toString(), entry.getValue());
95         }
96
97         return doc;
98     }
99
100     private ArrayList<Document> createDocuments(
101             ArrayList<HashMap<Object, Object>> storeResList) {
102
103         Iterator<HashMap<Object, Object>> resListIter = storeResList.iterator();
104
105         ArrayList<Document> docList = new ArrayList<>();
106
107         while (resListIter.hasNext()) {
108             Document doc = new Document();
109
110             HashMap<Object, Object> storeRes = resListIter.next();
111             Set<Entry<Object, Object>> resEntrySet = storeRes.entrySet();
112             Iterator<Entry<Object, Object>> entryIter = resEntrySet.iterator();
113
114             while (entryIter.hasNext()) {
115                 Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) entryIter
116                         .next();
117                 doc.append(entry.getKey().toString(), entry.getValue());
118             }
119             docList.add(doc);
120         }
121
122         return docList;
123     }
124
125     private HashMap<Object, Object> convertDocumentToHashMap(Document doc) {
126         HashMap<Object, Object> resourceMap = new HashMap<Object, Object>();
127
128         Set<Entry<String, Object>> entrySet = doc.entrySet();
129         Iterator<Entry<String, Object>> entryIter = entrySet.iterator();
130         while (entryIter.hasNext()) {
131             Map.Entry<String, Object> entry = (Map.Entry<String, Object>) entryIter
132                     .next();
133             if (entry.getValue() != null) {
134                 resourceMap.put(entry.getKey().toString(), entry.getValue());
135             }
136         }
137
138         return resourceMap;
139     }
140
141     /**
142      * API for storing information of published resources
143      *
144      * @param publishPayloadFormat
145      *            information of published resources to store in collection
146      * @param tableName
147      *            collection name
148      */
149     public ArrayList<ResPresencePayload> createRDResource(
150             ArrayList<HashMap<Object, Object>> storeResList, String tableName) {
151         ArrayList<Document> docList = createDocuments(storeResList);
152         Iterator<Document> docIter = docList.iterator();
153
154         MongoCollection<Document> collection = db.getCollection(tableName);
155
156         ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
157
158         while (docIter.hasNext()) {
159             Document doc = docIter.next();
160             byte trigger = 0;
161
162             if (collection.findOneAndReplace(
163                     Filters.and(
164                             Filters.eq(Constants.DEVICE_ID,
165                                     doc.get(Constants.DEVICE_ID)),
166                             Filters.eq(Constants.INS, doc.get(Constants.INS))),
167                     doc) == null) {
168                 collection.insertOne(doc);
169                 trigger = Constants.RES_CREATE;
170
171             } else {
172                 trigger = Constants.RES_CHANGE;
173
174             }
175
176             resPayloadList.add(makeResourcePresencePayload(doc, trigger));
177         }
178         return resPayloadList;
179     }
180
181     public void createDevicePresenceResource(HashMap<Object, Object> storeRes,
182             String tableName) {
183
184         Document doc = createDocument(storeRes);
185         MongoCollection<Document> collection = db.getCollection(tableName);
186
187         if (collection
188                 .findOneAndReplace(
189                         Filters.and(Filters.eq(Constants.DEVICE_ID,
190                                 doc.get(Constants.DEVICE_ID))),
191                         doc) == null) {
192
193             collection.insertOne(doc);
194         }
195
196         return;
197     }
198
199     private ResPresencePayload makeResourcePresencePayload(Document doc,
200             byte trigger) {
201
202         ResPresencePayload resPayload = new ResPresencePayload();
203
204         resPayload.setTrg(trigger);
205
206         Object rt = doc.get(Constants.RESOURCE_TYPE);
207         if (rt != null) {
208             resPayload.setRt(rt.toString());
209         }
210         Object href = doc.get(Constants.HREF);
211         if (rt != null) {
212             Object di = doc.get(Constants.DEVICE_ID);
213             if (di != null) {
214                 resPayload.setHref(href.toString());
215             }
216         }
217         Object ttl = doc.get(Constants.RESOURCE_TTL);
218         if (ttl != null) {
219             resPayload.setTtl((int) ttl);
220         }
221         return resPayload;
222     }
223
224     public String readDeviceState(String deviceId, String tableName) {
225
226         String deviceState = null;
227
228         MongoCollection<Document> collection = db.getCollection(tableName);
229
230         MongoCursor<Document> cursor = collection
231                 .find(Filters.eq(Constants.DEVICE_ID, deviceId))
232                 .iterator();
233
234         try {
235
236             while (cursor.hasNext()) {
237                 Document doc = cursor.next();
238                 deviceState = doc.getString(Constants.PRESENCE_STATE);
239                 break;
240             }
241
242         } finally {
243
244             cursor.close();
245         }
246
247         return deviceState;
248     }
249
250     public ArrayList<HashMap<Object, Object>> readResourceAboutDid(String di, String tableName) {
251         MongoCollection<Document> collection = db.getCollection(tableName);
252         ArrayList<HashMap<Object, Object>> resList = null;
253         MongoCursor<Document> cursor = collection
254                 .find(Filters.eq(Constants.DEVICE_ID, di))
255                 .iterator();
256
257         if (cursor.hasNext()) {
258             resList = new ArrayList<>();
259             try {
260                 while (cursor.hasNext()) {
261                     Document doc = cursor.next();
262                     resList.add(convertDocumentToHashMap(doc));
263                 }
264             } finally {
265                 cursor.close();
266             }
267         }
268
269         return resList;
270     }
271
272     /**
273      * API for finding resources matched filterValue of filterKey and a
274      * particular device ID in collection
275      *
276      * @param di
277      *            device id
278      * @param filterKey
279      *            field name in collection
280      * @param filterValue
281      *            field value about field name
282      * @param tableName
283      *            collection name
284      * @return ArrayList<PublishPayloadFormat> - array list of resource
285      *         information
286      */
287     public ArrayList<HashMap<Object, Object>> readResourceAboutDidAndFilter(String di,
288             String filterKey, String filterValue, String tableName) {
289         MongoCollection<Document> collection = db.getCollection(tableName);
290         ArrayList<HashMap<Object, Object>> resList = null;
291         MongoCursor<Document> cursor = collection
292                 .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
293                         Filters.eq(filterKey, filterValue)))
294                 .iterator();
295
296         if (cursor.hasNext()) {
297             resList = new ArrayList<>();
298             try {
299                 while (cursor.hasNext()) {
300                     Document doc = cursor.next();
301                     resList.add(convertDocumentToHashMap(doc));
302                 }
303             } finally {
304                 cursor.close();
305             }
306         }
307
308         return resList;
309     }
310
311     public Object readInsAboutDid(String di, String href, String tableName) {
312         MongoCollection<Document> collection = db.getCollection(tableName);
313         MongoCursor<Document> cursor = collection
314                 .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
315                         Filters.eq(Constants.HREF, href)))
316                 .iterator();
317         try {
318             while (cursor.hasNext()) {
319                 Document doc = cursor.next();
320                 return doc.get(Constants.INS);
321             }
322         } finally {
323             cursor.close();
324         }
325         return null;
326     }
327
328     /**
329      * API for deleting resources about a particular device ID in collection
330      *
331      * @param di
332      *            device id
333      * @param tableName
334      *            collection name
335      */
336     public ArrayList<ResPresencePayload> deleteResourceAboutDi(String di,
337             String tableName) {
338
339         MongoCollection<Document> collection = db.getCollection(tableName);
340
341         MongoCursor<Document> cursor = collection
342                 .find(Filters.eq(Constants.DEVICE_ID, di)).iterator();
343
344         ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
345
346         try {
347             while (cursor.hasNext()) {
348                 Document doc = cursor.next();
349                 resPayloadList.add(
350                         makeResourcePresencePayload(doc, Constants.RES_DELETE));
351             }
352
353         } finally {
354
355             cursor.close();
356         }
357
358         collection.deleteMany(Filters.eq(Constants.DEVICE_ID, di));
359
360         return resPayloadList;
361     }
362
363     /**
364      * API for deleting resources about a particular device ID and ins in
365      * collection
366      *
367      * @param di
368      *            device id
369      * @param ins
370      *            ins
371      * @param tableName
372      *            collection name
373      */
374     public ArrayList<ResPresencePayload> deleteResourceAboutDiAndIns(String di,
375             String ins, String tableName) {
376
377         MongoCollection<Document> collection = db.getCollection(tableName);
378
379         MongoCursor<Document> cursor = collection
380                 .find(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
381                         Filters.eq(Constants.INS, ins)))
382                 .iterator();
383
384         ArrayList<ResPresencePayload> resPayloadList = new ArrayList<>();
385
386         try {
387             while (cursor.hasNext()) {
388                 Document doc = cursor.next();
389                 resPayloadList.add(
390                         makeResourcePresencePayload(doc, Constants.RES_DELETE));
391             }
392
393         } finally {
394
395             cursor.close();
396         }
397
398         collection.deleteOne(Filters.and(Filters.eq(Constants.DEVICE_ID, di),
399                 Filters.eq(Constants.INS, ins)));
400
401         return resPayloadList;
402
403     }
404 }