Fix portable event on setting confirmation status (#2146)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-12-12 12:37:03 +02:00
committed by GitHub
parent c84fb13609
commit af50e8c938
12 changed files with 180 additions and 200 deletions

View File

@@ -99,7 +99,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void sendDownloadAndInstallStatus() {
final String controllerId = TARGET_PREFIX + "sendDownloadAndInstallStatus";
@@ -119,7 +119,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void sendDownloadStatusBeforeMaintenanceWindowStartTime() {
final String controllerId = TARGET_PREFIX + "sendDownloadStatusBeforeWindowStartTime";
@@ -144,7 +144,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void sendDownloadAndInstallStatusMessageDuringMaintenanceWindow() {
final String controllerId = TARGET_PREFIX + "sendDAndIStatusMessageDuringWindow";
@@ -165,13 +165,13 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 18), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 3) })
void assignDistributionSetMultipleTimes() {
final String controllerId = TARGET_PREFIX + "assignDistributionSetMultipleTimes";
@@ -212,13 +212,13 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = CancelTargetAssignmentEvent.class, count = 0),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 0),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
void assignMultipleDsInMultiAssignMode() {
@@ -290,19 +290,20 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Description("Handle cancelation process of an action in multi assignment mode.")
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
@Expect(type = MultiActionCancelEvent.class, count = 1),
@Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = CancelTargetAssignmentEvent.class, count = 0),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) // implicit lock
})
void cancelActionInMultiAssignMode() {
enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "cancelActionInMultiAssignMode";
@@ -332,13 +333,13 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = CancelTargetAssignmentEvent.class, count = 0),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 3),
@Expect(type = TargetUpdatedEvent.class, count = 3),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
void finishActionInMultiAssignMode() {
@@ -364,13 +365,13 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = CancelTargetAssignmentEvent.class, count = 0),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 0),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
void assignDsMultipleTimesInMultiAssignMode() {
@@ -396,15 +397,15 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@Expect(type = CancelTargetAssignmentEvent.class, count = 0),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = RolloutCreatedEvent.class, count = 2),
@Expect(type = RolloutCreatedEvent.class, count = 2),
@Expect(type = RolloutUpdatedEvent.class, count = 6),
@Expect(type = RolloutGroupCreatedEvent.class, count = 2),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 6),
@@ -432,16 +433,16 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = MultiActionAssignEvent.class, count = 3),
@Expect(type = ActionCreatedEvent.class, count = 3),
@Expect(type = ActionCreatedEvent.class, count = 3),
@Expect(type = ActionUpdatedEvent.class, count = 5),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 5),
@Expect(type = TargetUpdatedEvent.class, count = 5),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TargetAttributesRequestedEvent.class, count = 2),
@Expect(type = RolloutCreatedEvent.class, count = 3),
@Expect(type = RolloutCreatedEvent.class, count = 3),
@Expect(type = RolloutUpdatedEvent.class, count = 9),
@Expect(type = RolloutGroupCreatedEvent.class, count = 3),
@Expect(type = RolloutGroupUpdatedEvent.class, count = 9),
@@ -484,13 +485,13 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = CancelTargetAssignmentEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 2) })
void sendCancelStatus() {
final String controllerId = TARGET_PREFIX + "sendCancelStatus";
@@ -506,7 +507,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Description("Verify that when a target is deleted a target delete message is send.")
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TargetDeletedEvent.class, count = 1) })
void sendDeleteMessage() {
final String controllerId = TARGET_PREFIX + "sendDeleteMessage";
@@ -521,7 +522,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = ActionUpdatedEvent.class, count = 2),
@Expect(type = ActionCreatedEvent.class, count = 2),
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@@ -555,7 +556,7 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 1),
@Expect(type = TargetPollEvent.class, count = 1) })
void downloadOnlyAssignmentSendsDownloadMessageTopic() {
final String controllerId = TARGET_PREFIX + "registerTargets_1";
@@ -633,13 +634,13 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 3),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionCreatedEvent.class, count = 3),
@Expect(type = ActionCreatedEvent.class, count = 3),
@Expect(type = ActionUpdatedEvent.class, count = 0),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = TargetUpdatedEvent.class, count = 3),
@Expect(type = TargetUpdatedEvent.class, count = 3),
@Expect(type = TargetPollEvent.class, count = 3),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
void assertBatchAssignmentsMessagePayload(final EventTopic topic) {

View File

@@ -978,24 +978,25 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr
@Description("Verify the DMF download and install message is send directly if auto-confirmation is active")
@ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
@Expect(type = ActionUpdatedEvent.class, count = 0),
@Expect(type = ActionCreatedEvent.class, count = 1),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 9), // implicit lock
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class, count = 2),
@Expect(type = TargetPollEvent.class, count = 1),
@Expect(type = TenantConfigurationCreatedEvent.class, count = 1) })
@Expect(type = DistributionSetCreatedEvent.class, count = 1), })
void verifyDownloadAndInstallDirectlySendOnAutoConfirmationEnabled() {
enableConfirmationFlow();
final String controllerId = TARGET_PREFIX + "confirmedActionStatus";
registerAndAssertTargetWithExistingTenant(controllerId);
assertThat(targetManagement.getByControllerID(controllerId).map(Target::getAutoConfirmationStatus)).isEmpty();
confirmationManagement.activateAutoConfirmation(controllerId, null, null);
assertThat(targetManagement.getByControllerID(controllerId).map(Target::getAutoConfirmationStatus)).isPresent();
final DistributionSetAssignmentResult assignmentResult = prepareDistributionSetAndAssign(controllerId);
final Long actionId = getFirstAssignedActionId(assignmentResult);

View File

@@ -54,16 +54,19 @@ import org.springframework.test.web.servlet.MvcResult;
*/
@Feature("Component Tests - Management API")
@Story("Distribution Set Type Resource")
public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIntegrationTest {
class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIntegrationTest {
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes GET requests.")
public void getDistributionSetTypes() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key("test123").name("TestName123").description("Desc123").colour("col12"));
testType = distributionSetTypeManagement
.update(entityFactory.distributionSetType().update(testType.getId()).description("Desc1234"));
void getDistributionSetTypes() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(
entityFactory.distributionSetType().create()
.key("test123")
.name("TestName123")
.description("Desc123")
.colour("col12"));
testType = distributionSetTypeManagement.update(entityFactory.distributionSetType().update(testType.getId()).description("Desc1234"));
// 4 types overall (2 hawkbit tenant default, 1 test default and 1
// generated in this test)
@@ -84,8 +87,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
.andExpect(jsonPath("$.content.[?(@.key=='test123')].createdBy", contains("uploadTester")))
.andExpect(jsonPath("$.content.[?(@.key=='test123')].createdAt", contains(testType.getCreatedAt())))
.andExpect(jsonPath("$.content.[?(@.key=='test123')].lastModifiedBy", contains("uploadTester")))
.andExpect(jsonPath("$.content.[?(@.key=='test123')].lastModifiedAt",
contains(testType.getLastModifiedAt())))
.andExpect(jsonPath("$.content.[?(@.key=='test123')].lastModifiedAt", contains(testType.getLastModifiedAt())))
.andExpect(jsonPath("$.content.[?(@.key=='test123')].key", contains("test123")))
.andExpect(jsonPath("$.content.[?(@.key=='test123')]._links.self.href",
contains("http://localhost/rest/v1/distributionsettypes/" + testType.getId())))
@@ -95,15 +97,18 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes GET requests with sorting by KEY.")
public void getDistributionSetTypesSortedByKey() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key("zzzzz").name("TestName123").description("Desc123").colour("col12"));
testType = distributionSetTypeManagement
.update(entityFactory.distributionSetType().update(testType.getId()).description("Desc1234"));
void getDistributionSetTypesSortedByKey() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(
entityFactory.distributionSetType().create()
.key("zzzzz")
.name("TestName123")
.description("Desc123")
.colour("col12"));
testType = distributionSetTypeManagement.update(entityFactory.distributionSetType().update(testType.getId()).description("Desc1234"));
// descending
mvc.perform(get("/rest/v1/distributionsettypes").accept(MediaType.APPLICATION_JSON)
mvc.perform(get("/rest/v1/distributionsettypes")
.accept(MediaType.APPLICATION_JSON)
.param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "KEY:DESC"))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk())
@@ -120,7 +125,8 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
.andExpect(jsonPath("$.total", equalTo(DEFAULT_DS_TYPES + 1)));
// ascending
mvc.perform(get("/rest/v1/distributionsettypes").accept(MediaType.APPLICATION_JSON)
mvc.perform(get("/rest/v1/distributionsettypes")
.accept(MediaType.APPLICATION_JSON)
.param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "KEY:ASC"))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk())
@@ -140,31 +146,30 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes POST requests.")
public void createDistributionSetTypes() throws Exception {
final List<DistributionSetType> types = createTestDistributionSetTestTypes();
final MvcResult mvcResult = runPostDistributionSetType(types);
void createDistributionSetTypes() throws Exception {
final MvcResult mvcResult = runPostDistributionSetType(createTestDistributionSetTestTypes());
verifyCreatedDistributionSetTypes(mvcResult);
}
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes POST requests.")
public void addMandatoryModuleToDistributionSetType() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key("test123").name("TestName123").description("Desc123").colour("col12"));
assertThat(testType.getOptLockRevision()).isEqualTo(version(1));
void addMandatoryModuleToDistributionSetType() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(
entityFactory.distributionSetType().create()
.key("test123")
.name("TestName123")
.description("Desc123")
.colour("col12"));
mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType.getId())
.content("{\"id\":" + osType.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.contentType(MediaType.APPLICATION_JSON)
.content("{\"id\":" + osType.getId() + "}"))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
testType = distributionSetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo("uploadTester");
assertThat(testType.getOptLockRevision()).isEqualTo(version(2));
assertThat(testType.getMandatoryModuleTypes()).containsExactly(osType);
assertThat(testType.getOptionalModuleTypes()).isEmpty();
}
@@ -172,28 +177,30 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes POST requests.")
public void addOptionalModuleToDistributionSetType() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key("test123").name("TestName123").description("Desc123").colour("col12"));
assertThat(testType.getOptLockRevision()).isEqualTo(version(1));
void addOptionalModuleToDistributionSetType() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(
entityFactory.distributionSetType().create()
.key("test123")
.name("TestName123")
.description("Desc123")
.colour("col12"));
mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId())
.content("{\"id\":" + osType.getId() + "}").contentType(MediaType.APPLICATION_JSON))
.contentType(MediaType.APPLICATION_JSON)
.content("{\"id\":" + osType.getId() + "}"))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
testType = distributionSetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo("uploadTester");
assertThat(testType.getOptLockRevision()).isEqualTo(version(2));
assertThat(testType.getOptionalModuleTypes()).containsExactly(osType);
assertThat(testType.getMandatoryModuleTypes()).isEmpty();
}
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Verifies quota enforcement for /rest/v1/distributionsettypes/{ID}/optionalmoduletypes POST requests.")
public void assignModuleTypesToDistributionSetTypeUntilQuotaExceeded() throws Exception {
void assignModuleTypesToDistributionSetTypeUntilQuotaExceeded() throws Exception {
// create software module types
final int maxSoftwareModuleTypes = quotaManagement.getMaxSoftwareModuleTypesPerDistributionSetType();
final List<Long> moduleTypeIds = new ArrayList<>();
@@ -249,7 +256,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes GET requests.")
public void getMandatoryModulesOfDistributionSetType() throws Exception {
void getMandatoryModulesOfDistributionSetType() throws Exception {
final DistributionSetType testType = generateTestType();
mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType.getId())
@@ -266,7 +273,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes GET requests.")
public void getOptionalModulesOfDistributionSetType() throws Exception {
void getOptionalModulesOfDistributionSetType() throws Exception {
final DistributionSetType testType = generateTestType();
mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId())
@@ -283,7 +290,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes/{ID} GET requests.")
public void getMandatoryModuleOfDistributionSetType() throws Exception {
void getMandatoryModuleOfDistributionSetType() throws Exception {
final DistributionSetType testType = generateTestType();
mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes/{smtId}", testType.getId(),
@@ -302,7 +309,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes/{ID} GET requests.")
public void getOptionalModuleOfDistributionSetType() throws Exception {
void getOptionalModuleOfDistributionSetType() throws Exception {
final DistributionSetType testType = generateTestType();
mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes/{smtId}", testType.getId(),
@@ -321,7 +328,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes/{ID} DELETE requests.")
public void removeMandatoryModuleToDistributionSetType() throws Exception {
void removeMandatoryModuleToDistributionSetType() throws Exception {
DistributionSetType testType = generateTestType();
mvc.perform(delete("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes/{smtId}", testType.getId(),
@@ -331,7 +338,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
testType = distributionSetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo("uploadTester");
assertThat(testType.getOptLockRevision()).isEqualTo(version(2));
assertThat(testType.getOptionalModuleTypes()).containsExactly(appType);
assertThat(testType.getMandatoryModuleTypes()).isEmpty();
}
@@ -339,7 +345,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes/{ID} DELETE requests.")
public void removeOptionalModuleToDistributionSetType() throws Exception {
void removeOptionalModuleToDistributionSetType() throws Exception {
DistributionSetType testType = generateTestType();
mvc.perform(delete("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes/{smtId}", testType.getId(),
@@ -349,7 +355,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
testType = distributionSetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo("uploadTester");
assertThat(testType.getOptLockRevision()).isEqualTo(version(2));
assertThat(testType.getOptionalModuleTypes()).isEmpty();
assertThat(testType.getMandatoryModuleTypes()).containsExactly(osType);
}
@@ -357,7 +362,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID} GET requests.")
public void getDistributionSetType() throws Exception {
void getDistributionSetType() throws Exception {
DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key("test123").name("TestName123").description("Desc123"));
testType = distributionSetTypeManagement
@@ -378,7 +383,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Handles the GET request of retrieving all distribution set types within SP based on parameter.")
public void getDistributionSetTypesWithParameter() throws Exception {
void getDistributionSetTypesWithParameter() throws Exception {
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING
+ "?limit=10&sort=name:ASC&offset=0&q=name==a"))
.andDo(MockMvcResultPrinter.print())
@@ -388,7 +393,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/DistributionSetTypes/{ID} DELETE requests (hard delete scenario).")
public void deleteDistributionSetTypeUnused() throws Exception {
void deleteDistributionSetTypeUnused() throws Exception {
final DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType()
.create().key("test123").name("TestName123").description("Desc123").colour("col12"));
@@ -403,7 +408,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Ensures that DS type deletion request to API on an entity that does not exist results in NOT_FOUND.")
public void deleteDistributionSetTypeThatDoesNotExistLeadsToNotFound() throws Exception {
void deleteDistributionSetTypeThatDoesNotExistLeadsToNotFound() throws Exception {
mvc.perform(delete("/rest/v1/distributionsettypes/1234"))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isNotFound());
@@ -412,7 +417,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/DistributionSetTypes/{ID} DELETE requests (soft delete scenario).")
public void deleteDistributionSetTypeUsed() throws Exception {
void deleteDistributionSetTypeUsed() throws Exception {
final DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType()
.create().key("test123").name("TestName123").description("Desc123").colour("col12"));
@@ -442,7 +447,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID} PUT requests.")
public void updateDistributionSetTypeColourDescriptionAndNameUntouched() throws Exception {
void updateDistributionSetTypeColourDescriptionAndNameUntouched() throws Exception {
final DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType()
.create().key("test123").name("TestName123").description("Desc123").colour("col"));
@@ -463,7 +468,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Handles the PUT request for a single distribution set type within SP.")
public void updateDistributionSetTypeDescriptionAndColor() throws Exception {
void updateDistributionSetTypeDescriptionAndColor() throws Exception {
final DistributionSetType testType = distributionSetTypeManagement.update(entityFactory.distributionSetType()
.update(testdataFactory.createDistributionSet().getType().getId()).description("Desc1234"));
final String body = new JSONObject()
@@ -479,7 +484,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Tests the update of the deletion flag. It is verfied that the distribution set type can't be marked as deleted through update operation.")
public void updateDistributionSetTypeDeletedFlag() throws Exception {
void updateDistributionSetTypeDeletedFlag() throws Exception {
final DistributionSetType testType = distributionSetTypeManagement
.create(entityFactory.distributionSetType().create().key("test123").name("TestName123").colour("col"));
@@ -495,7 +500,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes GET requests with paging.")
public void getDistributionSetTypesWithoutAddtionalRequestParameters() throws Exception {
void getDistributionSetTypesWithoutAddtionalRequestParameters() throws Exception {
// 4 types overall (3 hawkbit tenant default, 1 test default
final int types = 4;
@@ -509,7 +514,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes GET requests with paging.")
public void getDistributionSetTypesWithPagingLimitRequestParameter() throws Exception {
void getDistributionSetTypesWithPagingLimitRequestParameter() throws Exception {
final int types = DEFAULT_DS_TYPES;
final int limitSize = 1;
@@ -524,7 +529,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes GET requests with paging.")
public void getDistributionSetTypesWithPagingLimitAndOffsetRequestParameter() throws Exception {
void getDistributionSetTypesWithPagingLimitAndOffsetRequestParameter() throws Exception {
final int types = DEFAULT_DS_TYPES;
final int offsetParam = 2;
final int expectedSize = types - offsetParam;
@@ -540,7 +545,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Ensures that the server is behaving as expected on invalid requests (wrong media type, wrong ID etc.).")
public void invalidRequestsOnDistributionSetTypesResource() throws Exception {
void invalidRequestsOnDistributionSetTypesResource() throws Exception {
final SoftwareModuleType testSmType = softwareModuleTypeManagement
.create(entityFactory.softwareModuleType().create().key("test123").name("TestName123"));
@@ -651,7 +656,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
@Test
@Description("Search erquest of software module types.")
public void searchDistributionSetTypeRsql() throws Exception {
void searchDistributionSetTypeRsql() throws Exception {
distributionSetTypeManagement
.create(entityFactory.distributionSetType().create().key("test123").name("TestName123"));
distributionSetTypeManagement

View File

@@ -41,21 +41,18 @@ public interface ConfirmationManagement {
* confirmation is active already, this method will fail with an exception.
*
* @param controllerId to activate the feature for
* @param initiator who initiated this operation. If 'null' we will take the current
* user from {@link TenantAware#getCurrentUsername()}
* @param initiator who initiated this operation. If 'null' we will take the current user from {@link TenantAware#getCurrentUsername()}
* @param remark optional field to set a remark
* @return the persisted {@link AutoConfirmationStatus}
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
AutoConfirmationStatus activateAutoConfirmation(@NotEmpty String controllerId, final String initiator,
final String remark);
AutoConfirmationStatus activateAutoConfirmation(@NotEmpty String controllerId, final String initiator, final String remark);
/**
* Get the current state of auto-confirmation for a given controllerId
*
* @param controllerId to check the state for
* @return instance of {@link AutoConfirmationStatus} wrapped in an
* {@link Optional}. Present if active and empty if disabled.
* @return instance of {@link AutoConfirmationStatus} wrapped in an {@link Optional}. Present if active and empty if disabled.
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.IS_CONTROLLER + SpPermission.SpringEvalExpressions.HAS_AUTH_OR +
SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)

View File

@@ -79,8 +79,7 @@ public interface DeploymentManagement {
* target and multiassignment is disabled
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> assignDistributionSets(
@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
List<DistributionSetAssignmentResult> assignDistributionSets(@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
/**
* Assigns {@link DistributionSet}s to {@link Target}s according to the

View File

@@ -31,18 +31,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
public interface DistributionSetTypeManagement
extends RepositoryManagement<DistributionSetType, DistributionSetTypeCreate, DistributionSetTypeUpdate> {
/**
* @param key as {@link DistributionSetType#getKey()}
* @return {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetType> getByKey(@NotEmpty String key);
/**
* @param name as {@link DistributionSetType#getName()}
* @return {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetType> getByName(@NotEmpty String name);
@@ -52,12 +43,10 @@ public interface DistributionSetTypeManagement
* @param id to update
* @param softwareModuleTypeIds to assign
* @return updated {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of
* the {@link SoftwareModuleType}s do not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of the {@link SoftwareModuleType}s do not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use by a {@link DistributionSet}
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is exceeded for the addressed
* {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignOptionalSoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
@@ -68,28 +57,24 @@ public interface DistributionSetTypeManagement
* @param id to update
* @param softwareModuleTypeIds to assign
* @return updated {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of
* the {@link SoftwareModuleType}s do not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of the {@link SoftwareModuleType}s do not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use by a {@link DistributionSet}
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is exceeded for the addressed
* {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignMandatorySoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
/**
* Unassigns a {@link SoftwareModuleType} from the
* {@link DistributionSetType}. Does nothing if {@link SoftwareModuleType}
* Unassigns a {@link SoftwareModuleType} from the {@link DistributionSetType}. Does nothing if {@link SoftwareModuleType}
* has not been assigned in the first place.
*
* @param id to update
* @param softwareModuleTypeId to unassign
* @return updated {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} does not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use
* by a {@link DistributionSet}
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use by a {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType unassignSoftwareModuleType(long id, long softwareModuleTypeId);
}
}

View File

@@ -15,6 +15,8 @@ import java.util.Optional;
import jakarta.persistence.EntityManager;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity;
import org.eclipse.hawkbit.repository.jpa.repository.NoCountSliceRepository;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
@@ -32,13 +34,12 @@ import org.springframework.util.StringUtils;
/**
* A collection of static helper methods for the management classes
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class JpaManagementHelper {
private JpaManagementHelper() {
}
public static <T, J extends T> Optional<J> findOneBySpec(final JpaSpecificationExecutor<J> repository,
final List<Specification<J>> specList) {
public static <T, J extends T> Optional<J> findOneBySpec(
final JpaSpecificationExecutor<J> repository, final List<Specification<J>> specList) {
return repository.findOne(combineWithAnd(specList));
}
@@ -84,8 +85,8 @@ public final class JpaManagementHelper {
return repository.count(combineWithAnd(specList));
}
public static <J extends AbstractJpaBaseEntity> J touch(final EntityManager entityManager,
final CrudRepository<J, ?> repository, final J entity) {
public static <J extends AbstractJpaBaseEntity> J touch(
final EntityManager entityManager, final CrudRepository<J, ?> repository, final J entity) {
// merge base entity so optLockRevision gets updated and audit
// log written because modifying e.g. metadata is modifying the base
// entity itself for auditing purposes.

View File

@@ -835,9 +835,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
ConfirmationManagement confirmationManagement(final TargetRepository targetRepository,
final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository,
final RepositoryProperties repositoryProperties, final QuotaManagement quotaManagement,
final EntityFactory entityFactory) {
final EntityManager entityManager, final EntityFactory entityFactory) {
return new JpaConfirmationManagement(targetRepository, actionRepository, actionStatusRepository,
repositoryProperties, quotaManagement, entityFactory);
repositoryProperties, quotaManagement, entityManager, entityFactory);
}
/**

View File

@@ -16,6 +16,8 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import jakarta.persistence.EntityManager;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.ConfirmationManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
@@ -25,6 +27,7 @@ import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.exception.AutoConfirmationAlreadyActiveException;
import org.eclipse.hawkbit.repository.exception.InvalidConfirmationFeedbackException;
import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusCreate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -56,6 +59,7 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
public static final String CONFIRMATION_CODE_MSG_PREFIX = "Confirmation status code: %d";
private final EntityManager entityManager;
private final EntityFactory entityFactory;
private final TargetRepository targetRepository;
@@ -63,9 +67,10 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
final TargetRepository targetRepository,
final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository,
final RepositoryProperties repositoryProperties, final QuotaManagement quotaManagement,
final EntityFactory entityFactory) {
final EntityManager entityManager, final EntityFactory entityFactory) {
super(actionRepository, actionStatusRepository, quotaManagement, repositoryProperties);
this.targetRepository = targetRepository;
this.entityManager = entityManager;
this.entityFactory = entityFactory;
}
@@ -86,6 +91,8 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
}
final JpaAutoConfirmationStatus confirmationStatus = new JpaAutoConfirmationStatus(initiator, remark, target);
target.setAutoConfirmationStatus(confirmationStatus);
// since the status is not part of the JpaTarget table (just ref) it might be needed to touch the entity to have updated lastModifiedAt
JpaManagementHelper.touch(entityManager, targetRepository, target);
final JpaTarget updatedTarget = targetRepository.save(target);
final AutoConfirmationStatus autoConfStatus = updatedTarget.getAutoConfirmationStatus();
if (autoConfStatus == null) {
@@ -159,6 +166,8 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
log.debug("Deactivate auto confirmation for controllerId '{}'", controllerId);
final JpaTarget target = targetRepository.getByControllerId(controllerId);
target.setAutoConfirmationStatus(null);
// since the status is not part of the JpaTarget table (just ref) it might be needed to touch the entity to have updated lastModifiedAt
JpaManagementHelper.touch(entityManager, targetRepository, target);
targetRepository.save(target);
}

View File

@@ -740,8 +740,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
final Long dsId, final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) {
final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback =
retryContext -> assignDistributionSetToTargets(
initiatedBy, dsId, targetsWithActionType, actionMessage, assignmentStrategy);
retryContext -> assignDistributionSetToTargets(initiatedBy, dsId, targetsWithActionType, actionMessage, assignmentStrategy);
return retryTemplate.execute(retryCallback);
}
@@ -764,10 +763,11 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
* @param actionMessage an optional message to be written into the action status
* @param assignmentStrategy the assignment strategy (online /offline)
* @return the assignment result
* @throws IncompleteDistributionSetException if mandatory {@link SoftwareModuleType} are not assigned as
* define by the {@link DistributionSetType}.
* @throws IncompleteDistributionSetException if mandatory {@link SoftwareModuleType} are not assigned as define by the
* {@link DistributionSetType}.
*/
private DistributionSetAssignmentResult assignDistributionSetToTargets(final String initiatedBy, final Long dsId,
private DistributionSetAssignmentResult assignDistributionSetToTargets(
final String initiatedBy, final Long dsId,
final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) {
final JpaDistributionSet distributionSet = (JpaDistributionSet) distributionSetManagement.getValidAndComplete(dsId);
@@ -780,28 +780,28 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
});
}
final List<String> providedTargetIds = targetsWithActionType.stream().map(TargetWithActionType::getControllerId)
.distinct().toList();
final List<String> providedTargetIds = targetsWithActionType.stream()
.map(TargetWithActionType::getControllerId)
.distinct()
.toList();
final List<String> existingTargetIds = ListUtils.partition(providedTargetIds, Constants.MAX_ENTRIES_IN_STATEMENT)
.stream()
.map(ids -> targetRepository.findAll(AccessController.Operation.UPDATE,
TargetSpecifications.hasControllerIdIn(ids)))
.flatMap(List::stream).map(JpaTarget::getControllerId).toList();
final List<JpaTarget> targetEntities = assignmentStrategy.findTargetsForAssignment(existingTargetIds,
distributionSet.getId());
.map(ids -> targetRepository.findAll(AccessController.Operation.UPDATE, TargetSpecifications.hasControllerIdIn(ids)))
.flatMap(List::stream).map(JpaTarget::getControllerId)
.toList();
final List<JpaTarget> targetEntities = assignmentStrategy.findTargetsForAssignment(existingTargetIds, distributionSet.getId());
if (targetEntities.isEmpty()) {
return allTargetsAlreadyAssignedResult(distributionSet, existingTargetIds.size());
}
final List<TargetWithActionType> existingTargetsWithActionType = targetsWithActionType.stream()
.filter(target -> existingTargetIds.contains(target.getControllerId())).toList();
.filter(target -> existingTargetIds.contains(target.getControllerId()))
.toList();
final List<JpaAction> assignedActions = doAssignDistributionSetToTargets(initiatedBy,
existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSet,
targetEntities);
final List<JpaAction> assignedActions = doAssignDistributionSetToTargets(
initiatedBy, existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSet, targetEntities);
return buildAssignmentResult(distributionSet, assignedActions, existingTargetsWithActionType.size());
}
@@ -824,17 +824,14 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
closeOrCancelActiveActions(assignmentStrategy, targetEntitiesIdsChunks);
}
// cancel all scheduled actions which are in-active, these actions were
// not active before and the manual assignment which has been done
// cancels them
// not active before and the manual assignment which has been done cancels them
targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets);
setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity,
targetEntitiesIdsChunks);
final Map<TargetWithActionType, JpaAction> assignedActions = createActions(initiatedBy, targetsWithActionType,
targetEntities, assignmentStrategy, distributionSetEntity);
// create initial action status when action is created so we remember
setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity, targetEntitiesIdsChunks);
final Map<TargetWithActionType, JpaAction> assignedActions = createActions(
targetsWithActionType, targetEntities, distributionSetEntity, assignmentStrategy, initiatedBy);
// create initial action status when action is created, so we remember
// the initial running status because we will change the status
// of the action itself and with this action status we have a nicer
// action history.
// of the action itself and with this action status we have a nicer action history.
createActionsStatus(assignedActions, assignmentStrategy, actionMessage);
detachEntitiesAndSendTargetUpdatedEvents(distributionSetEntity, targetEntities, assignmentStrategy);
@@ -872,12 +869,10 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
assignmentStrategy.setAssignedDistributionSetAndTargetStatus(set, targetIdsChunks, currentUser);
}
private Map<TargetWithActionType, JpaAction> createActions(final String initiatedBy,
final Collection<TargetWithActionType> targetsWithActionType, final List<JpaTarget> targets,
final AbstractDsAssignmentStrategy assignmentStrategy, final JpaDistributionSet set) {
private Map<TargetWithActionType, JpaAction> createActions(
final Collection<TargetWithActionType> targetsWithActionType, final List<JpaTarget> targets, final JpaDistributionSet set,
final AbstractDsAssignmentStrategy assignmentStrategy, final String initiatedBy) {
final Map<TargetWithActionType, JpaAction> persistedActions = new LinkedHashMap<>();
for (final TargetWithActionType twt : targetsWithActionType) {
final JpaAction targetAction = assignmentStrategy.createTargetAction(initiatedBy, twt, targets, set);
if (targetAction != null) {
@@ -887,7 +882,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
return persistedActions;
}
private void createActionsStatus(final Map<TargetWithActionType, JpaAction> actions,
private void createActionsStatus(
final Map<TargetWithActionType, JpaAction> actions,
final AbstractDsAssignmentStrategy assignmentStrategy, final String actionMessage) {
actionStatusRepository.saveAll(actions.entrySet().stream().map(entry -> {
final JpaAction action = entry.getValue();

View File

@@ -88,22 +88,19 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
@Override
public Optional<DistributionSetType> getByKey(final String key) {
return distributionSetTypeRepository
.findOne(DistributionSetTypeSpecification.byKey(key)).map(DistributionSetType.class::cast);
return distributionSetTypeRepository.findOne(DistributionSetTypeSpecification.byKey(key)).map(DistributionSetType.class::cast);
}
@Override
public Optional<DistributionSetType> getByName(final String name) {
return distributionSetTypeRepository
.findOne(DistributionSetTypeSpecification.byName(name)).map(DistributionSetType.class::cast);
return distributionSetTypeRepository.findOne(DistributionSetTypeSpecification.byName(name)).map(DistributionSetType.class::cast);
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public DistributionSetType assignOptionalSoftwareModuleTypes(final long id,
final Collection<Long> softwareModulesTypeIds) {
public DistributionSetType assignOptionalSoftwareModuleTypes(final long id, final Collection<Long> softwareModulesTypeIds) {
return assignSoftwareModuleTypes(id, softwareModulesTypeIds, false);
}
@@ -111,8 +108,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public DistributionSetType assignMandatorySoftwareModuleTypes(final long id,
final Collection<Long> softwareModuleTypeIds) {
public DistributionSetType assignMandatorySoftwareModuleTypes(final long id, final Collection<Long> softwareModuleTypeIds) {
return assignSoftwareModuleTypes(id, softwareModuleTypeIds, true);
}
@@ -122,11 +118,8 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public DistributionSetType unassignSoftwareModuleType(final long id, final long softwareModuleTypeId) {
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(id);
checkDistributionSetTypeNotAssigned(id);
type.removeModuleType(softwareModuleTypeId);
return distributionSetTypeRepository.save(type);
}
@@ -135,9 +128,9 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<DistributionSetType> create(final Collection<DistributionSetTypeCreate> types) {
final List<JpaDistributionSetType> typesToCreate = types.stream().map(JpaDistributionSetTypeCreate.class::cast)
final List<JpaDistributionSetType> typesToCreate = types.stream()
.map(JpaDistributionSetTypeCreate.class::cast)
.map(JpaDistributionSetTypeCreate::build).toList();
return Collections.unmodifiableList(
distributionSetTypeRepository.saveAll(AccessController.Operation.CREATE, typesToCreate));
}
@@ -148,7 +141,6 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public DistributionSetType create(final DistributionSetTypeCreate c) {
final JpaDistributionSetType distributionSetType = ((JpaDistributionSetTypeCreate) c).build();
return distributionSetTypeRepository.save(AccessController.Operation.CREATE, distributionSetType);
}
@@ -158,9 +150,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public DistributionSetType update(final DistributionSetTypeUpdate u) {
final GenericDistributionSetTypeUpdate update = (GenericDistributionSetTypeUpdate) u;
final JpaDistributionSetType type = findDistributionSetTypeAndThrowExceptionIfNotFound(update.getId());
update.getDescription().ifPresent(type::setDescription);
update.getColour().ifPresent(type::setColour);
@@ -245,13 +235,12 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
@Override
public Page<DistributionSetType> findByRsql(final Pageable pageable, final String rsqlParam) {
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTypeRepository, pageable, List.of(
RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetTypeFields.class, virtualPropertyReplacer,
database),
RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetTypeFields.class, virtualPropertyReplacer, database),
DistributionSetTypeSpecification.isNotDeleted()));
}
private static void removeModuleTypes(final Collection<Long> currentSmTypeIds,
final Collection<Long> updatedSmTypeIds,
private static void removeModuleTypes(
final Collection<Long> currentSmTypeIds, final Collection<Long> updatedSmTypeIds,
final LongFunction<JpaDistributionSetType> removeModuleTypeCallback) {
final Set<Long> smTypeIdsToRemove = currentSmTypeIds.stream().filter(id -> !updatedSmTypeIds.contains(id))
.collect(Collectors.toSet());
@@ -264,10 +253,10 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
return update.getOptional().isPresent() || update.getMandatory().isPresent();
}
private void addModuleTypes(final Collection<Long> currentSmTypeIds, final Collection<Long> updatedSmTypeIds,
private void addModuleTypes(
final Collection<Long> currentSmTypeIds, final Collection<Long> updatedSmTypeIds,
final Function<SoftwareModuleType, JpaDistributionSetType> addModuleTypeCallback) {
final Set<Long> smTypeIdsToAdd = updatedSmTypeIds.stream().filter(id -> !currentSmTypeIds.contains(id))
.collect(Collectors.toSet());
final Set<Long> smTypeIdsToAdd = updatedSmTypeIds.stream().filter(id -> !currentSmTypeIds.contains(id)).collect(Collectors.toSet());
if (!CollectionUtils.isEmpty(smTypeIdsToAdd)) {
softwareModuleTypeRepository.findAllById(smTypeIdsToAdd).forEach(addModuleTypeCallback::apply);
}
@@ -275,8 +264,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
private DistributionSetType assignSoftwareModuleTypes(
final long dsTypeId, final Collection<Long> softwareModulesTypeIds, final boolean mandatory) {
final Collection<JpaSoftwareModuleType> foundModules =
softwareModuleTypeRepository.findAllById(softwareModulesTypeIds);
final Collection<JpaSoftwareModuleType> foundModules = softwareModuleTypeRepository.findAllById(softwareModulesTypeIds);
if (foundModules.size() < softwareModulesTypeIds.size()) {
throw new EntityNotFoundException(
SoftwareModuleType.class, softwareModulesTypeIds, foundModules.stream().map(SoftwareModuleType::getId).toList());
@@ -315,8 +303,7 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
}
private JpaDistributionSetType findDistributionSetTypeAndThrowExceptionIfNotFound(final Long setId) {
return (JpaDistributionSetType) get(setId)
.orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, setId));
return (JpaDistributionSetType) get(setId).orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, setId));
}
private void checkDistributionSetTypeNotAssigned(final Long id) {
@@ -325,4 +312,4 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
"Distribution set type %s is already assigned to distribution sets and cannot be changed!", id));
}
}
}
}

View File

@@ -315,7 +315,8 @@ public abstract class AbstractIntegrationTest {
return assignDistributionSet(dsID, controllerIds, actionType, forcedTime, null);
}
protected DistributionSetAssignmentResult assignDistributionSet(final long dsID, final List<String> controllerIds,
protected DistributionSetAssignmentResult assignDistributionSet(
final long dsID, final List<String> controllerIds,
final ActionType actionType, final long forcedTime, final Integer weight) {
final boolean confirmationFlowActive = isConfirmationFlowActive();
@@ -323,16 +324,14 @@ public abstract class AbstractIntegrationTest {
.map(id -> DeploymentManagement.deploymentRequest(id, dsID).setActionType(actionType)
.setForceTime(forcedTime).setWeight(weight).setConfirmationRequired(confirmationFlowActive)
.build())
.collect(Collectors.toList());
final List<DistributionSetAssignmentResult> results = deploymentManagement
.assignDistributionSets(deploymentRequests);
.toList();
final List<DistributionSetAssignmentResult> results = deploymentManagement.assignDistributionSets(deploymentRequests);
assertThat(results).hasSize(1);
return results.get(0);
}
protected List<DistributionSetAssignmentResult> assignDistributionSets(final List<DeploymentRequest> requests) {
final List<DistributionSetAssignmentResult> distributionSetAssignmentResults = deploymentManagement
.assignDistributionSets(requests);
final List<DistributionSetAssignmentResult> distributionSetAssignmentResults = deploymentManagement.assignDistributionSets(requests);
assertThat(distributionSetAssignmentResults).hasSize(requests.size());
return distributionSetAssignmentResults;
}