Skip to content

Commit

Permalink
chore: get one trackedEntity via path and query param is identical
Browse files Browse the repository at this point in the history
  • Loading branch information
teleivo committed Jan 8, 2025
1 parent c5a6a4c commit c6630f1
Show file tree
Hide file tree
Showing 9 changed files with 542 additions and 555 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
import org.hisp.dhis.trackedentity.TrackedEntityAttribute;
import org.hisp.dhis.trackedentity.TrackedEntityAttributeService;
import org.hisp.dhis.trackedentity.TrackedEntityAudit;
import org.hisp.dhis.trackedentity.TrackedEntityProgramOwner;
import org.hisp.dhis.trackedentity.TrackedEntityType;
import org.hisp.dhis.trackedentity.TrackedEntityTypeService;
import org.hisp.dhis.trackedentityattributevalue.TrackedEntityAttributeValue;
Expand Down Expand Up @@ -217,83 +216,35 @@ public TrackedEntity getTrackedEntity(@Nonnull UID uid)
UserDetails currentUser = getCurrentUserDetails();
TrackedEntity trackedEntity =
mapTrackedEntity(
getTrackedEntity(uid, currentUser),
TrackedEntityParams.FALSE,
currentUser,
null,
false);
getTrackedEntity(uid, currentUser), TrackedEntityParams.FALSE, currentUser, false);
mapTrackedEntityTypeAttributes(trackedEntity);
return trackedEntity;
}

@Override
public TrackedEntity getTrackedEntity(
@Nonnull UID trackedEntityUid,
@CheckForNull UID programIdentifier,
@Nonnull TrackedEntityParams params)
@Nonnull UID trackedEntity, @CheckForNull UID program, @Nonnull TrackedEntityParams params)
throws NotFoundException, ForbiddenException {
Program program = null;
Page<TrackedEntity> trackedEntities;

if (programIdentifier != null) {
program = programService.getProgram(programIdentifier.getValue());
if (program == null) {
throw new NotFoundException(Program.class, programIdentifier);
}
}

TrackedEntity trackedEntity;
if (program != null) {
trackedEntity = getTrackedEntity(trackedEntityUid.getValue(), program, params);

if (params.isIncludeProgramOwners()) {
Set<TrackedEntityProgramOwner> filteredProgramOwners =
trackedEntity.getProgramOwners().stream()
.filter(te -> te.getProgram().getUid().equals(programIdentifier.getValue()))
.collect(Collectors.toSet());
trackedEntity.setProgramOwners(filteredProgramOwners);
}
} else {
UserDetails userDetails = getCurrentUserDetails();

trackedEntity =
mapTrackedEntity(
getTrackedEntity(trackedEntityUid, userDetails), params, userDetails, null, false);

mapTrackedEntityTypeAttributes(trackedEntity);
}
return trackedEntity;
}

/**
* Gets a tracked entity based on the program and org unit ownership
*
* @return the TE object if found and accessible by the current user
* @throws NotFoundException if uid does not exist
* @throws ForbiddenException if TE owner is not in user's scope or not enough sharing access
*/
private TrackedEntity getTrackedEntity(String uid, Program program, TrackedEntityParams params)
throws NotFoundException, ForbiddenException {
TrackedEntity trackedEntity = trackedEntityStore.getByUid(uid);
trackedEntityAuditService.addTrackedEntityAudit(trackedEntity, getCurrentUsername(), READ);
if (trackedEntity == null) {
throw new NotFoundException(TrackedEntity.class, uid);
}

UserDetails userDetails = getCurrentUserDetails();
List<String> errors =
trackerAccessManager.canReadProgramAndTrackedEntityType(
userDetails, trackedEntity, program);
if (!errors.isEmpty()) {
throw new ForbiddenException(errors.toString());
try {
TrackedEntityOperationParams operationParams =
TrackedEntityOperationParams.builder()
.trackedEntities(Set.of(trackedEntity))
.program(program)
.trackedEntityParams(params)
.build();
trackedEntities = getTrackedEntities(operationParams, new PageParams(1, 1, false));
} catch (BadRequestException e) {
throw new IllegalArgumentException(
"this must be a bug in how the TrackedEntityOperationParams are built");
}

String error =
trackerAccessManager.canAccessProgramOwner(userDetails, trackedEntity, program, false);
if (error != null) {
throw new ForbiddenException(error);
if (trackedEntities.getItems().isEmpty()) {
throw new NotFoundException(TrackedEntity.class, trackedEntity.getValue());
}

return mapTrackedEntity(trackedEntity, params, userDetails, program, false);
return trackedEntities.getItems().get(0);
}

/**
Expand Down Expand Up @@ -338,7 +289,6 @@ private TrackedEntity mapTrackedEntity(
TrackedEntity trackedEntity,
TrackedEntityParams params,
UserDetails user,
Program program,
boolean includeDeleted) {
TrackedEntity result = new TrackedEntity();
result.setId(trackedEntity.getId());
Expand All @@ -361,13 +311,13 @@ private TrackedEntity mapTrackedEntity(
result.setRelationshipItems(getRelationshipItems(trackedEntity, user, includeDeleted));
}
if (params.isIncludeEnrollments()) {
result.setEnrollments(getEnrollments(trackedEntity, user, includeDeleted, program));
result.setEnrollments(getEnrollments(trackedEntity, user, includeDeleted));
}
if (params.isIncludeProgramOwners()) {
result.setProgramOwners(trackedEntity.getProgramOwners());
}

result.setTrackedEntityAttributeValues(getTrackedEntityAttributeValues(trackedEntity, program));
result.setTrackedEntityAttributeValues(getTrackedEntityAttributeValues(trackedEntity));

return result;
}
Expand All @@ -388,9 +338,8 @@ private Set<RelationshipItem> getRelationshipItems(
}

private Set<Enrollment> getEnrollments(
TrackedEntity trackedEntity, UserDetails user, boolean includeDeleted, Program program) {
TrackedEntity trackedEntity, UserDetails user, boolean includeDeleted) {
return trackedEntity.getEnrollments().stream()
.filter(e -> program == null || program.getUid().equals(e.getProgram().getUid()))
.filter(e -> includeDeleted || !e.isDeleted())
.filter(e -> trackerAccessManager.canRead(user, e, false).isEmpty())
.map(
Expand All @@ -409,19 +358,12 @@ private Set<Enrollment> getEnrollments(
}

private Set<TrackedEntityAttributeValue> getTrackedEntityAttributeValues(
TrackedEntity trackedEntity, Program program) {
TrackedEntity trackedEntity) {
Set<String> readableAttributes =
trackedEntity.getTrackedEntityType().getTrackedEntityAttributes().stream()
.map(IdentifiableObject::getUid)
.collect(Collectors.toSet());

if (program != null) {
readableAttributes.addAll(
program.getTrackedEntityAttributes().stream()
.map(IdentifiableObject::getUid)
.collect(Collectors.toSet()));
}

return trackedEntity.getTrackedEntityAttributeValues().stream()
.filter(av -> readableAttributes.contains(av.getAttribute().getUid()))
.collect(Collectors.toSet());
Expand Down Expand Up @@ -484,10 +426,11 @@ private RelationshipItem getTrackedEntityInRelationshipItem(
}

relationshipItem.setTrackedEntity(
mapTrackedEntity(trackedEntity, params, currentUser, null, includeDeleted));
mapTrackedEntity(trackedEntity, params, currentUser, includeDeleted));
return relationshipItem;
}

@Nonnull
@Override
public List<TrackedEntity> getTrackedEntities(
@Nonnull TrackedEntityOperationParams operationParams)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ public class TrackedEntityOperationParams {
/** Tracked entity type to fetch. */
private UID trackedEntityType;

private OrganisationUnitSelectionMode orgUnitMode;
@Builder.Default
private OrganisationUnitSelectionMode orgUnitMode = OrganisationUnitSelectionMode.ACCESSIBLE;

@Getter @Builder.Default
private AssignedUserQueryParam assignedUserQueryParam = AssignedUserQueryParam.ALL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Multimap<String, Event> findByEnrollmentIds(List<Long> ids, Context ctx) {
Multimap<String, RelationshipItem> relationships = relationshipAsync.join();

for (Event event : events.values()) {
if (ctx.getParams().isIncludeRelationships()) {
if (ctx.getParams().getEventParams().isIncludeRelationships()) {
event.setRelationshipItems(new HashSet<>(relationships.get(event.getUid())));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,24 +173,59 @@ public static void assertNotEmpty(Collection<?> actual, String message) {
assertFalse(actual.isEmpty(), message);
}

/**
* Asserts that the given collection is not null and not empty.
*
* @param actual the collection.
* @param messageSupplier fails with this supplied message
*/
public static void assertNotEmpty(Collection<?> actual, Supplier<String> messageSupplier) {
assertNotNull(actual, messageSupplier);
assertFalse(actual.isEmpty(), messageSupplier);
}

/**
* Asserts that the given collection contains the expected number of elements.
*
* @param actual the collection.
*/
public static void assertHasSize(int expected, Collection<?> actual) {
assert expected > 0 : "use assertIsEmpty";

assertNotEmpty(actual);
assertEquals(
assertHasSize(
expected,
actual.size(),
actual,
() ->
String.format(
"expected collection to contain %d elements, it has %d instead: '%s'",
expected, actual.size(), actual));
}

/**
* Asserts that the given collection contains the expected number of elements.
*
* @param actual the collection.
* @param messageSupplier fails with this supplied message
*/
public static void assertHasSize(
int expected, Collection<?> actual, Supplier<String> messageSupplier) {
assert expected > 0 : "use assertIsEmpty";

assertNotEmpty(actual);
assertEquals(expected, actual.size(), messageSupplier);
}

/**
* Asserts that the given collection contains the expected number of elements.
*
* @param actual the collection.
* @param message fails with this message
*/
public static void assertHasSize(int expected, Collection<?> actual, String message) {
assert expected > 0 : "use assertIsEmpty";

assertNotEmpty(actual);
assertEquals(expected, actual.size(), message);
}

/**
* Asserts that the given string starts with the expected prefix.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1070,7 +1070,7 @@
"attribute": {
"id": "j45AR9cBQKc"
},
"value": "programStage qLZC0lvvxQH"
"value": "multi-program-stage-attribute"
}
],
"autoGenerateEvent": true,
Expand Down Expand Up @@ -1126,15 +1126,7 @@
}
],
"validationStrategy": "ON_UPDATE_AND_INSERT",
"featureType": "POINT",
"attributeValues": [
{
"attribute": {
"id": "j45AR9cBQKc"
},
"value": "multi-program-stage-attribute"
}
]
"featureType": "POINT"
},
{
"id": "SKNvpoLioON",
Expand Down Expand Up @@ -1851,6 +1843,29 @@
},
"relationshipEntity": "PROGRAM_STAGE_INSTANCE"
}
},
{
"id": "m1575931405",
"displayFromToName": "Parent Of",
"displayName": "Parent to Child",
"fromConstraint": {
"relationshipEntity": "TRACKED_ENTITY_INSTANCE",
"trackedEntityType": {
"id": "ja8NY4PW7Xm"
}
},
"fromToName": "Child Of",
"name": "Tracked entity to tracked entity",
"sharing": {
"owner": null,
"public": "r-------"
},
"toConstraint": {
"relationshipEntity": "TRACKED_ENTITY_INSTANCE",
"trackedEntityType": {
"id": "ja8NY4PW7Xm"
}
}
}
],
"trackedEntityAttributes": [
Expand Down Expand Up @@ -2230,6 +2245,41 @@
],
"username": "trackeradmin"
},
{
"id": "Z7870757a75",
"access": {
"delete": true,
"externalize": true,
"manage": true,
"read": true,
"update": true,
"write": true
},
"dataViewOrganisationUnits": [
{
"id": "h4w96yEMlzO"
}
],
"displayName": "basicuser",
"email": "basic@dhis2.org",
"firstName": "basic",
"name": "user",
"organisationUnits": [
{
"id": "h4w96yEMlzO"
}
],
"password": "Test123###...",
"passwordLastUpdated": "2020-05-31T08:57:59.060",
"phoneNumber": "+4740332255",
"surname": "basic",
"userRoles": [
{
"id": "UbhT3bXWUyb"
}
],
"username": "basicuser"
},
{
"id": "o1HMTIzBGo7",
"access": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,13 @@
import org.hisp.dhis.webapi.controller.tracker.JsonRelationshipItem;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

@Transactional
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class EventsExportControllerTest extends PostgresControllerIntegrationTestBase {
private static final String DATA_ELEMENT_VALUE = "value";

Expand Down
Loading

0 comments on commit c6630f1

Please sign in to comment.