From 724b9d0ac078538e275067e61accbec81cd38479 Mon Sep 17 00:00:00 2001 From: Enrico Colasante Date: Fri, 20 Dec 2024 04:17:31 -0300 Subject: [PATCH 1/5] chore: Make dependabot upgrade rule-engine library (#19543) Rule-engine doesn't have circular dependency anymore and it can be managed by dependabot as any other dependency --- .github/dependabot.yml | 12 ------------ dhis-2/pom.xml | 10 ---------- 2 files changed, 22 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index b9a55d7720e4..333fec034948 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -52,12 +52,6 @@ updates: - dependency-name: "org.springframework.ldap:*" # Spring ldap 3.x requires Spring 6 (see above) versions: - ">= 3.0" - - dependency-name: "org.hisp.dhis.parser:*" # Antlr parser must be upgraded manually due to circular dependency with rule engine - versions: - - ">= 1.0" - - dependency-name: "org.hisp.dhis.rules:*" # Rule engine must be upgraded manually due to circular dependency with ANTLR parser - versions: - - ">= 2.0" - dependency-name: "org.slf4j:slf4j-api" # will update in https://dhis2.atlassian.net/browse/DHIS2-16504 versions: - ">= 2.0" @@ -138,12 +132,6 @@ updates: - dependency-name: "org.springframework.ldap:*" # Spring ldap 3.x requires Spring 6 (see above) versions: - ">= 3.0" - - dependency-name: "org.hisp.dhis.parser:*" # Antlr parser must be upgraded manually due to circular dependency with rule engine - versions: - - ">= 1.0" - - dependency-name: "org.hisp.dhis.rules:*" # Rule engine must be upgraded manually due to circular dependency with ANTLR parser - versions: - - ">= 2.0" - dependency-name: "org.flywaydb:flyway-core" # It requires Postgres version to be >= 11 versions: - "> 9.22.3" diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index ead83aebaee0..a379992088b6 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -428,16 +428,6 @@ org.hisp.dhis.rules rule-engine-jvm ${dhis2-rule-engine.version} - - - commons-logging - commons-logging - - - org.slf4j - slf4j-simple - - From 73fa91e6c07fe396db105cd310224ee6402fb2bc Mon Sep 17 00:00:00 2001 From: Martina Kraus Date: Fri, 20 Dec 2024 09:50:41 +0100 Subject: [PATCH 2/5] feat: integrate dependency track (#19412) --- .github/workflows/generate-merge-boms.yml | 51 +++++++++++++++++++++++ dhis-2/pom.xml | 22 ++++++++++ 2 files changed, 73 insertions(+) create mode 100644 .github/workflows/generate-merge-boms.yml diff --git a/.github/workflows/generate-merge-boms.yml b/.github/workflows/generate-merge-boms.yml new file mode 100644 index 000000000000..50b23f38f675 --- /dev/null +++ b/.github/workflows/generate-merge-boms.yml @@ -0,0 +1,51 @@ +name: Generate and Merge SBOMs and Upload them to DependencyTrack every night + +on: + schedule: + - cron: "0 0 * * *" # Run every day at midnight + +concurrency: + group: ${{ github.workflow}}-${{ github.ref }} + cancel-in-progress: true + +jobs: + create-boms: + runs-on: ubuntu-latest + defaults: + run: + working-directory: dhis-2/ + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + fetch-depth: 0 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: 17 + distribution: temurin + cache: maven + + - name: Install CycloneDX CLI + run: | + curl -s https://api.github.com/repos/CycloneDX/cyclonedx-cli/releases/latest | grep "browser_download_url.*linux.x64" | cut -d '"' -f 4 | wget -i - + sudo mv cyclonedx-linux-x64 /usr/local/bin/ + sudo chmod +x /usr/local/bin/cyclonedx-linux-x64 + + - name: Generate BOMs + run: mvn cyclonedx:makeBom + + - name: Merge BOMs + run: cyclonedx-linux-x64 merge --input-files $(find . -name 'dxbom.json') --input-format json --output-file target/merged-bom.json --output-format json + + - name: Upload SBOM to DependencyTrack + env: + DEPENDENCY_TRACK_API: "https://dt.security.dhis2.org/api/v1/bom" + run: | + curl -X POST "$DEPENDENCY_TRACK_API" \ + --fail-with-body \ + -H "Content-Type: multipart/form-data" \ + -H "X-Api-Key: ${{ secrets.DEPENDENCYTRACK_APIKEY }}" \ + -F "project=56383704-d5a2-4a35-ad6a-081f80f5d6d3" \ + -F "bom=@target/merged-bom.json" diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index a379992088b6..6c723e47141c 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -1872,6 +1872,28 @@ sonar-maven-plugin 5.0.0.4389 + + org.cyclonedx + cyclonedx-maven-plugin + + library + 1.6 + true + true + true + true + true + false + false + true + all + dxbom + ${project.build.directory} + + false + + + org.codehaus.mojo versions-maven-plugin From 826a04921f77f4fbd9147203d44a616ff729fcf9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 07:57:58 -0300 Subject: [PATCH 3/5] chore(deps): bump org.springframework.session:spring-session-core (#19546) Bumps [org.springframework.session:spring-session-core](https://github.com/spring-projects/spring-session) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/spring-projects/spring-session/releases) - [Changelog](https://github.com/spring-projects/spring-session/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-session/compare/3.4.0...3.4.1) --- updated-dependencies: - dependency-name: org.springframework.session:spring-session-core dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dhis-2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index 6c723e47141c..5b9734d4bd45 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -104,7 +104,7 @@ 6.1.12 - 3.4.0 + 3.4.1 2.7.18 2.7.4 1.1.5.RELEASE From 900b01c73537a5686095d7492c013c1145308a47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 07:58:51 -0300 Subject: [PATCH 4/5] chore(deps-dev): bump org.hisp.dhis.rules:rule-engine-jvm in /dhis-2 (#19548) Bumps [org.hisp.dhis.rules:rule-engine-jvm](https://github.com/dhis2/dhis2-rule-engine) from 3.1.0 to 3.2.1. - [Release notes](https://github.com/dhis2/dhis2-rule-engine/releases) - [Commits](https://github.com/dhis2/dhis2-rule-engine/commits) --- updated-dependencies: - dependency-name: org.hisp.dhis.rules:rule-engine-jvm dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dhis-2/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dhis-2/pom.xml b/dhis-2/pom.xml index 5b9734d4bd45..164856cbd652 100644 --- a/dhis-2/pom.xml +++ b/dhis-2/pom.xml @@ -85,7 +85,7 @@ - 3.1.0 + 3.2.1 0.6.1 From 6cb0d1fdd63acfe76f5217afb7d7c35e6c77d525 Mon Sep 17 00:00:00 2001 From: Enrico Colasante Date: Fri, 20 Dec 2024 10:57:32 -0300 Subject: [PATCH 5/5] fix: Always add default order as last order param in tracker exporters [DHIS2-18659] (#19551) * fix: Always add default order as last order param for events [DHIS2-18659] * fix: Always add default order as last order param for enrollments [DHIS2-18659] * fix: Always add default order as last order param for relationships [DHIS2-18659] * fix: Always add default order as last order param for tracked entities [DHIS2-18659] --- .../enrollment/HibernateEnrollmentStore.java | 2 +- .../tracker/export/event/JdbcEventStore.java | 2 +- .../HibernateRelationshipStore.java | 8 +- .../HibernateTrackedEntityStore.java | 4 +- .../OrderAndPaginationExporterTest.java | 94 +++++++++++++++++++ .../tracker/event_and_enrollment.json | 16 ++++ 6 files changed, 120 insertions(+), 6 deletions(-) diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java index 49f165a22cc2..d67e20076ef6 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/enrollment/HibernateEnrollmentStore.java @@ -279,7 +279,7 @@ private static String orderBy(List orders) { orderJoiner.add( order.getField() + " " + (order.getDirection().isAscending() ? "asc" : "desc")); } - return " order by " + orderJoiner; + return " order by " + orderJoiner + ", " + DEFAULT_ORDER; } @Getter diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java index 09c6e1c9a542..2b5d9f11e8b6 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/event/JdbcEventStore.java @@ -1612,7 +1612,7 @@ private String getOrderQuery(EventQueryParams params) { } if (!orderFields.isEmpty()) { - return "order by " + StringUtils.join(orderFields, ',') + " "; + return "order by " + StringUtils.join(orderFields, ',') + ", " + DEFAULT_ORDER + " "; } else { return "order by " + DEFAULT_ORDER + " "; } diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java index 05801268d0c3..90c1715f9e8c 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/relationship/HibernateRelationshipStore.java @@ -41,6 +41,7 @@ import java.util.Set; import java.util.function.Function; import java.util.function.LongSupplier; +import java.util.stream.Stream; import javax.annotation.Nonnull; import org.apache.commons.collections4.CollectionUtils; import org.hisp.dhis.common.IdentifiableObject; @@ -264,10 +265,13 @@ private String getRelationshipEntityType(T entity private List orderBy( RelationshipQueryParams queryParams, CriteriaBuilder builder, Root root) { + List defaultOrder = orderBy(List.of(DEFAULT_ORDER), builder, root); if (!queryParams.getOrder().isEmpty()) { - return orderBy(queryParams.getOrder(), builder, root); + return Stream.concat( + orderBy(queryParams.getOrder(), builder, root).stream(), defaultOrder.stream()) + .toList(); } else { - return orderBy(List.of(DEFAULT_ORDER), builder, root); + return defaultOrder; } } diff --git a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java index 8aa3221956e8..948d63004212 100644 --- a/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java +++ b/dhis-2/dhis-services/dhis-service-tracker/src/main/java/org/hisp/dhis/tracker/export/trackedentity/HibernateTrackedEntityStore.java @@ -1007,10 +1007,10 @@ private String getQueryOrderBy(TrackedEntityQueryParams params, boolean innerOrd } if (!orderFields.isEmpty()) { - return "ORDER BY " + StringUtils.join(orderFields, ',') + SPACE; + return "ORDER BY " + StringUtils.join(orderFields, ',') + ", " + DEFAULT_ORDER + SPACE; } - return "ORDER BY " + DEFAULT_ORDER + " "; + return "ORDER BY " + DEFAULT_ORDER + SPACE; } /** diff --git a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java index b925005fca34..3106c4c8b009 100644 --- a/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java +++ b/dhis-2/dhis-test-integration/src/test/java/org/hisp/dhis/tracker/export/OrderAndPaginationExporterTest.java @@ -207,6 +207,32 @@ void shouldReturnPaginatedTrackedEntitiesGivenNonDefaultPageSizeAndTotalPages() trackedEntityService.getTrackedEntities(params, new PageParams(3, 3, true)).getItems()); } + @Test + void shouldOrderTrackedEntitiesByInactiveAndByDefaultOrder() + throws ForbiddenException, BadRequestException, NotFoundException { + List expected = + Stream.of( + get(TrackedEntity.class, "QesgJkTyTCk"), + get(TrackedEntity.class, "dUE514NMOlo"), + get(TrackedEntity.class, "mHWCacsGYYn")) + .sorted(Comparator.comparing(TrackedEntity::getId).reversed()) // reversed = desc + .map(TrackedEntity::getUid) + .toList(); + + TrackedEntityOperationParams params = + TrackedEntityOperationParams.builder() + .organisationUnits(orgUnit) + .orgUnitMode(SELECTED) + .trackedEntities(UID.of("mHWCacsGYYn", "QesgJkTyTCk", "dUE514NMOlo")) + .trackedEntityType(trackedEntityType) + .orderBy("inactive", SortDirection.ASC) + .build(); + + List trackedEntities = getTrackedEntities(params); + + assertEquals(expected, trackedEntities); + } + @Test void shouldOrderTrackedEntitiesByPrimaryKeyDescByDefault() throws ForbiddenException, BadRequestException, NotFoundException { @@ -566,6 +592,28 @@ void shouldOrderTrackedEntitiesByInactiveAsc() assertEquals(List.of("dUE514NMOlo", "QS6w44flWAf"), trackedEntities); } + @Test + void shouldOrderEnrollmentsByStatusAndByDefaultOrder() + throws ForbiddenException, BadRequestException { + List expected = + Stream.of(get(Enrollment.class, "HDWTYSYkICe"), get(Enrollment.class, "GYWSSZunTLk")) + .sorted(Comparator.comparing(Enrollment::getId).reversed()) // reversed = desc + .map(Enrollment::getUid) + .toList(); + + EnrollmentOperationParams operationParams = + EnrollmentOperationParams.builder() + .orgUnits(get(OrganisationUnit.class, "DiszpKrYNg8")) + .orgUnitMode(SELECTED) + .enrollments(UID.of("HDWTYSYkICe", "GYWSSZunTLk")) + .orderBy("status", SortDirection.DESC) + .build(); + + List actual = getEnrollments(operationParams); + + assertEquals(expected, actual); + } + @Test void shouldReturnPaginatedEnrollmentsGivenNonDefaultPageSize() throws ForbiddenException, BadRequestException { @@ -677,6 +725,29 @@ void shouldOrderEnrollmentsByEnrolledAtDesc() throws ForbiddenException, BadRequ assertEquals(List.of("TvctPPhpD8z", "nxP7UnKhomJ"), enrollments); } + @Test + void shouldOrderEventsByStatusAndByDefaultOrder() throws ForbiddenException, BadRequestException { + List expected = + Stream.of( + get(Event.class, "ck7DzdxqLqA"), + get(Event.class, "kWjSezkXHVp"), + get(Event.class, "OTmjvJDn0Fu")) + .sorted(Comparator.comparing(Event::getId).reversed()) // reversed = desc + .map(Event::getUid) + .toList(); + + EventOperationParams operationParams = + eventParamsBuilder + .orgUnit(get(OrganisationUnit.class, "DiszpKrYNg8")) + .events(UID.of("ck7DzdxqLqA", "kWjSezkXHVp", "OTmjvJDn0Fu")) + .orderBy("status", SortDirection.DESC) + .build(); + + List actual = getEvents(operationParams); + + assertEquals(expected, actual); + } + @Test void shouldReturnPaginatedEventsWithNotesGivenNonDefaultPageSize() throws ForbiddenException, BadRequestException { @@ -1274,6 +1345,29 @@ void shouldOrderByFieldInAscendingOrderWhenModeDescendants( assertEquals(List.of(firstEvent, secondEvent), events); } + @Test + void shouldOrderRelationshipsByCreatedAtClientAndByDefaultOrder() + throws ForbiddenException, BadRequestException, NotFoundException { + Relationship oLT07jKRu9e = get(Relationship.class, "fHn74P5T3r1"); + Relationship yZxjxJli9mO = get(Relationship.class, "yZxjxJli9mO"); + List expected = + Stream.of(oLT07jKRu9e, yZxjxJli9mO) + .sorted(Comparator.comparing(Relationship::getId).reversed()) // reversed = desc + .map(Relationship::getUid) + .toList(); + + RelationshipOperationParams params = + RelationshipOperationParams.builder() + .type(TrackerType.TRACKED_ENTITY) + .identifier(UID.of("dUE514NMOlo")) + .orderBy("createdAtClient", SortDirection.DESC) + .build(); + + List relationships = getRelationships(params); + + assertEquals(expected, relationships); + } + @Test void shouldOrderRelationshipsByPrimaryKeyDescByDefault() throws ForbiddenException, BadRequestException, NotFoundException { diff --git a/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json b/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json index d5ea8bc6e580..27db31bb7b87 100644 --- a/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json +++ b/dhis-2/dhis-test-integration/src/test/resources/tracker/event_and_enrollment.json @@ -1309,6 +1309,22 @@ "to": { "event": "pTzf9KYMk72" } + }, + { + "relationship": "fHn74P5T3r1", + "relationshipType": { + "idScheme": "UID", + "identifier": "TV9oB9LT3sh" + }, + "createdAtClient": "2018-11-01T13:24:37.118", + "bidirectional": false, + "deleted": false, + "from": { + "trackedEntity": "dUE514NMOlo" + }, + "to": { + "event": "D9PbzJY8bJM" + } } ], "username": "system-process"