From a5dba29e74b141a98b02fd3e8b12cf8e01708578 Mon Sep 17 00:00:00 2001 From: Denislav Prinov Date: Wed, 16 Aug 2023 11:09:46 +0300 Subject: [PATCH] Full representation with filtration (#1415) * fixed RSQL filtration while loading full representation of a Rollout Signed-off-by: Denislav Prinov * Added tests Signed-off-by: Denislav Prinov * review findings Signed-off-by: Denislav Prinov --------- Signed-off-by: Denislav Prinov --- .../hawkbit/repository/RolloutManagement.java | 10 ++++ .../repository/jpa/JpaRolloutManagement.java | 4 +- .../rest/resource/MgmtRolloutResource.java | 27 ++++------- .../resource/MgmtRolloutResourceTest.java | 46 +++++++++++++++++++ 4 files changed, 67 insertions(+), 20 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java index d073993ba..43ad4a715 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RolloutManagement.java @@ -458,4 +458,14 @@ public interface RolloutManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) void triggerNextGroup(long rolloutId); + /** + * Enrich the rollouts Slice with additional details + * + * @param rollouts + * the rollouts to be enriched. + * + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE) + void setRolloutStatusDetails(final Slice rollouts); + } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index 0e5d6939c..c5502d9c1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -575,8 +575,8 @@ public class JpaRolloutManagement implements RolloutManagement { return fromCache; } - - private void setRolloutStatusDetails(final Slice rollouts) { + @Override + public void setRolloutStatusDetails(final Slice rollouts) { final List rolloutIds = rollouts.getContent().stream().map(Rollout::getId).collect(Collectors.toList()); final Map> allStatesForRollout = getStatusCountItemForRollout( rolloutIds); diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java index 470419ca9..1b38d783e 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java @@ -103,26 +103,17 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { final boolean isFullMode = parseRepresentationMode(representationModeParam) == MgmtRepresentationMode.FULL; final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); - final Slice rollouts; - final long totalElements; + final Page rollouts; if (rsqlParam != null) { - if (isFullMode) { - rollouts = this.rolloutManagement.findByFiltersWithDetailedStatus(pageable, rsqlParam, false); - totalElements = this.rolloutManagement.countByFilters(rsqlParam); - } else { - final Page findRolloutsAll = this.rolloutManagement.findByRsql(pageable, rsqlParam, false); - totalElements = findRolloutsAll.getTotalElements(); - rollouts = findRolloutsAll; - } + rollouts = this.rolloutManagement.findByRsql(pageable, rsqlParam, false); } else { - if (isFullMode) { - rollouts = this.rolloutManagement.findAllWithDetailedStatus(pageable, false); - totalElements = this.rolloutManagement.count(); - } else { - final Page findRolloutsAll = this.rolloutManagement.findAll(pageable, false); - totalElements = findRolloutsAll.getTotalElements(); - rollouts = findRolloutsAll; - } + rollouts = this.rolloutManagement.findAll(pageable, false); + } + + final long totalElements = rollouts.getTotalElements(); + + if (isFullMode) { + this.rolloutManagement.setRolloutStatusDetails(rollouts); } final List rest = MgmtRolloutMapper.toResponseRollout(rollouts.getContent(), diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java index bace8c0af..c6161ae69 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java @@ -332,6 +332,52 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))); } + @Test + @Description("Retrieves the list of rollouts with representation mode 'full'.") + void retrieveRolloutListFullRepresentationWithFilter() throws Exception { + testdataFactory.createTargets(20, "rollout", "rollout"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + + // create a running rollout for the created targets + final Rollout rollout = rolloutManagement.create( + entityFactory.rollout().create().name("rollout1").set(dsA.getId()) + .targetFilterQuery("controllerId==rollout*"), + 4, false, new RolloutGroupConditionBuilder().withDefaults() + .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); + + rolloutManagement.create( + entityFactory.rollout().create().name("rollout2").set(dsA.getId()) + .targetFilterQuery("controllerId==rollout*"), + 4, false, new RolloutGroupConditionBuilder().withDefaults() + .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); + + rolloutHandler.handleAll(); + rolloutManagement.start(rollout.getId()); + rolloutHandler.handleAll(); + + // request the list of rollouts with full representation + mvc.perform(get("/rest/v1/rollouts?q=name==rollout1&representation=full").accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) + .andExpect(jsonPath("content[0].id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("content[0].name", equalTo("rollout1"))) + .andExpect(jsonPath("content[0].status", equalTo("running"))) + .andExpect(jsonPath("content[0].targetFilterQuery", equalTo("controllerId==rollout*"))) + .andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue()))) + .andExpect(jsonPath("content[0].totalTargets", equalTo(20))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus").exists()) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(5))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.notstarted", equalTo(0))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.scheduled", equalTo(15))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("content[0].deleted", equalTo(false))) + .andExpect(jsonPath("content[0].totalGroups", equalTo(4))) + .andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))); + } + @ParameterizedTest @ValueSource(booleans = { true, false }) @Description("Verify the confirmation required flag is not part of the rollout parent entity")