Skip to content

Commit

Permalink
Merge pull request #2422 from opencb/TASK-5922
Browse files Browse the repository at this point in the history
TASK-5922 - Organization info doesn't return array of projects
  • Loading branch information
pfurio authored Apr 17, 2024
2 parents 8879e3a + f5cb4d6 commit bdc444d
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ public static QueryParams getParam(String key) {
//
OpenCGAResult<Organization> insert(Organization organization, QueryOptions options)
throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException;
//
// OpenCGAResult<Project> get(String userId, QueryOptions options) throws CatalogDBException;
//

OpenCGAResult<Organization> get(String userId, QueryOptions options) throws CatalogDBException;

OpenCGAResult<Organization> get(QueryOptions options) throws CatalogDBException;
//
// OpenCGAResult incrementCurrentRelease(long projectId) throws CatalogDBException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,24 @@ Organization insert(ClientSession clientSession, Organization organization)
return organization;
}

@Override
public OpenCGAResult<Organization> get(String user, QueryOptions options) throws CatalogDBException {
return get(null, user, options);
}

@Override
public OpenCGAResult<Organization> get(QueryOptions options) throws CatalogDBException {
return get(null, options);
return get(null, null, options);
}

OpenCGAResult<Organization> get(ClientSession clientSession, String user, QueryOptions options) throws CatalogDBException {
long startTime = startQuery();
try (DBIterator<Organization> dbIterator = iterator(clientSession, user, options)) {
return endQuery(startTime, dbIterator);
}
}


@Override
public OpenCGAResult<Organization> update(String organizationId, ObjectMap parameters, QueryOptions queryOptions)
throws CatalogDBException, CatalogParameterException, CatalogAuthorizationException {
Expand Down Expand Up @@ -139,11 +152,11 @@ private OpenCGAResult<Organization> privateUpdate(ClientSession clientSession, S
List<Event> events = new ArrayList<>();
logger.debug("Update organization. Query: {}, Update: {}", queryBson.toBsonDocument(), organizationUpdate.toBsonDocument());

// Update study admins need to be before because we need to fetch the previous owner/admins in case of an update on these fields.
// Update study admins need to be executed before the actual update because we need to fetch the previous owner/admins in case
// of an update on these fields.
updateStudyAdmins(clientSession, parameters, queryOptions);
DataResult<?> updateResult = organizationCollection.update(clientSession, queryBson, organizationUpdate, null);


if (updateResult.getNumMatches() == 0) {
throw new CatalogDBException("Organization not found");
}
Expand All @@ -161,7 +174,7 @@ private void updateStudyAdmins(ClientSession clientSession, ObjectMap parameters
return;
}

Organization organization = get(clientSession, OrganizationManager.INCLUDE_ORGANIZATION_ADMINS).first();
Organization organization = get(clientSession, null, OrganizationManager.INCLUDE_ORGANIZATION_ADMINS).first();

if (parameters.containsKey(QueryParams.OWNER.key())) {
// Owner has changed
Expand Down Expand Up @@ -234,7 +247,7 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, Obj
throw new CatalogDBException("Could not update owner. User not found.");
}
// Fetch current owner
Organization organization = get(clientSession, OrganizationManager.INCLUDE_ORGANIZATION_ADMINS).first();
Organization organization = get(clientSession, null, OrganizationManager.INCLUDE_ORGANIZATION_ADMINS).first();
if (owner.equals(organization.getOwner())) {
logger.warn("Organization owner is already '{}'.", owner);
} else {
Expand Down Expand Up @@ -299,26 +312,19 @@ private UpdateDocument getValidatedUpdateParams(ClientSession clientSession, Obj
return document;
}

OpenCGAResult<Organization> get(ClientSession clientSession, QueryOptions options) throws CatalogDBException {
long startTime = startQuery();
try (DBIterator<Organization> dbIterator = iterator(clientSession, options)) {
return endQuery(startTime, dbIterator);
}
}

@Override
public OpenCGAResult<Organization> delete(Organization organization) throws CatalogDBException {
return null;
}

@Override
public DBIterator<Organization> iterator(QueryOptions options) throws CatalogDBException {
return iterator(null, options);
return iterator(null, null, options);
}

public DBIterator<Organization> iterator(ClientSession clientSession, QueryOptions options) throws CatalogDBException {
public DBIterator<Organization> iterator(ClientSession clientSession, String user, QueryOptions options) throws CatalogDBException {
MongoDBIterator<Document> mongoCursor = getMongoCursor(clientSession, options);
return new OrganizationCatalogMongoDBIterator<>(mongoCursor, clientSession, organizationConverter, dbAdaptorFactory, options);
return new OrganizationCatalogMongoDBIterator<>(mongoCursor, clientSession, organizationConverter, dbAdaptorFactory, options, user);
}

private MongoDBIterator<Document> getMongoCursor(ClientSession clientSession, QueryOptions options) {
Expand All @@ -338,7 +344,7 @@ private MongoDBIterator<Document> getMongoCursor(ClientSession clientSession, Qu
}

public List<String> getOwnerAndAdmins(ClientSession clientSession) throws CatalogDBException {
Organization organization = get(clientSession, OrganizationManager.INCLUDE_ORGANIZATION_ADMINS).first();
Organization organization = get(clientSession, null, OrganizationManager.INCLUDE_ORGANIZATION_ADMINS).first();
List<String> members = new ArrayList<>(organization.getAdmins().size() + 1);
if (StringUtils.isNotEmpty(organization.getOwner())) {
members.add(organization.getOwner());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,18 +542,27 @@ public OpenCGAResult<Project> get(Query query, QueryOptions options, String user
}

@Override
public OpenCGAResult<Document> nativeGet(Query query, QueryOptions options) throws CatalogDBException {
public OpenCGAResult nativeGet(Query query, QueryOptions options) throws CatalogDBException {
return nativeGet(null, query, options);
}

public OpenCGAResult<Document> nativeGet(ClientSession clientSession, Query query, QueryOptions options) throws CatalogDBException {
long startTime = startQuery();
try (DBIterator<Document> dbIterator = nativeIterator(query, options)) {
try (DBIterator<Document> dbIterator = nativeIterator(clientSession, query, options)) {
return endQuery(startTime, dbIterator);
}
}

@Override
public OpenCGAResult nativeGet(Query query, QueryOptions options, String user)
throws CatalogDBException, CatalogAuthorizationException {
return nativeGet(null, query, options, user);
}

public OpenCGAResult<Document> nativeGet(ClientSession clientSession, Query query, QueryOptions options, String user)
throws CatalogDBException, CatalogAuthorizationException {
long startTime = startQuery();
try (DBIterator<Document> dbIterator = nativeIterator(query, options, user)) {
try (DBIterator<Document> dbIterator = nativeIterator(clientSession, query, options, user)) {
return endQuery(startTime, dbIterator);
}
}
Expand All @@ -570,11 +579,15 @@ public DBIterator<Project> iterator(ClientSession clientSession, Query query, Qu

@Override
public DBIterator nativeIterator(Query query, QueryOptions options) throws CatalogDBException {
return nativeIterator(null, query, options);
}

public DBIterator nativeIterator(ClientSession clientSession, Query query, QueryOptions options) throws CatalogDBException {
QueryOptions queryOptions = options != null ? new QueryOptions(options) : new QueryOptions();
queryOptions.put(NATIVE_QUERY, true);

MongoDBIterator<Document> mongoCursor = getMongoCursor(null, query, queryOptions);
return new ProjectCatalogMongoDBIterator<>(mongoCursor, null, null, dbAdaptorFactory, options, null);
MongoDBIterator<Document> mongoCursor = getMongoCursor(clientSession, query, queryOptions);
return new ProjectCatalogMongoDBIterator<>(mongoCursor, clientSession, null, dbAdaptorFactory, options, null);
}

@Override
Expand All @@ -587,11 +600,16 @@ public DBIterator<Project> iterator(Query query, QueryOptions options, String us
@Override
public DBIterator nativeIterator(Query query, QueryOptions options, String user)
throws CatalogDBException, CatalogAuthorizationException {
return nativeIterator(null, query, options, user);
}

public DBIterator nativeIterator(ClientSession clientSession, Query query, QueryOptions options, String user)
throws CatalogDBException, CatalogAuthorizationException {
QueryOptions queryOptions = options != null ? new QueryOptions(options) : new QueryOptions();
queryOptions.put(NATIVE_QUERY, true);

MongoDBIterator<Document> mongoCursor = getMongoCursor(null, query, queryOptions, user);
return new ProjectCatalogMongoDBIterator<>(mongoCursor, null, null, dbAdaptorFactory, options, user);
MongoDBIterator<Document> mongoCursor = getMongoCursor(clientSession, query, queryOptions, user);
return new ProjectCatalogMongoDBIterator<>(mongoCursor, clientSession, null, dbAdaptorFactory, options, user);
}

// private MongoDBIterator<Document> getMongoCursor(ClientSession clientSession, Query query, QueryOptions options, String user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,25 +183,28 @@ protected QueryOptions createInnerQueryOptionsForVersionedEntity(QueryOptions op
}

protected boolean includeField(QueryOptions options, List<String> fields) {
Set<String> includedFields = new HashSet<>(fields);
if (options.containsKey(QueryOptions.INCLUDE)) {
List<String> currentIncludeList = options.getAsStringList(QueryOptions.INCLUDE);
for (String include : currentIncludeList) {
if (includedFields.contains(include)) {
return true;
for (String field : fields) {
if (include.startsWith(field)) {
return true;
}
}
}
return false;
} else if (options.containsKey(QueryOptions.EXCLUDE)) {
List<String> currentExcludeList = options.getAsStringList(QueryOptions.EXCLUDE);
for (String exclude : currentExcludeList) {
if (includedFields.contains(exclude)) {
return false;
for (String field : fields) {
if (exclude.equals(field)) {
return false;
}
}

}
return true;
}

return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opencb.opencga.catalog.db.mongodb.iterators;

import com.mongodb.client.ClientSession;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.opencb.commons.datastore.core.Query;
import org.opencb.commons.datastore.core.QueryOptions;
Expand All @@ -11,7 +12,10 @@
import org.opencb.opencga.catalog.db.mongodb.MigrationMongoDBAdaptor;
import org.opencb.opencga.catalog.db.mongodb.NoteMongoDBAdaptor;
import org.opencb.opencga.catalog.db.mongodb.OrganizationMongoDBAdaptorFactory;
import org.opencb.opencga.catalog.db.mongodb.ProjectMongoDBAdaptor;
import org.opencb.opencga.catalog.exceptions.CatalogAuthorizationException;
import org.opencb.opencga.catalog.exceptions.CatalogDBException;
import org.opencb.opencga.catalog.exceptions.CatalogRuntimeException;
import org.opencb.opencga.core.models.notes.Note;
import org.opencb.opencga.core.response.OpenCGAResult;
import org.slf4j.Logger;
Expand All @@ -23,24 +27,32 @@

public class OrganizationCatalogMongoDBIterator<E> extends CatalogMongoDBIterator<E> {

private final String user;

private final QueryOptions options;
private final QueryOptions projectOptions;

private final Queue<Document> organizationListBuffer;
private final NoteMongoDBAdaptor noteMongoDBAdaptor;
private final MigrationMongoDBAdaptor migrationDBAdaptor;
private final ProjectMongoDBAdaptor projectMongoDBAdaptor;
private final NoteMongoDBAdaptor noteMongoDBAdaptor;

private final Logger logger;


public OrganizationCatalogMongoDBIterator(MongoDBIterator<Document> mongoCursor, ClientSession clientSession,
GenericDocumentComplexConverter<E> converter, OrganizationMongoDBAdaptorFactory dbAdaptorFactory,
QueryOptions options) {
QueryOptions options, String user) {
super(mongoCursor, clientSession, converter, null);

this.options = options != null ? new QueryOptions(options) : new QueryOptions();
this.projectOptions = createInnerQueryOptionsForVersionedEntity(this.options, OrganizationDBAdaptor.QueryParams.PROJECTS.key(),
true);
this.user = user;

this.migrationDBAdaptor = dbAdaptorFactory.getMigrationDBAdaptor();
this.noteMongoDBAdaptor = dbAdaptorFactory.getCatalogNotesDBAdaptor();
this.projectMongoDBAdaptor = dbAdaptorFactory.getCatalogProjectDBAdaptor();

this.organizationListBuffer = new LinkedList<>();
this.logger = LoggerFactory.getLogger(OrganizationCatalogMongoDBIterator.class);
Expand Down Expand Up @@ -72,6 +84,7 @@ public E next() {
private void fetchNextBatch() {
if (mongoCursor.hasNext()) {
Document organizationDocument = mongoCursor.next();
String orgId = organizationDocument.getString(OrganizationDBAdaptor.QueryParams.ID.key());

if (!options.getBoolean(NATIVE_QUERY)) {
List<String> migrationFields = Arrays.asList(OrganizationDBAdaptor.QueryParams.INTERNAL.key(),
Expand Down Expand Up @@ -100,7 +113,24 @@ private void fetchNextBatch() {
OpenCGAResult<Document> result = noteMongoDBAdaptor.nativeGet(clientSession, query, noteOptions);
organizationDocument.put(OrganizationDBAdaptor.QueryParams.NOTES.key(), result.getResults());
} catch (CatalogDBException e) {
logger.warn("Could not obtain the organization notes", e);
throw CatalogRuntimeException.internalException(e, "Could not fetch notes for organization '" + orgId + "'.");
}
}

List<String> projectField = Collections.singletonList(OrganizationDBAdaptor.QueryParams.PROJECTS.key());
if (includeField(options, projectField)) {
OpenCGAResult<Document> openCGAResult = null;
try {
if (StringUtils.isNotEmpty(user)) {
openCGAResult = projectMongoDBAdaptor.nativeGet(clientSession, new Query(), projectOptions, user);
} else {
openCGAResult = projectMongoDBAdaptor.nativeGet(clientSession, new Query(), projectOptions);
}
organizationDocument.put(OrganizationDBAdaptor.QueryParams.PROJECTS.key(), openCGAResult.getResults());
} catch (CatalogAuthorizationException e) {
logger.warn("Could not fetch projects for organization '{}'.", orgId, e);
} catch (CatalogDBException | RuntimeException e) {
throw CatalogRuntimeException.internalException(e, "Could not fetch projects for organization '" + orgId + "'.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.opencb.opencga.catalog.exceptions;

import org.apache.commons.lang3.StringUtils;

public class CatalogRuntimeException extends IllegalArgumentException {

public CatalogRuntimeException(String message) {
super(message);
}

public CatalogRuntimeException(String message, Throwable cause) {
super(message, cause);
}

public static CatalogRuntimeException internalException(Exception e, String message) {
if (e instanceof CatalogRuntimeException) {
return ((CatalogRuntimeException) e);
} else {
if (StringUtils.isEmpty(message)) {
message = e.getMessage();
if (StringUtils.isEmpty(message)) {
message = e.toString();
}
}
return new CatalogRuntimeException("Internal exception: " + message, e);
}
}

public static CatalogRuntimeException internalException(Exception e) {
return internalException(e, "");
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public OpenCGAResult<Organization> get(String organizationId, QueryOptions optio
QueryOptions queryOptions = ParamUtils.defaultObject(options, QueryOptions::new);
boolean isOrgAdmin = authorizationManager.isAtLeastOrganizationOwnerOrAdmin(organizationId, userId);
queryOptions.put(OrganizationDBAdaptor.IS_ORGANIZATION_ADMIN_OPTION, isOrgAdmin);
queryResult = getOrganizationDBAdaptor(organizationId).get(queryOptions);
queryResult = getOrganizationDBAdaptor(organizationId).get(userId, queryOptions);
} catch (CatalogException e) {
auditManager.auditInfo(organizationId, userId, Enums.Resource.ORGANIZATION, organizationId, "", "", "", auditParams,
new AuditRecord.Status(AuditRecord.Status.Result.ERROR, e.getError()));
Expand Down
Loading

0 comments on commit bdc444d

Please sign in to comment.