Add statistics for Distribution Set (#1388)
* Add Statistics for Rollouts and Actions count by Status for a Distribution Set Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> * remove unused imports Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> * Refactoring and additional statistics for auto assignments Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> * Fixed review findings and added tests Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> * Added tests for the Management API Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> * Remove unused imports Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> * refactoring Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com> --------- Signed-off-by: Denislav Prinov <denislav.prinov@bosch.com>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Copyright (c) 2023 Bosch.IO GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
|
||||
package org.eclipse.hawkbit.mgmt.json.model.distributionset;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MgmtDistributionSetStatistics {
|
||||
private static final String TOTAL = "total";
|
||||
|
||||
@JsonProperty
|
||||
private Map<String, Long> totalActionsPerStatus;
|
||||
|
||||
@JsonProperty
|
||||
private Map<String, Long> totalRolloutsPerStatus;
|
||||
|
||||
@JsonProperty
|
||||
private Long totalAutoAssignments;
|
||||
|
||||
private MgmtDistributionSetStatistics() {
|
||||
// Private constructor to enforce the use of the builder pattern
|
||||
}
|
||||
|
||||
public Map<String, Long> getTotalActionsPerStatus() {
|
||||
return totalActionsPerStatus;
|
||||
}
|
||||
|
||||
public Map<String, Long> getTotalRolloutsPerStatus() {
|
||||
return totalRolloutsPerStatus;
|
||||
}
|
||||
|
||||
public Long getTotalAutoAssignments() {
|
||||
return totalAutoAssignments;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Map<String, Long> totalActionsPerStatus;
|
||||
private Map<String, Long> totalRolloutsPerStatus;
|
||||
|
||||
private Long totalAutoAssignments;
|
||||
|
||||
public Builder() {
|
||||
totalActionsPerStatus = new HashMap<>();
|
||||
totalRolloutsPerStatus = new HashMap<>();
|
||||
}
|
||||
|
||||
public Builder addTotalActionPerStatus(String status, Long count) {
|
||||
totalActionsPerStatus.put(status, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addTotalRolloutPerStatus(String status, Long count) {
|
||||
totalRolloutsPerStatus.put(status, count);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addTotalAutoAssignments(Long count) {
|
||||
totalAutoAssignments = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MgmtDistributionSetStatistics build() {
|
||||
MgmtDistributionSetStatistics statistics = new MgmtDistributionSetStatistics();
|
||||
statistics.totalActionsPerStatus = calculateTotalWithStatus(totalActionsPerStatus);
|
||||
statistics.totalRolloutsPerStatus = calculateTotalWithStatus(totalRolloutsPerStatus);
|
||||
statistics.totalAutoAssignments = totalAutoAssignments;
|
||||
return statistics;
|
||||
}
|
||||
|
||||
private Map<String, Long> calculateTotalWithStatus(Map<String, Long> statusMap) {
|
||||
if (statusMap.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long total = statusMap.values().stream().mapToLong(Long::longValue).sum();
|
||||
statusMap.put(TOTAL, total);
|
||||
return statusMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetRequestBodyPost;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetRequestBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetStatistics;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtInvalidateDistributionSetRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentResponseBody;
|
||||
@@ -397,6 +398,62 @@ public interface MgmtDistributionSetRestApi {
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam,
|
||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SORTING, required = false) String sortParam);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving Rollouts count by Status
|
||||
* for Distribution Set.
|
||||
*
|
||||
* @param distributionSetId
|
||||
* the ID of the set to retrieve
|
||||
*
|
||||
* @return a DistributionSetStatistics with status OK.
|
||||
*
|
||||
*/
|
||||
@GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/statistics/rollouts", produces = {
|
||||
MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtDistributionSetStatistics> getRolloutsCountByStatusForDistributionSet(@PathVariable("distributionSetId") Long distributionSetId);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving Actions count by Status
|
||||
* for Distribution Set.
|
||||
*
|
||||
* @param distributionSetId
|
||||
* the ID of the set to retrieve
|
||||
*
|
||||
* @return a DistributionSetStatistics with status OK.
|
||||
*
|
||||
*/
|
||||
@GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/statistics/actions", produces = {
|
||||
MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtDistributionSetStatistics> getActionsCountByStatusForDistributionSet(@PathVariable("distributionSetId") Long distributionSetId);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving Auto Assignments count
|
||||
* for Distribution Set.
|
||||
*
|
||||
* @param distributionSetId
|
||||
* the ID of the set to retrieve
|
||||
*
|
||||
* @return a DistributionSetStatistics with status OK.
|
||||
*
|
||||
*/
|
||||
@GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/statistics/autoassignments", produces = {
|
||||
MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtDistributionSetStatistics> getAutoAssignmentsCountForDistributionSet(@PathVariable("distributionSetId") Long distributionSetId);
|
||||
|
||||
/**
|
||||
* Handles the GET request of retrieving Rollouts, Actions and
|
||||
* Auto Assignments counts by Status for Distribution Set.
|
||||
*
|
||||
* @param distributionSetId
|
||||
* the ID of the set to retrieve
|
||||
*
|
||||
* @return a DistributionSetStatistics with status OK.
|
||||
*
|
||||
*/
|
||||
@GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/statistics", produces = {
|
||||
MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE })
|
||||
ResponseEntity<MgmtDistributionSetStatistics> getStatisticsForDistributionSet(@PathVariable("distributionSetId") Long distributionSetId);
|
||||
|
||||
/**
|
||||
* Invalidates a distribution set
|
||||
*
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.eclipse.hawkbit.mgmt.json.model.PagedList;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetRequestBodyPost;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetRequestBodyPut;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetStatistics;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtInvalidateDistributionSetRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtTargetAssignmentResponseBody;
|
||||
@@ -414,6 +415,40 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
||||
softwaremodules.getTotalElements()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtDistributionSetStatistics> getRolloutsCountByStatusForDistributionSet(Long distributionSetId) {
|
||||
MgmtDistributionSetStatistics.Builder statistics = new MgmtDistributionSetStatistics.Builder();
|
||||
distributionSetManagement.countRolloutsByStatusForDistributionSet(distributionSetId).forEach(statistic ->
|
||||
statistics.addTotalRolloutPerStatus(String.valueOf(statistic.getName()), Long.parseLong(statistic.getData().toString())));
|
||||
return ResponseEntity.ok(statistics.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtDistributionSetStatistics> getActionsCountByStatusForDistributionSet(Long distributionSetId) {
|
||||
MgmtDistributionSetStatistics.Builder statistics = new MgmtDistributionSetStatistics.Builder();
|
||||
distributionSetManagement.countActionsByStatusForDistributionSet(distributionSetId).forEach(statistic ->
|
||||
statistics.addTotalActionPerStatus(String.valueOf(statistic.getName()), Long.parseLong(statistic.getData().toString())));
|
||||
return ResponseEntity.ok(statistics.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtDistributionSetStatistics> getAutoAssignmentsCountForDistributionSet(Long distributionSetId) {
|
||||
MgmtDistributionSetStatistics.Builder statistics = new MgmtDistributionSetStatistics.Builder();
|
||||
statistics.addTotalAutoAssignments(distributionSetManagement.countAutoAssignmentsForDistributionSet(distributionSetId));
|
||||
return ResponseEntity.ok(statistics.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<MgmtDistributionSetStatistics> getStatisticsForDistributionSet(Long distributionSetId) {
|
||||
MgmtDistributionSetStatistics.Builder statistics = new MgmtDistributionSetStatistics.Builder();
|
||||
distributionSetManagement.countRolloutsByStatusForDistributionSet(distributionSetId).forEach(statistic ->
|
||||
statistics.addTotalRolloutPerStatus(String.valueOf(statistic.getName()), Long.parseLong(statistic.getData().toString())));
|
||||
distributionSetManagement.countActionsByStatusForDistributionSet(distributionSetId).forEach(statistic ->
|
||||
statistics.addTotalActionPerStatus(String.valueOf(statistic.getName()), Long.parseLong(statistic.getData().toString())));
|
||||
statistics.addTotalAutoAssignments(distributionSetManagement.countAutoAssignmentsForDistributionSet(distributionSetId));
|
||||
return ResponseEntity.ok(statistics.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Void> invalidateDistributionSet(
|
||||
@PathVariable("distributionSetId") final Long distributionSetId,
|
||||
|
||||
@@ -77,7 +77,6 @@ import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.validation.constraints.AssertTrue;
|
||||
|
||||
@Feature("Component Tests - Management API")
|
||||
@Story("Distribution Set Resource")
|
||||
@@ -1442,6 +1441,130 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
assertThat(actions.get(0).getWeight()).get().isEqualTo(weight);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Request to get the count of all Rollouts by status for specific Distribution set")
|
||||
public void statisticsForRolloutsCountByStatus() throws Exception {
|
||||
testdataFactory.createTargets("targets", 4);
|
||||
DistributionSet ds1 = testdataFactory.createDistributionSet("DS1");
|
||||
DistributionSet ds2 = testdataFactory.createDistributionSet("DS2");
|
||||
|
||||
testdataFactory.createRolloutByVariables("rollout1", "description",
|
||||
1, "name==targets*", ds1, "50", "5", false);
|
||||
Rollout rollout = testdataFactory.createRolloutByVariables("rollout2", "description",
|
||||
1, "name==targets*", ds1, "50", "5", false);
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/rollouts", ds1.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus.READY", equalTo(1)))
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus.RUNNING", equalTo(1)))
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus.total", equalTo(2)))
|
||||
.andExpect(jsonPath("totalActionsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalAutoAssignments").doesNotExist());
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/rollouts", ds2.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalActionsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalAutoAssignments").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Request to get the count of all Actions by status for specific Distribution set")
|
||||
public void statisticsForActionsCountByStatus() throws Exception {
|
||||
testdataFactory.createTargets("targets", 4);
|
||||
|
||||
DistributionSet ds1 = testdataFactory.createDistributionSet("DS1");
|
||||
DistributionSet ds2 = testdataFactory.createDistributionSet("DS2");
|
||||
|
||||
Rollout rollout = testdataFactory.createRolloutByVariables("rollout", "description",
|
||||
1, "name==targets*", ds1, "50", "5", false);
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/actions", ds1.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalActionsPerStatus.RUNNING", equalTo(4)))
|
||||
.andExpect(jsonPath("totalActionsPerStatus.total", equalTo(4)))
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalAutoAssignments").doesNotExist());
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/actions", ds2.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalActionsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalAutoAssignments").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Request to get the count of all Auto Assignments for specific Distribution set")
|
||||
public void statisticsForAutoAssignmentsCount() throws Exception {
|
||||
testdataFactory.createTargets("targets", 4);
|
||||
DistributionSet ds1 = testdataFactory.createDistributionSet("DS1");
|
||||
DistributionSet ds2 = testdataFactory.createDistributionSet("DS2");
|
||||
|
||||
targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("test filter 1").autoAssignDistributionSet(ds1.getId()).query("name==targets*"));
|
||||
|
||||
targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("test filter 2").autoAssignDistributionSet(ds1.getId()).query("name==targets*"));
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds1.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalAutoAssignments", equalTo(2)))
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalActionsPerStatus").doesNotExist());
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalActionsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalAutoAssignments").doesNotExist());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Request to get full Statistics for specific Distribution set")
|
||||
public void statisticsForDistributionSet() throws Exception {
|
||||
testdataFactory.createTargets("targets", 4);
|
||||
testdataFactory.createTargets("autoAssignments", 4);
|
||||
DistributionSet ds1 = testdataFactory.createDistributionSet("DS1");
|
||||
DistributionSet ds2 = testdataFactory.createDistributionSet("DS2");
|
||||
|
||||
targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("test filter 1").autoAssignDistributionSet(ds1.getId()).query("name==autoAssignments*"));
|
||||
|
||||
Rollout rollout = testdataFactory.createRolloutByVariables("rollout", "description",
|
||||
1, "name==targets*", ds1, "50", "5", false);
|
||||
rolloutManagement.start(rollout.getId());
|
||||
rolloutHandler.handleAll();
|
||||
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics", ds1.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalAutoAssignments", equalTo(1)))
|
||||
.andExpect(jsonPath("totalActionsPerStatus.RUNNING", equalTo(4)))
|
||||
.andExpect(jsonPath("totalActionsPerStatus.total", equalTo(4)))
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus.RUNNING", equalTo(1)))
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus.total", equalTo(1)));
|
||||
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("totalRolloutsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalActionsPerStatus").doesNotExist())
|
||||
.andExpect(jsonPath("totalAutoAssignments").doesNotExist());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments, stops rollouts and cancels assignments")
|
||||
public void invalidateDistributionSet() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user