IOT-3214 rd mongo query optimalisation - reverify
[iotivity.git] / cloud / resourcedirectory / src / main / java / org / iotivity / cloud / rdserver / resources / directory / RDManager.java
index 281c8f4..7a01402 100644 (file)
  */
 package org.iotivity.cloud.rdserver.resources.directory;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
 import org.iotivity.cloud.rdserver.Constants;
 import org.iotivity.cloud.rdserver.db.DBManager;
 import org.iotivity.cloud.rdserver.resources.directory.rd.InsManager;
-import org.iotivity.cloud.util.Log;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
- * 
+ *
  * This class provides a set of APIs handle requests about resource information
  *
  */
 public class RDManager {
-
+    private final static Logger                Log               = LoggerFactory.getLogger(RDManager.class);
     private InsManager                         mInsManager       = new InsManager();
     private PayloadManager                     mPayloadManager   = new PayloadManager();
 
     private ArrayList<HashMap<String, Object>> mResourcePresence = new ArrayList<>();
 
+    private static final RDManager INSTANCE = new RDManager();
+
+    public static RDManager getInstance(){
+        return INSTANCE;
+    }
+
+
     /**
      * API for handling resource-publish process
-     * 
+     *
      * @param requestPayload
      *            request payload
      * @return response payload
@@ -81,7 +88,7 @@ public class RDManager {
     }
 
     private void storeResource(ArrayList<HashMap<String, Object>> links,
-            HashMap<String, Object> deviceInfo) {
+                               HashMap<String, Object> deviceInfo) {
 
         ArrayList<HashMap<String, Object>> resourcePresence = new ArrayList<>();
 
@@ -116,7 +123,7 @@ public class RDManager {
     }
 
     private void setResourceIns(String di,
-            ArrayList<HashMap<String, Object>> links) {
+                                ArrayList<HashMap<String, Object>> links) {
 
         for (HashMap<String, Object> link : links) {
             String href = link.get(Constants.HREF).toString();
@@ -148,10 +155,10 @@ public class RDManager {
 
     /**
      * API for handling resource-delete process
-     * 
+     *
      * @param di
      *            device id
-     * @param ins
+     * @param insList
      *            unique id of resource
      */
     public void deleteResource(String di, List<String> insList) {
@@ -176,6 +183,10 @@ public class RDManager {
         }
 
         if (!foundRecord.isEmpty()) {
+            // set resource presence
+            for (HashMap<String, Object> record : foundRecord) {
+                record.put(Constants.TRIGGER, Constants.RES_DELETE);
+            }
             setmResourcePresence(foundRecord);
         }
     }
@@ -190,7 +201,7 @@ public class RDManager {
 
     /**
      * API for handling resource-discover process
-     * 
+     *
      * @param diList
      *            list of device id
      * @param rtList
@@ -200,48 +211,56 @@ public class RDManager {
      * @return response payload
      */
     public ArrayList<Object> discoverResource(List<String> diList,
-            List<String> rtList, List<String> ifList) {
-
-        HashMap<String, Object> condition = new HashMap<>();
+                                              List<String> rtList, List<String> ifList) {
 
         ArrayList<Object> response = new ArrayList<>();
 
-        if (rtList == null && ifList == null) {
-            readResource(diList, condition, response);
+        if (diList == null) {
+            return response;
         }
 
-        if (rtList != null) {
-            for (String rt : rtList) {
-                condition.put(Constants.RESOURCE_TYPE, rt);
-                readResource(diList, condition, response);
-            }
+        final List<String> diFiltered = filterDeviceByStatus(diList);
+        if(diFiltered == null || diFiltered.size() == 0){
+            return response;
         }
+        final HashMap<String,Object> conditions = new HashMap<>();
+        conditions.put("di",buildInQuery(diFiltered));
 
-        if (ifList != null) {
-            for (String itf : ifList) {
-                condition.put(Constants.INTERFACE, itf);
-                readResource(diList, condition, response);
-            }
+        if(rtList != null && rtList.size() > 0){
+            conditions.put("rt",buildInQuery(rtList));
+        }
+
+        if(ifList != null && ifList.size() > 0){
+            conditions.put("if",buildInQuery(rtList));
         }
 
-        Log.d("discovery payload : " + response);
+        readResource(conditions,response);
+
+        Log.debug("discovery payload : " + response);
 
         return response;
     }
 
-    private void readResource(List<String> diList,
+    private void readResource(
             HashMap<String, Object> condition, ArrayList<Object> response) {
 
-        for (String di : diList) {
-            condition.put(Constants.DEVICE_ID, di);
-            ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
-                    .selectRecord(Constants.RD_TABLE, condition);
+        ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
+                .selectRecord(Constants.RD_TABLE, condition);
+        if (!records.isEmpty()) {
+            response.add(makeDiscoverResponseSegment(records));
+        }
+    }
 
-            if (!records.isEmpty()) {
-                response.add(makeDiscoverResponseSegment(records));
-            }
+    private List<String> filterDeviceByStatus(final List<String> diList){
 
+        final HashMap<String,Object> query = new HashMap<>();
+        if(diList != null && diList.size() > 0){
+            query.put("di",buildInQuery(diList));
         }
+        query.put("state",Constants.PRESENCE_ON);
+        ArrayList<HashMap<String, Object>> records = DBManager.getInstance()
+                .selectRecord(Constants.PRESENCE_TABLE, query);
+        return records.stream().map(record -> (String)record.get("di")).collect(Collectors.toList());
     }
 
     private HashMap<String, Object> makeDiscoverResponseSegment(
@@ -275,11 +294,18 @@ public class RDManager {
 
     /**
      * API for getting resource information to notify
-     * 
+     *
      * @return resource information
      */
     public ArrayList<HashMap<String, Object>> getmResourcePresence() {
         return mResourcePresence;
     }
 
-}
+
+    private <T extends Object> HashMap<String,Object> buildInQuery(final Collection<T> items){
+        final HashMap<String,Object> query = new HashMap<>();
+        query.put("$in",items);
+        return query;
+    }
+
+}
\ No newline at end of file