Prioritisation of assignments via mgmt-API (#895)
* Updating the schema for targetfilterquery and rollout * Updating the weight validation logic and tests * Make weight optional * Fix existing multi assignment tests by adding weight, remove weight from TargetFilterQuery * Add weight validation tests, fix tests * Add mgmt api tests for assignment and getting action with weight * Add management layer validation and tests for creating rollouts with weight * Fix amqp test, add repo level validation to resource tests * Add weight to rollout mgmt-api and tests * Add weight to mgmt api target Filter create and update * Add target filter auto assign weight. disable enforcement of setting a weight in multiassign mode * Remove ignored tests, fix api doc * Fix minor findings * Fix findings * Remove hardcoded min weight * Add docu text, fix findings * Fix api documentation * Expose weight via DMF * Expose actions according to weight via ddi * Fix documentation * Add method to get actions ordered by weight to deploymentManagement * Updating the schema for targetfilterquery and rollout * Updated the indentation * Updated the helper class, fixed the randomUID in test factory * Updated the class name with prefix JPA * Adding the missing License for WeightValidationHelper class * Adding documentation to the dmf api on weight * Removed the merger markers * Updated the class name * Removed the redundant method * Addressed final PR comments * Updated the missing testcase with latest default weight value * Reverting the default value of weight back to 1000 and updated tests Signed-off-by: Shruthi Manavalli Ramanna <shruthimanavalli.ramanna@bosch-si.com> Signed-off-by: Stefan Klotz <stefan.klotz@bosch-si.com>
This commit is contained in:
committed by
Stefan Behl
parent
09f2d8a481
commit
9cb5d31396
@@ -149,7 +149,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
||||
|
||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, IpUtil
|
||||
.getClientIpFromRequest(requestResponseContextHolder.getHttpServletRequest(), securityProperties));
|
||||
final Action action = controllerManagement.findOldestActiveActionByTarget(controllerId).orElse(null);
|
||||
final Action action = controllerManagement.findActiveActionWithHighestWeight(controllerId).orElse(null);
|
||||
|
||||
checkAndCancelExpiredAction(action);
|
||||
|
||||
|
||||
@@ -105,12 +105,12 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.")
|
||||
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = {CONTROLLER_ROLE,
|
||||
SYSTEM_ROLE}, autoCreateTenant = false)
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = { CONTROLLER_ROLE,
|
||||
SYSTEM_ROLE }, autoCreateTenant = false)
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetTypeCreatedEvent.class, count = 3),
|
||||
@Expect(type = SoftwareModuleTypeCreatedEvent.class, count = 2)})
|
||||
@Expect(type = SoftwareModuleTypeCreatedEvent.class, count = 2) })
|
||||
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
||||
|
||||
mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
||||
@@ -131,10 +131,10 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that target poll request does not change audit data on the entity.")
|
||||
@WithUser(principal = "knownPrincipal", authorities = {SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET,
|
||||
SpPermission.CREATE_TARGET}, allSpPermissions = false)
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1)})
|
||||
@WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET,
|
||||
SpPermission.CREATE_TARGET }, allSpPermissions = false)
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void targetPollDoesNotModifyAuditData() throws Exception {
|
||||
// create target first with "knownPrincipal" user and audit data
|
||||
final String knownTargetControllerId = "target1";
|
||||
@@ -162,15 +162,15 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that server returns a not found response in case of empty controlloer ID.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 0)})
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 0) })
|
||||
public void rootRsWithoutId() throws Exception {
|
||||
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1)})
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void rootRsPlugAndPlay() throws Exception {
|
||||
|
||||
final long current = System.currentTimeMillis();
|
||||
@@ -198,8 +198,8 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.")
|
||||
@WithUser(principal = "knownpricipal", allSpPermissions = false)
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1)})
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void pollWithModifiedGloablPollingTime() throws Exception {
|
||||
securityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
||||
@@ -218,14 +218,14 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that etag check results in not modified response if provided etag by client is identical to entity in repository.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 6),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 3), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 2),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6)})
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 6) })
|
||||
public void rootRsNotModified() throws Exception {
|
||||
final String etag = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
@@ -289,8 +289,8 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@Description("Ensures that the target state machine of a precomissioned target switches from "
|
||||
+ "UNKNOWN to REGISTERED when the target polls for the first time.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1)})
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 1), @Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void rootRsPrecommissioned() throws Exception {
|
||||
testdataFactory.createTarget("4711");
|
||||
|
||||
@@ -314,8 +314,8 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the source IP address of the polling target is correctly stored in repository")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1)})
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void rootRsPlugAndPlayIpAddress() throws Exception {
|
||||
// test
|
||||
final String knownControllerId1 = "0815";
|
||||
@@ -341,8 +341,8 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Ensures that the source IP address of the polling target is not stored in repository if disabled")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1)})
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetPollEvent.class, count = 1) })
|
||||
public void rootRsIpAddressNotStoredIfDisabled() throws Exception {
|
||||
securityProperties.getClients().setTrackRemoteIp(false);
|
||||
|
||||
@@ -360,12 +360,12 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Controller trys to finish an update process after it has been finished by an error action status.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 1),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void tryToFinishAnUpdateProcessAfterItHasBeenFinished() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget("911");
|
||||
@@ -384,13 +384,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Controller sends attribute update request after device successfully closed software update.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 2),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 2), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 6), @Expect(type = TargetPollEvent.class, count = 4),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1)})
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1) })
|
||||
public void attributeUpdateRequestSendingAfterSuccessfulDeployment() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("1");
|
||||
final Target savedTarget = testdataFactory.createTarget("922");
|
||||
@@ -463,13 +463,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Test to verify that only a specific count of messages are returned based on the input actionHistory for getControllerDeploymentActionFeedback endpoint.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void testActionHistoryCount() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget("911");
|
||||
@@ -498,13 +498,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Test to verify that a zero input value of actionHistory results in no action history appended for getControllerDeploymentActionFeedback endpoint.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void testActionHistoryZeroInput() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget("911");
|
||||
@@ -529,13 +529,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
|
||||
@Test
|
||||
@Description("Test to verify that entire action history is returned if the input value for actionHistory is -1, for getControllerDeploymentActionFeedback endpoint.")
|
||||
@ExpectEvents({@Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
|
||||
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
|
||||
@Expect(type = TargetAssignDistributionSetEvent.class, count = 1),
|
||||
@Expect(type = ActionCreatedEvent.class, count = 1), @Expect(type = ActionUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetUpdatedEvent.class, count = 2),
|
||||
@Expect(type = TargetAttributesRequestedEvent.class, count = 1),
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3)})
|
||||
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3) })
|
||||
public void testActionHistoryNegativeInput() throws Exception {
|
||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||
Target savedTarget = testdataFactory.createTarget("911");
|
||||
@@ -654,12 +654,13 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@Description("Assign multiple DS in multi-assignment mode. The earliest active Action is exposed to the controller.")
|
||||
public void earliestActionIsExposedToControllerInMultiAssignMode() throws Exception {
|
||||
setMultiAssignmentsEnabled();
|
||||
enableMultiAssignments();
|
||||
final Target target = testdataFactory.createTarget();
|
||||
final DistributionSet ds1 = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
final DistributionSet ds2 = testdataFactory.createDistributionSet(UUID.randomUUID().toString());
|
||||
final Action action1 = getFirstAssignedAction(assignDistributionSet(ds1, target));
|
||||
final Long action2Id = getFirstAssignedActionId(assignDistributionSet(ds2, target));
|
||||
final Action action1 = getFirstAssignedAction(assignDistributionSet(ds1.getId(), target.getControllerId(), 56));
|
||||
final Long action2Id = getFirstAssignedActionId(
|
||||
assignDistributionSet(ds2.getId(), target.getControllerId(), 34));
|
||||
|
||||
assertDeploymentActionIsExposedToTarget(target.getControllerId(), action1.getId());
|
||||
sendDeploymentActionFeedback(target, action1, "closed", "success");
|
||||
@@ -670,7 +671,7 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
@Test
|
||||
@Description("The system should not create a new target because of a too long controller id.")
|
||||
public void rootRsWithInvalidControllerId() throws Exception {
|
||||
String invalidControllerId = RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
||||
final String invalidControllerId = RandomStringUtils.randomAlphabetic(Target.CONTROLLER_ID_MAX_SIZE + 1);
|
||||
mvc.perform(get("/{tenant}/controller/v1/{controllerId}", tenantAware.getCurrentTenant(), invalidControllerId))
|
||||
.andExpect(status().isBadRequest());
|
||||
}
|
||||
@@ -684,8 +685,4 @@ public class DdiRootControllerTest extends AbstractDDiApiIntegrationTest {
|
||||
.andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink)));
|
||||
|
||||
}
|
||||
|
||||
private void setMultiAssignmentsEnabled() {
|
||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,12 @@ public class MgmtAction extends MgmtBaseEntity {
|
||||
@JsonProperty
|
||||
private Long forceTime;
|
||||
|
||||
@JsonProperty(value="forceType")
|
||||
@JsonProperty(value = "forceType")
|
||||
private MgmtActionType actionType;
|
||||
|
||||
@JsonProperty
|
||||
private Integer weight;
|
||||
|
||||
@JsonProperty
|
||||
private MgmtMaintenanceWindow maintenanceWindow;
|
||||
|
||||
@@ -79,6 +82,14 @@ public class MgmtAction extends MgmtBaseEntity {
|
||||
this.forceTime = forceTime;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public MgmtActionType getActionType() {
|
||||
return actionType;
|
||||
}
|
||||
@@ -110,5 +121,4 @@ public class MgmtAction extends MgmtBaseEntity {
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public class MgmtTargetAssignmentRequestBody {
|
||||
private long forcetime;
|
||||
private MgmtActionType type;
|
||||
private MgmtMaintenanceWindowRequestBody maintenanceWindow;
|
||||
private Integer weight;
|
||||
|
||||
/**
|
||||
* JsonCreator Constructor
|
||||
@@ -61,6 +62,14 @@ public class MgmtTargetAssignmentRequestBody {
|
||||
this.forcetime = forcetime;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public MgmtMaintenanceWindowRequestBody getMaintenanceWindow() {
|
||||
return maintenanceWindow;
|
||||
}
|
||||
@@ -68,5 +77,4 @@ public class MgmtTargetAssignmentRequestBody {
|
||||
public void setMaintenanceWindow(final MgmtMaintenanceWindowRequestBody maintenanceWindow) {
|
||||
this.maintenanceWindow = maintenanceWindow;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtNamedEntity;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -47,6 +47,9 @@ public class MgmtRolloutResponseBody extends MgmtNamedEntity {
|
||||
@JsonProperty
|
||||
private MgmtActionType type;
|
||||
|
||||
@JsonProperty
|
||||
private Integer weight;
|
||||
|
||||
public boolean isDeleted() {
|
||||
return deleted;
|
||||
}
|
||||
@@ -114,4 +117,12 @@ public class MgmtRolloutResponseBody extends MgmtNamedEntity {
|
||||
public MgmtActionType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setWeight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroup;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Model for request containing a rollout body e.g. in a POST request of
|
||||
@@ -34,6 +35,9 @@ public class MgmtRolloutRestRequestBody extends AbstractMgmtRolloutConditionsEnt
|
||||
|
||||
private Long startAt;
|
||||
|
||||
@JsonProperty(required = false)
|
||||
private Integer weight;
|
||||
|
||||
private MgmtActionType type;
|
||||
|
||||
private List<MgmtRolloutGroup> groups;
|
||||
@@ -124,7 +128,7 @@ public class MgmtRolloutRestRequestBody extends AbstractMgmtRolloutConditionsEnt
|
||||
* @param groups
|
||||
* List of {@link MgmtRolloutGroup}
|
||||
*/
|
||||
public void setGroups(List<MgmtRolloutGroup> groups) {
|
||||
public void setGroups(final List<MgmtRolloutGroup> groups) {
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
@@ -139,7 +143,22 @@ public class MgmtRolloutRestRequestBody extends AbstractMgmtRolloutConditionsEnt
|
||||
* @param startAt
|
||||
* the start at timestamp in millis or null
|
||||
*/
|
||||
public void setStartAt(Long startAt) {
|
||||
public void setStartAt(final Long startAt) {
|
||||
this.startAt = startAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the priority of {@link Rollout}
|
||||
*/
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param weight
|
||||
* the priority of {@link Rollout}
|
||||
*/
|
||||
public void setWeight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
public class MgmtDistributionSetAssignment extends MgmtId {
|
||||
|
||||
private long forcetime;
|
||||
@JsonProperty(required = false)
|
||||
private Integer weight;
|
||||
private MgmtActionType type;
|
||||
private MgmtMaintenanceWindowRequestBody maintenanceWindow;
|
||||
|
||||
@@ -47,6 +49,14 @@ public class MgmtDistributionSetAssignment extends MgmtId {
|
||||
this.forcetime = forcetime;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(final int weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link MgmtMaintenanceWindowRequestBody} for distribution set
|
||||
* assignment.
|
||||
|
||||
@@ -22,6 +22,9 @@ public class MgmtDistributionSetAutoAssignment extends MgmtId {
|
||||
@JsonProperty(required = false)
|
||||
private MgmtActionType type;
|
||||
|
||||
@JsonProperty(required = false)
|
||||
private Integer weight;
|
||||
|
||||
public MgmtActionType getType() {
|
||||
return type;
|
||||
}
|
||||
@@ -29,4 +32,12 @@ public class MgmtDistributionSetAutoAssignment extends MgmtId {
|
||||
public void setType(final MgmtActionType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(final Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ public class MgmtTargetFilterQuery extends MgmtBaseEntity {
|
||||
@JsonProperty
|
||||
private MgmtActionType autoAssignActionType;
|
||||
|
||||
@JsonProperty
|
||||
private Integer autoAssignWeight;
|
||||
|
||||
public Long getFilterId() {
|
||||
return filterId;
|
||||
}
|
||||
@@ -80,4 +83,11 @@ public class MgmtTargetFilterQuery extends MgmtBaseEntity {
|
||||
this.autoAssignActionType = actionType;
|
||||
}
|
||||
|
||||
public Integer getAutoAssignWeight() {
|
||||
return autoAssignWeight;
|
||||
}
|
||||
|
||||
public void setAutoAssignWeight(final Integer autoAssignWeight) {
|
||||
this.autoAssignWeight = autoAssignWeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,7 @@ public class MgmtTargetFilterQueryRequestBody {
|
||||
return query;
|
||||
}
|
||||
|
||||
public void setQuery(String query) {
|
||||
public void setQuery(final String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public final class MgmtDeploymentRequestMapper {
|
||||
final String targetId) {
|
||||
|
||||
return createAssignmentRequest(targetId, dsAssignment.getId(), dsAssignment.getType(),
|
||||
dsAssignment.getForcetime(), dsAssignment.getMaintenanceWindow());
|
||||
dsAssignment.getForcetime(), dsAssignment.getWeight(), dsAssignment.getMaintenanceWindow());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,13 +54,14 @@ public final class MgmtDeploymentRequestMapper {
|
||||
final Long dsId) {
|
||||
|
||||
return createAssignmentRequest(targetAssignment.getId(), dsId, targetAssignment.getType(),
|
||||
targetAssignment.getForcetime(), targetAssignment.getMaintenanceWindow());
|
||||
targetAssignment.getForcetime(), targetAssignment.getWeight(), targetAssignment.getMaintenanceWindow());
|
||||
}
|
||||
|
||||
private static DeploymentRequest createAssignmentRequest(final String targetId, final Long dsId,
|
||||
final MgmtActionType type, final long forcetime, final MgmtMaintenanceWindowRequestBody maintenanceWindow) {
|
||||
final MgmtActionType type, final long forcetime, final Integer weight,
|
||||
final MgmtMaintenanceWindowRequestBody maintenanceWindow) {
|
||||
final DeploymentRequestBuilder request = DeploymentManagement.deploymentRequest(targetId, dsId)
|
||||
.setActionType(MgmtRestModelMapper.convertActionType(type)).setForceTime(forcetime);
|
||||
.setActionType(MgmtRestModelMapper.convertActionType(type)).setForceTime(forcetime).setWeight(weight);
|
||||
if (maintenanceWindow != null) {
|
||||
final String cronSchedule = maintenanceWindow.getSchedule();
|
||||
final String duration = maintenanceWindow.getDuration();
|
||||
@@ -70,5 +71,4 @@ public final class MgmtDeploymentRequestMapper {
|
||||
}
|
||||
return request.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -266,7 +266,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
||||
final List<DistributionSetAssignmentResult> assignmentResults = deployManagament
|
||||
.assignDistributionSets(deploymentRequests);
|
||||
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(assignmentResults));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -79,6 +79,7 @@ final class MgmtRolloutMapper {
|
||||
body.setTotalTargets(rollout.getTotalTargets());
|
||||
body.setDeleted(rollout.isDeleted());
|
||||
body.setType(MgmtRestModelMapper.convertActionType(rollout.getActionType()));
|
||||
rollout.getWeight().ifPresent(body::setWeight);
|
||||
|
||||
if (withDetails) {
|
||||
for (final TotalTargetCountStatus.Status status : TotalTargetCountStatus.Status.values()) {
|
||||
@@ -106,7 +107,8 @@ final class MgmtRolloutMapper {
|
||||
return entityFactory.rollout().create().name(restRequest.getName()).description(restRequest.getDescription())
|
||||
.set(distributionSet).targetFilterQuery(restRequest.getTargetFilterQuery())
|
||||
.actionType(MgmtRestModelMapper.convertActionType(restRequest.getType()))
|
||||
.forcedTime(restRequest.getForcetime()).startAt(restRequest.getStartAt());
|
||||
.forcedTime(restRequest.getForcetime()).startAt(restRequest.getStartAt())
|
||||
.weight(restRequest.getWeight());
|
||||
}
|
||||
|
||||
static RolloutGroupCreate fromRequest(final EntityFactory entityFactory, final MgmtRolloutGroup restRequest) {
|
||||
@@ -249,5 +251,4 @@ final class MgmtRolloutMapper {
|
||||
private static String createIllegalArgumentLiteral(final Condition condition) {
|
||||
return "Condition " + condition + NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,11 +15,14 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtDistributionSetAutoAssignment;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetFilterQueryRestApi;
|
||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||
import org.eclipse.hawkbit.repository.builder.AutoAssignDistributionSetUpdate;
|
||||
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -58,6 +61,7 @@ public final class MgmtTargetFilterQueryMapper {
|
||||
if (distributionSet != null) {
|
||||
targetRest.setAutoAssignDistributionSet(distributionSet.getId());
|
||||
targetRest.setAutoAssignActionType(MgmtRestModelMapper.convertActionType(filter.getAutoAssignActionType()));
|
||||
filter.getAutoAssignWeight().ifPresent(targetRest::setAutoAssignWeight);
|
||||
}
|
||||
|
||||
targetRest.add(linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withSelfRel());
|
||||
@@ -76,4 +80,12 @@ public final class MgmtTargetFilterQueryMapper {
|
||||
return entityFactory.targetFilterQuery().create().name(filterRest.getName()).query(filterRest.getQuery());
|
||||
}
|
||||
|
||||
static AutoAssignDistributionSetUpdate fromRequest(final EntityFactory entityFactory, final long filterId,
|
||||
final MgmtDistributionSetAutoAssignment assignRest) {
|
||||
final ActionType type = MgmtRestModelMapper.convertActionType(assignRest.getType());
|
||||
|
||||
return entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(assignRest.getId()).actionType(type)
|
||||
.weight(assignRest.getWeight());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,8 +108,9 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
||||
@RequestBody final MgmtTargetFilterQueryRequestBody targetFilterRest) {
|
||||
LOG.debug("updating target filter query {}", filterId);
|
||||
|
||||
final TargetFilterQuery updateFilter = filterManagement.update(entityFactory.targetFilterQuery()
|
||||
.update(filterId).name(targetFilterRest.getName()).query(targetFilterRest.getQuery()));
|
||||
final TargetFilterQuery updateFilter = filterManagement
|
||||
.update(entityFactory.targetFilterQuery().update(filterId).name(targetFilterRest.getName())
|
||||
.query(targetFilterRest.getQuery()));
|
||||
|
||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter);
|
||||
MgmtTargetFilterQueryMapper.addLinks(response);
|
||||
@@ -127,10 +128,10 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
||||
@Override
|
||||
public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(
|
||||
@PathVariable("filterId") final Long filterId,
|
||||
@RequestBody final MgmtDistributionSetAutoAssignment dsIdWithActionType) {
|
||||
@RequestBody final MgmtDistributionSetAutoAssignment autoAssignRequest) {
|
||||
|
||||
final TargetFilterQuery updateFilter = filterManagement.updateAutoAssignDSWithActionType(filterId,
|
||||
dsIdWithActionType.getId(), MgmtRestModelMapper.convertActionType(dsIdWithActionType.getType()));
|
||||
final TargetFilterQuery updateFilter = filterManagement.updateAutoAssignDS(
|
||||
MgmtTargetFilterQueryMapper.fromRequest(entityFactory, filterId, autoAssignRequest));
|
||||
|
||||
final MgmtTargetFilterQuery response = MgmtTargetFilterQueryMapper.toResponse(updateFilter);
|
||||
MgmtTargetFilterQueryMapper.addLinks(response);
|
||||
@@ -156,7 +157,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
|
||||
|
||||
@Override
|
||||
public ResponseEntity<Void> deleteAssignedDistributionSet(@PathVariable("filterId") final Long filterId) {
|
||||
filterManagement.updateAutoAssignDS(filterId, null);
|
||||
filterManagement.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(null));
|
||||
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
@@ -206,6 +206,7 @@ public final class MgmtTargetMapper {
|
||||
if (ActionType.TIMEFORCED == action.getActionType()) {
|
||||
result.setForceTime(action.getForcedTime());
|
||||
}
|
||||
action.getWeight().ifPresent(result::setWeight);
|
||||
result.setActionType(MgmtRestModelMapper.convertActionType(action.getActionType()));
|
||||
|
||||
if (action.isActive()) {
|
||||
@@ -289,5 +290,4 @@ public final class MgmtTargetMapper {
|
||||
static List<MgmtMetadata> toResponseTargetMetadata(final List<TargetMetadata> metadata) {
|
||||
return metadata.stream().map(MgmtTargetMapper::toResponseTargetMetadata).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
@@ -21,6 +22,8 @@ import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
||||
import org.eclipse.hawkbit.rest.RestConfiguration;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
@@ -197,4 +200,24 @@ public abstract class AbstractManagementApiIntegrationTest extends AbstractRestI
|
||||
};
|
||||
}
|
||||
|
||||
protected static JSONObject getAssignmentObject(final Object id, final MgmtActionType type) {
|
||||
final JSONObject obj = new JSONObject();
|
||||
try {
|
||||
obj.put("id", id);
|
||||
obj.put("type", type.getName());
|
||||
} catch (final JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
protected static JSONObject getAssignmentObject(final Object id, final MgmtActionType type, final int weight) {
|
||||
try {
|
||||
return getAssignmentObject(id, type).put("weight", weight);
|
||||
} catch (final JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new JSONObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -555,9 +555,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
||||
final DistributionSet createdDs = createDistributionSetsAlphabetical.iterator().next();
|
||||
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(knownFilterName).query("name==y")).getId(),
|
||||
createdDs.getId());
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(knownFilterName)
|
||||
.query("name==y").autoAssignDistributionSet(createdDs.getId()));
|
||||
|
||||
// create some dummy target filter queries
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("b").query("name==y"));
|
||||
@@ -615,12 +614,10 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
|
||||
private void prepareTestFilters(final String filterNamePrefix, final DistributionSet createdDs) {
|
||||
// create target filter queries that should be found
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "1").query("name==y"))
|
||||
.getId(), createdDs.getId());
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "2").query("name==y"))
|
||||
.getId(), createdDs.getId());
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "1")
|
||||
.query("name==y").autoAssignDistributionSet(createdDs.getId()));
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "2")
|
||||
.query("name==y").autoAssignDistributionSet(createdDs.getId()));
|
||||
// create some dummy target filter queries
|
||||
targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "b").query("name==y"));
|
||||
@@ -1247,8 +1244,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Ensures that multi target assignment through API is reflected by the repository in the case of " +
|
||||
"DOWNLOAD_ONLY.")
|
||||
@Description("Ensures that multi target assignment through API is reflected by the repository in the case of "
|
||||
+ "DOWNLOAD_ONLY.")
|
||||
public void assignMultipleTargetsToDistributionSetAsDownloadOnly() throws Exception {
|
||||
final DistributionSet createdDs = testdataFactory.createDistributionSet();
|
||||
|
||||
@@ -1263,8 +1260,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
assignDistributionSet(createdDs.getId(), knownTargetIds[0], Action.ActionType.DOWNLOAD_ONLY);
|
||||
|
||||
mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", createdDs.getId())
|
||||
.contentType(MediaType.APPLICATION_JSON).content(list.toString()))
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1)))
|
||||
.contentType(MediaType.APPLICATION_JSON).content(list.toString())).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1)))
|
||||
.andExpect(jsonPath("$.alreadyAssigned", equalTo(1)))
|
||||
.andExpect(jsonPath("$.total", equalTo(knownTargetIds.length)));
|
||||
|
||||
@@ -1310,10 +1307,10 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
|
||||
final JSONArray body = new JSONArray();
|
||||
body.put(getAssignmentObject(targetIds.get(0), MgmtActionType.FORCED));
|
||||
body.put(getAssignmentObject(targetIds.get(0), MgmtActionType.FORCED));
|
||||
body.put(getAssignmentObject(targetIds.get(1), MgmtActionType.FORCED));
|
||||
body.put(getAssignmentObject(targetIds.get(1), MgmtActionType.SOFT));
|
||||
body.put(getAssignmentObject(targetIds.get(0), MgmtActionType.FORCED, 56));
|
||||
body.put(getAssignmentObject(targetIds.get(0), MgmtActionType.FORCED, 78));
|
||||
body.put(getAssignmentObject(targetIds.get(1), MgmtActionType.FORCED, 67));
|
||||
body.put(getAssignmentObject(targetIds.get(1), MgmtActionType.SOFT, 34));
|
||||
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(body.toString())
|
||||
@@ -1321,14 +1318,32 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
|
||||
.andExpect(jsonPath("total", equalTo(body.length())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("An assignment request containing a weight is only accepted when weight is valide and multi assignment is on.")
|
||||
public void weightValidation() throws Exception {
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
final int weight = 78;
|
||||
|
||||
final JSONArray bodyValide = new JSONArray().put(getAssignmentObject(targetId, MgmtActionType.FORCED, weight));
|
||||
final JSONArray bodyInvalide = new JSONArray()
|
||||
.put(getAssignmentObject(targetId, MgmtActionType.FORCED, Action.WEIGHT_MIN - 1));
|
||||
|
||||
public static JSONObject getAssignmentObject(final String targetId, final MgmtActionType type)
|
||||
throws JSONException {
|
||||
final JSONObject obj = new JSONObject();
|
||||
obj.put("id", targetId);
|
||||
obj.put("type", type.getName());
|
||||
return obj;
|
||||
mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyValide.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.multiassignmentNotEnabled")));
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyInvalide.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation")));
|
||||
mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyValide.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).get().collect(Collectors.toList());
|
||||
assertThat(actions).size().isEqualTo(1);
|
||||
assertThat(actions.get(0).getWeight()).get().isEqualTo(weight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -916,6 +916,36 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
||||
postRollout("rollout1", 10, dsA.getId(), "id==target*", 20, Action.ActionType.DOWNLOAD_ONLY);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("A rollout create request containing a weight is only accepted when weight is valide and multi assignment is on.")
|
||||
public void weightValidation() throws Exception {
|
||||
testdataFactory.createTargets(4, "rollout", "description");
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
final int weight = 66;
|
||||
|
||||
final String invalideWeightRequest = JsonBuilder.rollout("withWeight", "d", 2, dsId, "id==rollout*",
|
||||
new RolloutGroupConditionBuilder().withDefaults().build(), null, null, Action.WEIGHT_MIN - 1);
|
||||
final String valideWeightRequest = JsonBuilder.rollout("withWeight", "d", 2, dsId, "id==rollout*",
|
||||
new RolloutGroupConditionBuilder().withDefaults().build(), null, null, weight);
|
||||
|
||||
mvc.perform(post("/rest/v1/rollouts").content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.multiassignmentNotEnabled")));
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post("/rest/v1/rollouts").content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation")));
|
||||
mvc.perform(post("/rest/v1/rollouts").content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isCreated());
|
||||
|
||||
final List<Rollout> rollouts = rolloutManagement.findAll(PAGE, false).getContent();
|
||||
assertThat(rollouts).hasSize(1);
|
||||
assertThat(rollouts.get(0).getWeight()).get().isEqualTo(weight);
|
||||
}
|
||||
|
||||
protected <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
|
||||
final long timeout, final long pollInterval) throws Exception // NOPMD
|
||||
{
|
||||
@@ -955,14 +985,12 @@ public class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTes
|
||||
|
||||
private void postRollout(final String name, final int groupSize, final Long distributionSetId,
|
||||
final String targetFilterQuery, final int targets, final Action.ActionType type) throws Exception {
|
||||
String actionType = MgmtRestModelMapper.convertActionType(type).getName();
|
||||
String rollout = JsonBuilder.rollout(name, "desc", groupSize, distributionSetId, targetFilterQuery,
|
||||
new RolloutGroupConditionBuilder().withDefaults().build(), null, actionType);
|
||||
final String actionType = MgmtRestModelMapper.convertActionType(type).getName();
|
||||
final String rollout = JsonBuilder.rollout(name, "desc", groupSize, distributionSetId, targetFilterQuery,
|
||||
new RolloutGroupConditionBuilder().withDefaults().build(), null, actionType, null);
|
||||
|
||||
mvc.perform(post("/rest/v1/rollouts")
|
||||
.content(rollout)
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||
mvc.perform(post("/rest/v1/rollouts").content(rollout).contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||
.andExpect(jsonPath("$.name", equalTo(name))).andExpect(jsonPath("$.status", equalTo("creating")))
|
||||
.andExpect(jsonPath("$.type", equalTo(actionType)))
|
||||
.andExpect(jsonPath("$.targetFilterQuery", equalTo(targetFilterQuery)))
|
||||
|
||||
@@ -20,12 +20,15 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
@@ -104,8 +107,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
public void updateTargetWhichDoesNotExistsLeadsToEntityNotFound() throws Exception {
|
||||
final String notExistingId = "4395";
|
||||
mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + notExistingId).content("{}")
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(print())
|
||||
.andExpect(status().isNotFound());
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,8 +168,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
createSingleTargetFilterQuery(idB, testQuery);
|
||||
createSingleTargetFilterQuery(idC, testQuery);
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING)).andExpect(status().isOk())
|
||||
.andDo(print())
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING)).andExpect(status().isOk()).andDo(print())
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(knownTargetAmount)))
|
||||
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(knownTargetAmount)))
|
||||
@@ -252,9 +253,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
final String hrefPrefix = "http://localhost" + MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/"
|
||||
+ tfq.getId();
|
||||
// test
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()))
|
||||
.andDo(print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath(JSON_PATH_NAME, equalTo(knownName)))
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId())).andDo(print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath(JSON_PATH_NAME, equalTo(knownName)))
|
||||
.andExpect(jsonPath(JSON_PATH_QUERY, equalTo(knownQuery)))
|
||||
.andExpect(jsonPath("$._links.self.href", equalTo(hrefPrefix)))
|
||||
.andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS")));
|
||||
@@ -402,8 +402,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
? "{\"id\":" + set.getId() + ", \"type\":\"" + actionType.getName() + "\"}"
|
||||
: "{\"id\":" + set.getId() + "}";
|
||||
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS")
|
||||
.content(payload).contentType(MediaType.APPLICATION_JSON)).andDo(print())
|
||||
.andExpect(status().isOk());
|
||||
.content(payload).contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk());
|
||||
|
||||
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get();
|
||||
final MgmtActionType expectedActionType = actionType != null ? actionType : MgmtActionType.FORCED;
|
||||
@@ -412,9 +411,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
assertThat(updatedFilterQuery.getAutoAssignActionType())
|
||||
.isEqualTo(MgmtRestModelMapper.convertActionType(expectedActionType));
|
||||
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()))
|
||||
.andDo(print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath(JSON_PATH_NAME, equalTo(tfq.getName())))
|
||||
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId())).andDo(print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath(JSON_PATH_NAME, equalTo(tfq.getName())))
|
||||
.andExpect(jsonPath(JSON_PATH_QUERY, equalTo(tfq.getQuery())))
|
||||
.andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_DS, equalTo(set.getId().intValue())))
|
||||
.andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_ACTION_TYPE, equalTo(expectedActionType.getName())))
|
||||
@@ -427,8 +425,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
throws Exception {
|
||||
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS")
|
||||
.content("{\"id\":" + set.getId() + ", \"type\":\"" + MgmtActionType.TIMEFORCED.getName() + "\"}")
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS,
|
||||
equalTo(InvalidAutoAssignActionTypeException.class.getName())))
|
||||
.andExpect(jsonPath(JSON_PATH_ERROR_CODE,
|
||||
@@ -491,7 +488,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
|
||||
final DistributionSet set = testdataFactory.createDistributionSet(dsName);
|
||||
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
|
||||
targetFilterQueryManagement.updateAutoAssignDS(tfq.getId(), set.getId());
|
||||
targetFilterQueryManagement
|
||||
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(tfq.getId()).ds(set.getId()));
|
||||
|
||||
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get();
|
||||
|
||||
@@ -514,6 +512,34 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInte
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("An auto assignment containing a weight is only accepted when weight is valide and multi assignment is on.")
|
||||
public void weightValidation() throws Exception {
|
||||
final Long filterId = createSingleTargetFilterQuery("filter1", "name==*").getId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
|
||||
final String invalideWeightRequest = new JSONObject().put("id", dsId).put("weight", Action.WEIGHT_MIN - 1)
|
||||
.toString();
|
||||
final String valideWeightRequest = new JSONObject().put("id", dsId).put("weight", 45).toString();
|
||||
|
||||
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
|
||||
filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.multiassignmentNotEnabled")));
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
|
||||
filterId).content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation")));
|
||||
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
|
||||
filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
final List<TargetFilterQuery> filters = targetFilterQueryManagement.findAll(PAGE).getContent();
|
||||
assertThat(filters).hasSize(1);
|
||||
assertThat(filters.get(0).getAutoAssignWeight().get()).isEqualTo(45);
|
||||
}
|
||||
|
||||
private TargetFilterQuery createSingleTargetFilterQuery(final String name, final String query) {
|
||||
return targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(name).query(query));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -40,6 +39,7 @@ import javax.validation.ConstraintViolationException;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.ActionFields;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
@@ -61,7 +61,6 @@ import org.eclipse.hawkbit.rest.util.JsonBuilder;
|
||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||
import org.eclipse.hawkbit.util.IpUtil;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -1876,7 +1875,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
||||
final List<Long> dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final JSONArray body = getAssignmentBody(dsIds);
|
||||
final JSONArray body = new JSONArray();
|
||||
dsIds.forEach(id -> body.put(getAssignmentObject(id, MgmtActionType.FORCED, 67)));
|
||||
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(body.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
@@ -1889,8 +1889,7 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
|
||||
final JSONArray body = getAssignmentBody(Collections.singletonList(dsId));
|
||||
|
||||
final JSONArray body = new JSONArray().put(getAssignmentObject(dsId, MgmtActionType.FORCED));
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(body.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
@@ -1902,7 +1901,8 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
|
||||
final JSONArray body = getAssignmentBody(Arrays.asList(dsId, dsId));
|
||||
final JSONObject assignment = getAssignmentObject(dsId, MgmtActionType.FORCED);
|
||||
final JSONArray body = new JSONArray().put(assignment).put(assignment);
|
||||
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(body.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
@@ -1916,21 +1916,90 @@ public class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest
|
||||
final List<Long> dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
final JSONArray body = getAssignmentBody(dsIds);
|
||||
final JSONArray body = new JSONArray();
|
||||
dsIds.forEach(id -> body.put(getAssignmentObject(id, MgmtActionType.FORCED, 76)));
|
||||
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(body.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(2)));
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||
.andExpect(jsonPath("total", equalTo(2)));
|
||||
}
|
||||
|
||||
public static JSONArray getAssignmentBody(final Collection<Long> dsIds) throws JSONException {
|
||||
final JSONArray body = new JSONArray();
|
||||
for (final Long id : dsIds) {
|
||||
final JSONObject obj = new JSONObject();
|
||||
obj.put("id", id);
|
||||
body.put(obj);
|
||||
}
|
||||
return body;
|
||||
@Test
|
||||
@Description("An assignment request containing a weight is only accepted when weight is valide and multi assignment is on.")
|
||||
public void weightValidation() throws Exception {
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
final int weight = 98;
|
||||
|
||||
final JSONObject bodyValid = getAssignmentObject(dsId, MgmtActionType.FORCED, weight);
|
||||
final JSONObject bodyInvalid = getAssignmentObject(dsId, MgmtActionType.FORCED, Action.WEIGHT_MIN - 1);
|
||||
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyInvalid.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation")));
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyValid.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).get().collect(Collectors.toList());
|
||||
assertThat(actions).size().isEqualTo(1);
|
||||
assertThat(actions.get(0).getWeight()).get().isEqualTo(weight);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("An assignment request containing a valid weight when multi assignment is off.")
|
||||
public void weightWithSingleAssignment() throws Exception {
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
|
||||
final JSONObject bodyValid = getAssignmentObject(dsId, MgmtActionType.FORCED, 98);
|
||||
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyValid.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.multiassignmentNotEnabled")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("An assignment request containing a valid weight when multi assignment is on.")
|
||||
public void weightWithMultiAssignment() throws Exception {
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
final int weight = 98;
|
||||
|
||||
final JSONObject bodyValid = getAssignmentObject(dsId, MgmtActionType.FORCED, weight);
|
||||
|
||||
enableMultiAssignments();
|
||||
mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyValid.toString())
|
||||
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk());
|
||||
|
||||
final List<Action> actions = deploymentManagement.findActionsAll(PAGE).get().collect(Collectors.toList());
|
||||
assertThat(actions).size().isEqualTo(1);
|
||||
assertThat(actions.get(0).getWeight()).get().isEqualTo(weight);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Get weight of action")
|
||||
public void getActionWeight() throws Exception {
|
||||
final String targetId = testdataFactory.createTarget().getControllerId();
|
||||
final Long dsId = testdataFactory.createDistributionSet().getId();
|
||||
final int customWeightHigh = 800;
|
||||
final int customWeightLow = 300;
|
||||
assignDistributionSet(dsId, targetId);
|
||||
enableMultiAssignments();
|
||||
assignDistributionSet(dsId, targetId, customWeightHigh);
|
||||
assignDistributionSet(dsId, targetId, customWeightLow);
|
||||
|
||||
mvc.perform(get("/rest/v1/targets/{targetId}/actions", targetId)
|
||||
.param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "WEIGHT:ASC")).andDo(MockMvcResultPrinter.print())
|
||||
.andExpect(status().isOk()).andExpect(jsonPath("content.[0].weight").doesNotExist())
|
||||
.andExpect(jsonPath("content.[1].weight", equalTo(customWeightLow)))
|
||||
.andExpect(jsonPath("content.[2].weight", equalTo(customWeightHigh)));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ public class ResponseExceptionHandler {
|
||||
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_AUTO_ASSIGN_DISTRIBUTION_SET_INVALID, HttpStatus.BAD_REQUEST);
|
||||
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_CONFIGURATION_VALUE_CHANGE_NOT_ALLOWED, HttpStatus.FORBIDDEN);
|
||||
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_MULTIASSIGNMENT_NOT_ENABLED, HttpStatus.BAD_REQUEST);
|
||||
ERROR_TO_HTTP_STATUS.put(SpServerError.SP_NO_WEIGHT_PROVIDED_IN_MULTIASSIGNMENT_MODE, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
private static HttpStatus getStatusOrDefault(final SpServerError error) {
|
||||
|
||||
@@ -449,25 +449,27 @@ public abstract class JsonBuilder {
|
||||
|
||||
public static String rollout(final String name, final String description, final int groupSize,
|
||||
final long distributionSetId, final String targetFilterQuery, final RolloutGroupConditions conditions) {
|
||||
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, null, null);
|
||||
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, null, null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static String rollout(final String name, final String description, final Integer groupSize,
|
||||
final long distributionSetId, final String targetFilterQuery, final RolloutGroupConditions conditions,
|
||||
final List<RolloutGroup> groups) {
|
||||
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, groups, null);
|
||||
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, groups, null,
|
||||
null);
|
||||
}
|
||||
|
||||
public static String rollout(final String name, final String description, final Integer groupSize,
|
||||
final long distributionSetId, final String targetFilterQuery, final RolloutGroupConditions conditions,
|
||||
final String type) {
|
||||
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, null, type);
|
||||
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, null, type,
|
||||
null);
|
||||
}
|
||||
|
||||
public static String rollout(final String name, final String description, final Integer groupSize,
|
||||
final long distributionSetId, final String targetFilterQuery, final RolloutGroupConditions conditions,
|
||||
final List<RolloutGroup> groups, final String type) {
|
||||
|
||||
final List<RolloutGroup> groups, final String type, final Integer weight) {
|
||||
final JSONObject json = new JSONObject();
|
||||
|
||||
try {
|
||||
@@ -481,6 +483,10 @@ public abstract class JsonBuilder {
|
||||
json.put("type", type);
|
||||
}
|
||||
|
||||
if (weight != null) {
|
||||
json.put("weight", weight);
|
||||
}
|
||||
|
||||
if (conditions != null) {
|
||||
final JSONObject successCondition = new JSONObject();
|
||||
|
||||
|
||||
@@ -25,11 +25,13 @@ import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.eclipse.hawkbit.ddi.rest.resource.DdiApiConfiguration;
|
||||
import org.eclipse.hawkbit.mgmt.rest.resource.MgmtApiConfiguration;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.ArtifactUpload;
|
||||
import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
@@ -37,6 +39,7 @@ import org.eclipse.hawkbit.repository.test.TestConfiguration;
|
||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTest;
|
||||
import org.eclipse.hawkbit.rest.RestConfiguration;
|
||||
import org.eclipse.hawkbit.rest.util.FilterHttpResponse;
|
||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -98,8 +101,13 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
|
||||
}
|
||||
|
||||
public static MyFieldFieldDesc requestFieldWithPath(final String path, final boolean mandatory) {
|
||||
return requestFieldWithPath(path, mandatory, mandatory ? "X" : "");
|
||||
}
|
||||
|
||||
private static MyFieldFieldDesc requestFieldWithPath(final String path, final boolean mandatory,
|
||||
final String mandatoryMessage) {
|
||||
final MyFieldFieldDesc myFieldDesc = new MyFieldFieldDesc(path);
|
||||
myFieldDesc.attributes(key("mandatory").value(mandatory ? "X" : ""));
|
||||
myFieldDesc.attributes(key("mandatory").value(mandatoryMessage));
|
||||
// defaults
|
||||
myFieldDesc.attributes(key("value").value(""));
|
||||
|
||||
@@ -118,6 +126,10 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
|
||||
return requestFieldWithPath(path, false);
|
||||
}
|
||||
|
||||
public static MyFieldFieldDesc requestFieldWithPathMandatoryInMultiAssignMode(final String path) {
|
||||
return requestFieldWithPath(path, false, "when multi-assignment is enabled");
|
||||
}
|
||||
|
||||
public static class MyFieldFieldDesc extends SubsectionDescriptor {
|
||||
|
||||
/**
|
||||
@@ -154,11 +166,17 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
|
||||
final Target savedTarget = targetManagement.create(entityFactory.target().create().controllerId(name)
|
||||
.status(TargetUpdateStatus.UNKNOWN).address("http://192.168.0.1").description("My name is " + name)
|
||||
.lastTargetQuery(System.currentTimeMillis()));
|
||||
|
||||
final List<Target> updatedTargets = maintenanceWindowSchedule == null
|
||||
? assignWithoutMaintenanceWindow(distributionSet, savedTarget, timeforced)
|
||||
: assignWithMaintenanceWindow(distributionSet, savedTarget, timeforced, maintenanceWindowSchedule,
|
||||
maintenanceWindowDuration, maintenanceWindowTimeZone);
|
||||
final DeploymentRequestBuilder deploymentRequestBuilder = DeploymentManagement
|
||||
.deploymentRequest(savedTarget.getControllerId(), distributionSet.getId())
|
||||
.setMaintenance(maintenanceWindowSchedule, maintenanceWindowDuration, maintenanceWindowTimeZone);
|
||||
if (timeforced) {
|
||||
deploymentRequestBuilder.setActionType(ActionType.TIMEFORCED);
|
||||
}
|
||||
if (isMultiAssignmentsEnabled()) {
|
||||
deploymentRequestBuilder.setWeight(600);
|
||||
}
|
||||
final List<Target> updatedTargets = makeAssignment(deploymentRequestBuilder.build()).getAssignedEntity()
|
||||
.stream().map(Action::getTarget).collect(Collectors.toList());
|
||||
|
||||
if (inSync) {
|
||||
feedbackToByInSync(distributionSet);
|
||||
@@ -167,28 +185,6 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
|
||||
return updatedTargets.get(0);
|
||||
}
|
||||
|
||||
private List<Target> assignWithoutMaintenanceWindow(final DistributionSet distributionSet, final Target savedTarget,
|
||||
final boolean timeforced) {
|
||||
final List<Action> actions = timeforced
|
||||
? assignDistributionSet(distributionSet.getId(), savedTarget.getControllerId(), ActionType.TIMEFORCED)
|
||||
.getAssignedEntity()
|
||||
: assignDistributionSet(distributionSet, savedTarget).getAssignedEntity();
|
||||
return actions.stream().map(Action::getTarget).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<Target> assignWithMaintenanceWindow(final DistributionSet distributionSet, final Target savedTarget,
|
||||
final boolean timeforced, final String maintenanceWindowSchedule, final String maintenanceWindowDuration,
|
||||
final String maintenanceWindowTimeZone) {
|
||||
final List<Action> actions = timeforced
|
||||
? assignDistributionSetWithMaintenanceWindow(distributionSet.getId(), savedTarget.getControllerId(),
|
||||
ActionType.TIMEFORCED, maintenanceWindowSchedule, maintenanceWindowDuration,
|
||||
maintenanceWindowTimeZone).getAssignedEntity()
|
||||
: assignDistributionSetWithMaintenanceWindow(distributionSet.getId(), savedTarget.getControllerId(),
|
||||
maintenanceWindowSchedule, maintenanceWindowDuration, maintenanceWindowTimeZone)
|
||||
.getAssignedEntity();
|
||||
return actions.stream().map(Action::getTarget).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected DistributionSet createDistributionSet() {
|
||||
DistributionSet distributionSet = testdataFactory.createDistributionSet("");
|
||||
distributionSet = distributionSetManagement.update(entityFactory.distributionSet()
|
||||
@@ -314,4 +310,9 @@ public abstract class AbstractApiRestDocumentation extends AbstractRestIntegrati
|
||||
parameterWithName("q").description(ApiModelPropertiesGeneric.FIQL));
|
||||
}
|
||||
|
||||
protected boolean isMultiAssignmentsEnabled() {
|
||||
return Boolean.TRUE.equals(tenantConfigurationManagement
|
||||
.getConfigurationValue(TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED, Boolean.class).getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -109,6 +109,8 @@ public final class MgmtApiModelProperties {
|
||||
public static final String ROLLOUT_LINKS_GROUPS = "Link to retrieve the groups a rollout";
|
||||
public static final String ROLLOUT_START_ASYNC = "Start the rollout asynchronous";
|
||||
|
||||
public static final String RESULTING_ACTIONS_WEIGHT = "Weight of the resulting Actions";
|
||||
|
||||
public static final String UPDATE_STATUS = "Current update status of the target.";
|
||||
public static final String TARGET_ATTRIBUTES = "Target attributes.";
|
||||
|
||||
@@ -138,6 +140,8 @@ public final class MgmtApiModelProperties {
|
||||
|
||||
public static final String ACTION_LIST = "List of actions.";
|
||||
|
||||
public static final String ACTION_WEIGHT = "Weight of the action showing the importance of the update.";
|
||||
|
||||
public static final String IP_ADDRESS = "Last known IP address of the target. Only presented if IP address of the target itself is known (connected directly through DDI API).";
|
||||
|
||||
public static final String ADDRESS = "The last known address URI of the target. Includes information of the target is connected either directly (DDI) through HTTP or indirectly (DMF) through amqp.";
|
||||
@@ -188,6 +192,7 @@ public final class MgmtApiModelProperties {
|
||||
// request parameter
|
||||
public static final String FORCETIME = "Forcetime in milliseconds.";
|
||||
public static final String FORCE = "Force as boolean.";
|
||||
public static final String ASSIGNMENT_WEIGHT = "Importance of the assignment.";
|
||||
public static final String ASSIGNMENT_TYPE = "The type of the assignment.";
|
||||
public static final String TARGET_ASSIGNED = "The number of targets that have been assigned as part of this operation.";
|
||||
public static final String TARGET_ASSIGNED_ALREADY = "The number of targets which already had been the assignment.";
|
||||
|
||||
@@ -385,6 +385,9 @@ public class DistributionSetsDocumentationTest extends AbstractApiRestDocumentat
|
||||
.description(MgmtApiModelProperties.OFFLINE_UPDATE).optional()),
|
||||
requestFields(
|
||||
requestFieldWithPath("[].id").description(ApiModelPropertiesGeneric.ITEM_ID),
|
||||
requestFieldWithPathMandatoryInMultiAssignMode("[].weight")
|
||||
.description(MgmtApiModelProperties.ASSIGNMENT_WEIGHT)
|
||||
.type(JsonFieldType.NUMBER).attributes(key("value").value("0 - 1000")),
|
||||
optionalRequestFieldWithPath("[].forcetime")
|
||||
.description(MgmtApiModelProperties.FORCETIME),
|
||||
optionalRequestFieldWithPath("[].maintenanceWindow")
|
||||
|
||||
@@ -23,10 +23,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||
import org.eclipse.hawkbit.repository.builder.RolloutCreate;
|
||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorAction;
|
||||
@@ -52,6 +51,8 @@ import org.springframework.restdocs.payload.FieldDescriptor;
|
||||
import org.springframework.restdocs.payload.JsonFieldType;
|
||||
import org.springframework.restdocs.snippet.Snippet;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
@@ -80,7 +81,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
@Description("Handles the GET request of retrieving all rollouts. Required Permission: "
|
||||
+ SpPermission.READ_ROLLOUT)
|
||||
public void getRollouts() throws Exception {
|
||||
|
||||
enableMultiAssignments();
|
||||
createRolloutEntity();
|
||||
|
||||
mockMvc.perform(get(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING).accept(MediaTypes.HAL_JSON_VALUE))
|
||||
@@ -113,6 +114,8 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
|
||||
allFieldDescriptor.add(fieldWithPath(arrayPrefix + "id").description(ApiModelPropertiesGeneric.ITEM_ID));
|
||||
allFieldDescriptor.add(fieldWithPath(arrayPrefix + "name").description(ApiModelPropertiesGeneric.NAME));
|
||||
allFieldDescriptor.add(fieldWithPath(arrayPrefix + "weight")
|
||||
.description(MgmtApiModelProperties.RESULTING_ACTIONS_WEIGHT).type(JsonFieldType.NUMBER).optional());
|
||||
allFieldDescriptor.add(fieldWithPath(arrayPrefix + "deleted").description(ApiModelPropertiesGeneric.DELETED));
|
||||
allFieldDescriptor
|
||||
.add(fieldWithPath(arrayPrefix + "description").description(ApiModelPropertiesGeneric.DESCRPTION));
|
||||
@@ -159,7 +162,7 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
@Description("Handles the GET request of retrieving a single rollout. Required Permission: "
|
||||
+ SpPermission.READ_ROLLOUT)
|
||||
public void getRollout() throws Exception {
|
||||
|
||||
enableMultiAssignments();
|
||||
final Rollout rollout = createRolloutEntity();
|
||||
|
||||
mockMvc.perform(get(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}", rollout.getId())
|
||||
@@ -195,47 +198,47 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
.contentType(MediaTypes.HAL_JSON_UTF8).accept(MediaTypes.HAL_JSON_VALUE))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON_UTF8))
|
||||
.andDo(this.document.document(
|
||||
requestFields(requestFieldWithPath("name").description(ApiModelPropertiesGeneric.NAME),
|
||||
optionalRequestFieldWithPath("type").description(
|
||||
MgmtApiModelProperties.ROLLOUT_TYPE).attributes(
|
||||
key("value").value("['soft', 'forced', 'timeforced', 'downloadonly']")),
|
||||
requestFieldWithPath("distributionSetId")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_DS_ID),
|
||||
requestFieldWithPath("targetFilterQuery")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_FILTER_QUERY),
|
||||
requestFieldWithPath("amountGroups")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_AMOUNT_GROUPS),
|
||||
optionalRequestFieldWithPath("description")
|
||||
.description(ApiModelPropertiesGeneric.DESCRPTION),
|
||||
optionalRequestFieldWithPath("successCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION),
|
||||
optionalRequestFieldWithPath("successCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("successCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("successAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION),
|
||||
optionalRequestFieldWithPath("successAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_ACTION)
|
||||
.attributes(key("value").value("['nextgroup']")),
|
||||
optionalRequestFieldWithPath("successAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_EXP),
|
||||
optionalRequestFieldWithPath("errorCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION),
|
||||
optionalRequestFieldWithPath("errorCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("errorCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("errorAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION),
|
||||
optionalRequestFieldWithPath("errorAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_ACTION)
|
||||
.attributes(key("value").value("['pause']")),
|
||||
optionalRequestFieldWithPath("errorAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_EXP)),
|
||||
.andDo(this.document.document(requestFields(
|
||||
requestFieldWithPath("name").description(ApiModelPropertiesGeneric.NAME),
|
||||
requestFieldWithPathMandatoryInMultiAssignMode("weight").type(JsonFieldType.NUMBER)
|
||||
.description(MgmtApiModelProperties.RESULTING_ACTIONS_WEIGHT)
|
||||
.attributes(key("value").value("0 - 1000")),
|
||||
requestFieldWithPath("name").description(ApiModelPropertiesGeneric.NAME),
|
||||
optionalRequestFieldWithPath("type").description(MgmtApiModelProperties.ROLLOUT_TYPE)
|
||||
.attributes(key("value").value("['soft', 'forced', 'timeforced', 'downloadonly']")),
|
||||
requestFieldWithPath("distributionSetId").description(MgmtApiModelProperties.ROLLOUT_DS_ID),
|
||||
requestFieldWithPath("targetFilterQuery")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_FILTER_QUERY),
|
||||
requestFieldWithPath("amountGroups").description(MgmtApiModelProperties.ROLLOUT_AMOUNT_GROUPS),
|
||||
optionalRequestFieldWithPath("description").description(ApiModelPropertiesGeneric.DESCRPTION),
|
||||
optionalRequestFieldWithPath("successCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION),
|
||||
optionalRequestFieldWithPath("successCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("successCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("successAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION),
|
||||
optionalRequestFieldWithPath("successAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_ACTION)
|
||||
.attributes(key("value").value("['nextgroup']")),
|
||||
optionalRequestFieldWithPath("successAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_EXP),
|
||||
optionalRequestFieldWithPath("errorCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION),
|
||||
optionalRequestFieldWithPath("errorCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("errorCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("errorAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION),
|
||||
optionalRequestFieldWithPath("errorAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_ACTION)
|
||||
.attributes(key("value").value("['pause']")),
|
||||
optionalRequestFieldWithPath("errorAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_EXP)),
|
||||
|
||||
getRolloutResponseFields(false, true)));
|
||||
|
||||
@@ -283,77 +286,83 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaTypes.HAL_JSON_VALUE))
|
||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||
.andExpect(content().contentType(MediaTypes.HAL_JSON_UTF8))
|
||||
.andDo(this.document.document(requestFields(
|
||||
requestFieldWithPath("name").description(ApiModelPropertiesGeneric.NAME),
|
||||
requestFieldWithPath("distributionSetId").description(MgmtApiModelProperties.ROLLOUT_DS_ID),
|
||||
requestFieldWithPath("targetFilterQuery")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_FILTER_QUERY),
|
||||
optionalRequestFieldWithPath("description").description(ApiModelPropertiesGeneric.DESCRPTION),
|
||||
optionalRequestFieldWithPath("successCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION),
|
||||
optionalRequestFieldWithPath("successCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("successCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("successAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION),
|
||||
optionalRequestFieldWithPath("successAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_ACTION)
|
||||
.attributes(key("value").value("['nextgroup']")),
|
||||
optionalRequestFieldWithPath("successAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_EXP),
|
||||
optionalRequestFieldWithPath("errorCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION),
|
||||
optionalRequestFieldWithPath("errorCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("errorCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("errorAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION),
|
||||
optionalRequestFieldWithPath("errorAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_ACTION)
|
||||
.attributes(key("value").value("['pause']")),
|
||||
optionalRequestFieldWithPath("errorAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_EXP),
|
||||
|
||||
requestFieldWithPath("groups").description(MgmtApiModelProperties.ROLLOUT_GROUPS),
|
||||
requestFieldWithPath("groups[].name").description(ApiModelPropertiesGeneric.NAME),
|
||||
requestFieldWithPath("groups[].description").description(ApiModelPropertiesGeneric.DESCRPTION),
|
||||
optionalRequestFieldWithPath("groups[].targetFilterQuery")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_GROUP_FILTER_QUERY),
|
||||
optionalRequestFieldWithPath("groups[].targetPercentage")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_GROUP_TARGET_PERCENTAGE)
|
||||
.attributes(key("value").value("0..100")),
|
||||
optionalRequestFieldWithPath("groups[].successCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION),
|
||||
optionalRequestFieldWithPath("groups[].successCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("groups[].successCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("groups[].successAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION),
|
||||
optionalRequestFieldWithPath("groups[].successAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_ACTION)
|
||||
.attributes(key("value").value("['nextgroup']")),
|
||||
optionalRequestFieldWithPath("groups[].successAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_EXP),
|
||||
optionalRequestFieldWithPath("groups[].errorCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION),
|
||||
optionalRequestFieldWithPath("groups[].errorCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("groups[].errorCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("groups[].errorAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION),
|
||||
optionalRequestFieldWithPath("groups[].errorAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_ACTION)
|
||||
.attributes(key("value").value("['pause']")),
|
||||
optionalRequestFieldWithPath("groups[].errorAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_EXP)),
|
||||
.andDo(this.document.document(
|
||||
requestFields(requestFieldWithPath("name").description(ApiModelPropertiesGeneric.NAME),
|
||||
requestFieldWithPathMandatoryInMultiAssignMode("weight")
|
||||
.type(JsonFieldType.NUMBER)
|
||||
.description(MgmtApiModelProperties.RESULTING_ACTIONS_WEIGHT)
|
||||
.attributes(key("value").value("0 - 1000")),
|
||||
requestFieldWithPath("distributionSetId")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_DS_ID),
|
||||
requestFieldWithPath("targetFilterQuery")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_FILTER_QUERY),
|
||||
optionalRequestFieldWithPath("description")
|
||||
.description(ApiModelPropertiesGeneric.DESCRPTION),
|
||||
optionalRequestFieldWithPath("successCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION),
|
||||
optionalRequestFieldWithPath("successCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("successCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("successAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION),
|
||||
optionalRequestFieldWithPath("successAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_ACTION)
|
||||
.attributes(key("value").value("['nextgroup']")),
|
||||
optionalRequestFieldWithPath("successAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_EXP),
|
||||
optionalRequestFieldWithPath("errorCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION),
|
||||
optionalRequestFieldWithPath("errorCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("errorCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("errorAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION),
|
||||
optionalRequestFieldWithPath("errorAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_ACTION)
|
||||
.attributes(key("value").value("['pause']")),
|
||||
optionalRequestFieldWithPath("errorAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_EXP),
|
||||
requestFieldWithPath("groups").description(MgmtApiModelProperties.ROLLOUT_GROUPS),
|
||||
requestFieldWithPath("groups[].name").description(ApiModelPropertiesGeneric.NAME),
|
||||
requestFieldWithPath("groups[].description")
|
||||
.description(ApiModelPropertiesGeneric.DESCRPTION),
|
||||
optionalRequestFieldWithPath("groups[].targetFilterQuery")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_GROUP_FILTER_QUERY),
|
||||
optionalRequestFieldWithPath("groups[].targetPercentage")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_GROUP_TARGET_PERCENTAGE)
|
||||
.attributes(key("value").value("0..100")),
|
||||
optionalRequestFieldWithPath("groups[].successCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION),
|
||||
optionalRequestFieldWithPath("groups[].successCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("groups[].successCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("groups[].successAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION),
|
||||
optionalRequestFieldWithPath("groups[].successAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_ACTION)
|
||||
.attributes(key("value").value("['nextgroup']")),
|
||||
optionalRequestFieldWithPath("groups[].successAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_SUCCESS_ACTION_EXP),
|
||||
optionalRequestFieldWithPath("groups[].errorCondition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION),
|
||||
optionalRequestFieldWithPath("groups[].errorCondition.condition")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_CONDITION)
|
||||
.attributes(key("value").value("['threshold']")),
|
||||
optionalRequestFieldWithPath("groups[].errorCondition.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_CONDITION_EXP),
|
||||
optionalRequestFieldWithPath("groups[].errorAction")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION),
|
||||
optionalRequestFieldWithPath("groups[].errorAction.action")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_ACTION)
|
||||
.attributes(key("value").value("['pause']")),
|
||||
optionalRequestFieldWithPath("groups[].errorAction.expression")
|
||||
.description(MgmtApiModelProperties.ROLLOUT_ERROR_ACTION_EXP)),
|
||||
getRolloutResponseFields(false, true)));
|
||||
}
|
||||
|
||||
@@ -626,11 +635,13 @@ public class RolloutResourceDocumentationTest extends AbstractApiRestDocumentati
|
||||
|
||||
private Rollout createRolloutEntity() {
|
||||
testdataFactory.createTargets(20, "exampleTarget");
|
||||
final Rollout rollout = rolloutManagement.create(
|
||||
entityFactory.rollout().create().name("exampleRollout")
|
||||
.targetFilterQuery("controllerId==exampleTarget*").set(testdataFactory.createDistributionSet()),
|
||||
10, new RolloutGroupConditionBuilder().withDefaults()
|
||||
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10").build());
|
||||
final RolloutCreate rolloutCreate = entityFactory.rollout().create().name("exampleRollout")
|
||||
.targetFilterQuery("controllerId==exampleTarget*").set(testdataFactory.createDistributionSet());
|
||||
if (isMultiAssignmentsEnabled()) {
|
||||
rolloutCreate.weight(400);
|
||||
}
|
||||
final Rollout rollout = rolloutManagement.create(rolloutCreate, 10, new RolloutGroupConditionBuilder()
|
||||
.withDefaults().successCondition(RolloutGroupSuccessCondition.THRESHOLD, "10").build());
|
||||
|
||||
// Run here, because Scheduler is disabled during tests
|
||||
rolloutManagement.handleRollouts();
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.eclipse.hawkbit.rest.documentation.AbstractApiRestDocumentation;
|
||||
import org.eclipse.hawkbit.rest.documentation.ApiModelPropertiesGeneric;
|
||||
import org.eclipse.hawkbit.rest.documentation.MgmtApiModelProperties;
|
||||
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -183,15 +184,16 @@ public class TargetFilterQueriesResourceDocumentationTest extends AbstractApiRes
|
||||
@Test
|
||||
@Description("Handles the POST request of setting a distribution set for auto assignment within SP. Required Permission: CREATE_TARGET.")
|
||||
public void postAutoAssignDS() throws Exception {
|
||||
enableMultiAssignments();
|
||||
final TargetFilterQuery tfq = createTargetFilterQuery();
|
||||
final DistributionSet distributionSet = createDistributionSet();
|
||||
final String filterByDistSet = "{\"id\":\"" + distributionSet.getId() + "\", \"type\":\""
|
||||
+ MgmtActionType.SOFT.getName() + "\"}";
|
||||
final String autoAssignBody = new JSONObject().put("id", distributionSet.getId())
|
||||
.put("type", MgmtActionType.SOFT.getName()).put("weight", 200).toString();
|
||||
|
||||
this.mockMvc
|
||||
.perform(
|
||||
post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
|
||||
tfq.getId()).contentType(MediaType.APPLICATION_JSON).content(filterByDistSet))
|
||||
tfq.getId()).contentType(MediaType.APPLICATION_JSON).content(autoAssignBody.toString()))
|
||||
.andExpect(status().isOk()).andDo(MockMvcResultPrinter.print())
|
||||
.andDo(this.document.document(
|
||||
pathParameters(parameterWithName("targetFilterQueryId")
|
||||
@@ -199,7 +201,10 @@ public class TargetFilterQueriesResourceDocumentationTest extends AbstractApiRes
|
||||
requestFields(requestFieldWithPath("id").description(MgmtApiModelProperties.DS_ID),
|
||||
optionalRequestFieldWithPath("type")
|
||||
.description(MgmtApiModelProperties.ACTION_FORCE_TYPE)
|
||||
.attributes(key("value").value("['forced', 'soft', 'downloadonly']"))),
|
||||
.attributes(key("value").value("['forced', 'soft', 'downloadonly']")),
|
||||
requestFieldWithPathMandatoryInMultiAssignMode("weight")
|
||||
.description(MgmtApiModelProperties.RESULTING_ACTIONS_WEIGHT)
|
||||
.attributes(key("value").value("0 - 1000"))),
|
||||
getResponseFieldTargetFilterQuery(false)));
|
||||
}
|
||||
|
||||
@@ -227,6 +232,9 @@ public class TargetFilterQueriesResourceDocumentationTest extends AbstractApiRes
|
||||
fieldWithPath(arrayPrefix + "autoAssignActionType")
|
||||
.description(MgmtApiModelProperties.ACTION_FORCE_TYPE).type(JsonFieldType.STRING.toString())
|
||||
.attributes(key("value").value("['forced', 'soft', 'downloadonly']")),
|
||||
fieldWithPath(arrayPrefix + "autoAssignWeight")
|
||||
.description(MgmtApiModelProperties.RESULTING_ACTIONS_WEIGHT)
|
||||
.type(JsonFieldType.NUMBER.toString()),
|
||||
fieldWithPath(arrayPrefix + "createdAt").description(ApiModelPropertiesGeneric.CREATED_AT),
|
||||
fieldWithPath(arrayPrefix + "createdBy").description(ApiModelPropertiesGeneric.CREATED_BY),
|
||||
fieldWithPath(arrayPrefix + "lastModifiedAt").description(ApiModelPropertiesGeneric.LAST_MODIFIED_AT),
|
||||
@@ -235,7 +243,8 @@ public class TargetFilterQueriesResourceDocumentationTest extends AbstractApiRes
|
||||
.description(MgmtApiModelProperties.TARGET_FILTER_QUERY_LINK_AUTO_ASSIGN_DS));
|
||||
}
|
||||
|
||||
private String createTargetFilterQueryJson(final String name, final String query) throws JsonProcessingException {
|
||||
private String createTargetFilterQueryJson(final String name, final String query)
|
||||
throws JsonProcessingException {
|
||||
final Map<String, Object> target = new HashMap<>();
|
||||
target.put("name", name);
|
||||
target.put("query", query);
|
||||
@@ -249,6 +258,7 @@ public class TargetFilterQueriesResourceDocumentationTest extends AbstractApiRes
|
||||
|
||||
private TargetFilterQuery createTargetFilterQueryWithDS(final DistributionSet distributionSet) {
|
||||
final TargetFilterQuery targetFilterQuery = createTargetFilterQuery();
|
||||
return targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery.getId(), distributionSet.getId());
|
||||
return targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||
.updateAutoAssign(targetFilterQuery.getId()).ds(distributionSet.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
@Test
|
||||
@Description("Handles the GET request of retrieving the full action history of a specific target. Required Permission: READ_TARGET.")
|
||||
public void getActionsFromTarget() throws Exception {
|
||||
enableMultiAssignments();
|
||||
generateActionForTarget(targetId);
|
||||
|
||||
mockMvc.perform(
|
||||
@@ -229,12 +230,14 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
.description(MgmtApiModelProperties.ACTION_EXECUTION_STATUS)
|
||||
.attributes(key("value").value("['finished', 'pending']")),
|
||||
fieldWithPath("content[]._links").description(MgmtApiModelProperties.LINK_TO_ACTION),
|
||||
fieldWithPath("content[].id").description(MgmtApiModelProperties.ACTION_ID))));
|
||||
fieldWithPath("content[].id").description(MgmtApiModelProperties.ACTION_ID),
|
||||
fieldWithPath("content[].weight").description(MgmtApiModelProperties.ACTION_WEIGHT))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Handles the GET request of retrieving the full action history of a specific target with maintenance window. Required Permission: READ_TARGET.")
|
||||
public void getActionsFromTargetWithMaintenanceWindow() throws Exception {
|
||||
enableMultiAssignments();
|
||||
generateActionForTarget(targetId, true, false, getTestSchedule(2), getTestDuration(1), getTestTimeZone());
|
||||
|
||||
mockMvc.perform(
|
||||
@@ -262,6 +265,7 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
.attributes(key("value").value("['finished', 'pending']")),
|
||||
fieldWithPath("content[]._links").description(MgmtApiModelProperties.LINK_TO_ACTION),
|
||||
fieldWithPath("content[].id").description(MgmtApiModelProperties.ACTION_ID),
|
||||
fieldWithPath("content[].weight").description(MgmtApiModelProperties.ACTION_WEIGHT),
|
||||
fieldWithPath("content[].maintenanceWindow")
|
||||
.description(MgmtApiModelProperties.MAINTENANCE_WINDOW),
|
||||
fieldWithPath("content[].maintenanceWindow.schedule")
|
||||
@@ -317,6 +321,7 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
@Test
|
||||
@Description("Handles the GET request of retrieving a specific action on a specific target. Required Permission: READ_TARGET.")
|
||||
public void getActionFromTarget() throws Exception {
|
||||
enableMultiAssignments();
|
||||
final Action action = generateActionForTarget(targetId, true, true);
|
||||
assertThat(deploymentManagement.findAction(action.getId()).get().getActionType())
|
||||
.isEqualTo(ActionType.TIMEFORCED);
|
||||
@@ -330,6 +335,7 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
responseFields(fieldWithPath("createdBy").description(ApiModelPropertiesGeneric.CREATED_BY),
|
||||
fieldWithPath("createdAt").description(ApiModelPropertiesGeneric.CREATED_AT),
|
||||
fieldWithPath("id").description(MgmtApiModelProperties.ACTION_ID),
|
||||
fieldWithPath("weight").description(MgmtApiModelProperties.ACTION_WEIGHT),
|
||||
fieldWithPath("lastModifiedBy").description(ApiModelPropertiesGeneric.LAST_MODIFIED_BY)
|
||||
.type("String"),
|
||||
fieldWithPath("lastModifiedAt").description(ApiModelPropertiesGeneric.LAST_MODIFIED_AT)
|
||||
@@ -351,6 +357,7 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
@Test
|
||||
@Description("Handles the GET request of retrieving a specific action on a specific target. Required Permission: READ_TARGET.")
|
||||
public void getActionFromTargetWithMaintenanceWindow() throws Exception {
|
||||
enableMultiAssignments();
|
||||
final Action action = generateActionForTarget(targetId, true, true, getTestSchedule(2), getTestDuration(1),
|
||||
getTestTimeZone());
|
||||
|
||||
@@ -363,6 +370,7 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
responseFields(fieldWithPath("createdBy").description(ApiModelPropertiesGeneric.CREATED_BY),
|
||||
fieldWithPath("createdAt").description(ApiModelPropertiesGeneric.CREATED_AT),
|
||||
fieldWithPath("id").description(MgmtApiModelProperties.ACTION_ID),
|
||||
fieldWithPath("weight").description(MgmtApiModelProperties.ACTION_WEIGHT),
|
||||
fieldWithPath("lastModifiedBy").description(ApiModelPropertiesGeneric.LAST_MODIFIED_BY)
|
||||
.type("String"),
|
||||
fieldWithPath("lastModifiedAt").description(ApiModelPropertiesGeneric.LAST_MODIFIED_AT)
|
||||
@@ -514,6 +522,9 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
.description(MgmtApiModelProperties.OFFLINE_UPDATE).optional()),
|
||||
requestFields(
|
||||
requestFieldWithPath("id").description(ApiModelPropertiesGeneric.ITEM_ID),
|
||||
requestFieldWithPathMandatoryInMultiAssignMode("weight")
|
||||
.description(MgmtApiModelProperties.ASSIGNMENT_WEIGHT)
|
||||
.type(JsonFieldType.NUMBER).attributes(key("value").value("0 - 1000")),
|
||||
optionalRequestFieldWithPath("forcetime").description(MgmtApiModelProperties.FORCETIME),
|
||||
optionalRequestFieldWithPath("maintenanceWindow")
|
||||
.description(MgmtApiModelProperties.MAINTENANCE_WINDOW),
|
||||
@@ -537,12 +548,12 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
|
||||
final long forceTime = System.currentTimeMillis();
|
||||
final JSONArray body = new JSONArray();
|
||||
body.put(new JSONObject().put("id", sets.get(1).getId()).put("type", "timeforced")
|
||||
body.put(new JSONObject().put("id", sets.get(1).getId()).put("weight", 500).put("type", "timeforced")
|
||||
.put("forcetime", forceTime)
|
||||
.put("maintenanceWindow", new JSONObject().put("schedule", getTestSchedule(100))
|
||||
.put("duration", getTestDuration(10)).put("timezone", getTestTimeZone())))
|
||||
.toString();
|
||||
body.put(new JSONObject().put("id", sets.get(0).getId()).put("type", "forced"));
|
||||
body.put(new JSONObject().put("id", sets.get(0).getId()).put("type", "forced").put("weight", 800));
|
||||
|
||||
enableMultiAssignments();
|
||||
mockMvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/"
|
||||
@@ -555,6 +566,9 @@ public class TargetResourceDocumentationTest extends AbstractApiRestDocumentatio
|
||||
.description(MgmtApiModelProperties.OFFLINE_UPDATE).optional()),
|
||||
requestFields(
|
||||
requestFieldWithPath("[].id").description(ApiModelPropertiesGeneric.ITEM_ID),
|
||||
requestFieldWithPathMandatoryInMultiAssignMode("[].weight")
|
||||
.description(MgmtApiModelProperties.ASSIGNMENT_WEIGHT)
|
||||
.attributes(key("value").value("0 - 1000")),
|
||||
optionalRequestFieldWithPath("[].forcetime")
|
||||
.description(MgmtApiModelProperties.FORCETIME),
|
||||
optionalRequestFieldWithPath("[].maintenanceWindow")
|
||||
|
||||
Reference in New Issue
Block a user