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());
}
}