Skip to content

Commit

Permalink
better performance for dar list (#3618)
Browse files Browse the repository at this point in the history
  • Loading branch information
meek0 authored and kazoompa committed Jan 23, 2019
1 parent 16bf1b5 commit 3ae81d8
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 66 deletions.
Expand Up @@ -12,6 +12,7 @@

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import java.util.ArrayList;
import org.apache.shiro.SecurityUtils;
import org.obiba.mica.access.DataAccessRequestRepository;
import org.obiba.mica.access.domain.ActionLog;
Expand All @@ -26,12 +27,12 @@
import org.obiba.mica.security.service.SubjectAclService;
import org.obiba.mica.user.UserProfileService;
import org.obiba.shiro.realm.ObibaRealm;
import org.obiba.shiro.realm.ObibaRealm.Subject;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.Date;
Expand Down Expand Up @@ -78,27 +79,14 @@ public StatusChangeDtos getStatusChangeDtos() {
}

Mica.DataAccessRequestDto.Builder asDtoBuilder(@NotNull DataAccessEntity request) {
Mica.DataAccessRequestDto.Builder builder = Mica.DataAccessRequestDto.newBuilder();
builder.setApplicant(request.getApplicant()) //
.setStatus(request.getStatus().name()) //
.setTimestamps(TimestampsDtos.asDto(request)); //
if(request.hasContent()) builder.setContent(request.getContent()); //
if(!request.isNew()) builder.setId(request.getId());

String title = dataAccessRequestUtilService.getRequestTitle(request);
if(!Strings.isNullOrEmpty(title)) {
builder.setTitle(title);
}
Mica.DataAccessRequestDto.Builder builder = asMinimalistDtoBuilder(request);

boolean canAccessActionLogs = SecurityUtils.getSubject().hasRole(Roles.MICA_DAO) || SecurityUtils.getSubject().hasRole(Roles.MICA_ADMIN) || subjectAclService.isPermitted("/data-access-request/action-logs", "VIEW");
if (canAccessActionLogs) {
request.getActionLogHistory()
.forEach(actionLog -> builder.addActionLogHistory(actionLogDtos.asDto(actionLog)));
}

request.getStatusChangeHistory()
.forEach(statusChange -> builder.addStatusChangeHistory(statusChangeDtos.asDto(statusChange)));

ObibaRealm.Subject profile = userProfileService.getProfile(request.getApplicant());
if(profile != null) {
builder.setProfile(userProfileDtos.asDto(profile));
Expand All @@ -111,7 +99,7 @@ Mica.DataAccessRequestDto.Builder asDtoBuilder(@NotNull DataAccessEntity request
}

@NotNull
public Mica.DataAccessRequestDto asDto(@NotNull DataAccessRequest request, boolean includeAmendmentsSummary) {
public Mica.DataAccessRequestDto asDto(@NotNull DataAccessRequest request) {
Mica.DataAccessRequestDto.Builder builder = asDtoBuilder(request);

String title = dataAccessRequestUtilService.getRequestTitle(request);
Expand All @@ -128,21 +116,6 @@ public Mica.DataAccessRequestDto asDto(@NotNull DataAccessRequest request, boole
builder.addActions("ADD_AMENDMENTS");
}

if (includeAmendmentsSummary) {
Map<Object, LinkedHashMap> pendingAmendments = dataAccessRequestRepository.getAmendmentsSummary(request.getId());
if (!pendingAmendments.isEmpty()) {
LinkedHashMap map = pendingAmendments.get(request.getId());
builder.setAmendmentsSummary(
Mica.DataAccessRequestDto.AmendmentsSummaryDto.newBuilder()
.setId(map.get("_id") + "")
.setPending((double) map.get("pending"))
.setTotal((double) map.get("total"))
.setLastModifiedDate(map.get("lastModified") instanceof Date ? ((Date) map.get("lastModified")).toInstant().atOffset(ZoneOffset.systemDefault().getRules().getOffset(Instant.now())).toString() : "")
.build()
);
}
}

boolean hasAdministrativeRole = SecurityUtils.getSubject().hasRole(Roles.MICA_DAO) || SecurityUtils.getSubject().hasRole(Roles.MICA_ADMIN);

if (hasAdministrativeRole || subjectAclService.isPermitted("/data-access-request/private-comment", "VIEW")) {
Expand Down Expand Up @@ -200,24 +173,7 @@ public DataAccessRequest fromDto(@NotNull Mica.DataAccessRequestDto dto) {

@NotNull
public Mica.DataAccessRequestDto asAmendmentDto(@NotNull DataAccessAmendment amendment) {
Mica.DataAccessRequestDto.Builder builder = asDtoBuilder(amendment);
builder.setExtension(
Mica.DataAccessAmendmentDto.amendment,
Mica.DataAccessAmendmentDto.newBuilder().setParentId(amendment.getParentId()).build()
);

if (subjectAclService.isPermitted("/data-access-request", "VIEW", amendment.getParentId())) {
builder.addActions("VIEW");
}

builder.addAllActions(
addDataAccessEntityActions(
amendment,
String.format("/data-access-request/%s/amendment", amendment.getParentId())
)
);

return builder.build();
return asDtoBuilder(amendment).build();
}

@NotNull
Expand Down Expand Up @@ -252,23 +208,112 @@ public ActionLog fromDto(Mica.DataAccessRequestDto.ActionLogDto dto) {
return actionLogDtos.fromDto(dto);
}

List<Mica.DataAccessRequestDto> asDtoList(@NotNull List<DataAccessRequest> requests) {
if (requests != null) {

Map<String, Subject> micaProfiles = userProfileService.getProfilesByApplication("mica", null).stream().collect(Collectors.toMap(Subject::getUsername, profile -> profile));
Map<Object, LinkedHashMap> allAmendmentsSummary = dataAccessRequestRepository.getAllAmendmentsSummary();

return requests.stream()
.map(this::asMinimalistDtoBuilder)
.map(builder -> setUserProfileAndAmendmentsSummary(builder, micaProfiles, allAmendmentsSummary).build()).collect(Collectors.toList());
}

return new ArrayList<>();
}

private Mica.DataAccessRequestDto.Builder asMinimalistDtoBuilder(DataAccessEntity dataAccessEntity) {
Mica.DataAccessRequestDto.Builder builder = Mica.DataAccessRequestDto.newBuilder();

builder
.setApplicant(dataAccessEntity.getApplicant())
.setStatus(dataAccessEntity.getStatus().name())
.setTimestamps(TimestampsDtos.asDto(dataAccessEntity));

if(dataAccessEntity.hasContent()) builder.setContent(dataAccessEntity.getContent());
if(!dataAccessEntity.isNew()) builder.setId(dataAccessEntity.getId());

String title = dataAccessRequestUtilService.getRequestTitle(dataAccessEntity);
if(!Strings.isNullOrEmpty(title)) builder.setTitle(title);

dataAccessEntity.getStatusChangeHistory().forEach(statusChange -> builder.addStatusChangeHistory(statusChangeDtos.asMinimalistDtoBuilder(statusChange)));

setMinimalistActions(builder, dataAccessEntity);

return builder;
}

private void setMinimalistActions(Mica.DataAccessRequestDto.Builder builder, DataAccessEntity dataAccessEntity) {
if (dataAccessEntity instanceof DataAccessAmendment) {

DataAccessAmendment amendment = (DataAccessAmendment) dataAccessEntity;

builder.setExtension(
Mica.DataAccessAmendmentDto.amendment,
Mica.DataAccessAmendmentDto.newBuilder().setParentId(amendment.getParentId()).build()
);

builder.addAllActions(
addDataAccessEntityActions(
amendment,
String.format("/data-access-request/%s/amendment", amendment.getParentId())
)
);
} else {
builder.addAllActions(addDataAccessEntityActions(dataAccessEntity, "/data-access-request"));
}
}

private void setAmendmentsSummary(Mica.DataAccessRequestDto.Builder builder, Map<Object, LinkedHashMap> pendingAmendments) {
if (!pendingAmendments.isEmpty() && builder.hasId() && pendingAmendments.containsKey(builder.getId())) {

LinkedHashMap map = pendingAmendments.get(builder.getId());

builder.setAmendmentsSummary(
Mica.DataAccessRequestDto.AmendmentsSummaryDto.newBuilder()
.setId(map.get("_id") + "")
.setPending((double) map.get("pending"))
.setTotal((double) map.get("total"))
.setLastModifiedDate(map.get("lastModified") instanceof Date ? ((Date) map.get("lastModified")).toInstant().atOffset(ZoneOffset.systemDefault().getRules().getOffset(Instant.now())).toString() : "")
.build()
);
}
}

private Mica.DataAccessRequestDto.Builder setUserProfileAndAmendmentsSummary(Mica.DataAccessRequestDto.Builder dataAccessEntityBuilder, Map<String, Subject> micaProfiles, Map<Object, LinkedHashMap> pendingAmendments) {

if (micaProfiles != null && dataAccessEntityBuilder.hasApplicant() && micaProfiles.containsKey(dataAccessEntityBuilder.getApplicant())) {
dataAccessEntityBuilder.setProfile(userProfileDtos.asDto(micaProfiles.get(dataAccessEntityBuilder.getApplicant())));
}

setAmendmentsSummary(dataAccessEntityBuilder, pendingAmendments);

return dataAccessEntityBuilder;
}

private List<String> addDataAccessEntityActions(DataAccessEntity entity, String resource) {
List<String> actions = Lists.newArrayList();

// possible actions depending on the caller
if (entity instanceof DataAccessAmendment && subjectAclService.isPermitted("/data-access-request", "VIEW", ((DataAccessAmendment) entity).getParentId())) {
actions.add("VIEW");
}

if(entity instanceof DataAccessRequest && subjectAclService.isPermitted(resource, "VIEW", entity.getId())) {
actions.add("VIEW");
}

if(subjectAclService.isPermitted(resource, "EDIT", entity.getId())) {
actions.add("EDIT");
}

if(subjectAclService.isPermitted(resource, "DELETE", entity.getId())) {
actions.add("DELETE");
}
if(subjectAclService
.isPermitted(Paths.get(resource, entity.getId()).toString(), "EDIT", "_status")) {

if(subjectAclService.isPermitted(Paths.get(resource, entity.getId()).toString(), "EDIT", "_status")) {
actions.add("EDIT_STATUS");
}

return actions;
}
}
9 changes: 4 additions & 5 deletions mica-core/src/main/java/org/obiba/mica/web/model/Dtos.java
Expand Up @@ -346,7 +346,7 @@ public Mica.DatasetVariableDto asDto(@NotNull DatasetVariable variable) {
}

@NotNull
public List<Mica.DatasetVariableDto> asDtos(Map<String, List<DatasetVariable>> studyIdVariableMap, @NotNull List<Taxonomy> taxonomies) {
public List<Mica.DatasetVariableDto> asDtoList(Map<String, List<DatasetVariable>> studyIdVariableMap, @NotNull List<Taxonomy> taxonomies) {
return datasetDtos.asDtos(studyIdVariableMap, taxonomies, "en");
}

Expand Down Expand Up @@ -394,12 +394,11 @@ public Mica.DatasetVariableContingencyDto.Builder asContingencyDto(OpalTable opa

@NotNull
public Mica.DataAccessRequestDto asDto(@NotNull DataAccessRequest request) {
return dataAccessRequestDtos.asDto(request, false);
return dataAccessRequestDtos.asDto(request);
}

@NotNull
public Mica.DataAccessRequestDto asDto(@NotNull DataAccessRequest request, boolean includeAmendmentsSummary) {
return dataAccessRequestDtos.asDto(request, includeAmendmentsSummary);
public List<Mica.DataAccessRequestDto> asDtoList(@NotNull List<DataAccessRequest> requests) {
return dataAccessRequestDtos.asDtoList(requests);
}

@NotNull
Expand Down
Expand Up @@ -32,11 +32,7 @@ public class StatusChangeDtos {
private UserProfileDtos userProfileDtos;

StatusChangeDto.Builder asDtoBuilder(StatusChange statusChange) {
StatusChangeDto.Builder builder = StatusChangeDto.newBuilder() //
.setFrom(statusChange.getFrom().toString()) //
.setTo(statusChange.getTo().toString()) //
.setAuthor(statusChange.getAuthor()) //
.setChangedOn(statusChange.getChangedOn().toString());
StatusChangeDto.Builder builder = asMinimalistDtoBuilder(statusChange);

ObibaRealm.Subject profile = subjectProfileService.getProfile(statusChange.getAuthor());
if (profile != null) {
Expand All @@ -50,6 +46,14 @@ StatusChangeDto asDto(StatusChange statusChange) {
return asDtoBuilder(statusChange).build();
}

StatusChangeDto.Builder asMinimalistDtoBuilder(StatusChange statusChange) {
return StatusChangeDto.newBuilder() //
.setFrom(statusChange.getFrom().toString()) //
.setTo(statusChange.getTo().toString()) //
.setAuthor(statusChange.getAuthor()) //
.setChangedOn(statusChange.getChangedOn().toString());
}

StatusChange fromDto(StatusChangeDto dto) {
return StatusChange.newBuilder() //
.previous(DataAccessEntityStatus.valueOf(dto.getFrom())) //
Expand Down
Expand Up @@ -31,6 +31,7 @@
import org.obiba.mica.user.UserProfileService;
import org.obiba.mica.web.model.Dtos;
import org.obiba.mica.web.model.Mica;
import org.obiba.shiro.realm.ObibaRealm.Subject;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

Expand Down Expand Up @@ -82,9 +83,7 @@ public class DataAccessRequestsResource {
@GET
@Timed
public List<Mica.DataAccessRequestDto> listByStatus(@QueryParam("status") List<String> status) {
return listByStatusFilteringPermitted(status).stream()
.map(request -> dtos.asDto(request, true))
.collect(Collectors.toList());
return dtos.asDtoList(listByStatusFilteringPermitted(status));
}

@GET
Expand Down
Expand Up @@ -128,7 +128,7 @@ protected Mica.DatasetVariablesDto getDatasetVariableDtosInternal(String rql, in
}
}).filter(Objects::nonNull).collect(Collectors.groupingBy(DatasetVariable::getStudyId));

builder.addAllVariables(dtos.asDtos(studyIdVariableMap, taxonomies));
builder.addAllVariables(dtos.asDtoList(studyIdVariableMap, taxonomies));

log.info("Response /{}/{}", Indexer.PUBLISHED_VARIABLE_INDEX, Indexer.VARIABLE_TYPE);

Expand Down

0 comments on commit 3ae81d8

Please sign in to comment.