public void searchResource()

in data-resource-management-service/drms-graph-impl/drms-api/src/main/java/org/apache/airavata/drms/api/handlers/ResourceServiceHandler.java [400:722]


    public void searchResource(ResourceSearchRequest
                                       request, StreamObserver<ResourceSearchResponse> responseObserver) {
        try {
            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();

            List<ResourceSearchQuery> resourceSearchQueries = request.getQueriesList();
            int depth = request.getDepth();
            String value = request.getType();

            if (value == null || value.isEmpty()) {
                logger.error("Resource type required to continue search ");
                responseObserver
                        .onError(Status.FAILED_PRECONDITION.withDescription("Resource type required to continue search")
                                .asRuntimeException());
                return;
            }
            List<GenericResource> allowedResourceList = new ArrayList<>();
            List<String> storageList = new ArrayList<>();
            Optional<List<String>> globalStorages = getGlobalSourceStorage(callUser.getTenantId());
            if (globalStorages.isPresent()) {
                globalStorages.get().forEach(str -> {
                    storageList.add(str);
                });
            }

            List keyList = new ArrayList();

            keyList = new ArrayList();
            Map<String, Map<String, String>> searchParameterMap = new HashMap<>();
            boolean propertySearchEnabled = false;
            for (ResourceSearchQuery qry : resourceSearchQueries) {
                if (qry.getField().equals("storageId")) {
                    storageList.clear();
                    storageList.add(qry.getValue());
                } else if (qry.getField().equals("sharedBy")) {
                    searchParameterMap.computeIfAbsent("sharedBy", map -> new HashMap<>()).put("username", qry.getValue());
                    propertySearchEnabled = true;
                } else if (qry.getField().equals("sharedWith")) {
                    searchParameterMap.computeIfAbsent("sharedWith", map -> new HashMap<>()).put("username", qry.getValue());
                    propertySearchEnabled = true;
                } else {
                    searchParameterMap.computeIfAbsent("searchParams", map -> new HashMap<>()).put(qry.getField(), qry.getValue());
                    propertySearchEnabled = true;
                }
            }

            if (propertySearchEnabled) {
                if (searchParameterMap.containsKey("sharedBy") &&
                        (!searchParameterMap.containsKey("searchParams") || searchParameterMap.get("searchParams").isEmpty())) {
                    String val = searchParameterMap.get("sharedBy").get("username");
                    String query = " Match (m:" + value + ")-[r:SHARED_WITH]->(l) " +
                            "where r.sharedBy=$sharedBy AND m.tenantId=$tenantId AND  l.tenantId=$tenantId  AND NOT l.username=$sharedBy " +
                            "return m, r ";
                    Map<String, Object> objectMap = new HashMap<>();
                    objectMap.put("sharedBy", val);
                    objectMap.put("tenantId", callUser.getTenantId());
                    List<Record> records = this.neo4JConnector.searchNodes(objectMap, query);
                    keyList.add("m:r");
                    List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records, keyList);
                    ResourceSearchResponse.Builder builder = ResourceSearchResponse.newBuilder();
                    builder.addAllResources(genericResourceList);
                    responseObserver.onNext(builder.build());
                    responseObserver.onCompleted();
                    return;
                } else if (searchParameterMap.containsKey("sharedWith") &&
                        (!searchParameterMap.containsKey("searchParams") || searchParameterMap.get("searchParams").isEmpty())) {
                    String val = searchParameterMap.get("sharedWith").get("username");
                    String query = "MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId " +
                            " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u)  " +
                            " OPTIONAL MATCH (u)<-[pRel:SHARED_WITH]-(p:COLLECTION)" +
                            " where NOT  p.owner  = '" + val + "'  " +
                            " OPTIONAL MATCH (g)<-[pxRel:SHARED_WITH]-(pr:COLLECTION)" +
                            " where NOT  pr.owner  = '" + val + "'" +
                            " return distinct  p,pRel, pr,pxRel";
                    Map<String, Object> objectMap = new HashMap<>();
                    objectMap.put("username", val);
                    objectMap.put("tenantId", callUser.getTenantId());
                    List<Record> records = this.neo4JConnector.searchNodes(objectMap, query);
                    keyList.add("p:pRel");
                    keyList.add("px:pxRel");
                    List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records, keyList);
                    ResourceSearchResponse.Builder builder = ResourceSearchResponse.newBuilder();
                    builder.addAllResources(genericResourceList);
                    responseObserver.onNext(builder.build());
                    responseObserver.onCompleted();
                    return;
                }

                //TODO: replace with proper neo4j query


                if (searchParameterMap.containsKey("sharedBy") && (searchParameterMap.containsKey("searchParams")
                        && !searchParameterMap.get("searchParams").isEmpty())) {
                    String username = searchParameterMap.get("sharedBy").get("username");
                    searchParameterMap.get("searchParams").forEach((key, val) -> {
                        try {
                            for (String strId : storageList) {
                                List<GenericResource> genericResourceList = Utils
                                        .getMetadataSearchQueryForSharedByMe(value, key, val, strId, username, callUser.getTenantId(), neo4JConnector);
                                genericResourceList.forEach(res -> {
                                    try {
                                        if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), "COLLECTION")) {
                                            allowedResourceList.add(res);
                                        }
                                    } catch (Exception exception) {
                                        logger.error("Errored while searching generic resources");
                                        responseObserver
                                                .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                                        .asRuntimeException());
                                        return;
                                    }
                                });
                            }

                            List<GenericResource> genericResources = Utils
                                    .getPropertySearchQueryForSharedByMe(value, key, val, username, callUser.getTenantId(), neo4JConnector);
                            genericResources.forEach(res -> {
                                try {
                                    if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), "COLLECTION")) {
                                        allowedResourceList.add(res);
                                    }
                                } catch (Exception exception) {
                                    logger.error("Errored while searching generic resources");
                                    responseObserver
                                            .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                                    .asRuntimeException());
                                    return;
                                }
                            });

                        } catch (Exception exception) {
                            logger.error("Errored while searching generic resources");
                            responseObserver
                                    .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                            .asRuntimeException());
                            return;
                        }
                    });
                } else if (searchParameterMap.containsKey("sharedWith") && (searchParameterMap.containsKey("searchParams")
                        && !searchParameterMap.get("searchParams").isEmpty())) {
                    String username = searchParameterMap.get("sharedWith").get("username");
                    searchParameterMap.get("searchParams").forEach((key, val) -> {
                        try {
                            for (String strId : storageList) {
                                List<GenericResource> genericResourceList = Utils
                                        .getMetadataSearchQueryForSharedWithMe(value, key, val, strId, username, callUser.getTenantId(), neo4JConnector);
                                genericResourceList.forEach(res -> {
                                    try {
                                        if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), "COLLECTION")) {
                                            allowedResourceList.add(res);
                                        }
                                    } catch (Exception exception) {
                                        logger.error("Errored while searching generic resources");
                                        responseObserver
                                                .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                                        .asRuntimeException());
                                        return;
                                    }
                                });
                            }

                            List<GenericResource> genericResources = Utils
                                    .getPropertySearchQueryForSharedWithMe(value, key, val, username, callUser.getTenantId(), neo4JConnector);
                            genericResources.forEach(res -> {
                                try {
                                    if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), "COLLECTION")) {
                                        allowedResourceList.add(res);
                                    }
                                } catch (Exception exception) {
                                    logger.error("Errored while searching generic resources");
                                    responseObserver
                                            .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                                    .asRuntimeException());
                                    return;
                                }
                            });
                        } catch (Exception exception) {
                            logger.error("Errored while searching generic resources");
                            responseObserver
                                    .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                            .asRuntimeException());
                            return;
                        }
                    });

                } else {
                    for (String strId : storageList) {
                        Optional<String> metadataSearchQueryOP = Utils.getMetadataSearchQuery(resourceSearchQueries, value, strId);
                        Optional<String> ownPropertySearchQuery = Utils.getPropertySearchQuery(resourceSearchQueries, value, strId);
                        if (metadataSearchQueryOP.isPresent()) {
                            String query = metadataSearchQueryOP.get();

                            List<Record> records = this.neo4JConnector.searchNodes(query);
                            List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);


                            genericResourceList.forEach(res -> {
                                try {
                                    if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), "COLLECTION")) {
                                        allowedResourceList.add(res);
                                    }
                                } catch (Exception exception) {
                                    logger.error("Errored while searching generic resources");
                                    responseObserver
                                            .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                                    .asRuntimeException());
                                    return;
                                }
                            });

                            if (ownPropertySearchQuery.isPresent()) {
                                List<Record> ownPropertySearchRecords = this.neo4JConnector.searchNodes(ownPropertySearchQuery.get());
                                List<GenericResource> genericResources = GenericResourceDeserializer.deserializeList(ownPropertySearchRecords);
                                genericResources.forEach(res -> {
                                    try {
                                        if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), "COLLECTION")) {
                                            allowedResourceList.add(res);
                                        }
                                    } catch (Exception exception) {
                                        logger.error("Errored while searching generic resources");
                                        responseObserver
                                                .onError(Status.INTERNAL.withDescription("Errored while searching generic resources ")
                                                        .asRuntimeException());
                                        return;
                                    }
                                });

                            }
                        }

                    }
                }
                ResourceSearchResponse.Builder builder = ResourceSearchResponse.newBuilder();
                builder.addAllResources(allowedResourceList);
                responseObserver.onNext(builder.build());
                responseObserver.onCompleted();
                return;

            } else {
                String query = "";
                Map<String, Object> userProps = new HashMap<>();
                userProps.put("username", callUser.getUsername());
                userProps.put("tenantId", callUser.getTenantId());
                if ((value.equals("FILE") || value.equals("COLLECTION"))) {
                    for (String storageId : storageList) {

                        query = " MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId with u" +
                                " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u) " +
                                " OPTIONAL MATCH (u)<-[relRM:SHARED_WITH]-(m)<-[:CHILD_OF*]-(rm:" + value + ")-[:CHILD_OF*]->(s:Storage{entityId:'" + storageId + "'})" +
                                " , (s:Storage{entityId:'" + storageId + "'})<-[:CHILD_OF*]-(r:" + value + ")-[relR:SHARED_WITH]->(u)" +
                                " OPTIONAL MATCH (g)<-[relRMG:SHARED_WITH]-(mg)<-[:CHILD_OF*]-(rmg:" + value + ")-[:CHILD_OF*]->(s:Storage{entityId:'" + storageId + "'})" +
                                " , (s:Storage{entityId:'" + storageId + "'})<-[:CHILD_OF*]-(rg:" + value + ")-[relRG:SHARED_WITH]->(g)" +
                                " return distinct  rm,relRM, r,relR, rmg,relRMG, rg,relRG ";
                        keyList = new ArrayList();
                        keyList.add("rm:relRM");
                        keyList.add("r:relR");
                        keyList.add("rmg:relRMG");
                        keyList.add("rg:relRG");
                        if (depth == 1) {
                            query = " MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId with u" +
                                    " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u) " +
                                    " OPTIONAL MATCH (s:Storage{entityId:'" + storageId + "'})<-[:CHILD_OF]-(r:" + value + ")-[relR:SHARED_WITH]->(u)" +
                                    " OPTIONAL MATCH (sp:Storage{entityId:'" + storageId + "'})<-[:CHILD_OF]-(rg:" + value + ")-[relRG:SHARED_WITH]->(g)" +
                                    " OPTIONAL MATCH (s2:Storage{entityId:'" + storageId + "'})<-[:CHILD_OF*]-(r2:" + value + ")-[relR2:SHARED_WITH]->(u) where NOT r2.owner=$username " +
                                    " AND NOT (r2)-[:CHILD_OF*]->(r)" +
                                    " return distinct   r,relR, rg,relRG, r2,relR2";
                            keyList = new ArrayList();
                            keyList.add("r:relR");
                            keyList.add("rg:relRG");
                            keyList.add("r2:relR2");
                            keyList.add("r3:relR3");
                        }
                        logger.debug("Search query {}", query);

                        List<Record> records = this.neo4JConnector.searchNodes(userProps, query);

                        List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records, keyList);
                        allowedResourceList.addAll(genericResourceList);
                    }
                } else {
                    query = " MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId with u" +
                            " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u) " +
                            " OPTIONAL MATCH (u)<-[relRM:SHARED_WITH]-(m)<-[:CHILD_OF*]-(rm:" + value + ")" +
                            " , (r:" + value + ")-[relR:SHARED_WITH]->(u)" +
                            " OPTIONAL MATCH (g)<-[relRMG:SHARED_WITH]-(mg)<-[:CHILD_OF*]-(rmg:" + value + ")" +
                            " , (rg:" + value + ")-[relRG:SHARED_WITH]->(g)" +
                            " return distinct  rm,relRM, r,relR, rmg,relRMG, rg, relRG ";
                    keyList = new ArrayList();
                    keyList.add("rm:relRM");
                    keyList.add("r:relR");
                    keyList.add("rmg:relRMG");
                    keyList.add("rg:relRG");
                    if (depth == 1) {
                        query = " MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId with u" +
                                " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u) " +
                                " OPTIONAL MATCH (r:" + value + ")-[relR:SHARED_WITH]->(u)" +
                                " OPTIONAL MATCH (rg:" + value + ")-[relRG:SHARED_WITH]->(g)" +
                                " return distinct   r,relR, rg, relRG ";
                        keyList = new ArrayList();
                        keyList.add("r:relR");
                        keyList.add("rg:relRG");
                    }
                    List<Record> records = this.neo4JConnector.searchNodes(userProps, query);

                    List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records, keyList);
                    allowedResourceList.addAll(genericResourceList);
                }


            }
            ResourceSearchResponse.Builder builder = ResourceSearchResponse.newBuilder();
            builder.addAllResources(allowedResourceList);
            responseObserver.onNext(builder.build());
            responseObserver.onCompleted();

        } catch (
                Exception e) {
            logger.error("Errored while searching generic resources; Message: {}", e.getMessage(), e);
            responseObserver.onError(Status.INTERNAL.withDescription("Errored while searching generic resources "
                    + e.getMessage()).asRuntimeException());
        }

    }