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

@@ -290,6 +290,9 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Description("Handle cancelation process of an action in multi assignment mode.") @Description("Handle cancelation process of an action in multi assignment mode.")
@ExpectEvents({ @ExpectEvents({
@Expect(type = TargetCreatedEvent.class, count = 1), @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 = MultiActionCancelEvent.class, count = 1),
@Expect(type = MultiActionAssignEvent.class, count = 2), @Expect(type = MultiActionAssignEvent.class, count = 2),
@Expect(type = TargetAssignDistributionSetEvent.class, count = 0), @Expect(type = TargetAssignDistributionSetEvent.class, count = 0),
@@ -299,10 +302,8 @@ class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpServiceInt
@Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = DistributionSetCreatedEvent.class, count = 2),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6),
@Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock
@Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // 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) })
void cancelActionInMultiAssignMode() { void cancelActionInMultiAssignMode() {
enableMultiAssignments(); enableMultiAssignments();
final String controllerId = TARGET_PREFIX + "cancelActionInMultiAssignMode"; final String controllerId = TARGET_PREFIX + "cancelActionInMultiAssignMode";

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

View File

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

View File

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

View File

@@ -79,8 +79,7 @@ public interface DeploymentManagement {
* target and multiassignment is disabled * target and multiassignment is disabled
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
List<DistributionSetAssignmentResult> assignDistributionSets( List<DistributionSetAssignmentResult> assignDistributionSets(@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
@Valid @NotEmpty List<DeploymentRequest> deploymentRequests);
/** /**
* Assigns {@link DistributionSet}s to {@link Target}s according to the * 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 public interface DistributionSetTypeManagement
extends RepositoryManagement<DistributionSetType, DistributionSetTypeCreate, DistributionSetTypeUpdate> { extends RepositoryManagement<DistributionSetType, DistributionSetTypeCreate, DistributionSetTypeUpdate> {
/**
* @param key as {@link DistributionSetType#getKey()}
* @return {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetType> getByKey(@NotEmpty String key); Optional<DistributionSetType> getByKey(@NotEmpty String key);
/**
* @param name as {@link DistributionSetType#getName()}
* @return {@link DistributionSetType}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Optional<DistributionSetType> getByName(@NotEmpty String name); Optional<DistributionSetType> getByName(@NotEmpty String name);
@@ -52,12 +43,10 @@ public interface DistributionSetTypeManagement
* @param id to update * @param id to update
* @param softwareModuleTypeIds to assign * @param softwareModuleTypeIds to assign
* @return updated {@link DistributionSetType} * @return updated {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of * @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of the {@link SoftwareModuleType}s do not exist
* the {@link SoftwareModuleType}s do 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 * @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is exceeded for the addressed
* by a {@link DistributionSet} * {@link DistributionSetType}
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignOptionalSoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds); DistributionSetType assignOptionalSoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
@@ -68,27 +57,23 @@ public interface DistributionSetTypeManagement
* @param id to update * @param id to update
* @param softwareModuleTypeIds to assign * @param softwareModuleTypeIds to assign
* @return updated {@link DistributionSetType} * @return updated {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of * @throws EntityNotFoundException in case the {@link DistributionSetType} or at least one of the {@link SoftwareModuleType}s do not exist
* the {@link SoftwareModuleType}s do 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 * @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is exceeded for the addressed
* by a {@link DistributionSet} * {@link DistributionSetType}
* @throws AssignmentQuotaExceededException if the maximum number of {@link SoftwareModuleType}s is
* exceeded for the addressed {@link DistributionSetType}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType assignMandatorySoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds); DistributionSetType assignMandatorySoftwareModuleTypes(long id, @NotEmpty Collection<Long> softwareModuleTypeIds);
/** /**
* Unassigns a {@link SoftwareModuleType} from the * Unassigns a {@link SoftwareModuleType} from the {@link DistributionSetType}. Does nothing if {@link SoftwareModuleType}
* {@link DistributionSetType}. Does nothing if {@link SoftwareModuleType}
* has not been assigned in the first place. * has not been assigned in the first place.
* *
* @param id to update * @param id to update
* @param softwareModuleTypeId to unassign * @param softwareModuleTypeId to unassign
* @return updated {@link DistributionSetType} * @return updated {@link DistributionSetType}
* @throws EntityNotFoundException in case the {@link DistributionSetType} does not exist * @throws EntityNotFoundException in case the {@link DistributionSetType} does not exist
* @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use * @throws EntityReadOnlyException if the {@link DistributionSetType} while it is already in use by a {@link DistributionSet}
* by a {@link DistributionSet}
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
DistributionSetType unassignSoftwareModuleType(long id, long softwareModuleTypeId); DistributionSetType unassignSoftwareModuleType(long id, long softwareModuleTypeId);

View File

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

View File

@@ -835,9 +835,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
ConfirmationManagement confirmationManagement(final TargetRepository targetRepository, ConfirmationManagement confirmationManagement(final TargetRepository targetRepository,
final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository, final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository,
final RepositoryProperties repositoryProperties, final QuotaManagement quotaManagement, final RepositoryProperties repositoryProperties, final QuotaManagement quotaManagement,
final EntityFactory entityFactory) { final EntityManager entityManager, final EntityFactory entityFactory) {
return new JpaConfirmationManagement(targetRepository, actionRepository, actionStatusRepository, 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.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.persistence.EntityManager;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.ConfirmationManagement; import org.eclipse.hawkbit.repository.ConfirmationManagement;
import org.eclipse.hawkbit.repository.EntityFactory; 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.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.exception.AutoConfirmationAlreadyActiveException; import org.eclipse.hawkbit.repository.exception.AutoConfirmationAlreadyActiveException;
import org.eclipse.hawkbit.repository.exception.InvalidConfirmationFeedbackException; 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.builder.JpaActionStatusCreate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction; 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"; public static final String CONFIRMATION_CODE_MSG_PREFIX = "Confirmation status code: %d";
private final EntityManager entityManager;
private final EntityFactory entityFactory; private final EntityFactory entityFactory;
private final TargetRepository targetRepository; private final TargetRepository targetRepository;
@@ -63,9 +67,10 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
final TargetRepository targetRepository, final TargetRepository targetRepository,
final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository, final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository,
final RepositoryProperties repositoryProperties, final QuotaManagement quotaManagement, final RepositoryProperties repositoryProperties, final QuotaManagement quotaManagement,
final EntityFactory entityFactory) { final EntityManager entityManager, final EntityFactory entityFactory) {
super(actionRepository, actionStatusRepository, quotaManagement, repositoryProperties); super(actionRepository, actionStatusRepository, quotaManagement, repositoryProperties);
this.targetRepository = targetRepository; this.targetRepository = targetRepository;
this.entityManager = entityManager;
this.entityFactory = entityFactory; this.entityFactory = entityFactory;
} }
@@ -86,6 +91,8 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
} }
final JpaAutoConfirmationStatus confirmationStatus = new JpaAutoConfirmationStatus(initiator, remark, target); final JpaAutoConfirmationStatus confirmationStatus = new JpaAutoConfirmationStatus(initiator, remark, target);
target.setAutoConfirmationStatus(confirmationStatus); 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 JpaTarget updatedTarget = targetRepository.save(target);
final AutoConfirmationStatus autoConfStatus = updatedTarget.getAutoConfirmationStatus(); final AutoConfirmationStatus autoConfStatus = updatedTarget.getAutoConfirmationStatus();
if (autoConfStatus == null) { if (autoConfStatus == null) {
@@ -159,6 +166,8 @@ public class JpaConfirmationManagement extends JpaActionManagement implements Co
log.debug("Deactivate auto confirmation for controllerId '{}'", controllerId); log.debug("Deactivate auto confirmation for controllerId '{}'", controllerId);
final JpaTarget target = targetRepository.getByControllerId(controllerId); final JpaTarget target = targetRepository.getByControllerId(controllerId);
target.setAutoConfirmationStatus(null); 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); 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 Long dsId, final Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) { final AbstractDsAssignmentStrategy assignmentStrategy) {
final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback = final RetryCallback<DistributionSetAssignmentResult, ConcurrencyFailureException> retryCallback =
retryContext -> assignDistributionSetToTargets( retryContext -> assignDistributionSetToTargets(initiatedBy, dsId, targetsWithActionType, actionMessage, assignmentStrategy);
initiatedBy, dsId, targetsWithActionType, actionMessage, assignmentStrategy);
return retryTemplate.execute(retryCallback); 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 actionMessage an optional message to be written into the action status
* @param assignmentStrategy the assignment strategy (online /offline) * @param assignmentStrategy the assignment strategy (online /offline)
* @return the assignment result * @return the assignment result
* @throws IncompleteDistributionSetException if mandatory {@link SoftwareModuleType} are not assigned as * @throws IncompleteDistributionSetException if mandatory {@link SoftwareModuleType} are not assigned as define by the
* define by the {@link DistributionSetType}. * {@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 Collection<TargetWithActionType> targetsWithActionType, final String actionMessage,
final AbstractDsAssignmentStrategy assignmentStrategy) { final AbstractDsAssignmentStrategy assignmentStrategy) {
final JpaDistributionSet distributionSet = (JpaDistributionSet) distributionSetManagement.getValidAndComplete(dsId); 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) final List<String> providedTargetIds = targetsWithActionType.stream()
.distinct().toList(); .map(TargetWithActionType::getControllerId)
.distinct()
.toList();
final List<String> existingTargetIds = ListUtils.partition(providedTargetIds, Constants.MAX_ENTRIES_IN_STATEMENT) final List<String> existingTargetIds = ListUtils.partition(providedTargetIds, Constants.MAX_ENTRIES_IN_STATEMENT)
.stream() .stream()
.map(ids -> targetRepository.findAll(AccessController.Operation.UPDATE, .map(ids -> targetRepository.findAll(AccessController.Operation.UPDATE, TargetSpecifications.hasControllerIdIn(ids)))
TargetSpecifications.hasControllerIdIn(ids))) .flatMap(List::stream).map(JpaTarget::getControllerId)
.flatMap(List::stream).map(JpaTarget::getControllerId).toList(); .toList();
final List<JpaTarget> targetEntities = assignmentStrategy.findTargetsForAssignment(existingTargetIds,
distributionSet.getId());
final List<JpaTarget> targetEntities = assignmentStrategy.findTargetsForAssignment(existingTargetIds, distributionSet.getId());
if (targetEntities.isEmpty()) { if (targetEntities.isEmpty()) {
return allTargetsAlreadyAssignedResult(distributionSet, existingTargetIds.size()); return allTargetsAlreadyAssignedResult(distributionSet, existingTargetIds.size());
} }
final List<TargetWithActionType> existingTargetsWithActionType = targetsWithActionType.stream() 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, final List<JpaAction> assignedActions = doAssignDistributionSetToTargets(
existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSet, initiatedBy, existingTargetsWithActionType, actionMessage, assignmentStrategy, distributionSet, targetEntities);
targetEntities);
return buildAssignmentResult(distributionSet, assignedActions, existingTargetsWithActionType.size()); return buildAssignmentResult(distributionSet, assignedActions, existingTargetsWithActionType.size());
} }
@@ -824,17 +824,14 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
closeOrCancelActiveActions(assignmentStrategy, targetEntitiesIdsChunks); closeOrCancelActiveActions(assignmentStrategy, targetEntitiesIdsChunks);
} }
// cancel all scheduled actions which are in-active, these actions were // cancel all scheduled actions which are in-active, these actions were
// not active before and the manual assignment which has been done // not active before and the manual assignment which has been done cancels them
// cancels them
targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets); targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets);
setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity, setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity, targetEntitiesIdsChunks);
targetEntitiesIdsChunks); final Map<TargetWithActionType, JpaAction> assignedActions = createActions(
final Map<TargetWithActionType, JpaAction> assignedActions = createActions(initiatedBy, targetsWithActionType, targetsWithActionType, targetEntities, distributionSetEntity, assignmentStrategy, initiatedBy);
targetEntities, assignmentStrategy, distributionSetEntity); // create initial action status when action is created, so we remember
// create initial action status when action is created so we remember
// the initial running status because we will change the status // the initial running status because we will change the status
// of the action itself and with this action status we have a nicer // of the action itself and with this action status we have a nicer action history.
// action history.
createActionsStatus(assignedActions, assignmentStrategy, actionMessage); createActionsStatus(assignedActions, assignmentStrategy, actionMessage);
detachEntitiesAndSendTargetUpdatedEvents(distributionSetEntity, targetEntities, assignmentStrategy); detachEntitiesAndSendTargetUpdatedEvents(distributionSetEntity, targetEntities, assignmentStrategy);
@@ -872,12 +869,10 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
assignmentStrategy.setAssignedDistributionSetAndTargetStatus(set, targetIdsChunks, currentUser); assignmentStrategy.setAssignedDistributionSetAndTargetStatus(set, targetIdsChunks, currentUser);
} }
private Map<TargetWithActionType, JpaAction> createActions(final String initiatedBy, private Map<TargetWithActionType, JpaAction> createActions(
final Collection<TargetWithActionType> targetsWithActionType, final List<JpaTarget> targets, final Collection<TargetWithActionType> targetsWithActionType, final List<JpaTarget> targets, final JpaDistributionSet set,
final AbstractDsAssignmentStrategy assignmentStrategy, final JpaDistributionSet set) { final AbstractDsAssignmentStrategy assignmentStrategy, final String initiatedBy) {
final Map<TargetWithActionType, JpaAction> persistedActions = new LinkedHashMap<>(); final Map<TargetWithActionType, JpaAction> persistedActions = new LinkedHashMap<>();
for (final TargetWithActionType twt : targetsWithActionType) { for (final TargetWithActionType twt : targetsWithActionType) {
final JpaAction targetAction = assignmentStrategy.createTargetAction(initiatedBy, twt, targets, set); final JpaAction targetAction = assignmentStrategy.createTargetAction(initiatedBy, twt, targets, set);
if (targetAction != null) { if (targetAction != null) {
@@ -887,7 +882,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
return persistedActions; return persistedActions;
} }
private void createActionsStatus(final Map<TargetWithActionType, JpaAction> actions, private void createActionsStatus(
final Map<TargetWithActionType, JpaAction> actions,
final AbstractDsAssignmentStrategy assignmentStrategy, final String actionMessage) { final AbstractDsAssignmentStrategy assignmentStrategy, final String actionMessage) {
actionStatusRepository.saveAll(actions.entrySet().stream().map(entry -> { actionStatusRepository.saveAll(actions.entrySet().stream().map(entry -> {
final JpaAction action = entry.getValue(); final JpaAction action = entry.getValue();

View File

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

View File

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