diff --git a/hawkbit-rest/hawkbit-mgmt-resource/README.md b/hawkbit-rest/hawkbit-mgmt-resource/README.md index 3bad53d61..8f53ea7c4 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/README.md +++ b/hawkbit-rest/hawkbit-mgmt-resource/README.md @@ -1,6 +1,7 @@ -# Eclipse.IoT hawkBit - Mgmt Resource +# Eclipse.IoT hawkBit - Mgmt Resource -This is the server-side implementation of the hawkBit Mgmt API that is used to manage and monitor the HawkBit Update Server via HTTP. +This is the server-side implementation of the hawkBit Mgmt API that is used to manage and monitor the HawkBit Update +Server via HTTP. # Compile diff --git a/hawkbit-rest/hawkbit-mgmt-resource/pom.xml b/hawkbit-rest/hawkbit-mgmt-resource/pom.xml index 8e7f3e7e5..db434c444 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/pom.xml +++ b/hawkbit-rest/hawkbit-mgmt-resource/pom.xml @@ -9,108 +9,108 @@ SPDX-License-Identifier: EPL-2.0 --> - - 4.0.0 - - org.eclipse.hawkbit - hawkbit-rest-parent - ${revision} - - hawkbit-mgmt-resource - hawkBit :: REST :: Management Resources + + 4.0.0 + + org.eclipse.hawkbit + hawkbit-rest-parent + ${revision} + + hawkbit-mgmt-resource + hawkBit :: REST :: Management Resources - - - org.eclipse.hawkbit - hawkbit-repository-api - ${project.version} - - - org.eclipse.hawkbit - hawkbit-mgmt-api - ${project.version} - - - org.eclipse.hawkbit - hawkbit-rest-core - ${project.version} - - - org.springframework.plugin - spring-plugin-core - - - org.springframework - spring-context - - - jakarta.servlet - jakarta.servlet-api - provided - + + + org.eclipse.hawkbit + hawkbit-repository-api + ${project.version} + + + org.eclipse.hawkbit + hawkbit-mgmt-api + ${project.version} + + + org.eclipse.hawkbit + hawkbit-rest-core + ${project.version} + + + org.springframework.plugin + spring-plugin-core + + + org.springframework + spring-context + + + jakarta.servlet + jakarta.servlet-api + provided + - - - org.eclipse.hawkbit - hawkbit-repository-test - ${project.version} - test - - - org.eclipse.hawkbit - hawkbit-repository-jpa - ${project.version} - test - - - org.eclipse.hawkbit - hawkbit-rest-core - ${project.version} - tests - test - - - javax.el - javax.el-api - test - - - org.springframework.security - spring-security-config - test - - - org.eclipse.hawkbit - hawkbit-http-security - ${project.version} - test - - - org.springframework.boot - spring-boot-starter-json - test - - - org.springframework.boot - spring-boot-starter-test - test - - - org.springframework.security - spring-security-aspects - test - - - io.qameta.allure - allure-junit5 - test - - - org.springframework - spring-context-support - test - - + + + org.eclipse.hawkbit + hawkbit-repository-test + ${project.version} + test + + + org.eclipse.hawkbit + hawkbit-repository-jpa + ${project.version} + test + + + org.eclipse.hawkbit + hawkbit-rest-core + ${project.version} + tests + test + + + javax.el + javax.el-api + test + + + org.springframework.security + spring-security-config + test + + + org.eclipse.hawkbit + hawkbit-http-security + ${project.version} + test + + + org.springframework.boot + spring-boot-starter-json + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-aspects + test + + + io.qameta.allure + allure-junit5 + test + + + org.springframework + spring-context-support + test + + \ No newline at end of file diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionMapper.java index 1df95a931..e22cfd945 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionMapper.java @@ -31,11 +31,8 @@ public final class MgmtActionMapper { /** * Create a response for actions. * - * @param actions - * list of actions - * @param repMode - * the representation mode - * + * @param actions list of actions + * @param repMode the representation mode * @return the response */ public static List toResponse(final Collection actions, final MgmtRepresentationMode repMode) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResource.java index 419982d2d..c95ce0f45 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResource.java @@ -65,19 +65,19 @@ public class MgmtActionResource implements MgmtActionRestApi { @Override public ResponseEntity getAction(final Long actionId) { - final Action action = deploymentManagement.findAction(actionId) - .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); + final Action action = deploymentManagement.findAction(actionId) + .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); - return ResponseEntity.ok(MgmtActionMapper.toResponse(action, MgmtRepresentationMode.FULL)); + return ResponseEntity.ok(MgmtActionMapper.toResponse(action, MgmtRepresentationMode.FULL)); } private MgmtRepresentationMode getRepresentationModeFromString(final String representationModeParam) { return MgmtRepresentationMode.fromValue(representationModeParam) - .orElseGet(() -> { - // no need for a 400, just apply a safe fallback - log.warn("Received an invalid representation mode: {}", representationModeParam); - return MgmtRepresentationMode.COMPACT; - }); + .orElseGet(() -> { + // no need for a 400, just apply a safe fallback + log.warn("Received an invalid representation mode: {}", representationModeParam); + return MgmtRepresentationMode.COMPACT; + }); } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtApiConfiguration.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtApiConfiguration.java index 608f38a60..574ba4a00 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtApiConfiguration.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtApiConfiguration.java @@ -24,7 +24,7 @@ import org.springframework.stereotype.Controller; */ @Configuration @ComponentScan -@Import({RestConfiguration.class, OpenApiConfiguration.class}) +@Import({ RestConfiguration.class, OpenApiConfiguration.class }) @PropertySource("classpath:/hawkbit-mgmt-api-defaults.properties") public class MgmtApiConfiguration { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResource.java index ab922a247..e28088340 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResource.java @@ -26,8 +26,7 @@ public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi { /** * Default constructor * - * @param tenantAware - * tenantAware + * @param tenantAware tenantAware */ public MgmtBasicAuthResource(TenantAware tenantAware) { this.tenantAware = tenantAware; diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDeploymentRequestMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDeploymentRequestMapper.java index ef2b5d483..12240df09 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDeploymentRequestMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDeploymentRequestMapper.java @@ -21,17 +21,16 @@ import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder; * A mapper for assignment requests */ public final class MgmtDeploymentRequestMapper { + private MgmtDeploymentRequestMapper() { // Utility class } /** * Convert assignment information to an {@link DeploymentRequestBuilder} - * - * @param dsAssignment - * DS assignment information - * @param targetId - * target to assign the DS to + * + * @param dsAssignment DS assignment information + * @param targetId target to assign the DS to * @return resulting {@link DeploymentRequestBuilder} */ public static DeploymentRequestBuilder createAssignmentRequestBuilder( @@ -43,11 +42,9 @@ public final class MgmtDeploymentRequestMapper { /** * Convert assignment information to an {@link DeploymentRequestBuilder} - * - * @param targetAssignment - * target assignment information - * @param dsId - * DS to assign the target to + * + * @param targetAssignment target assignment information + * @param dsId DS to assign the target to * @return resulting {@link DeploymentRequestBuilder} */ public static DeploymentRequestBuilder createAssignmentRequestBuilder( diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java index 05d48d9df..f55985693 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java @@ -54,32 +54,6 @@ public final class MgmtDistributionSetMapper { return sets.stream().map(dsRest -> fromRequest(dsRest, entityFactory)).collect(Collectors.toList()); } - /** - * {@link MgmtDistributionSetRequestBodyPost} to {@link DistributionSet}. - * - * @param dsRest to convert - * @return converted {@link DistributionSet} - */ - private static DistributionSetCreate fromRequest(final MgmtDistributionSetRequestBodyPost dsRest, - final EntityFactory entityFactory) { - final List modules = new ArrayList<>(); - if (dsRest.getOs() != null) { - modules.add(dsRest.getOs().getId()); - } - if (dsRest.getApplication() != null) { - modules.add(dsRest.getApplication().getId()); - } - if (dsRest.getRuntime() != null) { - modules.add(dsRest.getRuntime().getId()); - } - if (dsRest.getModules() != null) { - dsRest.getModules().forEach(module -> modules.add(module.getId())); - } - return entityFactory.distributionSet().create().name(dsRest.getName()).version(dsRest.getVersion()) - .description(dsRest.getDescription()).type(dsRest.getType()).modules(modules) - .requiredMigrationStep(dsRest.getRequiredMigrationStep()); - } - static List fromRequestDsMetadata(final List metadata, final EntityFactory entityFactory) { if (metadata == null) { return Collections.emptyList(); @@ -122,7 +96,7 @@ public final class MgmtDistributionSetMapper { response.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getAssignedSoftwareModules(response.getDsId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null)) - .withRel(MgmtRestConstants.DISTRIBUTIONSET_V1_MODULE).expand()); + .withRel(MgmtRestConstants.DISTRIBUTIONSET_V1_MODULE).expand()); response.add(linkTo(methodOn(MgmtDistributionSetTypeRestApi.class) .getDistributionSetType(distributionSet.getType().getId())).withRel("type").expand()); @@ -130,7 +104,7 @@ public final class MgmtDistributionSetMapper { response.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getMetadata(response.getDsId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata") - .expand()); + .expand()); } static MgmtTargetAssignmentResponseBody toResponse(final DistributionSetAssignmentResult dsAssignmentResult) { @@ -186,4 +160,30 @@ public final class MgmtDistributionSetMapper { return sets.stream().map(MgmtDistributionSetMapper::toResponse).collect(Collectors.toList()); } + + /** + * {@link MgmtDistributionSetRequestBodyPost} to {@link DistributionSet}. + * + * @param dsRest to convert + * @return converted {@link DistributionSet} + */ + private static DistributionSetCreate fromRequest(final MgmtDistributionSetRequestBodyPost dsRest, + final EntityFactory entityFactory) { + final List modules = new ArrayList<>(); + if (dsRest.getOs() != null) { + modules.add(dsRest.getOs().getId()); + } + if (dsRest.getApplication() != null) { + modules.add(dsRest.getApplication().getId()); + } + if (dsRest.getRuntime() != null) { + modules.add(dsRest.getRuntime().getId()); + } + if (dsRest.getModules() != null) { + dsRest.getModules().forEach(module -> modules.add(module.getId())); + } + return entityFactory.distributionSet().create().name(dsRest.getName()).version(dsRest.getVersion()) + .description(dsRest.getDescription()).type(dsRest.getType()).modules(modules) + .requiredMigrationStep(dsRest.getRequiredMigrationStep()); + } } \ No newline at end of file diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java index 1a08be338..3c6e2b51d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java @@ -52,10 +52,10 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.DeploymentRequest; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; @@ -98,7 +98,7 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { private final SystemSecurityContext systemSecurityContext; private final DistributionSetInvalidationManagement distributionSetInvalidationManagement; - + private final TenantConfigHelper tenantConfigHelper; MgmtDistributionSetResource(final SoftwareModuleManagement softwareModuleManagement, diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java index f3d0845e3..8f94d9ecd 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java @@ -202,17 +202,6 @@ public class MgmtDistributionSetTagResource implements MgmtDistributionSetTagRes return ResponseEntity.ok().build(); } - private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) { - return distributionSetTagManagement.get(distributionsetTagId) - .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, distributionsetTagId)); - } - - private static List findDistributionSetIds( - final List assignedDistributionSetRequestBodies) { - return assignedDistributionSetRequestBodies.stream() - .map(MgmtAssignedDistributionSetRequestBody::getDistributionSetId).collect(Collectors.toList()); - } - @Override public ResponseEntity toggleTagAssignment( @PathVariable("distributionsetTagId") final Long distributionsetTagId, @@ -247,4 +236,15 @@ public class MgmtDistributionSetTagResource implements MgmtDistributionSetTagRes log.debug("Assigned DistributionSet {}", assignedDs.size()); return ResponseEntity.ok(MgmtDistributionSetMapper.toResponseDistributionSets(assignedDs)); } + + private static List findDistributionSetIds( + final List assignedDistributionSetRequestBodies) { + return assignedDistributionSetRequestBodies.stream() + .map(MgmtAssignedDistributionSetRequestBody::getDistributionSetId).collect(Collectors.toList()); + } + + private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) { + return distributionSetTagManagement.get(distributionsetTagId) + .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, distributionsetTagId)); + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java index da54788ba..0ffd305fa 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java @@ -31,7 +31,6 @@ import org.eclipse.hawkbit.rest.data.ResponseList; /** * A mapper which maps repository model to RESTful model representation and * back. - * */ final class MgmtDistributionSetTypeMapper { @@ -49,25 +48,6 @@ final class MgmtDistributionSetTypeMapper { return smTypesRest.stream().map(smRest -> fromRequest(entityFactory, smRest)).collect(Collectors.toList()); } - private static DistributionSetTypeCreate fromRequest(final EntityFactory entityFactory, - final MgmtDistributionSetTypeRequestBodyPost smsRest) { - return entityFactory.distributionSetType().create().key(smsRest.getKey()).name(smsRest.getName()) - .description(smsRest.getDescription()).colour(smsRest.getColour()) - .mandatory(getMandatoryModules(smsRest)).optional(getOptionalmodules(smsRest)); - } - - private static Collection getMandatoryModules(final MgmtDistributionSetTypeRequestBodyPost smsRest) { - return Optional.ofNullable(smsRest.getMandatorymodules()).map( - modules -> modules.stream().map(MgmtSoftwareModuleTypeAssigment::getId).collect(Collectors.toList())) - .orElse(Collections.emptyList()); - } - - private static Collection getOptionalmodules(final MgmtDistributionSetTypeRequestBodyPost smsRest) { - return Optional.ofNullable(smsRest.getOptionalmodules()).map( - modules -> modules.stream().map(MgmtSoftwareModuleTypeAssigment::getId).collect(Collectors.toList())) - .orElse(Collections.emptyList()); - } - static List toListResponse(final Collection types) { if (types == null) { return Collections.emptyList(); @@ -98,4 +78,23 @@ final class MgmtDistributionSetTypeMapper { .withRel(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULES).expand()); } + private static DistributionSetTypeCreate fromRequest(final EntityFactory entityFactory, + final MgmtDistributionSetTypeRequestBodyPost smsRest) { + return entityFactory.distributionSetType().create().key(smsRest.getKey()).name(smsRest.getName()) + .description(smsRest.getDescription()).colour(smsRest.getColour()) + .mandatory(getMandatoryModules(smsRest)).optional(getOptionalmodules(smsRest)); + } + + private static Collection getMandatoryModules(final MgmtDistributionSetTypeRequestBodyPost smsRest) { + return Optional.ofNullable(smsRest.getMandatorymodules()).map( + modules -> modules.stream().map(MgmtSoftwareModuleTypeAssigment::getId).collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } + + private static Collection getOptionalmodules(final MgmtDistributionSetTypeRequestBodyPost smsRest) { + return Optional.ofNullable(smsRest.getOptionalmodules()).map( + modules -> modules.stream().map(MgmtSoftwareModuleTypeAssigment::getId).collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } + } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResource.java index d21dedb14..65ee1b96a 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResource.java @@ -131,11 +131,6 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR .body(MgmtDistributionSetTypeMapper.toListResponse(createdSoftwareModules)); } - private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final Long distributionSetTypeId) { - return distributionSetTypeManagement.get(distributionSetTypeId) - .orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, distributionSetTypeId)); - } - @Override public ResponseEntity> getMandatoryModules( @PathVariable("distributionSetTypeId") final Long distributionSetTypeId) { @@ -219,6 +214,11 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR return ResponseEntity.ok().build(); } + private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final Long distributionSetTypeId) { + return distributionSetTypeManagement.get(distributionSetTypeId) + .orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, distributionSetTypeId)); + } + private SoftwareModuleType findSoftwareModuleTypeWithExceptionIfNotFound(final Long softwareModuleTypeId) { return softwareModuleTypeManagement.get(softwareModuleTypeId) diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java index 9b35b8b9d..adf8e4e4a 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadArtifactResource.java @@ -40,6 +40,7 @@ import org.springframework.web.context.WebApplicationContext; @RestController @Scope(value = WebApplicationContext.SCOPE_REQUEST) public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi { + @Autowired private SoftwareModuleManagement softwareModuleManagement; @@ -49,11 +50,8 @@ public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi /** * Handles the GET request for downloading an artifact. * - * @param softwareModuleId - * of the parent SoftwareModule - * @param artifactId - * of the related Artifact - * + * @param softwareModuleId of the parent SoftwareModule + * @param artifactId of the related Artifact * @return responseEntity with status ok if successful */ @Override diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRestModelMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRestModelMapper.java index 6bc2980f5..c34708e09 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRestModelMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRestModelMapper.java @@ -23,7 +23,6 @@ import org.eclipse.hawkbit.repository.model.Type; /** * A mapper which maps repository model to RESTful model representation and * back. - * */ public final class MgmtRestModelMapper { @@ -32,6 +31,82 @@ public final class MgmtRestModelMapper { } + /** + * Convert the given {@link MgmtActionType} into a corresponding repository + * {@link ActionType}. + * + * @param actionTypeRest the REST representation of the action type + * @return or the repository action type + */ + public static ActionType convertActionType(final MgmtActionType actionTypeRest) { + if (actionTypeRest == null) { + return null; + } + + switch (actionTypeRest) { + case SOFT: + return ActionType.SOFT; + case FORCED: + return ActionType.FORCED; + case TIMEFORCED: + return ActionType.TIMEFORCED; + case DOWNLOAD_ONLY: + return ActionType.DOWNLOAD_ONLY; + default: + throw new IllegalStateException("Action Type is not supported"); + } + } + + /** + * Converts the given repository {@link ActionType} into a corresponding + * {@link MgmtActionType}. + * + * @param actionType the repository representation of the action type + * @return or the REST action type + */ + public static MgmtActionType convertActionType(final ActionType actionType) { + if (actionType == null) { + return null; + } + + switch (actionType) { + case SOFT: + return MgmtActionType.SOFT; + case FORCED: + return MgmtActionType.FORCED; + case TIMEFORCED: + return MgmtActionType.TIMEFORCED; + case DOWNLOAD_ONLY: + return MgmtActionType.DOWNLOAD_ONLY; + default: + throw new IllegalStateException("Action Type is not supported"); + } + } + + /** + * Converts the given repository {@link CancelationType} into a + * corresponding {@link MgmtCancelationType}. + * + * @param cancelationType the repository representation of the cancellation type + * @return or the REST cancellation type + */ + public static CancelationType convertCancelationType(final MgmtCancelationType cancelationType) { + if (cancelationType == null) { + return null; + } + + switch (cancelationType) { + case SOFT: + return CancelationType.SOFT; + case FORCE: + return CancelationType.FORCE; + case NONE: + return CancelationType.NONE; + default: + throw new IllegalStateException("Action Cancelation Type is not supported"); + } + } + static void mapBaseToBase(final MgmtBaseEntity response, final TenantAwareBaseEntity base) { response.setCreatedBy(base.getCreatedBy()); response.setLastModifiedBy(base.getLastModifiedBy()); @@ -57,86 +132,4 @@ public final class MgmtRestModelMapper { response.setColour(base.getColour()); response.setDeleted(base.isDeleted()); } - - /** - * Convert the given {@link MgmtActionType} into a corresponding repository - * {@link ActionType}. - * - * @param actionTypeRest - * the REST representation of the action type - * - * @return or the repository action type - */ - public static ActionType convertActionType(final MgmtActionType actionTypeRest) { - if (actionTypeRest == null) { - return null; - } - - switch (actionTypeRest) { - case SOFT: - return ActionType.SOFT; - case FORCED: - return ActionType.FORCED; - case TIMEFORCED: - return ActionType.TIMEFORCED; - case DOWNLOAD_ONLY: - return ActionType.DOWNLOAD_ONLY; - default: - throw new IllegalStateException("Action Type is not supported"); - } - } - - /** - * Converts the given repository {@link ActionType} into a corresponding - * {@link MgmtActionType}. - * - * @param actionType - * the repository representation of the action type - * - * @return or the REST action type - */ - public static MgmtActionType convertActionType(final ActionType actionType) { - if (actionType == null) { - return null; - } - - switch (actionType) { - case SOFT: - return MgmtActionType.SOFT; - case FORCED: - return MgmtActionType.FORCED; - case TIMEFORCED: - return MgmtActionType.TIMEFORCED; - case DOWNLOAD_ONLY: - return MgmtActionType.DOWNLOAD_ONLY; - default: - throw new IllegalStateException("Action Type is not supported"); - } - } - - /** - * Converts the given repository {@link CancelationType} into a - * corresponding {@link MgmtCancelationType}. - * - * @param cancelationType - * the repository representation of the cancellation type - * - * @return or the REST cancellation type - */ - public static CancelationType convertCancelationType(final MgmtCancelationType cancelationType) { - if (cancelationType == null) { - return null; - } - - switch (cancelationType) { - case SOFT: - return CancelationType.SOFT; - case FORCE: - return CancelationType.FORCE; - case NONE: - return CancelationType.NONE; - default: - throw new IllegalStateException("Action Cancelation Type is not supported"); - } - } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java index 014e1060e..1fe391948 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java @@ -52,8 +52,6 @@ import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; /** * A mapper which maps repository model to RESTful model representation and * back. - * - * */ final class MgmtRolloutMapper { @@ -116,7 +114,7 @@ final class MgmtRolloutMapper { body.add(linkTo(methodOn(MgmtRolloutRestApi.class).getRolloutGroups(rollout.getId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null, null)).withRel("groups") - .expand()); + .expand()); final DistributionSet distributionSet = rollout.getDistributionSet(); body.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSet(distributionSet.getId())) diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java index 16c2b4dff..8a82dff65 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResource.java @@ -174,15 +174,6 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { return ResponseEntity.status(HttpStatus.CREATED).body(MgmtRolloutMapper.toResponseRollout(rollout, true)); } - private Optional isConfirmationRequiredForGroup(final MgmtRolloutGroup group, - final MgmtRolloutRestRequestBodyPost request) { - if (group.getConfirmationRequired() != null) { - return Optional.of(group.getConfirmationRequired()); - } else if (request.getConfirmationRequired() != null) { - return Optional.of(request.getConfirmationRequired()); - } - return Optional.empty(); - } @Override public ResponseEntity update( @@ -282,12 +273,6 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { tenantConfigHelper.isConfirmationFlowEnabled())); } - private void findRolloutOrThrowException(final Long rolloutId) { - if (!rolloutManagement.exists(rolloutId)) { - throw new EntityNotFoundException(Rollout.class, rolloutId); - } - } - @Override public ResponseEntity> getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId, @PathVariable("groupId") final Long groupId, @@ -349,4 +334,20 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi { }); } + private Optional isConfirmationRequiredForGroup(final MgmtRolloutGroup group, + final MgmtRolloutRestRequestBodyPost request) { + if (group.getConfirmationRequired() != null) { + return Optional.of(group.getConfirmationRequired()); + } else if (request.getConfirmationRequired() != null) { + return Optional.of(request.getConfirmationRequired()); + } + return Optional.empty(); + } + + private void findRolloutOrThrowException(final Long rolloutId) { + if (!rolloutManagement.exists(rolloutId)) { + throw new EntityNotFoundException(Rollout.class, rolloutId); + } + } + } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java index 5a110e9ab..5dc9584e2 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java @@ -48,13 +48,6 @@ import org.springframework.hateoas.Link; @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class MgmtSoftwareModuleMapper { - private static SoftwareModuleCreate fromRequest(final EntityFactory entityFactory, - final MgmtSoftwareModuleRequestBodyPost smsRest) { - return entityFactory.softwareModule().create().type(smsRest.getType()).name(smsRest.getName()) - .version(smsRest.getVersion()).description(smsRest.getDescription()).vendor(smsRest.getVendor()) - .encrypted(smsRest.isEncrypted()); - } - static List fromRequestSwMetadata(final EntityFactory entityFactory, final Long softwareModuleId, final Collection metadata) { if (metadata == null) { @@ -130,12 +123,12 @@ public final class MgmtSoftwareModuleMapper { response.add(linkTo( methodOn(MgmtSoftwareModuleTypeRestApi.class).getSoftwareModuleType(softwareModule.getType().getId())) - .withRel(MgmtRestConstants.SOFTWAREMODULE_V1_TYPE).expand()); + .withRel(MgmtRestConstants.SOFTWAREMODULE_V1_TYPE).expand()); response.add(linkTo(methodOn(MgmtSoftwareModuleResource.class).getMetadata(response.getModuleId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata") - .expand().expand()); + .expand().expand()); } static MgmtArtifact toResponse(final Artifact artifact) { @@ -158,7 +151,7 @@ public final class MgmtSoftwareModuleMapper { static void addLinks(final Artifact artifact, final MgmtArtifact response) { response.add(linkTo(methodOn(MgmtDownloadArtifactResource.class) .downloadArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withRel("download") - .expand()); + .expand()); } static void addLinks(final Artifact artifact, final MgmtArtifact response, @@ -170,4 +163,11 @@ public final class MgmtSoftwareModuleMapper { artifact.getId(), artifact.getSha1Hash())), ApiType.MGMT, null); urls.forEach(entry -> response.add(Link.of(entry.getRef()).withRel(entry.getRel()).expand())); } + + private static SoftwareModuleCreate fromRequest(final EntityFactory entityFactory, + final MgmtSoftwareModuleRequestBodyPost smsRest) { + return entityFactory.softwareModule().create().type(smsRest.getType()).name(smsRest.getName()) + .version(smsRest.getVersion()).description(smsRest.getDescription()).vendor(smsRest.getVendor()) + .encrypted(smsRest.isEncrypted()); + } } \ No newline at end of file diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java index 3d202e193..74da7ae27 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResource.java @@ -136,14 +136,6 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi { return ResponseEntity.ok(new ResponseList<>(response)); } - private static MgmtRepresentationMode parseRepresentationMode(final String representationModeParam) { - return MgmtRepresentationMode.fromValue(representationModeParam).orElseGet(() -> { - // no need for a 400, just apply a safe fallback - log.warn("Received an invalid representation mode: {}", representationModeParam); - return MgmtRepresentationMode.COMPACT; - }); - } - @Override @ResponseBody // Exception squid:S3655 - Optional access is checked in @@ -339,6 +331,14 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi { return ResponseEntity.status(HttpStatus.CREATED).body(MgmtSoftwareModuleMapper.toResponseSwMetadata(created)); } + private static MgmtRepresentationMode parseRepresentationMode(final String representationModeParam) { + return MgmtRepresentationMode.fromValue(representationModeParam).orElseGet(() -> { + // no need for a 400, just apply a safe fallback + log.warn("Received an invalid representation mode: {}", representationModeParam); + return MgmtRepresentationMode.COMPACT; + }); + } + private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId, final Long artifactId) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java index f5999c02b..3e601462d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java @@ -28,7 +28,6 @@ import org.eclipse.hawkbit.rest.data.ResponseList; /** * A mapper which maps repository model to RESTful model representation and * back. - * */ final class MgmtSoftwareModuleTypeMapper { @@ -46,13 +45,6 @@ final class MgmtSoftwareModuleTypeMapper { return smTypesRest.stream().map(smRest -> fromRequest(entityFactory, smRest)).collect(Collectors.toList()); } - private static SoftwareModuleTypeCreate fromRequest(final EntityFactory entityFactory, - final MgmtSoftwareModuleTypeRequestBodyPost smsRest) { - return entityFactory.softwareModuleType().create().key(smsRest.getKey()).name(smsRest.getName()) - .description(smsRest.getDescription()).colour(smsRest.getColour()) - .maxAssignments(smsRest.getMaxAssignments()); - } - static List toTypesResponse(final Collection types) { if (types == null) { return Collections.emptyList(); @@ -75,4 +67,11 @@ final class MgmtSoftwareModuleTypeMapper { return result; } + private static SoftwareModuleTypeCreate fromRequest(final EntityFactory entityFactory, + final MgmtSoftwareModuleTypeRequestBodyPost smsRest) { + return entityFactory.softwareModuleType().create().key(smsRest.getKey()).name(smsRest.getName()) + .description(smsRest.getDescription()).colour(smsRest.getColour()) + .maxAssignments(smsRest.getMaxAssignments()); + } + } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResource.java index 4773e9298..14efc83c2 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResource.java @@ -21,8 +21,6 @@ import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.OffsetBasedPageRequest; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.model.Artifact; -import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -37,7 +35,6 @@ import org.springframework.web.bind.annotation.RestController; /** * REST Resource handling for {@link SoftwareModuleType} CRUD operations. - * */ @RestController public class MgmtSoftwareModuleTypeResource implements MgmtSoftwareModuleTypeRestApi { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java index 6c201870f..189202d8c 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemManagementResource.java @@ -48,8 +48,7 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi /** * Deletes the tenant data of a given tenant. USE WITH CARE! * - * @param tenant - * to delete + * @param tenant to delete * @return HttpStatus.OK */ @Override @@ -79,19 +78,6 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi return ResponseEntity.ok(result); } - private static MgmtSystemTenantServiceUsage convertTenant(final TenantUsage tenant) { - final MgmtSystemTenantServiceUsage result = new MgmtSystemTenantServiceUsage(); - result.setTenantName(tenant.getTenantName()); - result.setActions(tenant.getActions()); - result.setArtifacts(tenant.getArtifacts()); - result.setOverallArtifactVolumeInBytes(tenant.getOverallArtifactVolumeInBytes()); - result.setTargets(tenant.getTargets()); - if (!tenant.getUsageData().isEmpty()) { - result.setUsageData(tenant.getUsageData()); - } - return result; - } - /** * Returns a list of all caches. * @@ -121,4 +107,17 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi cacheNames.forEach(cacheName -> cacheManager.getCache(cacheName).clear()); return ResponseEntity.ok(cacheNames); } + + private static MgmtSystemTenantServiceUsage convertTenant(final TenantUsage tenant) { + final MgmtSystemTenantServiceUsage result = new MgmtSystemTenantServiceUsage(); + result.setTenantName(tenant.getTenantName()); + result.setActions(tenant.getActions()); + result.setArtifacts(tenant.getArtifacts()); + result.setOverallArtifactVolumeInBytes(tenant.getOverallArtifactVolumeInBytes()); + result.setTargets(tenant.getTargets()); + if (!tenant.getUsageData().isEmpty()) { + result.setUsageData(tenant.getUsageData()); + } + return result; + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java index d463403c8..3df1e9568 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java @@ -69,7 +69,7 @@ final class MgmtTagMapper { response.add(linkTo(methodOn(MgmtTargetTagRestApi.class).getAssignedTargets(targetTag.getId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("assignedTargets") - .expand()); + .expand()); } @@ -106,7 +106,7 @@ final class MgmtTagMapper { response.add(linkTo(methodOn(MgmtDistributionSetTagRestApi.class).getAssignedDistributionSets( distributionSetTag.getId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)) - .withRel("assignedDistributionSets").expand()); + .withRel("assignedDistributionSets").expand()); } static List mapTagFromRequest(final EntityFactory entityFactory, diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java index e566b09bb..269f1949d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java @@ -20,7 +20,6 @@ import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtDistributionSetAutoA 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.MgmtDistributionSetRestApi; -import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetFilterQueryRestApi; import org.eclipse.hawkbit.repository.EntityFactory; @@ -29,13 +28,11 @@ 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.hateoas.Link; import org.springframework.util.CollectionUtils; /** * A mapper which maps repository model to RESTful model representation and * back. - * */ public final class MgmtTargetFilterQueryMapper { @@ -52,7 +49,7 @@ public final class MgmtTargetFilterQueryMapper { } static MgmtTargetFilterQuery toResponse(final TargetFilterQuery filter, final boolean confirmationFlowEnabled, - final boolean isReprentationFull) { + final boolean isReprentationFull) { final MgmtTargetFilterQuery targetRest = new MgmtTargetFilterQuery(); targetRest.setFilterId(filter.getId()); targetRest.setName(filter.getName()); @@ -78,9 +75,10 @@ public final class MgmtTargetFilterQueryMapper { linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withSelfRel().expand()); if (isReprentationFull && distributionSet != null) { targetRest.add( - linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSets(Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET), - Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, - "name==" + distributionSet.getName() + ";version==" + distributionSet.getVersion())).withRel("DS").expand()); + linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSets( + Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET), + Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, + "name==" + distributionSet.getName() + ";version==" + distributionSet.getVersion())).withRel("DS").expand()); } return targetRest; diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResource.java index cbb016d0e..8902b9202 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResource.java @@ -51,7 +51,7 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA private final TargetFilterQueryManagement filterManagement; private final EntityFactory entityFactory; - + private final TenantConfigHelper tenantConfigHelper; MgmtTargetFilterQueryResource(final TargetFilterQueryManagement filterManagement, final EntityFactory entityFactory, @@ -81,7 +81,6 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE_DEFAULT) String representationModeParam) { - final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); final Sort sorting = PagingUtility.sanitizeTargetFilterQuerySortParam(sortParam); @@ -141,6 +140,22 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA return ResponseEntity.ok().build(); } + @Override + public ResponseEntity getAssignedDistributionSet( + @PathVariable("filterId") final Long filterId) { + final TargetFilterQuery filter = findFilterWithExceptionIfNotFound(filterId); + final DistributionSet autoAssignDistributionSet = filter.getAutoAssignDistributionSet(); + + if (autoAssignDistributionSet == null) { + return ResponseEntity.noContent().build(); + } + + final MgmtDistributionSet response = MgmtDistributionSetMapper.toResponse(autoAssignDistributionSet); + MgmtDistributionSetMapper.addLinks(autoAssignDistributionSet, response); + + return ResponseEntity.ok(response); + } + @Override public ResponseEntity postAssignedDistributionSet( @PathVariable("filterId") final Long filterId, @@ -162,22 +177,6 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA return ResponseEntity.ok(response); } - @Override - public ResponseEntity getAssignedDistributionSet( - @PathVariable("filterId") final Long filterId) { - final TargetFilterQuery filter = findFilterWithExceptionIfNotFound(filterId); - final DistributionSet autoAssignDistributionSet = filter.getAutoAssignDistributionSet(); - - if (autoAssignDistributionSet == null) { - return ResponseEntity.noContent().build(); - } - - final MgmtDistributionSet response = MgmtDistributionSetMapper.toResponse(autoAssignDistributionSet); - MgmtDistributionSetMapper.addLinks(autoAssignDistributionSet, response); - - return ResponseEntity.ok(response); - } - @Override public ResponseEntity deleteAssignedDistributionSet(@PathVariable("filterId") final Long filterId) { filterManagement.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(null)); @@ -185,11 +184,6 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA return ResponseEntity.noContent().build(); } - private TargetFilterQuery findFilterWithExceptionIfNotFound(final Long filterId) { - return filterManagement.get(filterId) - .orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, filterId)); - } - private static MgmtRepresentationMode parseRepresentationMode(final String representationModeParam) { return MgmtRepresentationMode.fromValue(representationModeParam).orElseGet(() -> { // no need for a 400, just apply a safe fallback @@ -198,4 +192,9 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA }); } + private TargetFilterQuery findFilterWithExceptionIfNotFound(final Long filterId) { + return filterManagement.get(filterId) + .orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, filterId)); + } + } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index e2c63eca9..140eea89d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -59,7 +59,6 @@ import org.springframework.util.ObjectUtils; /** * A mapper which maps repository model to RESTful model representation and * back. - * */ public final class MgmtTargetMapper { @@ -70,8 +69,7 @@ public final class MgmtTargetMapper { /** * Add links to a target response. * - * @param response - * the target response + * @param response the target response */ public static void addTargetLinks(final MgmtTarget response) { response.add(linkTo(methodOn(MgmtTargetRestApi.class).getAssignedDistributionSet(response.getControllerId())) @@ -83,11 +81,11 @@ public final class MgmtTargetMapper { response.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionHistory(response.getControllerId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionFields.ID.getJpaEntityFieldName() + ":" + SortDirection.DESC, null)) - .withRel(MgmtRestConstants.TARGET_V1_ACTIONS).expand()); + .withRel(MgmtRestConstants.TARGET_V1_ACTIONS).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getMetadata(response.getControllerId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata") - .expand()); + .expand()); if (response.getTargetType() != null) { response.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getTargetType(response.getTargetType())) .withRel(MgmtRestConstants.TARGET_V1_ASSIGNED_TARGET_TYPE).expand()); @@ -115,24 +113,10 @@ public final class MgmtTargetMapper { return response; } - private static void addPollStatus(final Target target, final MgmtTarget targetRest, final Function pollStatusResolver) { - final PollStatus pollStatus = pollStatusResolver == null ? target.getPollStatus() : pollStatusResolver.apply(target); - if (pollStatus != null) { - final MgmtPollStatus pollStatusRest = new MgmtPollStatus(); - pollStatusRest.setLastRequestAt( - Date.from(pollStatus.getLastPollDate().atZone(ZoneId.systemDefault()).toInstant()).getTime()); - pollStatusRest.setNextExpectedRequestAt( - Date.from(pollStatus.getNextPollDate().atZone(ZoneId.systemDefault()).toInstant()).getTime()); - pollStatusRest.setOverdue(pollStatus.isOverdue()); - targetRest.setPollStatus(pollStatusRest); - } - } - /** * Create a response for targets. * - * @param targets - * list of targets + * @param targets list of targets * @return the response */ public static List toResponse(final Collection targets, final TenantConfigHelper configHelper) { @@ -148,11 +132,11 @@ public final class MgmtTargetMapper { /** * Create a response for target. * - * @param target - * the target + * @param target the target * @return the response */ - public static MgmtTarget toResponse(final Target target, final TenantConfigHelper configHelper, final Function pollStatusResolver) { + public static MgmtTarget toResponse(final Target target, final TenantConfigHelper configHelper, + final Function pollStatusResolver) { if (target == null) { return null; } @@ -215,12 +199,6 @@ public final class MgmtTargetMapper { .collect(Collectors.toList()); } - private static TargetCreate fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) { - return entityFactory.target().create().controllerId(targetRest.getControllerId()).name(targetRest.getName()) - .description(targetRest.getDescription()).securityToken(targetRest.getSecurityToken()) - .address(targetRest.getAddress()).targetType(targetRest.getTargetType()); - } - static List fromRequestTargetMetadata(final List metadata, final EntityFactory entityFactory) { if (metadata == null) { @@ -228,7 +206,7 @@ public final class MgmtTargetMapper { } return metadata.stream().map( - metadataRest -> entityFactory.generateTargetMetadata(metadataRest.getKey(), metadataRest.getValue())) + metadataRest -> entityFactory.generateTargetMetadata(metadataRest.getKey(), metadataRest.getValue())) .collect(Collectors.toList()); } @@ -241,7 +219,7 @@ public final class MgmtTargetMapper { return actionStatus.stream() .map(status -> toResponse(status, deploymentManagement.findMessagesByActionStatusId( - PageRequest.of(0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_MAX_LIMIT), status.getId()) + PageRequest.of(0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_MAX_LIMIT), status.getId()) .getContent())) .collect(Collectors.toList()); } @@ -317,7 +295,7 @@ public final class MgmtTargetMapper { result.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionStatusList(controllerId, action.getId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionStatusFields.ID.getJpaEntityFieldName() + ":" + SortDirection.DESC)) - .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS).expand()); + .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS).expand()); final Rollout rollout = action.getRollout(); if (rollout != null) { @@ -336,6 +314,36 @@ public final class MgmtTargetMapper { return actions.stream().map(action -> toResponse(targetId, action)).collect(Collectors.toList()); } + static MgmtMetadata toResponseTargetMetadata(final TargetMetadata metadata) { + final MgmtMetadata metadataRest = new MgmtMetadata(); + metadataRest.setKey(metadata.getKey()); + metadataRest.setValue(metadata.getValue()); + return metadataRest; + } + + static List toResponseTargetMetadata(final List metadata) { + return metadata.stream().map(MgmtTargetMapper::toResponseTargetMetadata).collect(Collectors.toList()); + } + + private static void addPollStatus(final Target target, final MgmtTarget targetRest, final Function pollStatusResolver) { + final PollStatus pollStatus = pollStatusResolver == null ? target.getPollStatus() : pollStatusResolver.apply(target); + if (pollStatus != null) { + final MgmtPollStatus pollStatusRest = new MgmtPollStatus(); + pollStatusRest.setLastRequestAt( + Date.from(pollStatus.getLastPollDate().atZone(ZoneId.systemDefault()).toInstant()).getTime()); + pollStatusRest.setNextExpectedRequestAt( + Date.from(pollStatus.getNextPollDate().atZone(ZoneId.systemDefault()).toInstant()).getTime()); + pollStatusRest.setOverdue(pollStatus.isOverdue()); + targetRest.setPollStatus(pollStatusRest); + } + } + + private static TargetCreate fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) { + return entityFactory.target().create().controllerId(targetRest.getControllerId()).name(targetRest.getName()) + .description(targetRest.getDescription()).securityToken(targetRest.getSecurityToken()) + .address(targetRest.getAddress()).targetType(targetRest.getTargetType()); + } + private static String getType(final Action action) { if (!action.isCancelingOrCanceled()) { return MgmtAction.ACTION_UPDATE; @@ -357,15 +365,4 @@ public final class MgmtTargetMapper { return result; } - - static MgmtMetadata toResponseTargetMetadata(final TargetMetadata metadata) { - final MgmtMetadata metadataRest = new MgmtMetadata(); - metadataRest.setKey(metadata.getKey()); - metadataRest.setValue(metadata.getValue()); - return metadataRest; - } - - static List toResponseTargetMetadata(final List metadata) { - return metadata.stream().map(MgmtTargetMapper::toResponseTargetMetadata).collect(Collectors.toList()); - } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java index ffa81d5b4..60e7d4b35 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResource.java @@ -74,7 +74,7 @@ import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController public class MgmtTargetResource implements MgmtTargetRestApi { - + private static final String ACTION_TARGET_MISSING_ASSIGN_WARN = "given action ({}) is not assigned to given target ({})."; private final TargetManagement targetManagement; @@ -163,14 +163,15 @@ public class MgmtTargetResource implements MgmtTargetRestApi { this.targetManagement.unassignType(targetId); // update target without targetType here ... updateTarget = this.targetManagement.update(entityFactory.target().update(targetId) - .name(targetRest.getName()).description(targetRest.getDescription()).address(targetRest.getAddress()) - .securityToken(targetRest.getSecurityToken()).requestAttributes(targetRest.getRequestAttributes())); + .name(targetRest.getName()).description(targetRest.getDescription()).address(targetRest.getAddress()) + .securityToken(targetRest.getSecurityToken()).requestAttributes(targetRest.getRequestAttributes())); } else { updateTarget = this.targetManagement.update( - entityFactory.target().update(targetId).name(targetRest.getName()).description(targetRest.getDescription()) - .address(targetRest.getAddress()).targetType(targetRest.getTargetType()).securityToken(targetRest.getSecurityToken()) - .requestAttributes(targetRest.getRequestAttributes())); + entityFactory.target().update(targetId).name(targetRest.getName()).description(targetRest.getDescription()) + .address(targetRest.getAddress()).targetType(targetRest.getTargetType()) + .securityToken(targetRest.getSecurityToken()) + .requestAttributes(targetRest.getRequestAttributes())); } @@ -278,6 +279,26 @@ public class MgmtTargetResource implements MgmtTargetRestApi { return ResponseEntity.noContent().build(); } + @Override + public ResponseEntity updateAction(@PathVariable("targetId") final String targetId, + @PathVariable("actionId") final Long actionId, @RequestBody final MgmtActionRequestBodyPut actionUpdate) { + + Action action = deploymentManagement.findAction(actionId) + .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); + if (!action.getTarget().getControllerId().equals(targetId)) { + log.warn(ACTION_TARGET_MISSING_ASSIGN_WARN, action.getId(), targetId); + return ResponseEntity.notFound().build(); + } + + if (MgmtActionType.FORCED != actionUpdate.getActionType()) { + throw new ValidationException("Resource supports only switch to FORCED."); + } + + action = deploymentManagement.forceTargetAction(actionId); + + return ResponseEntity.ok(MgmtTargetMapper.toResponseWithLinks(targetId, action)); + } + @Override public ResponseEntity> getActionStatusList( @PathVariable("targetId") final String targetId, @PathVariable("actionId") final Long actionId, @@ -370,31 +391,6 @@ public class MgmtTargetResource implements MgmtTargetRestApi { return ResponseEntity.ok(distributionSetRest); } - private Target findTargetWithExceptionIfNotFound(final String targetId) { - return targetManagement.getByControllerID(targetId) - .orElseThrow(() -> new EntityNotFoundException(Target.class, targetId)); - } - - @Override - public ResponseEntity updateAction(@PathVariable("targetId") final String targetId, - @PathVariable("actionId") final Long actionId, @RequestBody final MgmtActionRequestBodyPut actionUpdate) { - - Action action = deploymentManagement.findAction(actionId) - .orElseThrow(() -> new EntityNotFoundException(Action.class, actionId)); - if (!action.getTarget().getControllerId().equals(targetId)) { - log.warn(ACTION_TARGET_MISSING_ASSIGN_WARN, action.getId(), targetId); - return ResponseEntity.notFound().build(); - } - - if (MgmtActionType.FORCED != actionUpdate.getActionType()) { - throw new ValidationException("Resource supports only switch to FORCED."); - } - - action = deploymentManagement.forceTargetAction(actionId); - - return ResponseEntity.ok(MgmtTargetMapper.toResponseWithLinks(targetId, action)); - } - @Override public ResponseEntity> getTags(@PathVariable("targetId") String targetId) { final Set tags = targetManagement.getTagsByControllerId(targetId); @@ -473,14 +469,19 @@ public class MgmtTargetResource implements MgmtTargetRestApi { return new ResponseEntity<>(HttpStatus.OK); } - private R getNullIfEmpty(final T object, final Function extractMethod) { - return object == null ? null : extractMethod.apply(object); - } - @Override public ResponseEntity deactivateAutoConfirm(@PathVariable("targetId") final String targetId) { confirmationManagement.deactivateAutoConfirmation(targetId); return new ResponseEntity<>(HttpStatus.OK); } + private Target findTargetWithExceptionIfNotFound(final String targetId) { + return targetManagement.getByControllerID(targetId) + .orElseThrow(() -> new EntityNotFoundException(Target.class, targetId)); + } + + private R getNullIfEmpty(final T object, final Function extractMethod) { + return object == null ? null : extractMethod.apply(object); + } + } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java index 2e51ae81a..8acda6938 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java @@ -161,24 +161,6 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi { return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements())); } - @Override - public ResponseEntity toggleTagAssignment( - @PathVariable("targetTagId") final Long targetTagId, - @RequestBody final List assignedTargetRequestBodies) { - log.debug("Toggle Target assignment {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId); - - final TargetTag targetTag = findTargetTagById(targetTagId); - final TargetTagAssignmentResult assigmentResult = this.targetManagement - .toggleTagAssignment(findTargetControllerIds(assignedTargetRequestBodies), targetTag.getName()); - - final MgmtTargetTagAssigmentResult tagAssigmentResultRest = new MgmtTargetTagAssigmentResult(); - tagAssigmentResultRest.setAssignedTargets( - MgmtTargetMapper.toResponse(assigmentResult.getAssignedEntity(), tenantConfigHelper)); - tagAssigmentResultRest.setUnassignedTargets( - MgmtTargetMapper.toResponse(assigmentResult.getUnassignedEntity(), tenantConfigHelper)); - return ResponseEntity.ok(tagAssigmentResultRest); - } - @Override public ResponseEntity assignTarget(final Long targetTagId, final String controllerId) { log.debug("Assign target {} for target tag {}", controllerId, targetTagId); @@ -187,7 +169,8 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi { } @Override - public ResponseEntity assignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, final List controllerIds) { + public ResponseEntity assignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, + final List controllerIds) { log.debug("Assign {} targets for target tag {}", controllerIds.size(), targetTagId); if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) { this.targetManagement.assignTag(controllerIds, targetTagId); @@ -213,7 +196,8 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi { } @Override - public ResponseEntity unassignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, final List controllerIds) { + public ResponseEntity unassignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, + final List controllerIds) { log.debug("Unassign {} targets for target tag {}", controllerIds.size(), targetTagId); if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) { this.targetManagement.unassignTag(controllerIds, targetTagId); @@ -230,6 +214,24 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi { return ResponseEntity.ok().build(); } + @Override + public ResponseEntity toggleTagAssignment( + @PathVariable("targetTagId") final Long targetTagId, + @RequestBody final List assignedTargetRequestBodies) { + log.debug("Toggle Target assignment {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId); + + final TargetTag targetTag = findTargetTagById(targetTagId); + final TargetTagAssignmentResult assigmentResult = this.targetManagement + .toggleTagAssignment(findTargetControllerIds(assignedTargetRequestBodies), targetTag.getName()); + + final MgmtTargetTagAssigmentResult tagAssigmentResultRest = new MgmtTargetTagAssigmentResult(); + tagAssigmentResultRest.setAssignedTargets( + MgmtTargetMapper.toResponse(assigmentResult.getAssignedEntity(), tenantConfigHelper)); + tagAssigmentResultRest.setUnassignedTargets( + MgmtTargetMapper.toResponse(assigmentResult.getUnassignedEntity(), tenantConfigHelper)); + return ResponseEntity.ok(tagAssigmentResultRest); + } + @Override public ResponseEntity> assignTargetsByRequestBody(@PathVariable("targetTagId") final Long targetTagId, @RequestBody final List assignedTargetRequestBodies) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java index 03ce3aa0d..797264f0b 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java @@ -46,20 +46,6 @@ public final class MgmtTargetTypeMapper { .collect(Collectors.toList()); } - private static TargetTypeCreate fromRequest(final EntityFactory entityFactory, - final MgmtTargetTypeRequestBodyPost targetTypesRest) { - return entityFactory.targetType().create() - .name(targetTypesRest.getName()).description(targetTypesRest.getDescription()) - .key(targetTypesRest.getKey()).colour(targetTypesRest.getColour()) - .compatible(getDistributionSets(targetTypesRest)); - } - - private static Collection getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) { - return Optional.ofNullable(targetTypesRest.getCompatibledistributionsettypes()) - .map(ds -> ds.stream().map(MgmtDistributionSetTypeAssignment::getId).collect(Collectors.toList())) - .orElse(Collections.emptyList()); - } - static List toListResponse(final List types) { if (types == null) { return Collections.emptyList(); @@ -81,4 +67,18 @@ public final class MgmtTargetTypeMapper { result.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getCompatibleDistributionSets(result.getTypeId())) .withRel(MgmtRestConstants.TARGETTYPE_V1_DS_TYPES).expand()); } + + private static TargetTypeCreate fromRequest(final EntityFactory entityFactory, + final MgmtTargetTypeRequestBodyPost targetTypesRest) { + return entityFactory.targetType().create() + .name(targetTypesRest.getName()).description(targetTypesRest.getDescription()) + .key(targetTypesRest.getKey()).colour(targetTypesRest.getColour()) + .compatible(getDistributionSets(targetTypesRest)); + } + + private static Collection getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) { + return Optional.ofNullable(targetTypesRest.getCompatibledistributionsettypes()) + .map(ds -> ds.stream().map(MgmtDistributionSetTypeAssignment::getId).collect(Collectors.toList())) + .orElse(Collections.emptyList()); + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java index 7ac886b1f..c04a5bf75 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; @@ -19,6 +20,7 @@ import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; * back. */ public final class MgmtTenantManagementMapper { + public static String DEFAULT_DISTRIBUTION_SET_TYPE_KEY = "default.ds.type"; private MgmtTenantManagementMapper() { @@ -43,7 +45,7 @@ public final class MgmtTenantManagementMapper { restConfValue.setValue(defaultDistributionSetType); restConfValue.setGlobal(Boolean.FALSE); restConfValue.add(linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) - .withSelfRel().expand()); + .withSelfRel().expand()); return restConfValue; } } \ No newline at end of file diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java index 0c0f23beb..0dd81874d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResource.java @@ -14,7 +14,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue; @@ -45,7 +44,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi MgmtTenantManagementResource(final TenantConfigurationManagement tenantConfigurationManagement, final TenantConfigurationProperties tenantConfigurationProperties, - final SystemManagement systemManagement) { + final SystemManagement systemManagement) { this.tenantConfigurationManagement = tenantConfigurationManagement; this.tenantConfigurationProperties = tenantConfigurationProperties; this.systemManagement = systemManagement; @@ -64,7 +63,8 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi }); // Load and Add Default DistributionSetType - final MgmtSystemTenantConfigurationValue defaultDsTypeId = loadTenantConfigurationValueBy(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY); + final MgmtSystemTenantConfigurationValue defaultDsTypeId = loadTenantConfigurationValueBy( + MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY); tenantConfigurationValueMap.put(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY, defaultDsTypeId); // return combined TenantConfiguration and TenantMetadata @@ -72,24 +72,6 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi return ResponseEntity.ok(tenantConfigurationValueMap); } - @Override - public ResponseEntity getTenantConfigurationValue( - @PathVariable("keyName") final String keyName) { - return ResponseEntity.ok(loadTenantConfigurationValueBy(keyName)); - } - - private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(String keyName) { - - //Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response - MgmtSystemTenantConfigurationValue response; - if (isDefaultDistributionSetTypeKey(keyName)) { - response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId()); - } else { - response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, tenantConfigurationManagement.getConfigurationValue(keyName)); - } - return response; - } - @Override public ResponseEntity deleteTenantConfigurationValue(@PathVariable("keyName") final String keyName) { @@ -104,17 +86,23 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi return ResponseEntity.ok().build(); } + @Override + public ResponseEntity getTenantConfigurationValue( + @PathVariable("keyName") final String keyName) { + return ResponseEntity.ok(loadTenantConfigurationValueBy(keyName)); + } + @Override public ResponseEntity updateTenantConfigurationValue( @PathVariable("keyName") final String keyName, @RequestBody final MgmtSystemTenantConfigurationValueRequest configurationValueRest) { - Serializable configurationValue = configurationValueRest.getValue(); + Serializable configurationValue = configurationValueRest.getValue(); final MgmtSystemTenantConfigurationValue responseUpdatedValue; if (isDefaultDistributionSetTypeKey(keyName)) { responseUpdatedValue = updateDefaultDsType(configurationValue); } else { final TenantConfigurationValue updatedTenantConfigurationValue = tenantConfigurationManagement - .addOrUpdateConfiguration(keyName, configurationValueRest.getValue()); + .addOrUpdateConfiguration(keyName, configurationValueRest.getValue()); responseUpdatedValue = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, updatedTenantConfigurationValue); } @@ -126,7 +114,7 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi Map configurationValueMap) { boolean containsNull = configurationValueMap.keySet().stream() - .anyMatch(Objects::isNull); + .anyMatch(Objects::isNull); if (containsNull) { return ResponseEntity.badRequest().build(); @@ -152,30 +140,44 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi throw ex; } - List tenantConfigurationListUpdated = new java.util.ArrayList<>(tenantConfigurationValues.entrySet().stream() - .map(entry -> MgmtTenantManagementMapper.toResponseTenantConfigurationValue(entry.getKey(), entry.getValue())).toList()); + List tenantConfigurationListUpdated = new java.util.ArrayList<>( + tenantConfigurationValues.entrySet().stream() + .map(entry -> MgmtTenantManagementMapper.toResponseTenantConfigurationValue(entry.getKey(), entry.getValue())) + .toList()); if (updatedDefaultDsType != null) { tenantConfigurationListUpdated.add(updatedDefaultDsType); } - return ResponseEntity.ok(tenantConfigurationListUpdated); } - private MgmtSystemTenantConfigurationValue updateDefaultDsType(Serializable defaultDsType) { - long updateDefaultDsType; - try { - updateDefaultDsType = ((Number) defaultDsType).longValue(); - } catch (ClassCastException cce) { - throw new TenantConfigurationValidatorException(String.format( - "Default DistributionSetType Value Type is incorrect. Expected Long, received %s", defaultDsType.getClass().getName())); - } - systemManagement.updateTenantMetadata(updateDefaultDsType); - return MgmtTenantManagementMapper.toResponseDefaultDsType(updateDefaultDsType); - } private static boolean isDefaultDistributionSetTypeKey(String keyName) { return MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY.equals(keyName); } + private MgmtSystemTenantConfigurationValue loadTenantConfigurationValueBy(String keyName) { + + //Check if requested key is TenantConfiguration or TenantMetadata, load it and return it as rest response + MgmtSystemTenantConfigurationValue response; + if (isDefaultDistributionSetTypeKey(keyName)) { + response = MgmtTenantManagementMapper.toResponseDefaultDsType(systemManagement.getTenantMetadata().getDefaultDsType().getId()); + } else { + response = MgmtTenantManagementMapper.toResponseTenantConfigurationValue(keyName, + tenantConfigurationManagement.getConfigurationValue(keyName)); + } + return response; + } + + private MgmtSystemTenantConfigurationValue updateDefaultDsType(Serializable defaultDsType) { + long updateDefaultDsType; + try { + updateDefaultDsType = ((Number) defaultDsType).longValue(); + } catch (ClassCastException cce) { + throw new TenantConfigurationValidatorException(String.format( + "Default DistributionSetType Value Type is incorrect. Expected Long, received %s", defaultDsType.getClass().getName())); + } + systemManagement.updateTenantMetadata(updateDefaultDsType); + return MgmtTenantManagementMapper.toResponseDefaultDsType(updateDefaultDsType); + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java index 2809db5cf..a9f4fd068 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java @@ -30,9 +30,9 @@ import org.springframework.data.domain.Sort.Direction; /** * Utility class for for paged body generation. - * */ public final class PagingUtility { + /* * utility constructor private. */ diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResourceTest.java index b396d0767..2b01c16e6 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtActionResourceTest.java @@ -27,6 +27,10 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Step; +import io.qameta.allure.Story; import org.awaitility.Awaitility; import org.eclipse.hawkbit.mgmt.rest.api.MgmtActionRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode; @@ -39,11 +43,6 @@ import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; import org.junit.jupiter.api.Test; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Step; -import io.qameta.allure.Story; import org.springframework.test.web.servlet.ResultActions; /** @@ -66,6 +65,18 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { private static final String JSON_PATH_ACTION_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID; + @Test + @Description("Handles the GET request of retrieving a specific action.") + public void getAction() throws Exception { + getAction(false); + } + + @Test + @Description("Handles the GET request of retrieving a specific action with external reference.") + public void getActionExtRef() throws Exception { + getAction(true); + } + @Test @Description("Verifies that actions can be filtered based on action status.") void filterActionsByStatus() throws Exception { @@ -214,7 +225,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { final String rsqlDsId = "distributionSet.id==" + ds.getId(); mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlDsName) - .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) + .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(1))) .andExpect(jsonPath("size", equalTo(1))).andExpect(jsonPath("content.[0]._links.distributionset.name", equalTo(ds.getName() + ":" + ds.getVersion()))); @@ -258,14 +269,14 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { final String rsqlRolloutId = "rollout.id==" + rollout.getId(); mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlRolloutName) - .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) + .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(1))) .andExpect(jsonPath("size", equalTo(1))) .andExpect(jsonPath("content.[0]._links.target.name", equalTo(target1.getName()))).andExpect(jsonPath( "content.[0]._links.distributionset.name", equalTo(ds.getName() + ":" + ds.getVersion()))); mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlRolloutId) - .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) + .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(1))) .andExpect(jsonPath("size", equalTo(1))) .andExpect(jsonPath("content.[0]._links.target.name", equalTo(target1.getName()))).andExpect(jsonPath( @@ -292,18 +303,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { verifyResultsByTargetPropertyFilter(target, ds, rsqlTargetAddress); } - @Step - private void verifyResultsByTargetPropertyFilter(final Target target, final DistributionSet ds, - final String rsqlTargetFilter) throws Exception { - // pending status one result - mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlTargetFilter) - .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(1))) - .andExpect(jsonPath("size", equalTo(1))) - .andExpect(jsonPath("content.[0]._links.target.name", equalTo(target.getName()))).andExpect(jsonPath( - "content.[0]._links.distributionset.name", equalTo(ds.getName() + ":" + ds.getVersion()))); - } - @Test @Description("Verifies that all available actions are returned if the complete collection is requested.") void getActions() throws Exception { @@ -316,55 +315,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { getActions(true); } - private void getActions(final boolean withExternalRef ) throws Exception { - final String knownTargetId = "targetId"; - final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); - - final Action action0 = actions.get(0); - final Action action1 = actions.get(1); - - final List externalRefs = new ArrayList<>(2); - if (withExternalRef) { - externalRefs.add("extRef#123_0"); - externalRefs.add("extRef#123_1"); - controllerManagement.updateActionExternalRef(action0.getId(), externalRefs.get(0)); - controllerManagement.updateActionExternalRef(action1.getId(), externalRefs.get(1)); - } - - final ResultActions resultActions = - mvc.perform( - get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING,"ID:ASC")) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - // verify action 1 - .andExpect(jsonPath("content.[1].id", equalTo(action1.getId().intValue()))) - .andExpect(jsonPath("content.[1].type", equalTo("update"))) - .andExpect(jsonPath("content.[1].status", equalTo("pending"))) - .andExpect(jsonPath("content.[1].detailStatus", equalTo("running"))) - .andExpect(jsonPath("content.[1]._links.self.href", - equalTo(generateActionLink(knownTargetId, action1.getId())))) - - // verify action 0 - .andExpect(jsonPath("content.[0].id", equalTo(action0.getId().intValue()))) - .andExpect(jsonPath("content.[0].type", equalTo("cancel"))) - .andExpect(jsonPath("content.[0].status", equalTo("pending"))) - .andExpect(jsonPath("content.[1].detailStatus", equalTo("running"))) - .andExpect(jsonPath("content.[0]._links.self.href", - equalTo(generateActionLink(knownTargetId, action0.getId())))) - - // verify collection properties - .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) - .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) - .andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); - - if (withExternalRef) { - resultActions - .andExpect(jsonPath("content.[1].externalRef", equalTo(externalRefs.get(1)))) - .andExpect(jsonPath("content.[0].externalRef", equalTo(externalRefs.get(0)))); - } - } - @Test @Description("Verifies that a full representation of all actions is returned if the collection is requested for representation mode 'full'.") void getActionsFullRepresentation() throws Exception { @@ -374,8 +324,8 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { final Action action0 = actions.get(0); final Action action1 = actions.get(1); mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC") - .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC") + .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) // verify action 1 @@ -414,47 +364,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("content", hasSize(0))).andExpect(jsonPath("total", equalTo(0))); } - @Test - @Description("Handles the GET request of retrieving a specific action.") - public void getAction() throws Exception { - getAction(false); - } - - @Test - @Description("Handles the GET request of retrieving a specific action with external reference.") - public void getActionExtRef() throws Exception { - getAction(true); - } - - private void getAction(final boolean withExternalRef) throws Exception { - final String knownTargetId = "targetId"; - // prepare ds - final DistributionSet ds = testdataFactory.createDistributionSet(); - // rollout - final Target target = testdataFactory.createTarget(knownTargetId); - final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1, - "name==" + target.getName(), ds, "50", "5"); - rolloutManagement.start(rollout.getId()); - rolloutHandler.handleAll(); - - final List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) - .getContent(); - assertThat(actions).hasSize(1); - final String externalRef = "externalRef#123"; - if (withExternalRef) { - controllerManagement.updateActionExternalRef(actions.get(0).getId(), externalRef); - } - - final ResultActions resultActions = - mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "/{actionId}", actions.get(0).getId())) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - - if (withExternalRef) { - resultActions.andExpect(jsonPath("externalRef", equalTo(externalRef))); - } - } - @Test @Description("Verifies paging is respected as expected.") void getMultipleActionsWithPagingLimitRequestParameter() throws Exception { @@ -464,8 +373,8 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { // page 1: one entry final Action action0 = actions.get(0); mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) // verify action 0 @@ -484,10 +393,10 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { // page 2: one entry final Action action1 = actions.get(1); mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) // verify action 1 @@ -541,6 +450,110 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(status().isNotFound()); } + private static String generateActionLink(final String targetId, final Long actionId) { + return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetId + "/" + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId; + } + + private static String generateTargetLink(final String targetId) { + return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetId; + } + + private static String generateDistributionSetLink(final Action action) { + return "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + + action.getDistributionSet().getId(); + } + + @Step + private void verifyResultsByTargetPropertyFilter(final Target target, final DistributionSet ds, + final String rsqlTargetFilter) throws Exception { + // pending status one result + mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "?q=" + rsqlTargetFilter) + .param(MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, MgmtRepresentationMode.FULL.toString())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(1))) + .andExpect(jsonPath("size", equalTo(1))) + .andExpect(jsonPath("content.[0]._links.target.name", equalTo(target.getName()))).andExpect(jsonPath( + "content.[0]._links.distributionset.name", equalTo(ds.getName() + ":" + ds.getVersion()))); + } + + private void getActions(final boolean withExternalRef) throws Exception { + final String knownTargetId = "targetId"; + final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); + + final Action action0 = actions.get(0); + final Action action1 = actions.get(1); + + final List externalRefs = new ArrayList<>(2); + if (withExternalRef) { + externalRefs.add("extRef#123_0"); + externalRefs.add("extRef#123_1"); + controllerManagement.updateActionExternalRef(action0.getId(), externalRefs.get(0)); + controllerManagement.updateActionExternalRef(action1.getId(), externalRefs.get(1)); + } + + final ResultActions resultActions = + mvc.perform( + get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + // verify action 1 + .andExpect(jsonPath("content.[1].id", equalTo(action1.getId().intValue()))) + .andExpect(jsonPath("content.[1].type", equalTo("update"))) + .andExpect(jsonPath("content.[1].status", equalTo("pending"))) + .andExpect(jsonPath("content.[1].detailStatus", equalTo("running"))) + .andExpect(jsonPath("content.[1]._links.self.href", + equalTo(generateActionLink(knownTargetId, action1.getId())))) + + // verify action 0 + .andExpect(jsonPath("content.[0].id", equalTo(action0.getId().intValue()))) + .andExpect(jsonPath("content.[0].type", equalTo("cancel"))) + .andExpect(jsonPath("content.[0].status", equalTo("pending"))) + .andExpect(jsonPath("content.[1].detailStatus", equalTo("running"))) + .andExpect(jsonPath("content.[0]._links.self.href", + equalTo(generateActionLink(knownTargetId, action0.getId())))) + + // verify collection properties + .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) + .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) + .andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); + + if (withExternalRef) { + resultActions + .andExpect(jsonPath("content.[1].externalRef", equalTo(externalRefs.get(1)))) + .andExpect(jsonPath("content.[0].externalRef", equalTo(externalRefs.get(0)))); + } + } + + private void getAction(final boolean withExternalRef) throws Exception { + final String knownTargetId = "targetId"; + // prepare ds + final DistributionSet ds = testdataFactory.createDistributionSet(); + // rollout + final Target target = testdataFactory.createTarget(knownTargetId); + final Rollout rollout = testdataFactory.createRolloutByVariables("TestRollout", "TestDesc", 1, + "name==" + target.getName(), ds, "50", "5"); + rolloutManagement.start(rollout.getId()); + rolloutHandler.handleAll(); + + final List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) + .getContent(); + assertThat(actions).hasSize(1); + final String externalRef = "externalRef#123"; + if (withExternalRef) { + controllerManagement.updateActionExternalRef(actions.get(0).getId(), externalRef); + } + + final ResultActions resultActions = + mvc.perform(get(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "/{actionId}", actions.get(0).getId())) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + + if (withExternalRef) { + resultActions.andExpect(jsonPath("externalRef", equalTo(externalRef))); + } + } + private List generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) { return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null); } @@ -566,7 +579,7 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { } else { final List updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(), target.getControllerId(), schedule, duration, timezone).getAssignedEntity().stream() - .map(Action::getTarget).collect(Collectors.toList()); + .map(Action::getTarget).collect(Collectors.toList()); // 2nd update // sleep 10ms to ensure that we can sort by reportedAt Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) @@ -583,18 +596,4 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest { assertThat(actions).hasSize(2); return actions; } - - private static String generateActionLink(final String targetId, final Long actionId) { - return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId; - } - - private static String generateTargetLink(final String targetId) { - return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetId; - } - - private static String generateDistributionSetLink(final Action action) { - return "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" - + action.getDistributionSet().getId(); - } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResourceTest.java index ba2023ec8..92b898dc8 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtBasicAuthResourceTest.java @@ -9,6 +9,12 @@ */ package org.eclipse.hawkbit.mgmt.rest.resource; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; @@ -43,12 +49,6 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.util.Base64Utils; import org.springframework.web.context.WebApplicationContext; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - /** * Test for {@link MgmtBasicAuthResource}. */ @@ -75,14 +75,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @Story("Basic auth Userinfo Resource") public class MgmtBasicAuthResourceTest { - private static final String TEST_USER = "testUser"; - private static final String DEFAULT = "default"; - - @Autowired - MockMvc defaultMock; - @Autowired protected WebApplicationContext webApplicationContext; + @Autowired + MockMvc defaultMock; + private static final String TEST_USER = "testUser"; + private static final String DEFAULT = "default"; @Test @Description("Test of userinfo api with basic auth validation") @@ -100,7 +98,7 @@ public class MgmtBasicAuthResourceTest { @Description("Test of userinfo api with invalid basic auth fails") public void validateBasicAuthFailsWithInvalidCredentials() throws Exception { defaultMock.perform(get(MgmtRestConstants.AUTH_V1_REQUEST_MAPPING) - .header(HttpHeaders.AUTHORIZATION, getBasicAuth("wrongUser", "wrongSecret"))) + .header(HttpHeaders.AUTHORIZATION, getBasicAuth("wrongUser", "wrongSecret"))) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnauthorized()); } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtContentTypeTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtContentTypeTest.java index a6b11ab02..f6e0dcb20 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtContentTypeTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtContentTypeTest.java @@ -9,6 +9,15 @@ */ package org.eclipse.hawkbit.mgmt.rest.resource; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.Arrays; + import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; @@ -26,15 +35,6 @@ import org.springframework.hateoas.MediaTypes; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; -import java.util.Arrays; - -import static org.hamcrest.CoreMatchers.equalTo; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; - /** * With Spring Boot 2.2.x the default charset encoding became deprecated. In * hawkBit we want to keep the old behavior for now and still return the charset @@ -47,8 +47,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @Story("Response Content-Type") public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { - private DistributionSet ds; private final String dsName = "DS-ö"; + private DistributionSet ds; @BeforeEach public void setupBeforeTest() { @@ -58,8 +58,9 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Test @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJsonUtf8_woAccept() throws Exception { - final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) - .contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(MockMvcResultPrinter.print()) + final MvcResult result = mvc.perform( + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) + .contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()).andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); assertEquals(MediaTypes.HAL_JSON_VALUE + ";charset=UTF-8", getResponseHeaderContentType(result)); @@ -68,8 +69,9 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Test @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJsonUtf8_wAcceptJson() throws Exception { - final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) - .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON)) + final MvcResult result = mvc.perform( + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) + .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); @@ -79,8 +81,9 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Test @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJsonUtf8_wAcceptJsonUtf8() throws Exception { - final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) - .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON_UTF8)) + final MvcResult result = mvc.perform( + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) + .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON_UTF8)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); @@ -90,8 +93,9 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Test @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJsonUtf8_wAcceptHalJson() throws Exception { - final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) - .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaTypes.HAL_JSON)) + final MvcResult result = mvc.perform( + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) + .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaTypes.HAL_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); @@ -101,8 +105,9 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Test @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJson_woAccept() throws Exception { - final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + final MvcResult result = mvc.perform( + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); @@ -112,8 +117,9 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Test @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJson_wAcceptJson() throws Exception { - final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + final MvcResult result = mvc.perform( + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); @@ -124,8 +130,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJson_wAcceptJsonUtf8() throws Exception { final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) - .content(JsonBuilder.distributionSets(Arrays.asList(ds))).contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON_UTF8)).andDo(MockMvcResultPrinter.print()) + .content(JsonBuilder.distributionSets(Arrays.asList(ds))).contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON_UTF8)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); @@ -136,8 +142,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { @Description("The response of a POST request shall contain charset=utf-8") public void postDistributionSet_ContentTypeJson_wAcceptHalJson() throws Exception { final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) - .content(JsonBuilder.distributionSets(Arrays.asList(ds))).contentType(MediaType.APPLICATION_JSON) - .accept(MediaTypes.HAL_JSON)).andDo(MockMvcResultPrinter.print()) + .content(JsonBuilder.distributionSets(Arrays.asList(ds))).contentType(MediaType.APPLICATION_JSON) + .accept(MediaTypes.HAL_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()) .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java index 302d502cd..5666b1f9f 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java @@ -36,6 +36,11 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; +import com.jayway.jsonpath.JsonPath; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Step; +import io.qameta.allure.Story; import org.apache.commons.lang3.RandomStringUtils; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType; @@ -73,20 +78,15 @@ import org.springframework.data.domain.PageRequest; import org.springframework.hateoas.MediaTypes; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; - -import com.jayway.jsonpath.JsonPath; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Step; -import io.qameta.allure.Story; import org.springframework.util.Assert; - @Feature("Component Tests - Management API") @Story("Distribution Set Resource") public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTest { + @Autowired + ActionRepository actionRepository; + @Test @Description("This test verifies the call of all Software Modules that are assigned to a Distribution Set through the RESTful API.") public void getSoftwareModules() throws Exception { @@ -124,7 +124,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr } // post assignment mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON).content(smList.toString())).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON).content(smList.toString())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); // create targets and assign DisSet to target @@ -136,8 +136,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr } assignDistributionSet(disSet.getId(), knownTargetIds[0]); mvc.perform( - post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedTargets") - .contentType(MediaType.APPLICATION_JSON).content(list.toString())) + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedTargets") + .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1))) .andExpect(jsonPath("$.alreadyAssigned", equalTo(1))) @@ -146,7 +146,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr // try to delete the Software Module from DistSet that has been assigned // to the target. mvc.perform(delete(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM/" - + smIDs.get(0)).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + + smIDs.get(0)).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()) .andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.entityreadonly"))); } @@ -166,7 +166,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr } // post assignment mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON).content(smList.toString())).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON).content(smList.toString())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); // create Targets @@ -175,8 +175,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr // assign DisSet to target and test assignment assignDistributionSet(disSet.getId(), knownTargetIds[0]); mvc.perform( - post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedTargets") - .contentType(MediaType.APPLICATION_JSON).content(list.toString())) + post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedTargets") + .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1))) .andExpect(jsonPath("$.alreadyAssigned", equalTo(1))) @@ -188,7 +188,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr smList2.put(new JSONObject().put("id", sm2.getId())); mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON).content(smList2.toString())) + .contentType(MediaType.APPLICATION_JSON).content(smList2.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()) .andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.entityreadonly"))); } @@ -209,7 +209,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr // post assignment mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON).content(JsonBuilder.ids(smIDs))) + .contentType(MediaType.APPLICATION_JSON).content(JsonBuilder.ids(smIDs))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); // Test if size is 3 mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM")) @@ -226,17 +226,17 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr // post assignment final String jsonIDs = JsonBuilder.ids(moduleIDs.subList(0, maxSoftwareModules - smIDs.size())); mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON).content(jsonIDs)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON).content(jsonIDs)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); // test if size corresponds with quota mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() - + "/assignedSM?limit={limit}", maxSoftwareModules * 2)).andDo(MockMvcResultPrinter.print()) + + "/assignedSM?limit={limit}", maxSoftwareModules * 2)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(maxSoftwareModules))); // post one more to cause the quota to be exceeded mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON) - .content(JsonBuilder.ids(Collections.singletonList(moduleIDs.get(moduleIDs.size() - 1))))) + .contentType(MediaType.APPLICATION_JSON) + .content(JsonBuilder.ids(Collections.singletonList(moduleIDs.get(moduleIDs.size() - 1))))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -244,7 +244,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr // verify quota is also enforced for bulk uploads final DistributionSet disSet2 = testdataFactory.createDistributionSetWithNoSoftwareModules("Saturn", "4.0"); mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + disSet2.getId() + "/assignedSM") - .contentType(MediaType.APPLICATION_JSON).content(JsonBuilder.ids(moduleIDs))) + .contentType(MediaType.APPLICATION_JSON).content(JsonBuilder.ids(moduleIDs))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -267,10 +267,10 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.size", equalTo(amountOfSM))); // test the removal of all software modules one by one - for (final Iterator iter = set.getModules().iterator(); iter.hasNext();) { + for (final Iterator iter = set.getModules().iterator(); iter.hasNext(); ) { final Long smId = iter.next().getId(); mvc.perform(delete( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + set.getId() + "/assignedSM/" + smId)) + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + set.getId() + "/assignedSM/" + smId)) .andExpect(status().isOk()); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + set.getId() + "/assignedSM")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) @@ -290,7 +290,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), knownTargetIds[0]); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1))) .andExpect(jsonPath("$.alreadyAssigned", equalTo(1))) @@ -317,7 +317,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr } mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isOk()); // we just need to make sure that no error 500 is returned @@ -328,9 +328,10 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr public void createDsFromAlreadyMarkedAsDeletedType() throws Exception { final SoftwareModule softwareModule = testdataFactory.createSoftwareModule("exampleKey"); final DistributionSetType type = testdataFactory.findOrCreateDistributionSetType( - "testKey", "testType", Collections.singletonList(softwareModule.getType()), - Collections.singletonList(softwareModule.getType())); - final DistributionSet ds = testdataFactory.createDistributionSet("dsName", "dsVersion", type, Collections.singletonList(softwareModule)); + "testKey", "testType", Collections.singletonList(softwareModule.getType()), + Collections.singletonList(softwareModule.getType())); + final DistributionSet ds = testdataFactory.createDistributionSet("dsName", "dsVersion", type, + Collections.singletonList(softwareModule)); final Target target = testdataFactory.createTarget("exampleControllerId"); assignDistributionSet(ds, target); @@ -348,12 +349,12 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr //request for ds creation of type which is already marked as deleted - should return bad request final DistributionSet generated = testdataFactory.generateDistributionSet( - "stanTest", "2", reloaded, Collections.singletonList(softwareModule)); + "stanTest", "2", reloaded, Collections.singletonList(softwareModule)); final MvcResult mvcResult = mvc - .perform(post("/rest/v1/distributionsets") - .content(JsonBuilder.distributionSets(Arrays.asList(generated))) - .contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) + .perform(post("/rest/v1/distributionsets") + .content(JsonBuilder.distributionSets(Arrays.asList(generated))) + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()).andReturn(); final ExceptionInfo exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString()); @@ -426,7 +427,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), targets.get(0).getControllerId()); mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() - + "/assignedTargets?offline=true").contentType(MediaType.APPLICATION_JSON).content(list.toString())) + + "/assignedTargets?offline=true").contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(targets.size() - 1))) .andExpect(jsonPath("$.alreadyAssigned", equalTo(1))) .andExpect(jsonPath("$.total", equalTo(targets.size()))); @@ -449,7 +450,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), knownTargetIds[0]); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isBadRequest()); } @@ -466,7 +467,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), knownTargetIds[0]); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isBadRequest()); } @@ -484,7 +485,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), knownTargetIds[0]); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isOk()); } @@ -502,7 +503,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), knownTargetIds[0]); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isBadRequest()); } @@ -529,7 +530,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignDistributionSet(createdDs.getId(), knownTargetIds[0]); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(list.toString())) .andExpect(status().isOk()); } @@ -546,45 +547,12 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assignTargetJson.put(new JSONObject().put("id", "notexistingtarget").put("type", "forced")); mvc.perform(post( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets") .contentType(MediaType.APPLICATION_JSON).content(assignTargetJson.toString())) .andExpect(status().isOk()).andExpect(jsonPath("$.alreadyAssigned", equalTo(1))) .andExpect(jsonPath("$.assigned", equalTo(2))).andExpect(jsonPath("$.total", equalTo(3))); } - private JSONArray createTargetAndJsonArray(final String schedule, final String duration, final String timezone, - final String type, final Boolean confirmationRequired, final String... targetIds) throws Exception { - final JSONArray result = new JSONArray(); - for (final String targetId : targetIds) { - testdataFactory.createTarget(targetId); - - final JSONObject targetJsonObject = new JSONObject(); - result.put(targetJsonObject); - targetJsonObject.put("id", Long.valueOf(targetId)); - if (type != null) { - targetJsonObject.put("type", type); - } - - if (schedule != null || duration != null || timezone != null) { - final JSONObject maintenanceJsonObject = new JSONObject(); - if (schedule != null) { - maintenanceJsonObject.put("schedule", schedule); - } - if (duration != null) { - maintenanceJsonObject.put("duration", duration); - } - if (timezone != null) { - maintenanceJsonObject.put("timezone", timezone); - } - targetJsonObject.put("maintenanceWindow", maintenanceJsonObject); - } - if (confirmationRequired != null) { - targetJsonObject.put("confirmationRequired", confirmationRequired); - } - } - return result; - } - @Test @Description("Ensures that assigned targets of DS are returned as reflected by the repository.") public void getAssignedTargetsOfDistributionSet() throws Exception { @@ -608,8 +576,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .getAssignedEntity(); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + set.getId() + "/assignedTargets") - .param("offset", "1").param("limit", "2").param("sort", "name:DESC") - .param("q", "controllerId==target*").accept(MediaType.APPLICATION_JSON)) + .param("offset", "1").param("limit", "2").param("sort", "name:DESC") + .param("q", "controllerId==target*").accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)); @@ -621,7 +589,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr public void getAssignedTargetsOfDistributionSetIsEmpty() throws Exception { final DistributionSet createdDs = testdataFactory.createDistributionSet(); mvc.perform(get( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets")) + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/assignedTargets")) .andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(0))) .andExpect(jsonPath("$.total", equalTo(0))); } @@ -643,7 +611,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr Collections.singletonList("some message")); mvc.perform(get( - MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/installedTargets")) + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() + "/installedTargets")) .andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(1))) .andExpect(jsonPath("$.content[0].controllerId", equalTo(knownTargetId))); } @@ -681,7 +649,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("c").query("name==y")); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() - + "/autoAssignTargetFilters")).andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(1))) + + "/autoAssignTargetFilters")).andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(1))) .andExpect(jsonPath("$.content[0].name", equalTo(knownFilterName))); } @@ -709,7 +677,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final String invalidQuery = "unknownField=le=42"; mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() - + "/autoAssignTargetFilters").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, invalidQuery)) + + "/autoAssignTargetFilters").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, invalidQuery)) .andExpect(status().isBadRequest()); } @@ -723,7 +691,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr prepareTestFilters(filterNamePrefix, createdDs); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() - + "/autoAssignTargetFilters").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, query)) + + "/autoAssignTargetFilters").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, query)) .andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(2))) .andExpect(jsonPath("$.content[0].name", equalTo(filterNamePrefix + "1"))) .andExpect(jsonPath("$.content[1].name", equalTo(filterNamePrefix + "2"))); @@ -739,23 +707,10 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr prepareTestFilters(filterNamePrefix, createdDs); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() - + "/autoAssignTargetFilters").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, query)) + + "/autoAssignTargetFilters").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, query)) .andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(0))); } - private void prepareTestFilters(final String filterNamePrefix, final DistributionSet createdDs) { - // create target filter queries that should be found - 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")); - targetFilterQueryManagement - .create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "c").query("name==y")); - } - @Test @Description("Ensures that DS in repository are listed with proper paging properties.") public void getDistributionSetsWithoutAdditionalRequestParameters() throws Exception { @@ -775,7 +730,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final int limitSize = 1; createDistributionSetsAlphabetical(sets); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(sets))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -790,8 +745,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final int expectedSize = sets - offsetParam; createDistributionSetsAlphabetical(sets); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(sets))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(sets))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(sets))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -904,19 +859,19 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assertThat( JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/distributionsets/" + one.getId()); + .isEqualTo("http://localhost/rest/v1/distributionsets/" + one.getId()); assertThat(JsonPath.compile("[0]id").read(mvcResult.getResponse().getContentAsString()).toString()) .isEqualTo(String.valueOf(one.getId())); assertThat( JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/distributionsets/" + two.getId()); + .isEqualTo("http://localhost/rest/v1/distributionsets/" + two.getId()); assertThat(JsonPath.compile("[1]id").read(mvcResult.getResponse().getContentAsString()).toString()) .isEqualTo(String.valueOf(two.getId())); assertThat( JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/distributionsets/" + three.getId()); + .isEqualTo("http://localhost/rest/v1/distributionsets/" + three.getId()); assertThat(JsonPath.compile("[2]id").read(mvcResult.getResponse().getContentAsString()).toString()) .isEqualTo(String.valueOf(three.getId())); @@ -932,56 +887,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assertThat(three.getCreatedAt()).isGreaterThanOrEqualTo(current); } - @Step - private MvcResult executeMgmtTargetPost(final DistributionSet one, final DistributionSet two, - final DistributionSet three) throws Exception { - return mvc - .perform(post("/rest/v1/distributionsets") - .content(JsonBuilder.distributionSets(Arrays.asList(one, two, three))) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("[0]name", equalTo(one.getName()))) - .andExpect(jsonPath("[0]description", equalTo(one.getDescription()))) - .andExpect(jsonPath("[0]type", equalTo(standardDsType.getKey()))) - .andExpect(jsonPath("[0]createdBy", equalTo("uploadTester"))) - .andExpect(jsonPath("[0]version", equalTo(one.getVersion()))) - .andExpect(jsonPath("[0]complete", equalTo(Boolean.TRUE))) - .andExpect(jsonPath("[0]requiredMigrationStep", equalTo(one.isRequiredMigrationStep()))) - .andExpect(jsonPath("[0].modules.[?(@.type=='" + runtimeType.getKey() + "')].id", - contains(one.findFirstModuleByType(runtimeType).get().getId().intValue()))) - .andExpect(jsonPath("[0].modules.[?(@.type=='" + appType.getKey() + "')].id", - contains(one.findFirstModuleByType(appType).get().getId().intValue()))) - .andExpect(jsonPath("[0].modules.[?(@.type=='" + osType.getKey() + "')].id", - contains(one.findFirstModuleByType(osType).get().getId().intValue()))) - .andExpect(jsonPath("[1]name", equalTo(two.getName()))) - .andExpect(jsonPath("[1]description", equalTo(two.getDescription()))) - .andExpect(jsonPath("[1]complete", equalTo(Boolean.TRUE))) - .andExpect(jsonPath("[1]type", equalTo(standardDsType.getKey()))) - .andExpect(jsonPath("[1]createdBy", equalTo("uploadTester"))) - .andExpect(jsonPath("[1]version", equalTo(two.getVersion()))) - .andExpect(jsonPath("[1].modules.[?(@.type=='" + runtimeType.getKey() + "')].id", - contains(two.findFirstModuleByType(runtimeType).get().getId().intValue()))) - .andExpect(jsonPath("[1].modules.[?(@.type=='" + appType.getKey() + "')].id", - contains(two.findFirstModuleByType(appType).get().getId().intValue()))) - .andExpect(jsonPath("[1].modules.[?(@.type=='" + osType.getKey() + "')].id", - contains(two.findFirstModuleByType(osType).get().getId().intValue()))) - .andExpect(jsonPath("[1]requiredMigrationStep", equalTo(two.isRequiredMigrationStep()))) - .andExpect(jsonPath("[2]name", equalTo(three.getName()))) - .andExpect(jsonPath("[2]description", equalTo(three.getDescription()))) - .andExpect(jsonPath("[2]complete", equalTo(Boolean.TRUE))) - .andExpect(jsonPath("[2]type", equalTo(standardDsType.getKey()))) - .andExpect(jsonPath("[2]createdBy", equalTo("uploadTester"))) - .andExpect(jsonPath("[2]version", equalTo(three.getVersion()))) - .andExpect(jsonPath("[2].modules.[?(@.type=='" + runtimeType.getKey() + "')].id", - contains(three.findFirstModuleByType(runtimeType).get().getId().intValue()))) - .andExpect(jsonPath("[2].modules.[?(@.type=='" + appType.getKey() + "')].id", - contains(three.findFirstModuleByType(appType).get().getId().intValue()))) - .andExpect(jsonPath("[2].modules.[?(@.type=='" + osType.getKey() + "')].id", - contains(three.findFirstModuleByType(osType).get().getId().intValue()))) - .andExpect(jsonPath("[2]requiredMigrationStep", equalTo(three.isRequiredMigrationStep()))).andReturn(); - } - @Test @Description("Ensures that DS deletion request to API is reflected by the repository.") public void deleteUnassignedistributionSet() throws Exception { @@ -1046,7 +951,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .put("deleted", true).toString(); mvc.perform(put("/rest/v1/distributionsets/{dsId}", set.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.version", equalTo("anotherVersion"))) .andExpect(jsonPath("$.requiredMigrationStep", equalTo(true))) @@ -1061,54 +966,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assertThat(setupdated.isDeleted()).isEqualTo(false); } - @Test - @Description("Tests the lock. It is verified that the distribution set can be marked as locked through update operation.") - void lockDistributionSet() throws Exception { - // prepare test data - assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(0); - - final DistributionSet set = testdataFactory.createDistributionSet("one"); - assertThat(distributionSetManagement.count()).isEqualTo(1); - assertThat(set.isLocked()).as("Created distribution set should not be locked").isFalse(); - - // lock - final String body = new JSONObject().put("locked", true).toString(); - mvc.perform(put("/rest/v1/distributionsets/{dsId}", set.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.locked", equalTo(true))); - - final DistributionSet updatedSet = distributionSetManagement.get(set.getId()).get(); - assertThat(updatedSet.isLocked()).isEqualTo(true); - } - - @Test - @Description("Tests the unlock.") - void unlockDistributionSet() throws Exception { - // prepare test data - assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(0); - - final DistributionSet set = testdataFactory.createDistributionSet("one"); - assertThat(distributionSetManagement.count()).isEqualTo(1); - distributionSetManagement.lock(set.getId()); - assertThat(distributionSetManagement.get(set.getId()) - .orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, set.getId())).isLocked()) - .as("Distribution set should be locked") - .isTrue(); - - // unlock - final String body = new JSONObject().put("locked", false).toString(); - mvc.perform(put("/rest/v1/distributionsets/{dsId}", set.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.locked", equalTo(false))); - - final DistributionSet updatedSet = distributionSetManagement.get(set.getId()).get(); - assertThat(updatedSet.isLocked()).isEqualTo(false); - } - @Test @Description("Ensures that DS property update on requiredMigrationStep fails if DS is assigned to a target.") public void updateRequiredMigrationStepFailsIfDistributionSetisInUse() throws Exception { @@ -1122,8 +979,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr assertThat(distributionSetManagement.count()).isEqualTo(1); mvc.perform(put("/rest/v1/distributionsets/{dsId}", set.getId()) - .content("{\"version\":\"anotherVersion\",\"requiredMigrationStep\":\"true\"}") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content("{\"version\":\"anotherVersion\",\"requiredMigrationStep\":\"true\"}") + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()); final DistributionSet setupdated = distributionSetManagement.get(set.getId()).get(); @@ -1154,23 +1011,23 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr // bad request - bad content mvc.perform(post("/rest/v1/distributionsets").content("sdfjsdlkjfskdjf".getBytes()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final DistributionSet missingName = entityFactory.distributionSet().create().build(); mvc.perform(post("/rest/v1/distributionsets").content(JsonBuilder.distributionSets(Arrays.asList(missingName))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final DistributionSet toLongName = testdataFactory .generateDistributionSet(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1)); mvc.perform(post("/rest/v1/distributionsets").content(JsonBuilder.distributionSets(Arrays.asList(toLongName))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); // unsupported media type mvc.perform(post("/rest/v1/distributionsets").content(JsonBuilder.distributionSets(sets)) - .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnsupportedMediaType()); // not allowed methods @@ -1201,7 +1058,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr metaData1.put(new JSONObject().put("key", knownKey2).put("value", knownValue2)); mvc.perform(post("/rest/v1/distributionsets/{dsId}/metadata", testDS.getId()).accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON).content(metaData1.toString())) + .contentType(MediaType.APPLICATION_JSON).content(metaData1.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("[0]key", equalTo(knownKey1))).andExpect(jsonPath("[0]value", equalTo(knownValue1))) @@ -1225,7 +1082,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr } mvc.perform(post("/rest/v1/distributionsets/{dsId}/metadata", testDS.getId()).accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON).content(metaData2.toString())) + .contentType(MediaType.APPLICATION_JSON).content(metaData2.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()); // verify that the number of meta data entries has not changed @@ -1250,8 +1107,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final JSONObject jsonObject = new JSONObject().put("key", knownKey).put("value", updateValue); mvc.perform(put("/rest/v1/distributionsets/{dsId}/metadata/{key}", testDS.getId(), knownKey) - .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON) - .content(jsonObject.toString())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON) + .content(jsonObject.toString())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(updateValue))); @@ -1318,7 +1175,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final String knownValuePrefix = "knownValue"; final DistributionSet testDS = testdataFactory.createDistributionSet("one"); for (int index = 0; index < totalMetadata; index++) { - distributionSetManagement.createMetaData(testDS.getId(), List.of(entityFactory.generateDsMetadata(knownKeyPrefix + index, knownValuePrefix + index))); + distributionSetManagement.createMetaData(testDS.getId(), + List.of(entityFactory.generateDsMetadata(knownKeyPrefix + index, knownValuePrefix + index))); } mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/metadata", @@ -1344,7 +1202,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr } mvc.perform(get("/rest/v1/distributionsets/{dsId}/metadata?offset=" + offsetParam + "&limit=" + limitParam, - testDS.getId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + testDS.getId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("size", equalTo(limitParam))).andExpect(jsonPath("total", equalTo(totalMetadata))) .andExpect(jsonPath("content[0].key", equalTo("knownKey0"))) .andExpect(jsonPath("content[0].value", equalTo("knownValue0"))); @@ -1402,7 +1260,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final String rsqlFindTargetId1 = "controllerId==1"; mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + createdDs.getId() - + "/assignedTargets?q=" + rsqlFindTargetId1).contentType(MediaType.APPLICATION_JSON)) + + "/assignedTargets?q=" + rsqlFindTargetId1).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()).andExpect(jsonPath("total", equalTo(1))) .andExpect(jsonPath("size", equalTo(1))).andExpect(jsonPath("content[0].controllerId", equalTo("1"))); } @@ -1427,17 +1285,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .andExpect(jsonPath("content[0].value", equalTo("knownValue1"))); } - private Set createDistributionSetsAlphabetical(final int amount) { - char character = 'a'; - final Set created = new HashSet<>(amount); - for (int index = 0; index < amount; index++) { - final String str = String.valueOf(character); - created.add(testdataFactory.createDistributionSet(str)); - character++; - } - return created; - } - @Test @Description("Ensures that multi target assignment through API is reflected by the repository in the case of " + "DOWNLOAD_ONLY.") @@ -1451,7 +1298,7 @@ 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()) + .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))); @@ -1460,8 +1307,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .as("Five targets in repository have DS assigned").hasSize(5); } - @Autowired - ActionRepository actionRepository; @ParameterizedTest @MethodSource("confirmationOptions") @Description("Ensures that confirmation option is considered in assignment request.") @@ -1478,7 +1323,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr final JSONArray list = createTargetAndJsonArray(null, null, null, null, confirmationRequired, targetId); mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", createdDs.getId()) - .contentType(MediaType.APPLICATION_JSON).content(list.toString())).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON).content(list.toString())).andExpect(status().isOk()) .andExpect(jsonPath("$.assigned", equalTo(1))).andExpect(jsonPath("$.alreadyAssigned", equalTo(0))) .andExpect(jsonPath("$.total", equalTo(1))); @@ -1495,11 +1340,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr }); } - private static Stream confirmationOptions() { - return Stream.of(Arguments.of(true, true), Arguments.of(true, false), Arguments.of(false, true), - Arguments.of(false, false), Arguments.of(true, null), Arguments.of(false, null)); - } - @Test @Description("A request for assigning a target multiple times results in a Bad Request when multiassignment is disabled.") public void multiAssignmentRequestNotAllowedIfDisabled() throws Exception { @@ -1511,7 +1351,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr body.put(getAssignmentObject(targetId, MgmtActionType.FORCED)); mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(body.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); } @@ -1526,7 +1366,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr body.put(getAssignmentObject(targetId, MgmtActionType.FORCED)); mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(body.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(1))); } @@ -1545,7 +1385,7 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr enableMultiAssignments(); mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(body.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(body.length()))); } @@ -1561,15 +1401,15 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .put(getAssignmentObject(targetId, MgmtActionType.FORCED, Action.WEIGHT_MIN - 1)); mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyValide.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); enableMultiAssignments(); mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyInvalide.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .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()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); final List actions = deploymentManagement.findActionsAll(PAGE).get().collect(Collectors.toList()); @@ -1591,7 +1431,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr rolloutManagement.start(rollout.getId()); rolloutHandler.handleAll(); - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/rollouts", ds1.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/rollouts", ds1.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("rollouts.READY", equalTo(1))) @@ -1600,7 +1441,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .andExpect(jsonPath("actions").doesNotExist()) .andExpect(jsonPath("totalAutoAssignments").doesNotExist()); - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/rollouts", ds2.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/rollouts", ds2.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("rollouts").doesNotExist()) @@ -1621,7 +1463,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr rolloutManagement.start(rollout.getId()); rolloutHandler.handleAll(); - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/actions", ds1.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/actions", ds1.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("actions.RUNNING", equalTo(4))) @@ -1629,7 +1472,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("totalAutoAssignments").doesNotExist()); - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/actions", ds2.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/actions", ds2.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("rollouts").doesNotExist()) @@ -1645,19 +1489,23 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr DistributionSet ds2 = testdataFactory.createDistributionSet("DS2"); targetFilterQueryManagement.create( - entityFactory.targetFilterQuery().create().name("test filter 1").autoAssignDistributionSet(ds1.getId()).query("name==targets*")); + entityFactory.targetFilterQuery().create().name("test filter 1").autoAssignDistributionSet(ds1.getId()) + .query("name==targets*")); targetFilterQueryManagement.create( - entityFactory.targetFilterQuery().create().name("test filter 2").autoAssignDistributionSet(ds1.getId()).query("name==targets*")); + entityFactory.targetFilterQuery().create().name("test filter 2").autoAssignDistributionSet(ds1.getId()) + .query("name==targets*")); - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds1.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds1.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("totalAutoAssignments", equalTo(2))) .andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("actions").doesNotExist()); - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("rollouts").doesNotExist()) @@ -1674,15 +1522,16 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr DistributionSet ds2 = testdataFactory.createDistributionSet("DS2"); targetFilterQueryManagement.create( - entityFactory.targetFilterQuery().create().name("test filter 1").autoAssignDistributionSet(ds1.getId()).query("name==autoAssignments*")); + entityFactory.targetFilterQuery().create().name("test filter 1").autoAssignDistributionSet(ds1.getId()) + .query("name==autoAssignments*")); Rollout rollout = testdataFactory.createRolloutByVariables("rollout", "description", 1, "name==targets*", ds1, "50", "5", false); rolloutManagement.start(rollout.getId()); rolloutHandler.handleAll(); - - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics", ds1.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics", ds1.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("totalAutoAssignments", equalTo(1))) @@ -1691,8 +1540,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .andExpect(jsonPath("rollouts.RUNNING", equalTo(1))) .andExpect(jsonPath("rollouts.total", equalTo(1))); - - mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType(MediaType.APPLICATION_JSON)) + mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType( + MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("rollouts").doesNotExist()) @@ -1700,7 +1549,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .andExpect(jsonPath("totalAutoAssignments").doesNotExist()); } - @Test @Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments, stops rollouts and cancels assignments") public void invalidateDistributionSet() throws Exception { @@ -1733,4 +1581,164 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr .getContent().get(0).getStatus()).isEqualTo(Status.CANCELING); } } + + @Test + @Description("Tests the lock. It is verified that the distribution set can be marked as locked through update operation.") + void lockDistributionSet() throws Exception { + // prepare test data + assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(0); + + final DistributionSet set = testdataFactory.createDistributionSet("one"); + assertThat(distributionSetManagement.count()).isEqualTo(1); + assertThat(set.isLocked()).as("Created distribution set should not be locked").isFalse(); + + // lock + final String body = new JSONObject().put("locked", true).toString(); + mvc.perform(put("/rest/v1/distributionsets/{dsId}", set.getId()).content(body) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.locked", equalTo(true))); + + final DistributionSet updatedSet = distributionSetManagement.get(set.getId()).get(); + assertThat(updatedSet.isLocked()).isEqualTo(true); + } + + @Test + @Description("Tests the unlock.") + void unlockDistributionSet() throws Exception { + // prepare test data + assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(0); + + final DistributionSet set = testdataFactory.createDistributionSet("one"); + assertThat(distributionSetManagement.count()).isEqualTo(1); + distributionSetManagement.lock(set.getId()); + assertThat(distributionSetManagement.get(set.getId()) + .orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, set.getId())).isLocked()) + .as("Distribution set should be locked") + .isTrue(); + + // unlock + final String body = new JSONObject().put("locked", false).toString(); + mvc.perform(put("/rest/v1/distributionsets/{dsId}", set.getId()).content(body) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.locked", equalTo(false))); + + final DistributionSet updatedSet = distributionSetManagement.get(set.getId()).get(); + assertThat(updatedSet.isLocked()).isEqualTo(false); + } + + private static Stream confirmationOptions() { + return Stream.of(Arguments.of(true, true), Arguments.of(true, false), Arguments.of(false, true), + Arguments.of(false, false), Arguments.of(true, null), Arguments.of(false, null)); + } + + private JSONArray createTargetAndJsonArray(final String schedule, final String duration, final String timezone, + final String type, final Boolean confirmationRequired, final String... targetIds) throws Exception { + final JSONArray result = new JSONArray(); + for (final String targetId : targetIds) { + testdataFactory.createTarget(targetId); + + final JSONObject targetJsonObject = new JSONObject(); + result.put(targetJsonObject); + targetJsonObject.put("id", Long.valueOf(targetId)); + if (type != null) { + targetJsonObject.put("type", type); + } + + if (schedule != null || duration != null || timezone != null) { + final JSONObject maintenanceJsonObject = new JSONObject(); + if (schedule != null) { + maintenanceJsonObject.put("schedule", schedule); + } + if (duration != null) { + maintenanceJsonObject.put("duration", duration); + } + if (timezone != null) { + maintenanceJsonObject.put("timezone", timezone); + } + targetJsonObject.put("maintenanceWindow", maintenanceJsonObject); + } + if (confirmationRequired != null) { + targetJsonObject.put("confirmationRequired", confirmationRequired); + } + } + return result; + } + + private void prepareTestFilters(final String filterNamePrefix, final DistributionSet createdDs) { + // create target filter queries that should be found + 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")); + targetFilterQueryManagement + .create(entityFactory.targetFilterQuery().create().name(filterNamePrefix + "c").query("name==y")); + } + + @Step + private MvcResult executeMgmtTargetPost(final DistributionSet one, final DistributionSet two, + final DistributionSet three) throws Exception { + return mvc + .perform(post("/rest/v1/distributionsets") + .content(JsonBuilder.distributionSets(Arrays.asList(one, two, three))) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("[0]name", equalTo(one.getName()))) + .andExpect(jsonPath("[0]description", equalTo(one.getDescription()))) + .andExpect(jsonPath("[0]type", equalTo(standardDsType.getKey()))) + .andExpect(jsonPath("[0]createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("[0]version", equalTo(one.getVersion()))) + .andExpect(jsonPath("[0]complete", equalTo(Boolean.TRUE))) + .andExpect(jsonPath("[0]requiredMigrationStep", equalTo(one.isRequiredMigrationStep()))) + .andExpect(jsonPath("[0].modules.[?(@.type=='" + runtimeType.getKey() + "')].id", + contains(one.findFirstModuleByType(runtimeType).get().getId().intValue()))) + .andExpect(jsonPath("[0].modules.[?(@.type=='" + appType.getKey() + "')].id", + contains(one.findFirstModuleByType(appType).get().getId().intValue()))) + .andExpect(jsonPath("[0].modules.[?(@.type=='" + osType.getKey() + "')].id", + contains(one.findFirstModuleByType(osType).get().getId().intValue()))) + .andExpect(jsonPath("[1]name", equalTo(two.getName()))) + .andExpect(jsonPath("[1]description", equalTo(two.getDescription()))) + .andExpect(jsonPath("[1]complete", equalTo(Boolean.TRUE))) + .andExpect(jsonPath("[1]type", equalTo(standardDsType.getKey()))) + .andExpect(jsonPath("[1]createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("[1]version", equalTo(two.getVersion()))) + .andExpect(jsonPath("[1].modules.[?(@.type=='" + runtimeType.getKey() + "')].id", + contains(two.findFirstModuleByType(runtimeType).get().getId().intValue()))) + .andExpect(jsonPath("[1].modules.[?(@.type=='" + appType.getKey() + "')].id", + contains(two.findFirstModuleByType(appType).get().getId().intValue()))) + .andExpect(jsonPath("[1].modules.[?(@.type=='" + osType.getKey() + "')].id", + contains(two.findFirstModuleByType(osType).get().getId().intValue()))) + .andExpect(jsonPath("[1]requiredMigrationStep", equalTo(two.isRequiredMigrationStep()))) + .andExpect(jsonPath("[2]name", equalTo(three.getName()))) + .andExpect(jsonPath("[2]description", equalTo(three.getDescription()))) + .andExpect(jsonPath("[2]complete", equalTo(Boolean.TRUE))) + .andExpect(jsonPath("[2]type", equalTo(standardDsType.getKey()))) + .andExpect(jsonPath("[2]createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("[2]version", equalTo(three.getVersion()))) + .andExpect(jsonPath("[2].modules.[?(@.type=='" + runtimeType.getKey() + "')].id", + contains(three.findFirstModuleByType(runtimeType).get().getId().intValue()))) + .andExpect(jsonPath("[2].modules.[?(@.type=='" + appType.getKey() + "')].id", + contains(three.findFirstModuleByType(appType).get().getId().intValue()))) + .andExpect(jsonPath("[2].modules.[?(@.type=='" + osType.getKey() + "')].id", + contains(three.findFirstModuleByType(osType).get().getId().intValue()))) + .andExpect(jsonPath("[2]requiredMigrationStep", equalTo(three.isRequiredMigrationStep()))).andReturn(); + } + + private Set createDistributionSetsAlphabetical(final int amount) { + char character = 'a'; + final Set created = new HashSet<>(amount); + for (int index = 0; index < amount; index++) { + final String str = String.valueOf(character); + created.add(testdataFactory.createDistributionSet(str)); + character++; + } + return created; + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java index 3bc45f2e1..536052c46 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java @@ -28,21 +28,20 @@ import java.util.Map; import java.util.Random; import java.util.stream.Collectors; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Story; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent; -import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.test.matcher.Expect; import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; @@ -53,16 +52,13 @@ import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Story; - @Feature("Component Tests - Management API") @Story("Distribution Set Tag Resource") public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiIntegrationTest { private static final String DISTRIBUTIONSETTAGS_ROOT = "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/"; + private static final Random RND = new Random(); @Test @Description("Verfies that a paged result list of DS tags reflects the content on the repository side.") @@ -109,28 +105,28 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt distributionSetManagement.assignTag(List.of(distributionSet1.getId()), tag2.getId()); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) - .queryParam(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "distributionset.id==" + distributionSet1.getId()) - .accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(applyBaseEntityMatcherOnPagedResult(tag1)) - .andExpect(applyBaseEntityMatcherOnPagedResult(tag2)) - .andExpect(applySelfLinkMatcherOnPagedResult(tag1, DISTRIBUTIONSETTAGS_ROOT + tag1.getId())) - .andExpect(applySelfLinkMatcherOnPagedResult(tag2, DISTRIBUTIONSETTAGS_ROOT + tag2.getId())) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); + .queryParam(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "distributionset.id==" + distributionSet1.getId()) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(applyBaseEntityMatcherOnPagedResult(tag1)) + .andExpect(applyBaseEntityMatcherOnPagedResult(tag2)) + .andExpect(applySelfLinkMatcherOnPagedResult(tag1, DISTRIBUTIONSETTAGS_ROOT + tag1.getId())) + .andExpect(applySelfLinkMatcherOnPagedResult(tag2, DISTRIBUTIONSETTAGS_ROOT + tag2.getId())) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) - .queryParam(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "distributionset.id==" + distributionSet2.getId()) - .accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(applyBaseEntityMatcherOnPagedResult(tag1)) - .andExpect(applySelfLinkMatcherOnPagedResult(tag1, DISTRIBUTIONSETTAGS_ROOT + tag1.getId())) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(1))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(1))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); + .queryParam(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "distributionset.id==" + distributionSet2.getId()) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(applyBaseEntityMatcherOnPagedResult(tag1)) + .andExpect(applySelfLinkMatcherOnPagedResult(tag1, DISTRIBUTIONSETTAGS_ROOT + tag1.getId())) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(1))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(1))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); } @Test @@ -148,16 +144,16 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt // pass here q directly as a pure string because .queryParam method delimiters the parameters in q with , // which is logical OR, we want AND here mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING - + "?" + MgmtRestConstants.REQUEST_PARAMETER_SEARCH + - "=distributionset.id==" + distributionSet1.getId() + ";description==" + tag1.getDescription()) - .accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(applyBaseEntityMatcherOnPagedResult(tag1)) - .andExpect(applySelfLinkMatcherOnPagedResult(tag1, DISTRIBUTIONSETTAGS_ROOT + tag1.getId())) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(1))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(1))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); + + "?" + MgmtRestConstants.REQUEST_PARAMETER_SEARCH + + "=distributionset.id==" + distributionSet1.getId() + ";description==" + tag1.getDescription()) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(applyBaseEntityMatcherOnPagedResult(tag1)) + .andExpect(applySelfLinkMatcherOnPagedResult(tag1, DISTRIBUTIONSETTAGS_ROOT + tag1.getId())) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(1))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(1))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); } @Test @@ -168,7 +164,7 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt final DistributionSetTag assigned = tags.get(0); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + assigned.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(applyTagMatcherOnSingleResult(assigned)) .andExpect(applySelfLinkMatcherOnSingleResult(DISTRIBUTIONSETTAGS_ROOT + assigned.getId())) @@ -275,7 +271,7 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt distributionSetManagement.assignTag(sets.stream().map(BaseEntity::getId).collect(Collectors.toList()), tag.getId()); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(setsAssigned))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -297,8 +293,8 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt distributionSetManagement.assignTag(sets.stream().map(BaseEntity::getId).collect(Collectors.toList()), tag.getId()); mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(setsAssigned))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(setsAssigned))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(setsAssigned))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -337,16 +333,6 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt assertThat(distributionSetManagement.findByTag(PAGE, tag.getId())).isEmpty(); } - private ResultActions toggle(final DistributionSetTag tag, final List sets) throws Exception { - return mvc - .perform(post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() - + "/assigned/toggleTagAssignment").content( - JsonBuilder.ids(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()))) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); - } - @Test @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @ExpectEvents({ @@ -377,9 +363,9 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt final List sets = testdataFactory.createDistributionSetsWithoutModules(2); mvc.perform( - put(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .content(JsonBuilder.toArray(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()))) - .contentType(MediaType.APPLICATION_JSON)) + put(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") + .content(JsonBuilder.toArray(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()))) + .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); final List updated = distributionSetManagement.findByTag(PAGE, tag.getId()).getContent(); @@ -435,12 +421,11 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt .containsOnly(assigned.getId()); } - private static final Random RND = new Random(); @Test @Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.") @ExpectEvents({ @Expect(type = DistributionSetTagCreatedEvent.class, count = 1), - @Expect(type = DistributionSetCreatedEvent.class, count = 2)}) + @Expect(type = DistributionSetCreatedEvent.class, count = 2) }) public void assignDistributionSetsNotFound() throws Exception { final DistributionSetTag tag = testdataFactory.createDistributionSetTags(1).get(0); final List sets = testdataFactory.createDistributionSetsWithoutModules(2).stream().map(DistributionSet::getId).toList(); @@ -475,8 +460,6 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt }); } - // DEPRECATED flows - @Test @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @ExpectEvents({ @@ -505,4 +488,16 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0))) .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1))); } + + // DEPRECATED flows + + private ResultActions toggle(final DistributionSetTag tag, final List sets) throws Exception { + return mvc + .perform(post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + + "/assigned/toggleTagAssignment").content( + JsonBuilder.ids(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()))) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResourceTest.java index 3b1660b6d..9795f86d8 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeResourceTest.java @@ -28,8 +28,12 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import com.jayway.jsonpath.JsonPath; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Step; +import io.qameta.allure.Story; import org.apache.commons.lang3.RandomStringUtils; -import org.assertj.core.util.Lists; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate; @@ -45,16 +49,8 @@ import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; -import com.jayway.jsonpath.JsonPath; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Step; -import io.qameta.allure.Story; - /** * Test for {@link MgmtDistributionSetTypeResource}. - * */ @Feature("Component Tests - Management API") @Story("Distribution Set Type Resource") @@ -108,7 +104,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn // descending mvc.perform(get("/rest/v1/distributionsettypes").accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "KEY:DESC")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "KEY:DESC")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[0].id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.content.[0].name", equalTo("TestName123"))) @@ -123,7 +119,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn // ascending mvc.perform(get("/rest/v1/distributionsettypes").accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "KEY:ASC")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "KEY:ASC")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[4].id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.content.[4].name", equalTo("TestName123"))) @@ -149,68 +145,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn verifyCreatedDistributionSetTypes(mvcResult); } - @Step - private void verifyCreatedDistributionSetTypes(final MvcResult mvcResult) throws UnsupportedEncodingException { - final DistributionSetType created1 = distributionSetTypeManagement.getByKey("testKey1").get(); - final DistributionSetType created2 = distributionSetTypeManagement.getByKey("testKey2").get(); - final DistributionSetType created3 = distributionSetTypeManagement.getByKey("testKey3").get(); - - assertThat(created1.getMandatoryModuleTypes()).containsOnly(osType); - assertThat(created1.getOptionalModuleTypes()).containsOnly(runtimeType); - assertThat(created2.getOptionalModuleTypes()).containsOnly(osType, runtimeType, appType); - assertThat(created3.getMandatoryModuleTypes()).containsOnly(osType, runtimeType); - - assertThat( - JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/distributionsettypes/" + created1.getId()); - assertThat( - JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/distributionsettypes/" + created2.getId()); - assertThat( - JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/distributionsettypes/" + created3.getId()); - - assertThat(distributionSetTypeManagement.count()).isEqualTo(7); - } - - @Step - private MvcResult runPostDistributionSetType(final List types) throws Exception { - return mvc - .perform(post("/rest/v1/distributionsettypes").content(JsonBuilder.distributionSetTypes(types)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("[0].name", equalTo("TestName1"))) - .andExpect(jsonPath("[0].key", equalTo("testKey1"))) - .andExpect(jsonPath("[0].description", equalTo("Desc1"))) - .andExpect(jsonPath("[0].colour", equalTo("col"))) - .andExpect(jsonPath("[0].createdBy", equalTo("uploadTester"))) - .andExpect(jsonPath("[1].name", equalTo("TestName2"))) - .andExpect(jsonPath("[1].key", equalTo("testKey2"))) - .andExpect(jsonPath("[1].description", equalTo("Desc2"))) - .andExpect(jsonPath("[1].createdBy", equalTo("uploadTester"))) - .andExpect(jsonPath("[2].name", equalTo("TestName3"))) - .andExpect(jsonPath("[2].key", equalTo("testKey3"))) - .andExpect(jsonPath("[2].description", equalTo("Desc3"))) - .andExpect(jsonPath("[2].createdBy", equalTo("uploadTester"))) - .andExpect(jsonPath("[2].createdAt", not(equalTo(0)))).andReturn(); - } - - @Step - private List createTestDistributionSetTestTypes() { - assertThat(distributionSetTypeManagement.count()).isEqualTo(DEFAULT_DS_TYPES); - - return Arrays.asList( - entityFactory.distributionSetType().create().key("testKey1").name("TestName1").description("Desc1") - .colour("col").mandatory(Arrays.asList(osType.getId())) - .optional(Arrays.asList(runtimeType.getId())).build(), - entityFactory.distributionSetType().create().key("testKey2").name("TestName2").description("Desc2") - .colour("col").optional(Arrays.asList(runtimeType.getId(), osType.getId(), appType.getId())) - .build(), - entityFactory.distributionSetType().create().key("testKey3").name("TestName3").description("Desc3") - .colour("col").mandatory(Arrays.asList(runtimeType.getId(), osType.getId())).build()); - } - @Test @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes POST requests.") @@ -220,7 +154,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn assertThat(testType.getOptLockRevision()).isEqualTo(1); mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType.getId()) - .content("{\"id\":" + osType.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + osType.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); testType = distributionSetTypeManagement.get(testType.getId()).get(); @@ -239,7 +173,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn assertThat(testType.getOptLockRevision()).isEqualTo(1); mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId()) - .content("{\"id\":" + osType.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + osType.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); testType = distributionSetTypeManagement.get(testType.getId()).get(); @@ -272,13 +206,13 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn for (int i = 0; i < moduleTypeIds.size() - 1; ++i) { mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId()) - .content("{\"id\":" + moduleTypeIds.get(i) + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + moduleTypeIds.get(i) + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); } mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId()) - .content("{\"id\":" + moduleTypeIds.get(moduleTypeIds.size() - 1) + "}") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content("{\"id\":" + moduleTypeIds.get(moduleTypeIds.size() - 1) + "}") + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -291,13 +225,13 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn for (int i = 0; i < moduleTypeIds.size() - 1; ++i) { mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType2.getId()) - .content("{\"id\":" + moduleTypeIds.get(i) + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + moduleTypeIds.get(i) + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); } mvc.perform(post("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType2.getId()) - .content("{\"id\":" + moduleTypeIds.get(moduleTypeIds.size() - 1) + "}") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content("{\"id\":" + moduleTypeIds.get(moduleTypeIds.size() - 1) + "}") + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -311,7 +245,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final DistributionSetType testType = generateTestType(); mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes", testType.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("[0].name", equalTo(osType.getName()))) .andExpect(jsonPath("[0].description", equalTo(osType.getDescription()))) @@ -325,7 +259,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final DistributionSetType testType = generateTestType(); mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes", testType.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("[0].name", equalTo(appType.getName()))) .andExpect(jsonPath("[0].description", equalTo(appType.getDescription()))) @@ -340,7 +274,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final DistributionSetType testType = generateTestType(); mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes/{smtId}", testType.getId(), - osType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + osType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("$.id", equalTo(osType.getId().intValue()))) .andExpect(jsonPath("$.name", equalTo(osType.getName()))) .andExpect(jsonPath("$.description", equalTo(osType.getDescription()))) @@ -350,16 +284,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn .andExpect(jsonPath("$.lastModifiedAt", equalTo(osType.getLastModifiedAt()))); } - private DistributionSetType generateTestType() { - final DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType() - .create().key("test123").name("TestName123").description("Desc123").colour("col") - .mandatory(Arrays.asList(osType.getId())).optional(Arrays.asList(appType.getId()))); - assertThat(testType.getOptLockRevision()).isEqualTo(1); - assertThat(testType.getOptionalModuleTypes()).containsExactly(appType); - assertThat(testType.getMandatoryModuleTypes()).containsExactly(osType); - return testType; - } - @Test @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes/{ID} GET requests.") @@ -367,7 +291,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final DistributionSetType testType = generateTestType(); mvc.perform(get("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes/{smtId}", testType.getId(), - appType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + appType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("$.id", equalTo(appType.getId().intValue()))) .andExpect(jsonPath("$.name", equalTo(appType.getName()))) .andExpect(jsonPath("$.description", equalTo(appType.getDescription()))) @@ -384,7 +308,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn DistributionSetType testType = generateTestType(); mvc.perform(delete("/rest/v1/distributionsettypes/{dstID}/mandatorymoduletypes/{smtId}", testType.getId(), - osType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + osType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); testType = distributionSetTypeManagement.get(testType.getId()).get(); @@ -401,7 +325,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn DistributionSetType testType = generateTestType(); mvc.perform(delete("/rest/v1/distributionsettypes/{dstID}/optionalmoduletypes/{smtId}", testType.getId(), - appType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + appType.getId()).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); testType = distributionSetTypeManagement.get(testType.getId()).get(); @@ -501,7 +425,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn .put("name", "nameShouldNotBeChanged").toString(); mvc.perform(put("/rest/v1/distributionsettypes/{smId}", testType.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.description", equalTo("foobardesc"))) .andExpect(jsonPath("$.colour", equalTo("updatedColour"))) @@ -533,7 +457,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final String body = new JSONObject().put("id", testType.getId()).put("deleted", true).toString(); mvc.perform(put("/rest/v1/distributionsettypes/{dstId}", testType.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.deleted", equalTo(false))); } @@ -558,7 +482,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final int types = DEFAULT_DS_TYPES; final int limitSize = 1; mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(types))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -573,8 +497,8 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn final int offsetParam = 2; final int expectedSize = types - offsetParam; mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(types))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(types))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(types))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -607,17 +531,17 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); mvc.perform(get( - "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/mandatorymoduletypes/" + osType.getId())) + "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/mandatorymoduletypes/" + osType.getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); mvc.perform(get("/rest/v1/distributionsettypes/" + standardDsType.getId() + "/mandatorymoduletypes/" + testSmType.getId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); mvc.perform(get( - "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" + osType.getId())) + "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" + osType.getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); mvc.perform(get( - "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" + appType.getId())) + "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" + appType.getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); mvc.perform(get("/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" @@ -630,8 +554,8 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn .optional(Collections.emptyList()).build(); mvc.perform(post("/rest/v1/distributionsettypes") - .content(JsonBuilder.distributionSetTypes(Arrays.asList(testNewType))) - .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) + .content(JsonBuilder.distributionSetTypes(Arrays.asList(testNewType))) + .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnsupportedMediaType()); // bad request - no content @@ -640,19 +564,19 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn // bad request - bad content mvc.perform(post("/rest/v1/distributionsettypes").content("sdfjsdlkjfskdjf".getBytes()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); // Missing mandatory field name mvc.perform(post("/rest/v1/distributionsettypes").content("[{\"description\":\"Desc123\",\"key\":\"test123\"}]") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final DistributionSetType toLongName = entityFactory.distributionSetType().create().key("test123") .name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1)).build(); mvc.perform(post("/rest/v1/distributionsettypes") - .content(JsonBuilder.distributionSetTypes(Arrays.asList(toLongName))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(JsonBuilder.distributionSetTypes(Arrays.asList(toLongName))) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); // not allowed methods @@ -665,7 +589,7 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn mvc.perform(put("/rest/v1/distributionsettypes/" + standardDsType.getId() + "/mandatorymoduletypes")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed()); mvc.perform(put( - "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" + osType.getId())) + "/rest/v1/distributionsettypes/" + standardDsType.getId() + "/optionalmoduletypes/" + osType.getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed()); } @@ -685,6 +609,78 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn .andExpect(jsonPath("content[1].name", equalTo("TestName1234"))); } + @Step + private void verifyCreatedDistributionSetTypes(final MvcResult mvcResult) throws UnsupportedEncodingException { + final DistributionSetType created1 = distributionSetTypeManagement.getByKey("testKey1").get(); + final DistributionSetType created2 = distributionSetTypeManagement.getByKey("testKey2").get(); + final DistributionSetType created3 = distributionSetTypeManagement.getByKey("testKey3").get(); + + assertThat(created1.getMandatoryModuleTypes()).containsOnly(osType); + assertThat(created1.getOptionalModuleTypes()).containsOnly(runtimeType); + assertThat(created2.getOptionalModuleTypes()).containsOnly(osType, runtimeType, appType); + assertThat(created3.getMandatoryModuleTypes()).containsOnly(osType, runtimeType); + + assertThat( + JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .isEqualTo("http://localhost/rest/v1/distributionsettypes/" + created1.getId()); + assertThat( + JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .isEqualTo("http://localhost/rest/v1/distributionsettypes/" + created2.getId()); + assertThat( + JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) + .isEqualTo("http://localhost/rest/v1/distributionsettypes/" + created3.getId()); + + assertThat(distributionSetTypeManagement.count()).isEqualTo(7); + } + + @Step + private MvcResult runPostDistributionSetType(final List types) throws Exception { + return mvc + .perform(post("/rest/v1/distributionsettypes").content(JsonBuilder.distributionSetTypes(types)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("[0].name", equalTo("TestName1"))) + .andExpect(jsonPath("[0].key", equalTo("testKey1"))) + .andExpect(jsonPath("[0].description", equalTo("Desc1"))) + .andExpect(jsonPath("[0].colour", equalTo("col"))) + .andExpect(jsonPath("[0].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("[1].name", equalTo("TestName2"))) + .andExpect(jsonPath("[1].key", equalTo("testKey2"))) + .andExpect(jsonPath("[1].description", equalTo("Desc2"))) + .andExpect(jsonPath("[1].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("[2].name", equalTo("TestName3"))) + .andExpect(jsonPath("[2].key", equalTo("testKey3"))) + .andExpect(jsonPath("[2].description", equalTo("Desc3"))) + .andExpect(jsonPath("[2].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("[2].createdAt", not(equalTo(0)))).andReturn(); + } + + @Step + private List createTestDistributionSetTestTypes() { + assertThat(distributionSetTypeManagement.count()).isEqualTo(DEFAULT_DS_TYPES); + + return Arrays.asList( + entityFactory.distributionSetType().create().key("testKey1").name("TestName1").description("Desc1") + .colour("col").mandatory(Arrays.asList(osType.getId())) + .optional(Arrays.asList(runtimeType.getId())).build(), + entityFactory.distributionSetType().create().key("testKey2").name("TestName2").description("Desc2") + .colour("col").optional(Arrays.asList(runtimeType.getId(), osType.getId(), appType.getId())) + .build(), + entityFactory.distributionSetType().create().key("testKey3").name("TestName3").description("Desc3") + .colour("col").mandatory(Arrays.asList(runtimeType.getId(), osType.getId())).build()); + } + + private DistributionSetType generateTestType() { + final DistributionSetType testType = distributionSetTypeManagement.create(entityFactory.distributionSetType() + .create().key("test123").name("TestName123").description("Desc123").colour("col") + .mandatory(Arrays.asList(osType.getId())).optional(Arrays.asList(appType.getId()))); + assertThat(testType.getOptLockRevision()).isEqualTo(1); + assertThat(testType.getOptionalModuleTypes()).containsExactly(appType); + assertThat(testType.getMandatoryModuleTypes()).containsExactly(osType); + return testType; + } + private void createSoftwareModulesAlphabetical(final int amount) { char character = 'a'; for (int index = 0; index < amount; index++) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java index 29f44b066..7f640b51c 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java @@ -34,6 +34,10 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Step; +import io.qameta.allure.Story; import org.awaitility.Awaitility; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.im.authentication.SpPermission; @@ -72,17 +76,13 @@ import org.springframework.http.MediaType; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.ResultMatcher; -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Step; -import io.qameta.allure.Story; - /** * Tests for covering the {@link MgmtRolloutResource}. */ @Feature("Component Tests - Management API") @Story("Rollout Resource") -@TestPropertySource(locations = "classpath:/mgmt-test.properties", properties = { "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" }) +@TestPropertySource(locations = "classpath:/mgmt-test.properties", properties = { + "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" }) class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { private static final String HREF_ROLLOUT_PREFIX = "http://localhost/rest/v1/rollouts/"; @@ -96,11 +96,218 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { @Autowired private RolloutTestApprovalStrategy approvalStrategy; + @Test + @Description("Handles the GET request of retrieving a single rollout.") + public void getRollout() throws Exception { + enableMultiAssignments(); + approvalStrategy.setApprovalNeeded(true); + try { + approvalStrategy.setApproveDecidedBy("exampleUsername"); + + testdataFactory.createTargets(4, "rollout", "description"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + // create a running rollout for the created targets + final Rollout rollout = rolloutManagement.create( + entityFactory + .rollout() + .create() + .name("rollout1") + .distributionSetId(dsA.getId()) + .targetFilterQuery("controllerId==rollout*"), + 4, false, new RolloutGroupConditionBuilder().withDefaults() + .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); + + rolloutHandler.handleAll(); + + rolloutManagement.approveOrDeny(rollout.getId(), Rollout.ApprovalDecision.APPROVED, "Approved remark."); + + mvc.perform(get(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}", rollout.getId()) + .accept(MediaTypes.HAL_JSON_VALUE)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)); + } finally { + approvalStrategy.setApprovalNeeded(false); + } + } + + @Test + @Description("Handles the GET request of retrieving a all targets of a specific deploy group of a rollout.") + public void getRolloutDeployGroupTargetsWithParameters() throws Exception { + testdataFactory.createTargets(4, "rollout", "description"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + final Rollout rollout = createRollout("rollout1", 2, dsA.getId(), "controllerId==rollout*"); + final RolloutGroup firstRolloutGroup = rolloutGroupManagement + .findByRollout(PageRequest.of(0, 1), rollout.getId()).getContent().get(0); + + mvc.perform(get(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/deploygroups/{deployGroupId}/targets", + rollout.getId(), firstRolloutGroup.getId()).param("offset", "0").param("limit", "2") + .param("sort", "name:ASC").param("q", "controllerId==exampleTarget0") + .accept(MediaTypes.HAL_JSON_VALUE)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)); + } + + @Test + @Description("Handles the POST request of approving a rollout.") + public void approveRollout() throws Exception { + approvalStrategy.setApprovalNeeded(true); + try { + testdataFactory.createTargets(4, "rollout", "description"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + final Rollout rollout = createRollout("rollout1", 3, dsA.getId(), "controllerId==rollout*", false); + mvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/approve", rollout.getId()) + .accept(MediaTypes.HAL_JSON_VALUE)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + } finally { + approvalStrategy.setApprovalNeeded(false); + } + } + + @Test + @Description("Handles the POST request of denying a rollout. Required Permission: " + SpPermission.APPROVE_ROLLOUT) + public void denyRollout() throws Exception { + approvalStrategy.setApprovalNeeded(true); + try { + testdataFactory.createTargets(4, "rollout", "description"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + final Rollout rollout = createRollout("rollout1", 3, dsA.getId(), "controllerId==rollout*", false); + mvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/deny", rollout.getId()) + .accept(MediaTypes.HAL_JSON_VALUE)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + } finally { + approvalStrategy.setApprovalNeeded(false); + } + } + + @Test + @Description("Check if approvalDecidedBy and approvalRemark are present when rollout is approved") + public void validateIfApprovalFieldsArePresentAfterApproval() throws Exception { + approvalStrategy.setApprovalNeeded(true); + approvalStrategy.setApproveDecidedBy("testUser"); + final int amountTargets = 2; + final String remark = "Some remark"; + final List targets = testdataFactory.createTargets(amountTargets, "rollout"); + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + final Rollout rollout = createRollout("rollout1", 3, dsA.getId(), "controllerId==rollout*", false); + + rolloutHandler.handleAll(); + + mvc.perform(get("/rest/v1/rollouts/{rolloutid}", rollout.getId())).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()).andExpect(jsonPath("$.status", equalTo("waiting_for_approval"))); + + rolloutManagement.approveOrDeny(rollout.getId(), Rollout.ApprovalDecision.APPROVED, remark); + + mvc.perform(get("/rest/v1/rollouts/{rolloutid}", rollout.getId())).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.status", equalTo("ready"))) + .andExpect(jsonPath("$.approvalRemark", equalTo(remark))) + .andExpect(jsonPath("$.approveDecidedBy", equalTo("testUser"))); + + // revert + approvalStrategy.setApprovalNeeded(false); + } + + @Test + @Description("Retry rollout test scenario") + public void retryRolloutTest() throws Exception { + + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + final List successTargets = testdataFactory.createTargets("retryRolloutTargetSuccess-", 6); + final List failedTargets = testdataFactory.createTargets("retryRolloutTargetFailed-", 4); + + final List allTargets = new ArrayList<>(successTargets); + allTargets.addAll(failedTargets); + + postRollout("rolloutToBeRetried", 1, dsA.getId(), "id==retryRolloutTarget*", 10, Action.ActionType.FORCED); + + Rollout rollout = rolloutManagement.getByName("rolloutToBeRetried").orElseThrow(); + + // no scheduler so invoke here + rolloutHandler.handleAll(); + rolloutManagement.start(rollout.getId()); + // no scheduler so invoke here + rolloutHandler.handleAll(); + + testdataFactory.sendUpdateActionStatusToTargets(successTargets, Status.FINISHED, "Finished successfully!"); + testdataFactory.sendUpdateActionStatusToTargets(failedTargets, Status.ERROR, "Finished error!"); + + rolloutHandler.handleAll(); + + for (Target target : allTargets) { + final List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent(); + for (Action action : actions) { + if (action.getTarget().getControllerId().startsWith("retryRolloutTargetFailed")) { + Assertions.assertEquals(Status.ERROR, action.getStatus()); + } else { + Assertions.assertEquals(Status.FINISHED, action.getStatus()); + } + Assertions.assertEquals(rollout.getId(), action.getRollout().getId()); + } + } + + //retry rollout + mvc.perform(post("/rest/v1/rollouts/{rolloutId}/retry", rollout.getId())).andDo(MockMvcResultPrinter.print()) + .andExpect(status().is(201)); + + //search for _retried suffix + Rollout retriedRollout = rolloutManagement.getByName(rollout.getName() + "_retry").orElseThrow(); + //assert 4 targets involved + rolloutHandler.handleAll(); + + rolloutManagement.start(retriedRollout.getId()); + rolloutHandler.handleAll(); + + for (Target target : failedTargets) { + // for failed targets - check for 2 actions - one from old rollout and one from the retried + List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent(); + Assertions.assertEquals(2, actions.size()); + Assertions.assertEquals(Status.ERROR, actions.get(0).getStatus()); + Assertions.assertEquals(rollout.getId(), actions.get(0).getRollout().getId()); + Assertions.assertEquals(Status.RUNNING, actions.get(1).getStatus()); + Assertions.assertEquals(retriedRollout.getId(), actions.get(1).getRollout().getId()); + } + + for (Target target : successTargets) { + //ensure no other actions from the success targets are created + List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent(); + Assertions.assertEquals(1, actions.size()); + Assertions.assertEquals(rollout.getId(), actions.get(0).getRollout().getId()); + } + } + + @Test + @Description("Retrying a running rollout should not be allowed.") + public void retryNotFinishedRolloutShouldNotBeAllowed() throws Exception { + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + testdataFactory.createTargets("retryRolloutTarget-", 10); + postRollout("rolloutToBeRetried", 1, dsA.getId(), "id==retryRolloutTarget*", 10, Action.ActionType.FORCED); + Rollout rollout = rolloutManagement.getByName("rolloutToBeRetried").orElseThrow(); + // no scheduler so invoke here + rolloutHandler.handleAll(); + rolloutManagement.start(rollout.getId()); + // no scheduler so invoke here + rolloutHandler.handleAll(); + + mvc.perform(post("/rest/v1/rollouts/{rolloutId}/retry", rollout.getId())).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isBadRequest()); + } + + @Test + @Description("Retrying a non-existing rollout should lead to NOT FOUND.") + public void retryNonExistingRolloutShouldLeadToNotFound() throws Exception { + mvc.perform(post("/rest/v1/rollouts/{rolloutId}/retry", 6782623)).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isNotFound()); + } + @Test @Description("Testing that creating rollout with wrong body returns bad request") void createRolloutWithInvalidBodyReturnsBadRequest() throws Exception { mvc.perform(post("/rest/v1/rollouts").content("invalid body").contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()) .andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.body.notReadable"))); } @@ -111,8 +318,8 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { void createRolloutWithInsufficientPermissionReturnsForbidden() throws Exception { final DistributionSet dsA = testdataFactory.createDistributionSet(""); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("name", "desc", 10, dsA.getId(), "name==test", null)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("name", "desc", 10, dsA.getId(), "name==test", null)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().is(403)).andReturn(); } @@ -120,7 +327,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { @Description("Testing that creating rollout with not existing distribution set returns not found") void createRolloutWithNotExistingDistributionSetReturnsNotFound() throws Exception { mvc.perform(post("/rest/v1/rollouts").content(JsonBuilder.rollout("name", "desc", 10, 1234, "name==test", null)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()).andReturn(); } @@ -129,8 +336,8 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { void createRolloutWithNotWellFormedFilterReturnsBadRequest() throws Exception { final DistributionSet dsA = testdataFactory.createDistributionSet(""); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("name", "desc", 5, dsA.getId(), "name=test", null)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("name", "desc", 5, dsA.getId(), "name=test", null)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()) .andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.param.rsqlParamSyntax"))) .andReturn(); @@ -144,8 +351,8 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { final DistributionSet dsA = testdataFactory.createDistributionSet(""); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("rollout1", "desc", 10, dsA.getId(), targetFilterQuery, null)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("rollout1", "desc", 10, dsA.getId(), targetFilterQuery, null)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()) .andExpect(jsonPath("errorCode", equalTo("hawkbit.server.error.rest.param.rsqlParamSyntax"))) .andReturn(); @@ -169,10 +376,10 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { testdataFactory.createTargets(20, "target", "rollout"); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("rollout1", "rollout1Desc", maxGroups + 1, - testdataFactory.createDistributionSet("ds").getId(), "id==target*", - new RolloutGroupConditionBuilder().withDefaults().build())) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("rollout1", "rollout1Desc", maxGroups + 1, + testdataFactory.createDistributionSet("ds").getId(), "id==target*", + new RolloutGroupConditionBuilder().withDefaults().build())) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -187,10 +394,10 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { testdataFactory.createTargets(maxTargets + 1, "target", "rollout"); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("rollout1", "rollout1Desc", 1, - testdataFactory.createDistributionSet("ds").getId(), "id==target*", - new RolloutGroupConditionBuilder().withDefaults().build())) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("rollout1", "rollout1Desc", 1, + testdataFactory.createDistributionSet("ds").getId(), "id==target*", + new RolloutGroupConditionBuilder().withDefaults().build())) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -217,9 +424,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build(); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rolloutWithGroups("rollout2", "desc", null, dsA.getId(), "id==ro-target*", - rolloutGroupConditions, rolloutGroups)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rolloutWithGroups("rollout2", "desc", null, dsA.getId(), "id==ro-target*", + rolloutGroupConditions, rolloutGroups)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()).andReturn(); } @@ -233,7 +440,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { testdataFactory.createTargets(amountTargets, "rollout-dynamic", "rollout"); postRollout("rollout1", 1, dsA.getId(), "name==rollout*", 10, Action.ActionType.FORCED, - null, null, true, null, 1); + null, null, true, null, 1); rolloutHandler.handleAll(); @@ -243,18 +450,18 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { rolloutHandler.handleAll(); mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) - .andExpect(jsonPath("content[0].id", equalTo(rollout.getId().intValue()))) - .andExpect(jsonPath("content[0].name", equalTo("rollout1"))) - .andExpect(jsonPath("content[0].status", equalTo("running"))) - .andExpect(jsonPath("content[0].targetFilterQuery", equalTo("name==rollout*"))) - .andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue()))) - .andExpect(jsonPath("content[0].totalTargets", equalTo(10))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus").exists()) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(10))) - .andExpect(jsonPath("content[0].totalGroups", equalTo(2))); + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) + .andExpect(jsonPath("content[0].id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("content[0].name", equalTo("rollout1"))) + .andExpect(jsonPath("content[0].status", equalTo("running"))) + .andExpect(jsonPath("content[0].targetFilterQuery", equalTo("name==rollout*"))) + .andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue()))) + .andExpect(jsonPath("content[0].totalTargets", equalTo(10))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus").exists()) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(10))) + .andExpect(jsonPath("content[0].totalGroups", equalTo(2))); final int amountOfDynamicTargets = 2; testdataFactory.createTargets(amountOfDynamicTargets, "rollout-dynamic-addition-", "rollout"); @@ -282,25 +489,25 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { } mvc.perform(get("/rest/v1/rollouts?representation=full").accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) - .andExpect(jsonPath("content[0].id", equalTo(rollout.getId().intValue()))) - .andExpect(jsonPath("content[0].name", equalTo("rollout1"))) - .andExpect(jsonPath("content[0].status", equalTo("running"))) - .andExpect(jsonPath("content[0].targetFilterQuery", equalTo("name==rollout*"))) - .andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue()))) - .andExpect(jsonPath("content[0].totalTargets", equalTo(amountTargets + amountOfDynamicTargets))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus").exists()) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(1))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.notstarted", equalTo(0))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.scheduled", equalTo(1))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.cancelled", equalTo(10))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("content[0].totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("content[0].deleted", equalTo(false))) - .andExpect(jsonPath("content[0].totalGroups", equalTo(4))) - .andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))); + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) + .andExpect(jsonPath("content[0].id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("content[0].name", equalTo("rollout1"))) + .andExpect(jsonPath("content[0].status", equalTo("running"))) + .andExpect(jsonPath("content[0].targetFilterQuery", equalTo("name==rollout*"))) + .andExpect(jsonPath("content[0].distributionSetId", equalTo(dsA.getId().intValue()))) + .andExpect(jsonPath("content[0].totalTargets", equalTo(amountTargets + amountOfDynamicTargets))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus").exists()) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.running", equalTo(1))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.notstarted", equalTo(0))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.scheduled", equalTo(1))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.cancelled", equalTo(10))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("content[0].totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("content[0].deleted", equalTo(false))) + .andExpect(jsonPath("content[0].totalGroups", equalTo(4))) + .andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))); } @Test @@ -320,9 +527,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build(); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rolloutWithGroups("rollout4", "desc", null, dsA.getId(), "id==ro-target*", - rolloutGroupConditions, rolloutGroups)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rolloutWithGroups("rollout4", "desc", null, dsA.getId(), "id==ro-target*", + rolloutGroupConditions, rolloutGroups)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()) .andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation"))); @@ -345,9 +552,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { final RolloutGroupConditions rolloutGroupConditions = new RolloutGroupConditionBuilder().withDefaults().build(); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rolloutWithGroups("rollout4", "desc", null, dsA.getId(), "id==ro-target*", - rolloutGroupConditions, rolloutGroups)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rolloutWithGroups("rollout4", "desc", null, dsA.getId(), "id==ro-target*", + rolloutGroupConditions, rolloutGroups)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()) .andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation"))); @@ -369,7 +576,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { 4, false, new RolloutGroupConditionBuilder().withDefaults() .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); - mvc.perform(put("/rest/v1/rollouts/" + rollout.getId()).content( new JSONObject().put("name", "newName").put("description", "newDesc").toString() ).contentType(MediaType.APPLICATION_JSON) @@ -491,41 +697,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))); } - @Test - @Description("Handles the GET request of retrieving a single rollout.") - public void getRollout() throws Exception { - enableMultiAssignments(); - approvalStrategy.setApprovalNeeded(true); - try { - approvalStrategy.setApproveDecidedBy("exampleUsername"); - - testdataFactory.createTargets(4, "rollout", "description"); - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - // create a running rollout for the created targets - final Rollout rollout = rolloutManagement.create( - entityFactory - .rollout() - .create() - .name("rollout1") - .distributionSetId(dsA.getId()) - .targetFilterQuery("controllerId==rollout*"), - 4, false, new RolloutGroupConditionBuilder().withDefaults() - .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); - - rolloutHandler.handleAll(); - - rolloutManagement.approveOrDeny(rollout.getId(), Rollout.ApprovalDecision.APPROVED, "Approved remark."); - - mvc.perform(get(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}", rollout.getId()) - .accept(MediaTypes.HAL_JSON_VALUE)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)); - } finally { - approvalStrategy.setApprovalNeeded(false); - } - } - @ParameterizedTest @ValueSource(booleans = { true, false }) @Description("Verify the confirmation required flag is not part of the rollout parent entity") @@ -594,9 +765,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { rolloutGroupConditions)); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("rollout2", "desc", null, dsA.getId(), "id==ro-target*", - rolloutGroupConditions, rolloutGroups, null, null, null, null, false)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("rollout2", "desc", null, dsA.getId(), "id==ro-target*", + rolloutGroupConditions, rolloutGroups, null, null, null, null, false)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()).andReturn(); final List content = rolloutManagement.findAll(PAGE, false).getContent(); @@ -635,9 +806,9 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { rolloutGroupConditions)); mvc.perform(post("/rest/v1/rollouts") - .content(JsonBuilder.rollout("rollout2", "desc", null, dsA.getId(), "id==ro-target*", - rolloutGroupConditions, rolloutGroups, null, null, null, null, null)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .content(JsonBuilder.rollout("rollout2", "desc", null, dsA.getId(), "id==ro-target*", + rolloutGroupConditions, rolloutGroups, null, null, null, null, null)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()).andReturn(); final List content = rolloutManagement.findAll(PAGE, false).getContent(); @@ -654,94 +825,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { }); } - @Step - private void retrieveAndVerifyRolloutInRunning(final Rollout rollout) throws Exception { - rolloutHandler.handleAll(); - - mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) - .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("running"))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(5))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(15))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); - } - - @Step - private void retrieveAndVerifyRolloutInStarting(final Rollout rollout) throws Exception { - rolloutManagement.start(rollout.getId()); - - mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) - .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("starting"))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(20))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); - } - - @Step - private void retrieveAndVerifyRolloutInReady(final Rollout rollout) throws Exception { - rolloutHandler.handleAll(); - - mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) - .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("ready"))) - .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(20))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); - } - - @Step - private void retrieveAndVerifyRolloutInCreating(final DistributionSet dsA, final Rollout rollout) throws Exception { - mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) - .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("creating"))) - .andExpect(jsonPath("$.targetFilterQuery", equalTo("controllerId==rollout*"))) - .andExpect(jsonPath("$.distributionSetId", equalTo(dsA.getId().intValue()))) - .andExpect(jsonPath("$.createdBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.createdAt", not(equalTo(0)))) - .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) - .andExpect(jsonPath("$.totalTargets", equalTo(20))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(20))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("$._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))) - .andExpect(jsonPath("$._links.start.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/start")))) - .andExpect(jsonPath("$._links.pause.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/pause")))) - .andExpect( - jsonPath("$._links.resume.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/resume")))) - .andExpect(jsonPath("$._links.triggerNextGroup.href", - allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/triggerNextGroup")))) - .andExpect(jsonPath("$._links.groups.href", - allOf(startsWith(HREF_ROLLOUT_PREFIX), containsString("/deploygroups")))) - .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); - } - @Test @Description("Testing that rollout paged list contains rollouts") void rolloutPagedListContainsAllRollouts() throws Exception { @@ -859,7 +942,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve rollout groups from created rollout mvc.perform( - get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()).accept(MediaType.APPLICATION_JSON)) + get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(4))).andExpect(jsonPath("$.total", equalTo(4))) @@ -891,17 +974,17 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // create rollout including the created targets with prefix 'rollout' final Rollout rollout1 = createRollout("rollout1", 4, dsA.getId(), "controllerId==rollout*", - false); + false); final Rollout rollout2 = createRollout("rollout2", 1, dsA.getId(), "controllerId==rollout*", - false); + false); rolloutManagement.start(rollout1.getId()); rolloutManagement.start(rollout2.getId()); rolloutHandler.handleAll(); final RolloutGroup firstGroup = rolloutGroupManagement - .findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout1.getId()).getContent().get(0); + .findByRollout(PageRequest.of(0, 1, Direction.ASC, "id"), rollout1.getId()).getContent().get(0); // make request for firstGroupId and the rolloutId of the second rollout (the one with no groups) mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout2.getId(), firstGroup.getId()) @@ -1067,7 +1150,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve rollout groups from created rollout - 2 groups exists // (amountTargets / groupSize = 2) mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups?sort=ID:ASC", rollout.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(2))).andExpect(jsonPath("$.total", equalTo(2))) .andExpect(jsonPath("$.content[0].status", equalTo("running"))) @@ -1106,95 +1189,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { confirmationRequired); } - private static Stream confirmationOptions() { - return Stream.of(Arguments.of(true, false), Arguments.of(true, true), Arguments.of(false, true)); - } - - @Step - private void retrieveAndVerifyRolloutGroupInRunningAndScheduled(final Rollout rollout, - final RolloutGroup firstGroup, final RolloutGroup secondGroup, final boolean confirmationFlowEnabled, - final boolean confirmationRequired) throws Exception { - rolloutManagement.start(rollout.getId()); - rolloutHandler.handleAll(); - mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("status", equalTo("running"))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(5))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired", equalTo(confirmationRequired)) - : jsonPath("confirmationRequired").doesNotExist()); - - mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), secondGroup.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("status", equalTo("scheduled"))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(5))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired", equalTo(confirmationRequired)) - : jsonPath("confirmationRequired").doesNotExist()); - ; - } - - @Step - private void retrieveAndVerifyRolloutGroupInReady(final Rollout rollout, final RolloutGroup firstGroup) - throws Exception { - rolloutHandler.handleAll(); - mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("status", equalTo("ready"))) - .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) - .andExpect(jsonPath("$.totalTargets", equalTo(5))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(5))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired").exists() - : jsonPath("confirmationRequired").doesNotExist()); - ; - } - - @Step - private void retrieveAndVerifyRolloutGroupInCreating(final Rollout rollout, final RolloutGroup firstGroup) - throws Exception { - mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) - .accept(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("id", equalTo(firstGroup.getId().intValue()))) - .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired").exists() - : jsonPath("confirmationRequired").doesNotExist()) - .andExpect(jsonPath("status", equalTo("creating"))).andExpect(jsonPath("name", endsWith("1"))) - .andExpect(jsonPath("description", endsWith("1"))) - .andExpect(jsonPath("$.targetFilterQuery", equalTo(""))) - .andExpect(jsonPath("$.targetPercentage", equalTo(25.0))) - .andExpect(jsonPath("$.createdBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.createdAt", not(equalTo(0)))) - .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) - .andExpect(jsonPath("$.totalTargets", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("$._links.self.href", equalTo( - HREF_ROLLOUT_PREFIX + rollout.getId() + "/deploygroups/" + firstGroup.getId().intValue()))); - } - @Test @Description("Testing that the targets of rollout group can be retrieved") void retrieveTargetsFromRolloutGroup() throws Exception { @@ -1211,31 +1205,13 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve targets from the first rollout group with known ID mvc.perform( - get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}/targets", rollout.getId(), firstGroup.getId()) - .accept(MediaType.APPLICATION_JSON)) + get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}/targets", rollout.getId(), firstGroup.getId()) + .accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(5))).andExpect(jsonPath("$.total", equalTo(5))); } - @Test - @Description("Handles the GET request of retrieving a all targets of a specific deploy group of a rollout.") - public void getRolloutDeployGroupTargetsWithParameters() throws Exception { - testdataFactory.createTargets(4, "rollout", "description"); - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - final Rollout rollout = createRollout("rollout1", 2, dsA.getId(), "controllerId==rollout*"); - final RolloutGroup firstRolloutGroup = rolloutGroupManagement - .findByRollout(PageRequest.of(0, 1), rollout.getId()).getContent().get(0); - - mvc.perform(get(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/deploygroups/{deployGroupId}/targets", - rollout.getId(), firstRolloutGroup.getId()).param("offset", "0").param("limit", "2") - .param("sort", "name:ASC").param("q", "controllerId==exampleTarget0") - .accept(MediaTypes.HAL_JSON_VALUE)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)); - } - @Test @Description("Testing that the targets of rollout group can be retrieved with rsql query param") void retrieveTargetsFromRolloutGroupWithQuery() throws Exception { @@ -1255,8 +1231,8 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve targets from the first rollout group with known ID mvc.perform( - get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}/targets", rollout.getId(), firstGroup.getId()) - .accept(MediaType.APPLICATION_JSON).param("q", "controllerId==" + targetInGroup)) + get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}/targets", rollout.getId(), firstGroup.getId()) + .accept(MediaType.APPLICATION_JSON).param("q", "controllerId==" + targetInGroup)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))); @@ -1283,8 +1259,8 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve targets from the first rollout group with known ID mvc.perform( - get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}/targets", rollout.getId(), firstGroup.getId()) - .accept(MediaType.APPLICATION_JSON)) + get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}/targets", rollout.getId(), firstGroup.getId()) + .accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(5))).andExpect(jsonPath("$.total", equalTo(5))); @@ -1312,22 +1288,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { awaitRunningState(rollout.getId()); } - private void awaitRunningState(final Long rolloutId) { - Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with() - .until(() -> SecurityContextSwitch - .runAsPrivileged( - () -> rolloutManagement.get(rolloutId).orElseThrow(NoSuchElementException::new)) - .getStatus().equals(RolloutStatus.RUNNING)); - } - - private void awaitActionStatus(final Long actionId, final Status status) { - Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with() - .until(() -> SecurityContextSwitch - .runAsPrivileged( - () -> deploymentManagement.findAction(actionId).orElseThrow(NoSuchElementException::new)) - .getStatus().equals(status)); - } - @Test @Description("Deletion of a rollout") void deleteRollout() throws Exception { @@ -1355,11 +1315,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { assertStatusIs(rollout, RolloutStatus.DELETED); } - private void assertStatusIs(final Rollout rollout, final RolloutStatus expected) { - final Optional updatedRollout = rolloutManagement.get(rollout.getId()); - assertThat(updatedRollout).get().extracting(Rollout::getStatus).isEqualTo(expected); - } - @Test @Description("Testing that rollout paged list with rsql parameter") void getRolloutWithRSQLParam() throws Exception { @@ -1380,19 +1335,19 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { createRollout("other1", 5, dsA.getId(), "controllerId==other1*"); mvc.perform(get("/rest/v1/rollouts").param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==*2") - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) .andExpect(jsonPath("$.content[0].name", equalTo(rollout2.getName()))); mvc.perform(get("/rest/v1/rollouts").accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==rollout*")) + .param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==rollout*")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(3))).andExpect(jsonPath("$.total", equalTo(3))); mvc.perform(get("/rest/v1/rollouts").accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==*1")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==*1")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(2))).andExpect(jsonPath("$.total", equalTo(2))); @@ -1411,7 +1366,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve rollout groups from created rollout mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()) - .accept(MediaType.APPLICATION_JSON).param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group-1")) + .accept(MediaType.APPLICATION_JSON).param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group-1")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) @@ -1419,14 +1374,14 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("$.content[0].totalTargetsPerStatus").doesNotExist()); mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()) - .accept(MediaType.APPLICATION_JSON).param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group*")) + .accept(MediaType.APPLICATION_JSON).param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group*")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(4))).andExpect(jsonPath("$.total", equalTo(4))); mvc.perform( - get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()).accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group-1,name==group-2")) + get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()).accept(MediaType.APPLICATION_JSON) + .param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group-1,name==group-2")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(2))).andExpect(jsonPath("$.total", equalTo(2))) @@ -1456,8 +1411,8 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { // retrieve the rollout groups of the created rollout // filter for the first group by RSQL mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups", rollout.getId()) - .accept(MediaType.APPLICATION_JSON).param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group-1") - .param("representation", "full")).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON).param(MgmtRestConstants.REQUEST_PARAMETER_SEARCH, "name==group-1") + .param("representation", "full")).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) .andExpect(jsonPath("$.content[0].name", equalTo("group-1"))) @@ -1495,15 +1450,15 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { new RolloutGroupConditionBuilder().withDefaults().build(), null, null, weight, null, null, null); mvc.perform(post("/rest/v1/rollouts").content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()); enableMultiAssignments(); mvc.perform(post("/rest/v1/rollouts").content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .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(valideWeightRequestMultiAssignment).contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()); final List rollouts = rolloutManagement.findAll(PAGE, false).getContent(); @@ -1511,137 +1466,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { assertThat(rollouts.get(0).getWeight()).get().isEqualTo(weight); } - @Test - @Description("Handles the POST request of approving a rollout.") - public void approveRollout() throws Exception { - approvalStrategy.setApprovalNeeded(true); - try { - testdataFactory.createTargets(4, "rollout", "description"); - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - final Rollout rollout = createRollout("rollout1", 3, dsA.getId(), "controllerId==rollout*", false); - mvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/approve", rollout.getId()) - .accept(MediaTypes.HAL_JSON_VALUE)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - } finally { - approvalStrategy.setApprovalNeeded(false); - } - } - - @Test - @Description("Handles the POST request of denying a rollout. Required Permission: " + SpPermission.APPROVE_ROLLOUT) - public void denyRollout() throws Exception { - approvalStrategy.setApprovalNeeded(true); - try { - testdataFactory.createTargets(4, "rollout", "description"); - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - final Rollout rollout = createRollout("rollout1", 3, dsA.getId(), "controllerId==rollout*", false); - mvc.perform(post(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/deny", rollout.getId()) - .accept(MediaTypes.HAL_JSON_VALUE)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - } finally { - approvalStrategy.setApprovalNeeded(false); - } - } - - @Test - @Description("Check if approvalDecidedBy and approvalRemark are present when rollout is approved") - public void validateIfApprovalFieldsArePresentAfterApproval() throws Exception { - approvalStrategy.setApprovalNeeded(true); - approvalStrategy.setApproveDecidedBy("testUser"); - final int amountTargets = 2; - final String remark = "Some remark"; - final List targets = testdataFactory.createTargets(amountTargets, "rollout"); - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - final Rollout rollout = createRollout("rollout1", 3, dsA.getId(), "controllerId==rollout*", false); - - rolloutHandler.handleAll(); - - mvc.perform(get("/rest/v1/rollouts/{rolloutid}", rollout.getId())).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()).andExpect(jsonPath("$.status", equalTo("waiting_for_approval"))); - - rolloutManagement.approveOrDeny(rollout.getId(), Rollout.ApprovalDecision.APPROVED, remark); - - mvc.perform(get("/rest/v1/rollouts/{rolloutid}", rollout.getId())).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.status", equalTo("ready"))) - .andExpect(jsonPath("$.approvalRemark", equalTo(remark))) - .andExpect(jsonPath("$.approveDecidedBy", equalTo("testUser"))); - - // revert - approvalStrategy.setApprovalNeeded(false); - } - - private void postRollout(final String name, final int groupSize, final Long distributionSetId, - final String targetFilterQuery, final int targets, final Action.ActionType type) throws Exception { - postRollout(name, groupSize, distributionSetId, targetFilterQuery, targets, type, null, null); - } - - private void postRollout(final String name, final int groupSize, final Long distributionSetId, - final String targetFilterQuery, final int targets, final Action.ActionType type, final Long startTime, - final Long forceTime) throws Exception { - postRollout(name, groupSize, distributionSetId, targetFilterQuery, targets, type, startTime, forceTime, false, null, 0); - } - - private void postRollout(final String name, final int groupSize, final Long distributionSetId, - final String targetFilterQuery, final int targets, final Action.ActionType type, final Long startTime, - final Long forceTime, boolean isDynamic, String dynamicGroupSuffix, int dynamicGroupTargetsCount) throws Exception { - final String actionType = MgmtRestModelMapper.convertActionType(type).getName(); - final String rollout = JsonBuilder.rollout(name, "desc", groupSize, distributionSetId, targetFilterQuery, - new RolloutGroupConditionBuilder().withDefaults().build(), null, actionType, null, startTime, forceTime, - null, isDynamic, dynamicGroupSuffix, dynamicGroupTargetsCount); - - 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))) - .andExpect(jsonPath("$.description", equalTo("desc"))) - .andExpect(jsonPath("$.distributionSetId", equalTo(distributionSetId.intValue()))) - .andExpect(jsonPath("$.createdBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.createdAt", not(equalTo(0)))) - .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) - .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) - .andExpect(jsonPath("$.totalTargets", equalTo(targets))) - .andExpect(startTime != null ? jsonPath("$.startAt", equalTo(startTime.intValue())) - : jsonPath("$.startAt").doesNotExist()) - .andExpect(forceTime != null ? jsonPath("$.forcetime", equalTo(forceTime.intValue())) - : jsonPath("$.forcetime", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(targets))) - .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) - .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) - .andExpect(jsonPath("$._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))) - .andExpect(jsonPath("$._links.start.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/start")))) - .andExpect(jsonPath("$._links.pause.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/pause")))) - .andExpect(jsonPath("$.dynamic", equalTo(isDynamic))) - .andExpect( - jsonPath("$._links.resume.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/resume")))) - .andExpect(jsonPath("$._links.groups.href", - allOf(startsWith(HREF_ROLLOUT_PREFIX), containsString("/deploygroups")))); - } - - private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, - final String targetFilterQuery) { - return createRollout(name, amountGroups, distributionSetId, targetFilterQuery, false); - } - - private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, - final String targetFilterQuery, final boolean confirmationRequired) { - final Rollout rollout = rolloutManagement.create( - entityFactory.rollout().create().name(name).distributionSetId(distributionSetId).targetFilterQuery(targetFilterQuery), - amountGroups, confirmationRequired, new RolloutGroupConditionBuilder().withDefaults() - .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); - - // Run here, because Scheduler is disabled during tests - rolloutHandler.handleAll(); - - return rolloutManagement.get(rollout.getId()).orElseThrow(NoSuchElementException::new); - } - @Test @Description("Trigger next rollout group") void triggeringNextGroupRollout() throws Exception { @@ -1703,97 +1527,271 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { } - @Test - @Description("Retry rollout test scenario") - public void retryRolloutTest() throws Exception { - - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - final List successTargets = testdataFactory.createTargets("retryRolloutTargetSuccess-", 6); - final List failedTargets = testdataFactory.createTargets("retryRolloutTargetFailed-", 4); - - final List allTargets = new ArrayList<>(successTargets); - allTargets.addAll(failedTargets); - - postRollout("rolloutToBeRetried", 1, dsA.getId(), "id==retryRolloutTarget*", 10, Action.ActionType.FORCED); - - Rollout rollout = rolloutManagement.getByName("rolloutToBeRetried").orElseThrow(); - - // no scheduler so invoke here - rolloutHandler.handleAll(); - rolloutManagement.start(rollout.getId()); - // no scheduler so invoke here - rolloutHandler.handleAll(); - - - testdataFactory.sendUpdateActionStatusToTargets(successTargets, Status.FINISHED, "Finished successfully!"); - testdataFactory.sendUpdateActionStatusToTargets(failedTargets, Status.ERROR, "Finished error!"); - - rolloutHandler.handleAll(); - - for (Target target : allTargets) { - final List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent(); - for (Action action : actions) { - if (action.getTarget().getControllerId().startsWith("retryRolloutTargetFailed")) { - Assertions.assertEquals(Status.ERROR, action.getStatus()); - } else { - Assertions.assertEquals(Status.FINISHED, action.getStatus()); - } - Assertions.assertEquals(rollout.getId(), action.getRollout().getId()); - } - } - - //retry rollout - mvc.perform(post("/rest/v1/rollouts/{rolloutId}/retry", rollout.getId())).andDo(MockMvcResultPrinter.print()) - .andExpect(status().is(201)); - - //search for _retried suffix - Rollout retriedRollout = rolloutManagement.getByName(rollout.getName() + "_retry").orElseThrow(); - //assert 4 targets involved - rolloutHandler.handleAll(); - - rolloutManagement.start(retriedRollout.getId()); - rolloutHandler.handleAll(); - - for (Target target : failedTargets) { - // for failed targets - check for 2 actions - one from old rollout and one from the retried - List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent(); - Assertions.assertEquals(2, actions.size()); - Assertions.assertEquals(Status.ERROR, actions.get(0).getStatus()); - Assertions.assertEquals(rollout.getId(), actions.get(0).getRollout().getId()); - Assertions.assertEquals(Status.RUNNING, actions.get(1).getStatus()); - Assertions.assertEquals(retriedRollout.getId(), actions.get(1).getRollout().getId()); - } - - for (Target target : successTargets) { - //ensure no other actions from the success targets are created - List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).getContent(); - Assertions.assertEquals(1, actions.size()); - Assertions.assertEquals(rollout.getId(), actions.get(0).getRollout().getId()); - } + private static Stream confirmationOptions() { + return Stream.of(Arguments.of(true, false), Arguments.of(true, true), Arguments.of(false, true)); } - @Test - @Description("Retrying a running rollout should not be allowed.") - public void retryNotFinishedRolloutShouldNotBeAllowed() throws Exception { - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - testdataFactory.createTargets("retryRolloutTarget-", 10); - postRollout("rolloutToBeRetried", 1, dsA.getId(), "id==retryRolloutTarget*", 10, Action.ActionType.FORCED); - Rollout rollout = rolloutManagement.getByName("rolloutToBeRetried").orElseThrow(); - // no scheduler so invoke here - rolloutHandler.handleAll(); - rolloutManagement.start(rollout.getId()); - // no scheduler so invoke here + @Step + private void retrieveAndVerifyRolloutInRunning(final Rollout rollout) throws Exception { rolloutHandler.handleAll(); - mvc.perform(post("/rest/v1/rollouts/{rolloutId}/retry", rollout.getId())).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isBadRequest()); + mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("running"))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(5))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(15))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); } - @Test - @Description("Retrying a non-existing rollout should lead to NOT FOUND.") - public void retryNonExistingRolloutShouldLeadToNotFound() throws Exception { - mvc.perform(post("/rest/v1/rollouts/{rolloutId}/retry", 6782623)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isNotFound()); + @Step + private void retrieveAndVerifyRolloutInStarting(final Rollout rollout) throws Exception { + rolloutManagement.start(rollout.getId()); + + mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("starting"))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(20))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); + } + + @Step + private void retrieveAndVerifyRolloutInReady(final Rollout rollout) throws Exception { + rolloutHandler.handleAll(); + + mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("ready"))) + .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(20))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); + } + + @Step + private void retrieveAndVerifyRolloutInCreating(final DistributionSet dsA, final Rollout rollout) throws Exception { + mvc.perform(get("/rest/v1/rollouts/" + rollout.getId()).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id", equalTo(rollout.getId().intValue()))) + .andExpect(jsonPath("$.name", equalTo("rollout1"))).andExpect(jsonPath("$.status", equalTo("creating"))) + .andExpect(jsonPath("$.targetFilterQuery", equalTo("controllerId==rollout*"))) + .andExpect(jsonPath("$.distributionSetId", equalTo(dsA.getId().intValue()))) + .andExpect(jsonPath("$.createdBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.createdAt", not(equalTo(0)))) + .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) + .andExpect(jsonPath("$.totalTargets", equalTo(20))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(20))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("$._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))) + .andExpect(jsonPath("$._links.start.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/start")))) + .andExpect(jsonPath("$._links.pause.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/pause")))) + .andExpect( + jsonPath("$._links.resume.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/resume")))) + .andExpect(jsonPath("$._links.triggerNextGroup.href", + allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/triggerNextGroup")))) + .andExpect(jsonPath("$._links.groups.href", + allOf(startsWith(HREF_ROLLOUT_PREFIX), containsString("/deploygroups")))) + .andExpect(jsonPath("$.deleted", equalTo(false))).andExpect(jsonPath("$.totalGroups", equalTo(4))); + } + + @Step + private void retrieveAndVerifyRolloutGroupInRunningAndScheduled(final Rollout rollout, + final RolloutGroup firstGroup, final RolloutGroup secondGroup, final boolean confirmationFlowEnabled, + final boolean confirmationRequired) throws Exception { + rolloutManagement.start(rollout.getId()); + rolloutHandler.handleAll(); + mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("status", equalTo("running"))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(5))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired", equalTo(confirmationRequired)) + : jsonPath("confirmationRequired").doesNotExist()); + + mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), secondGroup.getId()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("status", equalTo("scheduled"))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(5))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired", equalTo(confirmationRequired)) + : jsonPath("confirmationRequired").doesNotExist()); + ; + } + + @Step + private void retrieveAndVerifyRolloutGroupInReady(final Rollout rollout, final RolloutGroup firstGroup) + throws Exception { + rolloutHandler.handleAll(); + mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("status", equalTo("ready"))) + .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) + .andExpect(jsonPath("$.totalTargets", equalTo(5))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(5))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired").exists() + : jsonPath("confirmationRequired").doesNotExist()); + ; + } + + @Step + private void retrieveAndVerifyRolloutGroupInCreating(final Rollout rollout, final RolloutGroup firstGroup) + throws Exception { + mvc.perform(get("/rest/v1/rollouts/{rolloutId}/deploygroups/{groupId}", rollout.getId(), firstGroup.getId()) + .accept(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("id", equalTo(firstGroup.getId().intValue()))) + .andExpect(isConfirmationFlowEnabled() ? jsonPath("confirmationRequired").exists() + : jsonPath("confirmationRequired").doesNotExist()) + .andExpect(jsonPath("status", equalTo("creating"))).andExpect(jsonPath("name", endsWith("1"))) + .andExpect(jsonPath("description", endsWith("1"))) + .andExpect(jsonPath("$.targetFilterQuery", equalTo(""))) + .andExpect(jsonPath("$.targetPercentage", equalTo(25.0))) + .andExpect(jsonPath("$.createdBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.createdAt", not(equalTo(0)))) + .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) + .andExpect(jsonPath("$.totalTargets", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("$._links.self.href", equalTo( + HREF_ROLLOUT_PREFIX + rollout.getId() + "/deploygroups/" + firstGroup.getId().intValue()))); + } + + private void awaitRunningState(final Long rolloutId) { + Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with() + .until(() -> SecurityContextSwitch + .runAsPrivileged( + () -> rolloutManagement.get(rolloutId).orElseThrow(NoSuchElementException::new)) + .getStatus().equals(RolloutStatus.RUNNING)); + } + + private void awaitActionStatus(final Long actionId, final Status status) { + Awaitility.await().atMost(Duration.ofMinutes(1)).pollInterval(Duration.ofMillis(100)).with() + .until(() -> SecurityContextSwitch + .runAsPrivileged( + () -> deploymentManagement.findAction(actionId).orElseThrow(NoSuchElementException::new)) + .getStatus().equals(status)); + } + + private void assertStatusIs(final Rollout rollout, final RolloutStatus expected) { + final Optional updatedRollout = rolloutManagement.get(rollout.getId()); + assertThat(updatedRollout).get().extracting(Rollout::getStatus).isEqualTo(expected); + } + + private void postRollout(final String name, final int groupSize, final Long distributionSetId, + final String targetFilterQuery, final int targets, final Action.ActionType type) throws Exception { + postRollout(name, groupSize, distributionSetId, targetFilterQuery, targets, type, null, null); + } + + private void postRollout(final String name, final int groupSize, final Long distributionSetId, + final String targetFilterQuery, final int targets, final Action.ActionType type, final Long startTime, + final Long forceTime) throws Exception { + postRollout(name, groupSize, distributionSetId, targetFilterQuery, targets, type, startTime, forceTime, false, null, 0); + } + + private void postRollout(final String name, final int groupSize, final Long distributionSetId, + final String targetFilterQuery, final int targets, final Action.ActionType type, final Long startTime, + final Long forceTime, boolean isDynamic, String dynamicGroupSuffix, int dynamicGroupTargetsCount) throws Exception { + final String actionType = MgmtRestModelMapper.convertActionType(type).getName(); + final String rollout = JsonBuilder.rollout(name, "desc", groupSize, distributionSetId, targetFilterQuery, + new RolloutGroupConditionBuilder().withDefaults().build(), null, actionType, null, startTime, forceTime, + null, isDynamic, dynamicGroupSuffix, dynamicGroupTargetsCount); + + 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))) + .andExpect(jsonPath("$.description", equalTo("desc"))) + .andExpect(jsonPath("$.distributionSetId", equalTo(distributionSetId.intValue()))) + .andExpect(jsonPath("$.createdBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.createdAt", not(equalTo(0)))) + .andExpect(jsonPath("$.lastModifiedBy", equalTo("bumlux"))) + .andExpect(jsonPath("$.lastModifiedAt", not(equalTo(0)))) + .andExpect(jsonPath("$.totalTargets", equalTo(targets))) + .andExpect(startTime != null ? jsonPath("$.startAt", equalTo(startTime.intValue())) + : jsonPath("$.startAt").doesNotExist()) + .andExpect(forceTime != null ? jsonPath("$.forcetime", equalTo(forceTime.intValue())) + : jsonPath("$.forcetime", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.running", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.notstarted", equalTo(targets))) + .andExpect(jsonPath("$.totalTargetsPerStatus.scheduled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.cancelled", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.finished", equalTo(0))) + .andExpect(jsonPath("$.totalTargetsPerStatus.error", equalTo(0))) + .andExpect(jsonPath("$._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))) + .andExpect(jsonPath("$._links.start.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/start")))) + .andExpect(jsonPath("$._links.pause.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/pause")))) + .andExpect(jsonPath("$.dynamic", equalTo(isDynamic))) + .andExpect( + jsonPath("$._links.resume.href", allOf(startsWith(HREF_ROLLOUT_PREFIX), endsWith("/resume")))) + .andExpect(jsonPath("$._links.groups.href", + allOf(startsWith(HREF_ROLLOUT_PREFIX), containsString("/deploygroups")))); + } + + private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, + final String targetFilterQuery) { + return createRollout(name, amountGroups, distributionSetId, targetFilterQuery, false); + } + + private Rollout createRollout(final String name, final int amountGroups, final long distributionSetId, + final String targetFilterQuery, final boolean confirmationRequired) { + final Rollout rollout = rolloutManagement.create( + entityFactory.rollout().create().name(name).distributionSetId(distributionSetId).targetFilterQuery(targetFilterQuery), + amountGroups, confirmationRequired, new RolloutGroupConditionBuilder().withDefaults() + .successCondition(RolloutGroupSuccessCondition.THRESHOLD, "100").build()); + + // Run here, because Scheduler is disabled during tests + rolloutHandler.handleAll(); + + return rolloutManagement.get(rollout.getId()).orElseThrow(NoSuchElementException::new); } private void triggerNextGroupAndExpect(final Rollout rollout, final ResultMatcher expect) throws Exception { @@ -1865,7 +1863,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { : jsonPath("content[0]._links.groups.href").doesNotExist()) .andExpect(isFullRepresentation ? jsonPath("$.content[0]._links.distributionset.href", - startsWith("http://localhost/rest/v1/distributionsets/")) + startsWith("http://localhost/rest/v1/distributionsets/")) : jsonPath("content[0]._links.distributionset.href").doesNotExist()) .andExpect(jsonPath("content[0]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))) .andExpect(jsonPath("content[1].name", equalTo("rollout2"))) @@ -1908,7 +1906,7 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { : jsonPath("content[1]._links.groups.href").doesNotExist()) .andExpect(isFullRepresentation ? jsonPath("$.content[1]._links.distributionset.href", - startsWith("http://localhost/rest/v1/distributionsets/")) + startsWith("http://localhost/rest/v1/distributionsets/")) : jsonPath("content[1]._links.distributionset.href").doesNotExist()) .andExpect(jsonPath("content[1]._links.self.href", startsWith(HREF_ROLLOUT_PREFIX))); } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java index 45bb29b12..8403c5a89 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleResourceTest.java @@ -37,6 +37,10 @@ import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; +import com.jayway.jsonpath.JsonPath; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Story; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.RandomStringUtils; import org.awaitility.Awaitility; @@ -79,12 +83,6 @@ import org.springframework.test.web.servlet.ResultActions; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RestController; -import com.jayway.jsonpath.JsonPath; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Story; - /** * Tests for {@link MgmtSoftwareModuleResource} {@link RestController}. */ @@ -99,6 +97,119 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes assertThat(softwareModuleManagement.findAll(PAGE)).as("no softwaremodule should be founded").isEmpty(); } + @Test + @Description("Trying to create a SM from already marked as deleted type - should get as response 400 Bad Request") + public void createSMFromAlreadyMarkedAsDeletedType() throws Exception { + final String SM_TYPE = "someSmType"; + final SoftwareModule sm = testdataFactory.createSoftwareModule(SM_TYPE); + final DistributionSetType t = testdataFactory.findOrCreateDistributionSetType( + "testKey", "testType", Collections.singletonList(sm.getType()), + Collections.singletonList(sm.getType())); + final DistributionSetType type = testdataFactory.findOrCreateDistributionSetType("testKey", "testType"); + final DistributionSet ds = testdataFactory.createDistributionSet("name", "version", type, Collections.singletonList(sm)); + final Target target = testdataFactory.createTarget("test"); + + assignDistributionSet(ds, target); + //delete sm type + softwareModuleTypeManagement.delete(sm.getType().getId()); + + //check if it is marked as deleted + final Optional opt = softwareModuleTypeManagement.getByKey(SM_TYPE); + if (opt.isEmpty()) { + throw new AssertionError("The Optional object of software module type should not be empty!"); + } + final SoftwareModuleType smType = opt.get(); + Assert.isTrue(smType.isDeleted(), "Software Module Type not marked as deleted!"); + + //check if we'll get bad request if we try to create module from the deleted type + final MvcResult mvcResult = mvc.perform(post("/rest/v1/softwaremodules") + .content("[{\"description\":\"someDescription\",\"key\":\"someTestKey\", \"type\":\"" + SM_TYPE + "\"}]") + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isBadRequest()) + .andReturn(); + + final ExceptionInfo exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString()); + assertEquals("jakarta.validation.ValidationException", exceptionInfo.getExceptionClass()); + assertTrue(exceptionInfo.getMessage().contains("Software Module Type already deleted")); + } + + @Test + @Description("Handles the GET request of retrieving all meta data of artifacts assigned to a software module (in full representation mode including a download URL by the artifact provider).") + public void getArtifactsWithParameters() throws Exception { + final SoftwareModule sm = testdataFactory.createSoftwareModuleOs(); + + final byte[] random = RandomStringUtils.random(5).getBytes(); + + artifactManagement.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, 0)); + + mvc.perform( + get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts", sm.getId()) + .param("representation", MgmtRepresentationMode.FULL.toString()) + .param("useartifacturlhandler", Boolean.TRUE.toString())) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)); + } + + @Test + @Description(" Get a paged list of meta data for a software module.") + public void getMetadata() throws Exception { + final int totalMetadata = 4; + final String knownKeyPrefix = "knownKey"; + final String knownValuePrefix = "knownValue"; + final SoftwareModule module = testdataFactory.createDistributionSet("one").findFirstModuleByType(osType).get(); + + for (int index = 0; index < totalMetadata; index++) { + softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata().create(module.getId()) + .key(knownKeyPrefix + index).value(knownValuePrefix + index)); + } + + mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata", + module.getId())).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)); + } + + @Test + @Description(" Get a paged list of meta data for a software module with defined page size and sorting by name descending and key starting with 'known'.") + public void getMetadataWithParameters() throws Exception { + final int totalMetadata = 4; + final String knownKeyPrefix = "knownKey"; + final String knownValuePrefix = "knownValue"; + final SoftwareModule module = testdataFactory.createDistributionSet("one").findFirstModuleByType(osType).get(); + + for (int index = 0; index < totalMetadata; index++) { + softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata().create(module.getId()) + .key(knownKeyPrefix + index).value(knownValuePrefix + index)); + } + + mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata", + module.getId()).param("offset", "1").param("limit", "2").param("sort", "key:DESC").param("q", + "key==known*")) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)); + } + + @Test + @Description(" Get a single meta data value for a meta data key.") + public void getMetadataValue() throws Exception { + + // prepare and create metadata + final String knownKey = "knownKey"; + final String knownValue = "knownValue"; + final SoftwareModule module = testdataFactory.createDistributionSet("one").findFirstModuleByType(osType).get(); + softwareModuleManagement.createMetaData( + entityFactory.softwareModuleMetadata().create(module.getId()).key(knownKey).value(knownValue)); + + mvc.perform( + get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata/{metadataKey}", + module.getId(), knownKey)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + } + @Test @Description("Tests the update of software module metadata. It is verfied that only the selected fields for the update are really updated and the modification values are filled (i.e. updated by and at).") @WithUser(principal = "smUpdateTester", allSpPermissions = true) @@ -335,35 +446,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes .andExpect(jsonPath("$.message", containsString("Invalid characters in string"))); } - private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException { - // check result in db... - // repo - assertThat(artifactManagement.count()).as("Wrong artifact size").isEqualTo(1); - - // binary - try (final InputStream fileInputStream = artifactManagement - .loadArtifactBinary(softwareModuleManagement.get(sm.getId()).get().getArtifacts().get(0).getSha1Hash(), - sm.getId(), sm.isEncrypted()) - .get().getFileInputStream()) { - assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random), fileInputStream), - "Wrong artifact content"); - } - - // hashes - assertThat(artifactManagement.getByFilename("origFilename").get().getSha1Hash()).as("Wrong sha1 hash") - .isEqualTo(HashGeneratorUtils.generateSHA1(random)); - - assertThat(artifactManagement.getByFilename("origFilename").get().getMd5Hash()).as("Wrong md5 hash") - .isEqualTo(HashGeneratorUtils.generateMD5(random)); - - assertThat(artifactManagement.getByFilename("origFilename").get().getSha256Hash()).as("Wrong sha256 hash") - .isEqualTo(HashGeneratorUtils.generateSHA256(random)); - - // metadata - assertThat(softwareModuleManagement.get(sm.getId()).get().getArtifacts().get(0).getFilename()) - .as("wrong metadata of the filename").isEqualTo("origFilename"); - } - @Test @Description("Verifies that the system does not accept empty artifact uploads. Expected response: BAD REQUEST") void emptyUploadArtifact() throws Exception { @@ -430,43 +512,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes assertThat(artifactManagement.getByFilename("customFilename")).as("Local artifact is wrong").isPresent(); } - @Test - @Description("Trying to create a SM from already marked as deleted type - should get as response 400 Bad Request") - public void createSMFromAlreadyMarkedAsDeletedType() throws Exception { - final String SM_TYPE = "someSmType"; - final SoftwareModule sm = testdataFactory.createSoftwareModule(SM_TYPE); - final DistributionSetType t = testdataFactory.findOrCreateDistributionSetType( - "testKey", "testType", Collections.singletonList(sm.getType()), - Collections.singletonList(sm.getType())); - final DistributionSetType type = testdataFactory.findOrCreateDistributionSetType("testKey", "testType"); - final DistributionSet ds = testdataFactory.createDistributionSet("name", "version", type, Collections.singletonList(sm)); - final Target target = testdataFactory.createTarget("test"); - - assignDistributionSet(ds, target); - //delete sm type - softwareModuleTypeManagement.delete(sm.getType().getId()); - - //check if it is marked as deleted - final Optional opt = softwareModuleTypeManagement.getByKey(SM_TYPE); - if (opt.isEmpty()) { - throw new AssertionError("The Optional object of software module type should not be empty!"); - } - final SoftwareModuleType smType = opt.get(); - Assert.isTrue(smType.isDeleted(), "Software Module Type not marked as deleted!"); - - //check if we'll get bad request if we try to create module from the deleted type - final MvcResult mvcResult = mvc.perform(post("/rest/v1/softwaremodules") - .content("[{\"description\":\"someDescription\",\"key\":\"someTestKey\", \"type\":\"" + SM_TYPE + "\"}]") - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isBadRequest()) - .andReturn(); - - final ExceptionInfo exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString()); - assertEquals("jakarta.validation.ValidationException", exceptionInfo.getExceptionClass()); - assertTrue(exceptionInfo.getMessage().contains("Software Module Type already deleted")); - } - @Test @Description("Verifies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST") void uploadArtifactWithHashCheck() throws Exception { @@ -515,7 +560,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes .isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH.getKey()); mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file) - .param("md5sum", md5sum).param("sha1sum", sha1sum)).andDo(MockMvcResultPrinter.print()) + .param("md5sum", md5sum).param("sha1sum", sha1sum)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()); assertArtifact(sm, random); @@ -538,7 +583,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // upload mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.hashes.md5", equalTo(md5sum))) .andExpect(jsonPath("$.hashes.sha1", equalTo(sha1sum))) @@ -553,7 +598,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // upload mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -581,7 +626,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // upload final SoftwareModule sm = testdataFactory.createSoftwareModuleOs("sm" + i); mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.hashes.md5", equalTo(md5sum))) .andExpect(jsonPath("$.hashes.sha1", equalTo(sha1sum))) @@ -597,7 +642,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // upload final SoftwareModule sm = testdataFactory.createSoftwareModuleOs("sm" + numArtifacts); mvc.perform(multipart("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(StorageQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_STORAGE_QUOTA_EXCEEDED.getKey()))); @@ -624,17 +669,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes assertThat(artifactManagement.count()).isEqualTo(2); } - private void downloadAndVerify(final SoftwareModule sm, final byte[] random, final Artifact artifact) - throws Exception { - final MvcResult result = mvc - .perform( - get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download", sm.getId(), artifact.getId())) - .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)) - .andExpect(header().string("ETag", artifact.getSha1Hash())).andReturn(); - - assertTrue(Arrays.equals(result.getResponse().getContentAsByteArray(), random), "Wrong response content"); - } - @Test @Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.") void getArtifact() throws Exception { @@ -649,7 +683,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // perform test mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue()))) .andExpect(jsonPath("$.size", equalTo(random.length))) @@ -680,8 +714,8 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // perform test mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}", sm.getId(), artifact.getId()) - .param("useartifacturlhandler", String.valueOf(useArtifactUrlHandler)) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .param("useartifacturlhandler", String.valueOf(useArtifactUrlHandler)) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.id", equalTo(artifact.getId().intValue()))) .andExpect(jsonPath("$.size", equalTo(random.length))) @@ -760,24 +794,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes "http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artifact2.getId()))); } - @Test - @Description("Handles the GET request of retrieving all meta data of artifacts assigned to a software module (in full representation mode including a download URL by the artifact provider).") - public void getArtifactsWithParameters() throws Exception { - final SoftwareModule sm = testdataFactory.createSoftwareModuleOs(); - - final byte[] random = RandomStringUtils.random(5).getBytes(); - - artifactManagement.create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file1", false, 0)); - - mvc.perform( - get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/artifacts", sm.getId()) - .param("representation", MgmtRepresentationMode.FULL.toString()) - .param("useartifacturlhandler", Boolean.TRUE.toString())) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)); - } - @ParameterizedTest @ValueSource(booleans = { true, false }) @Description("Verifies the listing of all artifacts assigned to a software module. That includes the artifact metadata and download links.") @@ -793,9 +809,9 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes .create(new ArtifactUpload(new ByteArrayInputStream(random), sm.getId(), "file2", false, artifactSize)); mvc.perform(get("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()) - .param("representation", MgmtRepresentationMode.FULL.toString()) - .param("useartifacturlhandler", String.valueOf(useArtifactUrlHandler)) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .param("representation", MgmtRepresentationMode.FULL.toString()) + .param("useartifacturlhandler", String.valueOf(useArtifactUrlHandler)) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[0].id", equalTo(artifact.getId().intValue()))) .andExpect(jsonPath("$.[0].size", equalTo(random.length))) @@ -932,27 +948,27 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes .andExpect(status().isBadRequest()); mvc.perform(post("/rest/v1/softwaremodules") - .content("[{\"description\":\"Desc123\",\"key\":\"test123\", \"type\":\"os\"}]") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content("[{\"description\":\"Desc123\",\"key\":\"test123\", \"type\":\"os\"}]") + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final SoftwareModule toLongName = entityFactory.softwareModule().create().type(osType) .name(RandomStringUtils.randomAlphanumeric(80)).build(); mvc.perform(post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(Arrays.asList(toLongName))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); // unsupported media type mvc.perform(post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(modules)) - .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnsupportedMediaType()); final SoftwareModule swm = entityFactory.softwareModule().create().name("encryptedModule").type(osType) .version("version").vendor("vendor").description("description").encrypted(true).build(); // artifact decryption is not supported mvc.perform( - post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(Collections.singletonList(swm))) - .contentType(MediaType.APPLICATION_JSON)) + post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(Collections.singletonList(swm))) + .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()); // not allowed methods @@ -1069,7 +1085,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // by type, 2 software modules per type exists mvc.perform(get("/rest/v1/softwaremodules?q=type==" + Constants.SMT_DEFAULT_APP_KEY) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[?(@.id==" + app1.getId() + ")].name", contains(app1.getName()))) .andExpect(jsonPath("$.content.[?(@.id==" + app1.getId() + ")].version", contains(app1.getVersion()))) @@ -1089,7 +1105,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes // by type and version=2.0.0 -> only one result mvc.perform(get( - "/rest/v1/softwaremodules?q=type==" + Constants.SMT_DEFAULT_APP_KEY + ";version==" + app1.getVersion()) + "/rest/v1/softwaremodules?q=type==" + Constants.SMT_DEFAULT_APP_KEY + ";version==" + app1.getVersion()) .accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -1292,7 +1308,7 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes metaData1.put(new JSONObject().put("key", knownKey2).put("value", knownValue2).put("targetVisible", true)); mvc.perform(post("/rest/v1/softwaremodules/{swId}/metadata", sm.getId()).accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON).content(metaData1.toString())) + .contentType(MediaType.APPLICATION_JSON).content(metaData1.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("[0].key", equalTo(knownKey1))) @@ -1316,75 +1332,17 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes } mvc.perform(post("/rest/v1/softwaremodules/{swId}/metadata", sm.getId()).accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON).content(metaData2.toString())) + .contentType(MediaType.APPLICATION_JSON).content(metaData2.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()); // verify that the number of meta data entries has not changed // (we cannot use the PAGE constant here as it tries to sort by ID) assertThat(softwareModuleManagement .findMetaDataBySoftwareModuleId(PageRequest.of(0, Integer.MAX_VALUE), sm.getId()).getTotalElements()) - .isEqualTo(metaData1.length()); + .isEqualTo(metaData1.length()); } - @Test - @Description(" Get a paged list of meta data for a software module.") - public void getMetadata() throws Exception { - final int totalMetadata = 4; - final String knownKeyPrefix = "knownKey"; - final String knownValuePrefix = "knownValue"; - final SoftwareModule module = testdataFactory.createDistributionSet("one").findFirstModuleByType(osType).get(); - - for (int index = 0; index < totalMetadata; index++) { - softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata().create(module.getId()) - .key(knownKeyPrefix + index).value(knownValuePrefix + index)); - } - - mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata", - module.getId())).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)); - } - - @Test - @Description(" Get a paged list of meta data for a software module with defined page size and sorting by name descending and key starting with 'known'.") - public void getMetadataWithParameters() throws Exception { - final int totalMetadata = 4; - final String knownKeyPrefix = "knownKey"; - final String knownValuePrefix = "knownValue"; - final SoftwareModule module = testdataFactory.createDistributionSet("one").findFirstModuleByType(osType).get(); - - for (int index = 0; index < totalMetadata; index++) { - softwareModuleManagement.createMetaData(entityFactory.softwareModuleMetadata().create(module.getId()) - .key(knownKeyPrefix + index).value(knownValuePrefix + index)); - } - - mvc.perform(get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata", - module.getId()).param("offset", "1").param("limit", "2").param("sort", "key:DESC").param("q", - "key==known*")) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)); - } - - @Test - @Description(" Get a single meta data value for a meta data key." ) - public void getMetadataValue() throws Exception { - - // prepare and create metadata - final String knownKey = "knownKey"; - final String knownValue = "knownValue"; - final SoftwareModule module = testdataFactory.createDistributionSet("one").findFirstModuleByType(osType).get(); - softwareModuleManagement.createMetaData( - entityFactory.softwareModuleMetadata().create(module.getId()).key(knownKey).value(knownValue)); - - mvc.perform( - get(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}/metadata/{metadataKey}", - module.getId(), knownKey)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - } - @Test @Description("Verifies the successful update of metadata based on given key.") void updateMetadataKey() throws Exception { @@ -1485,6 +1443,50 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes .andExpect(jsonPath("content[0].value", equalTo("knownValue1"))); } + private static byte[] randomBytes(final int len) { + return RandomStringUtils.randomAlphanumeric(len).getBytes(); + } + + private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException { + // check result in db... + // repo + assertThat(artifactManagement.count()).as("Wrong artifact size").isEqualTo(1); + + // binary + try (final InputStream fileInputStream = artifactManagement + .loadArtifactBinary(softwareModuleManagement.get(sm.getId()).get().getArtifacts().get(0).getSha1Hash(), + sm.getId(), sm.isEncrypted()) + .get().getFileInputStream()) { + assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random), fileInputStream), + "Wrong artifact content"); + } + + // hashes + assertThat(artifactManagement.getByFilename("origFilename").get().getSha1Hash()).as("Wrong sha1 hash") + .isEqualTo(HashGeneratorUtils.generateSHA1(random)); + + assertThat(artifactManagement.getByFilename("origFilename").get().getMd5Hash()).as("Wrong md5 hash") + .isEqualTo(HashGeneratorUtils.generateMD5(random)); + + assertThat(artifactManagement.getByFilename("origFilename").get().getSha256Hash()).as("Wrong sha256 hash") + .isEqualTo(HashGeneratorUtils.generateSHA256(random)); + + // metadata + assertThat(softwareModuleManagement.get(sm.getId()).get().getArtifacts().get(0).getFilename()) + .as("wrong metadata of the filename").isEqualTo("origFilename"); + } + + private void downloadAndVerify(final SoftwareModule sm, final byte[] random, final Artifact artifact) + throws Exception { + final MvcResult result = mvc + .perform( + get("/rest/v1/softwaremodules/{smId}/artifacts/{artId}/download", sm.getId(), artifact.getId())) + .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)) + .andExpect(header().string("ETag", artifact.getSha1Hash())).andReturn(); + + assertTrue(Arrays.equals(result.getResponse().getContentAsByteArray(), random), "Wrong response content"); + } + private void createSoftwareModulesAlphabetical(final int amount) { char character = 'a'; for (int index = 0; index < amount; index++) { @@ -1495,8 +1497,4 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes } } - private static byte[] randomBytes(final int len) { - return RandomStringUtils.randomAlphanumeric(len).getBytes(); - } - } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResourceTest.java index bf664391b..970212364 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeResourceTest.java @@ -26,6 +26,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.jayway.jsonpath.JsonPath; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Story; import org.apache.commons.lang3.RandomStringUtils; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.repository.model.NamedEntity; @@ -38,15 +42,8 @@ import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; -import com.jayway.jsonpath.JsonPath; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Story; - /** * Test for {@link MgmtSoftwareModuleTypeResource}. - * */ @Feature("Component Tests - Management API") @Story("Software Module Type Resource") @@ -109,14 +106,6 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt .andExpect(status().isOk()); } - private SoftwareModuleType createTestType() { - SoftwareModuleType testType = softwareModuleTypeManagement.create(entityFactory.softwareModuleType().create() - .key("test123").name("TestName123").description("Desc123").colour("colour").maxAssignments(5)); - testType = softwareModuleTypeManagement - .update(entityFactory.softwareModuleType().update(testType.getId()).description("Desc1234")); - return testType; - } - @Test @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Checks the correct behaviour of /rest/v1/softwaremoduletypes GET requests with sorting by MAXASSIGNMENTS field.") @@ -125,7 +114,7 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt // descending mvc.perform(get("/rest/v1/softwaremoduletypes").accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "MAXASSIGNMENTS:DESC")) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "MAXASSIGNMENTS:DESC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[1].id", equalTo(testType.getId().intValue()))) @@ -142,7 +131,7 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt // ascending mvc.perform(get("/rest/v1/softwaremoduletypes").accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "MAXASSIGNMENTS:ASC")) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "MAXASSIGNMENTS:ASC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[2].id", equalTo(testType.getId().intValue()))) @@ -167,14 +156,14 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt .build()); mvc.perform(post("/rest/v1/softwaremoduletypes").content(JsonBuilder.softwareModuleTypes(types)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()); types.clear(); types.add(entityFactory.softwareModuleType().create().key("test0").name("TestName0").maxAssignments(0).build()); mvc.perform(post("/rest/v1/softwaremoduletypes").content(JsonBuilder.softwareModuleTypes(types)) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()); } @@ -216,13 +205,13 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt assertThat( JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/softwaremoduletypes/" + created1.getId()); + .isEqualTo("http://localhost/rest/v1/softwaremoduletypes/" + created1.getId()); assertThat( JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/softwaremoduletypes/" + created2.getId()); + .isEqualTo("http://localhost/rest/v1/softwaremoduletypes/" + created2.getId()); assertThat( JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/softwaremoduletypes/" + created3.getId()); + .isEqualTo("http://localhost/rest/v1/softwaremoduletypes/" + created3.getId()); assertThat(softwareModuleTypeManagement.count()).isEqualTo(6); } @@ -299,7 +288,7 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt .put("colour", "updatedColour").put("name", "nameShouldNotBeChanged").toString(); mvc.perform(put("/rest/v1/softwaremoduletypes/{smId}", testType.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.description", equalTo("foobardesc"))) .andExpect(jsonPath("$.colour", equalTo("updatedColour"))) @@ -315,7 +304,7 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt final String body = new JSONObject().put("id", testType.getId()).put("deleted", true).toString(); mvc.perform(put("/rest/v1/softwaremoduletypes/{smtId}", testType.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.lastModifiedAt", equalTo(testType.getLastModifiedAt()))) .andExpect(jsonPath("$.deleted", equalTo(false))); @@ -342,7 +331,7 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt final int types = 3; final int limitSize = 1; mvc.perform(get(MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(types))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -356,8 +345,8 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt final int offsetParam = 2; final int expectedSize = types - offsetParam; mvc.perform(get(MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(types))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(types))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(types))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -384,24 +373,24 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt // bad request - bad content mvc.perform(post("/rest/v1/softwaremoduletypes").content("sdfjsdlkjfskdjf".getBytes()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); mvc.perform(post("/rest/v1/softwaremoduletypes").content( - "[{\"description\":\"Desc123\",\"id\":9223372036854775807,\"key\":\"test123\",\"maxAssignments\":5}]") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + "[{\"description\":\"Desc123\",\"id\":9223372036854775807,\"key\":\"test123\",\"maxAssignments\":5}]") + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final SoftwareModuleType toLongName = entityFactory.softwareModuleType().create().key("test123") .name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1)).build(); mvc.perform( - post("/rest/v1/softwaremoduletypes").content(JsonBuilder.softwareModuleTypes(Arrays.asList(toLongName))) - .contentType(MediaType.APPLICATION_JSON)) + post("/rest/v1/softwaremoduletypes").content(JsonBuilder.softwareModuleTypes(Arrays.asList(toLongName))) + .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()); // unsupported media type mvc.perform(post("/rest/v1/softwaremoduletypes").content(JsonBuilder.softwareModuleTypes(types)) - .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnsupportedMediaType()); // not allowed methods @@ -430,6 +419,14 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt } + private SoftwareModuleType createTestType() { + SoftwareModuleType testType = softwareModuleTypeManagement.create(entityFactory.softwareModuleType().create() + .key("test123").name("TestName123").description("Desc123").colour("colour").maxAssignments(5)); + testType = softwareModuleTypeManagement + .update(entityFactory.softwareModuleType().update(testType.getId()).description("Desc1234")); + return testType; + } + private void createSoftwareModulesAlphabetical(final int amount) { char character = 'a'; for (int index = 0; index < amount; index++) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java index 1e21305cb..fd8a0c8be 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java @@ -26,6 +26,10 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.stream.Stream; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Step; +import io.qameta.allure.Story; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; @@ -49,20 +53,14 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Step; -import io.qameta.allure.Story; import org.springframework.web.util.UriUtils; /** * Spring MVC Tests against the MgmtTargetResource. - * */ @Feature("Component Tests - Management API") @Story("Target Filter Query Resource") -public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiIntegrationTest { +public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiIntegrationTest { private static final String JSON_PATH_ROOT = "$"; @@ -72,19 +70,17 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt private static final String JSON_PATH_FIELD_QUERY = ".query"; private static final String JSON_PATH_FIELD_CONFIRMATION_REQUIRED = ".confirmationRequired"; private static final String JSON_PATH_FIELD_CONTENT = ".content"; + // target + // $.field + static final String JSON_PATH_PAGED_LIST_CONTENT = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTENT; private static final String JSON_PATH_FIELD_SIZE = ".size"; + static final String JSON_PATH_PAGED_LIST_SIZE = JSON_PATH_ROOT + JSON_PATH_FIELD_SIZE; private static final String JSON_PATH_FIELD_TOTAL = ".total"; + static final String JSON_PATH_PAGED_LIST_TOTAL = JSON_PATH_ROOT + JSON_PATH_FIELD_TOTAL; private static final String JSON_PATH_FIELD_AUTO_ASSIGN_DS = ".autoAssignDistributionSet"; private static final String JSON_PATH_FIELD_AUTO_ASSIGN_ACTION_TYPE = ".autoAssignActionType"; private static final String JSON_PATH_FIELD_EXCEPTION_CLASS = ".exceptionClass"; private static final String JSON_PATH_FIELD_ERROR_CODE = ".errorCode"; - - // target - // $.field - static final String JSON_PATH_PAGED_LIST_CONTENT = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTENT; - static final String JSON_PATH_PAGED_LIST_SIZE = JSON_PATH_ROOT + JSON_PATH_FIELD_SIZE; - static final String JSON_PATH_PAGED_LIST_TOTAL = JSON_PATH_ROOT + JSON_PATH_FIELD_TOTAL; - private static final String JSON_PATH_NAME = JSON_PATH_ROOT + JSON_PATH_FIELD_NAME; private static final String JSON_PATH_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID; private static final String JSON_PATH_QUERY = JSON_PATH_ROOT + JSON_PATH_FIELD_QUERY; @@ -170,7 +166,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt final TargetFilterQuery tfq = createSingleTargetFilterQuery(filterName, filterQuery); mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk()) .andExpect(jsonPath(JSON_PATH_ID, equalTo(tfq.getId().intValue()))) .andExpect(jsonPath(JSON_PATH_QUERY, equalTo(filterQuery2))) .andExpect(jsonPath(JSON_PATH_NAME, equalTo(filterName))) @@ -194,7 +190,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt .create(entityFactory.targetFilterQuery().create().name(filterName).query(filterQuery)); mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId()).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk()) .andExpect(jsonPath(JSON_PATH_ID, equalTo(tfq.getId().intValue()))) .andExpect(jsonPath(JSON_PATH_QUERY, equalTo(filterQuery))) .andExpect(jsonPath(JSON_PATH_NAME, equalTo(filterName2))) @@ -249,7 +245,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt createSingleTargetFilterQuery(idC, testQuery); mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andExpect(status().isOk()).andDo(print()) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount))) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -266,38 +262,38 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt final DistributionSet set = testdataFactory.createDistributionSet(); final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("a", testQuery); final String hrefPrefix = "http://localhost" + MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" - + filterQuery.getId(); + + filterQuery.getId(); final String distributionsetHrefPrefix = "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING; final String dsQuery = "?offset=0&limit=50&q=name==" + set.getName() + ";" + "version==" + set.getVersion(); mvc.perform( - post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) - .andDo(print()).andExpect(status().isOk()); + post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .andDo(print()).andExpect(status().isOk()); final String result = mvc.perform( - get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId())) - .andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS"))) - .andExpect(jsonPath("$._links.DS.href", startsWith(distributionsetHrefPrefix))) - .andReturn().getResponse().getContentAsString(); + get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId())) + .andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS"))) + .andExpect(jsonPath("$._links.DS.href", startsWith(distributionsetHrefPrefix))) + .andReturn().getResponse().getContentAsString(); final String multipleResult = mvc.perform( - get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "?representation=full")) - .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) - .andExpect(jsonPath("$.content[0]._links.DS.href", startsWith(distributionsetHrefPrefix))) - .andReturn().getResponse().getContentAsString(); + get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "?representation=full")) + .andExpect(jsonPath("$.content", hasSize(1))).andExpect(jsonPath("$.total", equalTo(1))) + .andExpect(jsonPath("$.content[0]._links.DS.href", startsWith(distributionsetHrefPrefix))) + .andReturn().getResponse().getContentAsString(); final JSONObject singleJson = new JSONObject(result); final JSONObject multipleJson = new JSONObject(multipleResult); final String resultDSURI = singleJson.getJSONObject("_links").getJSONObject("DS").getString("href"); final String resultDSURIFromMultipleJson = multipleJson.getJSONArray("content").getJSONObject(0) - .getJSONObject("_links").getJSONObject("DS").getString("href"); + .getJSONObject("_links").getJSONObject("DS").getString("href"); Assertions.assertEquals(distributionsetHrefPrefix + dsQuery, UriUtils.decode(resultDSURI, StandardCharsets.UTF_8)); Assertions.assertEquals(distributionsetHrefPrefix + dsQuery, - UriUtils.decode(resultDSURIFromMultipleJson, StandardCharsets.UTF_8)); + UriUtils.decode(resultDSURIFromMultipleJson, StandardCharsets.UTF_8)); } @Test @@ -318,8 +314,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt createSingleTargetFilterQuery(idE, testQuery); mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(knownTargetAmount))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(knownTargetAmount))) .andExpect(status().isOk()).andDo(print()) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount))) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -413,10 +409,9 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt final DistributionSet set = testdataFactory.createDistributionSet(); final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target*"); - mvc.perform( - post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(print()).andExpect(status().isForbidden()) .andExpect( jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(AssignmentQuotaExceededException.class.getName()))) @@ -438,8 +433,8 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt // assign the auto-assign distribution set, this should work mvc.perform( - post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(print()).andExpect(status().isOk()); implicitLock(set); @@ -450,7 +445,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt // update the query of the filter query to trigger a quota hit mvc.perform(put(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId()) - .content("{\"query\":\"controllerId==target*\"}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"query\":\"controllerId==target*\"}").contentType(MediaType.APPLICATION_JSON)) .andDo(print()).andExpect(status().isForbidden()) .andExpect( jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(AssignmentQuotaExceededException.class.getName()))) @@ -485,145 +480,6 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt verifyAutoAssignmentWithSoftDeletedDs(tfq); } - @ParameterizedTest - @ValueSource(booleans = { true, false }) - @Description("Verify the confirmation required flag will be set based on the feature state") - void verifyConfirmationStateIfNotProvided(final boolean confirmationFlowActive) throws Exception { - final String knownQuery = "name==test05"; - final String knownName = "filter05"; - - if (confirmationFlowActive) { - enableConfirmationFlow(); - } - - final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery); - final DistributionSet set = testdataFactory.createDistributionSet(); - - // do not provide something about the confirmation - verifyAutoAssignmentByActionType(tfq, set, null, null); - - assertThat(targetFilterQueryManagement.get(tfq.getId())).hasValueSatisfying(filter -> { - assertThat(filter.isConfirmationRequired()).isEqualTo(confirmationFlowActive); - }); - } - - private static Stream confirmationOptions() { - return Stream.of(Arguments.of(true, false), Arguments.of(true, true), Arguments.of(false, true), - Arguments.of(true, null), Arguments.of(false, null)); - } - - @Step - private void verifyAutoAssignmentWithoutActionType(final TargetFilterQuery tfq, final DistributionSet set, - final Boolean confirmationRequired) throws Exception { - verifyAutoAssignmentByActionType(tfq, set, null, confirmationRequired); - } - - @Step - private void verifyAutoAssignmentWithForcedActionType(final TargetFilterQuery tfq, final DistributionSet set, - final Boolean confirmationRequired) throws Exception { - verifyAutoAssignmentByActionType(tfq, set, MgmtActionType.FORCED, confirmationRequired); - } - - @Step - private void verifyAutoAssignmentWithSoftActionType(final TargetFilterQuery tfq, final DistributionSet set, - final Boolean confirmationRequired) throws Exception { - verifyAutoAssignmentByActionType(tfq, set, MgmtActionType.SOFT, confirmationRequired); - } - - private void verifyAutoAssignmentByActionType(final TargetFilterQuery tfq, final DistributionSet set, - final MgmtActionType actionType, final Boolean confirmationRequired) throws Exception { - final String hrefPrefix = "http://localhost" + MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" - + tfq.getId(); - - final JSONObject jsonObject = new JSONObject(); - jsonObject.put("id", set.getId()); - if (actionType != null) { - jsonObject.put("type", actionType.getName()); - } - if (confirmationRequired != null) { - jsonObject.put("confirmationRequired", confirmationRequired); - } - - mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") - .content(jsonObject.toString()).contentType(MediaType.APPLICATION_JSON)).andDo(print()) - .andExpect(status().isOk()); - implicitLock(set); - - final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get(); - final MgmtActionType expectedActionType = actionType != null ? actionType : MgmtActionType.FORCED; - - assertThat(updatedFilterQuery.getAutoAssignDistributionSet()).isEqualTo(set); - 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()))) - .andExpect(jsonPath(JSON_PATH_QUERY, equalTo(tfq.getQuery()))) - .andExpect(isConfirmationFlowEnabled() - ? jsonPath(JSON_PATH_CONFIRMATION_REQUIRED, - equalTo(confirmationRequired == null || confirmationRequired)) - : jsonPath(JSON_PATH_CONFIRMATION_REQUIRED).doesNotExist()) - .andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_DS, equalTo(set.getId().intValue()))) - .andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_ACTION_TYPE, equalTo(expectedActionType.getName()))) - .andExpect(jsonPath("$._links.self.href", equalTo(hrefPrefix))) - .andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS"))); - } - - @Step - private void verifyAutoAssignmentWithTimeForcedActionType(final TargetFilterQuery tfq, final DistributionSet set) - 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()) - .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, - equalTo(InvalidAutoAssignActionTypeException.class.getName()))) - .andExpect(jsonPath(JSON_PATH_ERROR_CODE, - equalTo(SpServerError.SP_AUTO_ASSIGN_ACTION_TYPE_INVALID.getKey()))); - } - - @Step - private void verifyAutoAssignmentWithDownloadOnlyActionType(final TargetFilterQuery tfq, final DistributionSet set, - final Boolean confirmationRequired) throws Exception { - verifyAutoAssignmentByActionType(tfq, set, MgmtActionType.DOWNLOAD_ONLY, confirmationRequired); - } - - @Step - private void verifyAutoAssignmentWithUnknownActionType(final TargetFilterQuery tfq, final DistributionSet set) - throws Exception { - mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") - .content("{\"id\":" + set.getId() + ", \"type\":\"unknown\"}").contentType(MediaType.APPLICATION_JSON)) - .andDo(print()).andExpect(status().isBadRequest()) - .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(MessageNotReadableException.class.getName()))) - .andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_REST_BODY_NOT_READABLE.getKey()))); - } - - @Step - private void verifyAutoAssignmentWithIncompleteDs(final TargetFilterQuery tfq) throws Exception { - final DistributionSet incompleteDistributionSet = distributionSetManagement - .create(entityFactory.distributionSet().create().name("incomplete").version("1") - .type(testdataFactory.findOrCreateDefaultTestDsType())); - - mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") - .content("{\"id\":" + incompleteDistributionSet.getId() + "}").contentType(MediaType.APPLICATION_JSON)) - .andDo(print()).andExpect(status().isBadRequest()) - .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, - equalTo(IncompleteDistributionSetException.class.getName()))) - .andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_DS_INCOMPLETE.getKey()))); - } - - @Step - private void verifyAutoAssignmentWithSoftDeletedDs(final TargetFilterQuery tfq) throws Exception { - final DistributionSet softDeletedDs = testdataFactory.createDistributionSet("softDeleted"); - assignDistributionSet(softDeletedDs, testdataFactory.createTarget("forSoftDeletedDs")); - distributionSetManagement.delete(softDeletedDs.getId()); - - mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") - .content("{\"id\":" + softDeletedDs.getId() + "}").contentType(MediaType.APPLICATION_JSON)) - .andDo(print()).andExpect(status().isNotFound()) - .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(DeletedException.class.getName()))) - .andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_DELETED.getKey()))); - } - @Test @Description("Handles the GET request of retrieving a the auto assign distribution set of a target filter query within SP.") public void getAssignDS() throws Exception { @@ -631,7 +487,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt final DistributionSet ds = testdataFactory.createDistributionSet("ds"); targetFilterQueryManagement .updateAutoAssignDS(entityFactory.targetFilterQuery() - .updateAutoAssign(filterQuery.getId()).ds(ds.getId())); + .updateAutoAssign(filterQuery.getId()).ds(ds.getId())); mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS", filterQuery.getId())) @@ -653,7 +509,7 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt mvc .perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS", - filterQuery.getId()).contentType(MediaType.APPLICATION_JSON).content(autoAssignBody.toString())) + filterQuery.getId()).contentType(MediaType.APPLICATION_JSON).content(autoAssignBody.toString())) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); } @@ -716,15 +572,15 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt 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()) + filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print()) .andExpect(status().isOk()); enableMultiAssignments(); mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS", - filterId).content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print()) + 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()) + filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print()) .andExpect(status().isOk()); final List filters = targetFilterQueryManagement.findAll(PAGE).getContent(); @@ -732,6 +588,145 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt assertThat(filters.get(0).getAutoAssignWeight().get()).isEqualTo(45); } + @ParameterizedTest + @ValueSource(booleans = { true, false }) + @Description("Verify the confirmation required flag will be set based on the feature state") + void verifyConfirmationStateIfNotProvided(final boolean confirmationFlowActive) throws Exception { + final String knownQuery = "name==test05"; + final String knownName = "filter05"; + + if (confirmationFlowActive) { + enableConfirmationFlow(); + } + + final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery); + final DistributionSet set = testdataFactory.createDistributionSet(); + + // do not provide something about the confirmation + verifyAutoAssignmentByActionType(tfq, set, null, null); + + assertThat(targetFilterQueryManagement.get(tfq.getId())).hasValueSatisfying(filter -> { + assertThat(filter.isConfirmationRequired()).isEqualTo(confirmationFlowActive); + }); + } + + private static Stream confirmationOptions() { + return Stream.of(Arguments.of(true, false), Arguments.of(true, true), Arguments.of(false, true), + Arguments.of(true, null), Arguments.of(false, null)); + } + + @Step + private void verifyAutoAssignmentWithoutActionType(final TargetFilterQuery tfq, final DistributionSet set, + final Boolean confirmationRequired) throws Exception { + verifyAutoAssignmentByActionType(tfq, set, null, confirmationRequired); + } + + @Step + private void verifyAutoAssignmentWithForcedActionType(final TargetFilterQuery tfq, final DistributionSet set, + final Boolean confirmationRequired) throws Exception { + verifyAutoAssignmentByActionType(tfq, set, MgmtActionType.FORCED, confirmationRequired); + } + + @Step + private void verifyAutoAssignmentWithSoftActionType(final TargetFilterQuery tfq, final DistributionSet set, + final Boolean confirmationRequired) throws Exception { + verifyAutoAssignmentByActionType(tfq, set, MgmtActionType.SOFT, confirmationRequired); + } + + private void verifyAutoAssignmentByActionType(final TargetFilterQuery tfq, final DistributionSet set, + final MgmtActionType actionType, final Boolean confirmationRequired) throws Exception { + final String hrefPrefix = "http://localhost" + MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + + tfq.getId(); + + final JSONObject jsonObject = new JSONObject(); + jsonObject.put("id", set.getId()); + if (actionType != null) { + jsonObject.put("type", actionType.getName()); + } + if (confirmationRequired != null) { + jsonObject.put("confirmationRequired", confirmationRequired); + } + + mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") + .content(jsonObject.toString()).contentType(MediaType.APPLICATION_JSON)).andDo(print()) + .andExpect(status().isOk()); + implicitLock(set); + + final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get(); + final MgmtActionType expectedActionType = actionType != null ? actionType : MgmtActionType.FORCED; + + assertThat(updatedFilterQuery.getAutoAssignDistributionSet()).isEqualTo(set); + 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()))) + .andExpect(jsonPath(JSON_PATH_QUERY, equalTo(tfq.getQuery()))) + .andExpect(isConfirmationFlowEnabled() + ? jsonPath(JSON_PATH_CONFIRMATION_REQUIRED, + equalTo(confirmationRequired == null || confirmationRequired)) + : jsonPath(JSON_PATH_CONFIRMATION_REQUIRED).doesNotExist()) + .andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_DS, equalTo(set.getId().intValue()))) + .andExpect(jsonPath(JSON_PATH_AUTO_ASSIGN_ACTION_TYPE, equalTo(expectedActionType.getName()))) + .andExpect(jsonPath("$._links.self.href", equalTo(hrefPrefix))) + .andExpect(jsonPath("$._links.autoAssignDS.href", equalTo(hrefPrefix + "/autoAssignDS"))); + } + + @Step + private void verifyAutoAssignmentWithTimeForcedActionType(final TargetFilterQuery tfq, final DistributionSet set) + 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()) + .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, + equalTo(InvalidAutoAssignActionTypeException.class.getName()))) + .andExpect(jsonPath(JSON_PATH_ERROR_CODE, + equalTo(SpServerError.SP_AUTO_ASSIGN_ACTION_TYPE_INVALID.getKey()))); + } + + @Step + private void verifyAutoAssignmentWithDownloadOnlyActionType(final TargetFilterQuery tfq, final DistributionSet set, + final Boolean confirmationRequired) throws Exception { + verifyAutoAssignmentByActionType(tfq, set, MgmtActionType.DOWNLOAD_ONLY, confirmationRequired); + } + + @Step + private void verifyAutoAssignmentWithUnknownActionType(final TargetFilterQuery tfq, final DistributionSet set) + throws Exception { + mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") + .content("{\"id\":" + set.getId() + ", \"type\":\"unknown\"}").contentType(MediaType.APPLICATION_JSON)) + .andDo(print()).andExpect(status().isBadRequest()) + .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(MessageNotReadableException.class.getName()))) + .andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_REST_BODY_NOT_READABLE.getKey()))); + } + + @Step + private void verifyAutoAssignmentWithIncompleteDs(final TargetFilterQuery tfq) throws Exception { + final DistributionSet incompleteDistributionSet = distributionSetManagement + .create(entityFactory.distributionSet().create().name("incomplete").version("1") + .type(testdataFactory.findOrCreateDefaultTestDsType())); + + mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") + .content("{\"id\":" + incompleteDistributionSet.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .andDo(print()).andExpect(status().isBadRequest()) + .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, + equalTo(IncompleteDistributionSetException.class.getName()))) + .andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_DS_INCOMPLETE.getKey()))); + } + + @Step + private void verifyAutoAssignmentWithSoftDeletedDs(final TargetFilterQuery tfq) throws Exception { + final DistributionSet softDeletedDs = testdataFactory.createDistributionSet("softDeleted"); + assignDistributionSet(softDeletedDs, testdataFactory.createTarget("forSoftDeletedDs")); + distributionSetManagement.delete(softDeletedDs.getId()); + + mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS") + .content("{\"id\":" + softDeletedDs.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .andDo(print()).andExpect(status().isNotFound()) + .andExpect(jsonPath(JSON_PATH_EXCEPTION_CLASS, equalTo(DeletedException.class.getName()))) + .andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_DELETED.getKey()))); + } + private TargetFilterQuery createSingleTargetFilterQuery(final String name, final String query) { return targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(name).query(query)); } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index 0980ff5d4..1be97f135 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -10,7 +10,9 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.*; +import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_V1_ACTIVATE_AUTO_CONFIRM; +import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_V1_AUTO_CONFIRM; +import static org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants.TARGET_V1_DEACTIVATE_AUTO_CONFIRM; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; @@ -46,6 +48,11 @@ import java.util.stream.Stream; import jakarta.validation.ConstraintViolationException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.jayway.jsonpath.JsonPath; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Step; +import io.qameta.allure.Story; import org.apache.commons.lang3.RandomStringUtils; import org.awaitility.Awaitility; import org.eclipse.hawkbit.exception.SpServerError; @@ -96,56 +103,174 @@ import org.springframework.hateoas.MediaTypes; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; - -import com.jayway.jsonpath.JsonPath; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Step; -import io.qameta.allure.Story; import org.springframework.test.web.servlet.ResultActions; /** * Spring MVC Tests against the MgmtTargetResource. - * */ @Feature("Component Tests - Management API") @Story("Target Resource") class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { + @Autowired + ActionRepository actionRepository; private static final String TARGET_DESCRIPTION_TEST = "created in test"; - private static final String JSON_PATH_ROOT = "$"; - // fields, attributes private static final String JSON_PATH_FIELD_ID = ".id"; private static final String JSON_PATH_FIELD_CONTROLLERID = ".controllerId"; private static final String JSON_PATH_FIELD_NAME = ".name"; private static final String JSON_PATH_FIELD_DESCRIPTION = ".description"; private static final String JSON_PATH_FIELD_CONTENT = ".content"; - private static final String JSON_PATH_FIELD_SIZE = ".size"; - private static final String JSON_PATH_FIELD_TOTAL = ".total"; - private static final String JSON_PATH_FIELD_LAST_REQUEST_AT = ".lastControllerRequestAt"; - private static final String JSON_PATH_FIELD_TARGET_TYPE = ".targetType"; - // target // $.field static final String JSON_PATH_PAGED_LIST_CONTENT = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTENT; + private static final String JSON_PATH_FIELD_SIZE = ".size"; static final String JSON_PATH_PAGED_LIST_SIZE = JSON_PATH_ROOT + JSON_PATH_FIELD_SIZE; + private static final String JSON_PATH_FIELD_TOTAL = ".total"; static final String JSON_PATH_PAGED_LIST_TOTAL = JSON_PATH_ROOT + JSON_PATH_FIELD_TOTAL; - + private static final String JSON_PATH_FIELD_LAST_REQUEST_AT = ".lastControllerRequestAt"; + private static final String JSON_PATH_FIELD_TARGET_TYPE = ".targetType"; private static final String JSON_PATH_NAME = JSON_PATH_ROOT + JSON_PATH_FIELD_NAME; private static final String JSON_PATH_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID; private static final String JSON_PATH_CONTROLLERID = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTROLLERID; private static final String JSON_PATH_DESCRIPTION = JSON_PATH_ROOT + JSON_PATH_FIELD_DESCRIPTION; private static final String JSON_PATH_LAST_REQUEST_AT = JSON_PATH_ROOT + JSON_PATH_FIELD_LAST_REQUEST_AT; private static final String JSON_PATH_TYPE = JSON_PATH_ROOT + JSON_PATH_FIELD_TARGET_TYPE; - @Autowired private ObjectMapper objectMapper; @Autowired private JpaProperties jpaProperties; + @Test + @Description("Ensures that when targetType value of -1 is provided the target type is unassigned from the target.") + public void updateTargetAndUnnasignTargetType() throws Exception { + final String knownControllerId = "123"; + final String knownNewAddress = "amqp://test123/foobar"; + final String knownNameNotModify = "controllerName"; + final Long unnasignTargetTypeValue = -1L; + + final TargetType targetType = targetTypeManagement.create( + entityFactory.targetType().create().name("targettype1").description("targettypedes1")); + + final String body = new JSONObject().put("targetType", unnasignTargetTypeValue).toString(); + + // create a target with the created TargetType + targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify) + .address(knownNewAddress).targetType(targetType.getId())); + + mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))) + .andExpect(jsonPath("$.targetType").exists()); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))) + .andExpect(jsonPath("$.targetType").doesNotExist()); + + } + + @Test + @Description("Ensures that when targetType value of -1 is provided the target type is unassigned from the target when updating multiple fields in target object.") + public void updateTargetNameAndUnnasignTargetType() throws Exception { + final String knownControllerId = "123"; + final String knownNewAddress = "amqp://test123/foobar"; + final String knownNameNotModify = "controllerName"; + final Long unnasignTargetTypeValue = -1L; + final String controllerNewName = "controllerNewName"; + + final TargetType targetType = targetTypeManagement.create( + entityFactory.targetType().create().name("targettype1").description("targettypedes1")); + + final String body = new JSONObject() + .put("targetType", unnasignTargetTypeValue).put("name", "controllerNewName") + .toString(); + + // create a target with the created TargetType + targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify) + .address(knownNewAddress).targetType(targetType.getId())); + + mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) + .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))) + .andExpect(jsonPath("$.targetType").exists()); + + //check if controller name is updated AND target type is missing (not assigned) + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) + .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) + .andExpect(jsonPath("$.name", equalTo(controllerNewName))) + .andExpect(jsonPath("$.targetType").doesNotExist()); + } + + @Test + @Description("Handles the GET request of retrieving all targets within SP..") + public void getTargets() throws Exception { + enableConfirmationFlow(); + mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING)).andExpect(status().isOk()) + .andDo(MockMvcResultPrinter.print()); + } + + @Test + @Description("Handles the GET request of retrieving all targets within SP based by parameter.") + public void getTargetsWithParameters() throws Exception { + mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "?limit=10&sort=name:ASC&offset=0&q=name==a")) + .andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()); + } + + @Test + @Description("Get a paged list of meta data for a target with standard page size.") + public void getMetadata() throws Exception { + final int totalMetadata = 4; + final String knownKeyPrefix = "knownKey"; + final String knownValuePrefix = "knownValue"; + final Target testTarget = testdataFactory.createTarget("targetId"); + for (int index = 0; index < totalMetadata; index++) { + targetManagement.createMetaData(testTarget.getControllerId(), List.of( + entityFactory.generateTargetMetadata(knownKeyPrefix + index, knownValuePrefix + index))); + } + + mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata", testTarget.getControllerId())) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)); + } + + @Test + @Description("Handles the POST request to activate auto-confirm on a target. Payload can be provided to specify more details about the operation.") + public void postActivateAutoConfirm() throws Exception { + final Target testTarget = testdataFactory.createTarget("targetId"); + + final MgmtTargetAutoConfirmUpdate body = new MgmtTargetAutoConfirmUpdate("custom_initiator_value", + "custom_remark_value"); + + mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/" + TARGET_V1_AUTO_CONFIRM + "/" + + TARGET_V1_ACTIVATE_AUTO_CONFIRM, testTarget.getControllerId()) + .content(objectMapper.writeValueAsString(body)).contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + } + + @Test + @Description("Handles the POST request to deactivate auto-confirm on a target.") + public void postDeactivateAutoConfirm() throws Exception { + final Target testTarget = testdataFactory.createTarget("targetId"); + confirmationManagement.activateAutoConfirmation(testTarget.getControllerId(), null, null); + + mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/" + TARGET_V1_AUTO_CONFIRM + "/" + + TARGET_V1_DEACTIVATE_AUTO_CONFIRM, testTarget.getControllerId())) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + } + @Test @Description("Ensures that actions list is in expected order.") void getActionStatusReturnsCorrectType() throws Exception { @@ -162,7 +287,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .stream().sorted((e1, e2) -> Long.compare(e2.getId(), e1.getId())).collect(Collectors.toList()).get(0); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId() + "/status") + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId() + "/status") .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)) .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:DESC")) .andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) @@ -225,11 +350,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { contains(IpUtil.createHttpUri("127.0.0.1").toString()))); } - private void createTarget(final String controllerId) { - targetManagement.create(entityFactory.target().create().controllerId(controllerId) - .address(IpUtil.createHttpUri("127.0.0.1").toString())); - } - @Test @Description("Ensures that actions history is returned as defined by filter status==pending,status==finished.") void searchActionsRsql() throws Exception { @@ -245,19 +365,19 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final String rsqlPendingOrFinishedStatus = rsqlFinishedStatus + "," + rsqlPendingStatus; // pending status one result mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions?q=" + rsqlPendingStatus, - createTarget.getControllerId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + createTarget.getControllerId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(1))).andExpect(jsonPath("size", equalTo(1))) .andExpect(jsonPath("content[0].status", equalTo("pending"))); // finished status none result mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions?q=" + rsqlFinishedStatus, - createTarget.getControllerId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + createTarget.getControllerId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(0))).andExpect(jsonPath("size", equalTo(0))); // pending or finished status one result mvc.perform(get( - MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions?q=" + rsqlPendingOrFinishedStatus, - createTarget.getControllerId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions?q=" + rsqlPendingOrFinishedStatus, + createTarget.getControllerId())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(1))).andExpect(jsonPath("size", equalTo(1))) .andExpect(jsonPath("content[0].status", equalTo("pending"))); } @@ -270,9 +390,9 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // test - cancel the active action mvc.perform( - delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", - tA.getControllerId(), deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE) - .getContent().get(0).getId())) + delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", + tA.getControllerId(), deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE) + .getContent().get(0).getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNoContent()); final Action action = deploymentManagement.findAction( @@ -305,7 +425,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // test - cancel an cancel action returns forbidden mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", - tA.getControllerId(), cancelActions.get(0).getId())).andDo(MockMvcResultPrinter.print()) + tA.getControllerId(), cancelActions.get(0).getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); } @@ -327,7 +447,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // test - force quit: Canceled actions should return 204 mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true", - tA.getControllerId(), cancelActions.get(0).getId())).andDo(MockMvcResultPrinter.print()) + tA.getControllerId(), cancelActions.get(0).getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNoContent()); } @@ -339,9 +459,9 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // test - cancel an cancel action returns forbidden mvc.perform( - delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true", - tA.getControllerId(), deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE) - .getContent().get(0).getId())) + delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}?force=true", + tA.getControllerId(), deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE) + .getContent().get(0).getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed()); } @@ -371,7 +491,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { void updateTargetWhichDoesNotExistsLeadsToNotFound() throws Exception { final String knownControllerId = "knownControllerIdUpdate"; mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content("{}") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNotFound()); } @@ -388,7 +508,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .description("old description")); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) .andExpect(jsonPath("$.description", equalTo(knownNewDescription))) .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))); @@ -411,7 +531,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .description("old description")); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final Target findTargetByControllerID = targetManagement.getByControllerID(knownControllerId).get(); @@ -431,7 +551,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify)); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) .andExpect(jsonPath("$.securityToken", equalTo(knownNewToken))) .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))); @@ -454,7 +574,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .address(knownNewAddress)); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))); @@ -464,75 +584,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModify); } - @Test - @Description("Ensures that when targetType value of -1 is provided the target type is unassigned from the target.") - public void updateTargetAndUnnasignTargetType() throws Exception { - final String knownControllerId = "123"; - final String knownNewAddress = "amqp://test123/foobar"; - final String knownNameNotModify = "controllerName"; - final Long unnasignTargetTypeValue = -1L; - - final TargetType targetType = targetTypeManagement.create( - entityFactory.targetType().create().name("targettype1").description("targettypedes1")); - - final String body = new JSONObject().put("targetType", unnasignTargetTypeValue).toString(); - - // create a target with the created TargetType - targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify) - .address(knownNewAddress).targetType(targetType.getId())); - - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) - .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) - .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))) - .andExpect(jsonPath("$.targetType").exists()); - - mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) - .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) - .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))) - .andExpect(jsonPath("$.targetType").doesNotExist()); - - } - - @Test - @Description("Ensures that when targetType value of -1 is provided the target type is unassigned from the target when updating multiple fields in target object.") - public void updateTargetNameAndUnnasignTargetType() throws Exception { - final String knownControllerId = "123"; - final String knownNewAddress = "amqp://test123/foobar"; - final String knownNameNotModify = "controllerName"; - final Long unnasignTargetTypeValue = -1L; - final String controllerNewName = "controllerNewName"; - - final TargetType targetType = targetTypeManagement.create( - entityFactory.targetType().create().name("targettype1").description("targettypedes1")); - - final String body = new JSONObject() - .put("targetType", unnasignTargetTypeValue).put("name", "controllerNewName") - .toString(); - - // create a target with the created TargetType - targetManagement.create(entityFactory.target().create().controllerId(knownControllerId).name(knownNameNotModify) - .address(knownNewAddress).targetType(targetType.getId())); - - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) - .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) - .andExpect(jsonPath("$.name", equalTo(knownNameNotModify))) - .andExpect(jsonPath("$.targetType").exists()); - - //check if controller name is updated AND target type is missing (not assigned) - mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(jsonPath("$.controllerId", equalTo(knownControllerId))) - .andExpect(jsonPath("$.address", equalTo(knownNewAddress))) - .andExpect(jsonPath("$.name", equalTo(controllerNewName))) - .andExpect(jsonPath("$.targetType").doesNotExist()); - } - @Test @Description("Ensures that target query returns list of targets in defined format.") void getTargetWithoutAdditionalRequestParameters() throws Exception { @@ -586,7 +637,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final String linksHrefPrefix = "http://localhost/rest/v1/targets/"; mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount))) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -614,8 +665,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { createTargetsAlphabetical(knownTargetAmount); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(knownTargetAmount))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(knownTargetAmount))) .andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(knownTargetAmount))) .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -783,7 +834,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { Math.min(JpaTarget.CONTROLLER_ID_MAX_SIZE, NamedEntity.NAME_MAX_SIZE)); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content(targetList) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isCreated()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isCreated()) .andExpect(jsonPath("[0].controllerId", equalTo(randomString))) .andExpect(jsonPath("[0].name", equalTo(expectedTargetName))); @@ -902,13 +953,13 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assertThat( JsonPath.compile("[0]._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/targets/id1"); + .isEqualTo("http://localhost/rest/v1/targets/id1"); assertThat( JsonPath.compile("[1]._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/targets/id2"); + .isEqualTo("http://localhost/rest/v1/targets/id2"); assertThat( JsonPath.compile("[2]._links.self.href").read(mvcResult.getResponse().getContentAsString()).toString()) - .isEqualTo("http://localhost/rest/v1/targets/id3"); + .isEqualTo("http://localhost/rest/v1/targets/id3"); final Target t1 = assertTarget("id1", "testname1", "testid1"); assertThat(t1.getSecurityToken()).isEqualTo("token"); @@ -918,15 +969,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assertTarget("id3", "testname3", "testid3"); } - private Target assertTarget(final String controllerId, final String name, final String description) { - final Optional target1 = targetManagement.getByControllerID(controllerId); - assertThat(target1).isPresent(); - final Target t = target1.get(); - assertThat(t.getName()).isEqualTo(name); - assertThat(t.getDescription()).isEqualTo(description); - return t; - } - @Test @Description("Ensures that a post request for creating one target within a list works.") void createTargetsSingleEntryListReturnsSuccessful() throws Exception { @@ -936,7 +978,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final String createTargetsJson = getCreateTargetsListJsonString(knownControllerId, knownName, knownDescription); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content(createTargetsJson) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().is2xxSuccessful()); final Slice findTargetsAll = targetManagement.findAll(PageRequest.of(0, 100)); @@ -958,7 +1000,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // create a taret first to provoke a already exists error mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content(createTargetsJson) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().is2xxSuccessful()); // create another one to retrieve the entity already exists exception final MvcResult mvcResult = mvc @@ -984,7 +1026,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { testdataFactory.createTarget(knownTargetId); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + + MgmtRestConstants.TARGET_V1_ACTIONS)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("size", equalTo(0))).andExpect(jsonPath("content", hasSize(0))) .andExpect(jsonPath("total", equalTo(0))); } @@ -996,7 +1038,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(1).getId())) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(1).getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("id", equalTo(actions.get(1).getId().intValue()))) .andExpect(jsonPath("type", equalTo("update"))).andExpect(jsonPath("status", equalTo("pending"))) @@ -1021,7 +1063,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { schedule, duration, timezone); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(1).getId())) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(1).getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("id", equalTo(actions.get(1).getId().intValue()))) .andExpect(jsonPath("type", equalTo("update"))).andExpect(jsonPath("status", equalTo("pending"))) @@ -1046,7 +1088,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId())) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("id", equalTo(actions.get(0).getId().intValue()))) .andExpect(jsonPath("type", equalTo("cancel"))).andExpect(jsonPath("status", equalTo("pending"))) @@ -1071,7 +1113,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { schedule, duration, timezone); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId())) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actions.get(0).getId())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("id", equalTo(actions.get(0).getId().intValue()))) .andExpect(jsonPath("forceType", equalTo("forced"))).andExpect(jsonPath("type", equalTo("cancel"))) @@ -1101,43 +1143,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { getActions(true); } - private void getActions(final boolean withExternalRef) throws Exception { - final String knownTargetId = "targetId"; - final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); - - final List externalRefs = new ArrayList<>(2); - if (withExternalRef) { - externalRefs.add("extRef#123_0"); - externalRefs.add("extRef#123_1"); - controllerManagement.updateActionExternalRef(actions.get(0).getId(), externalRefs.get(0)); - controllerManagement.updateActionExternalRef(actions.get(1).getId(), externalRefs.get(1)); - } - - final ResultActions resultActions = - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue()))) - .andExpect(jsonPath("content.[1].type", equalTo("update"))) - .andExpect(jsonPath("content.[1].status", equalTo("pending"))) - .andExpect(jsonPath("content.[1]._links.self.href", - equalTo(generateActionSelfLink(knownTargetId, actions.get(1).getId())))) - .andExpect(jsonPath("content.[0].id", equalTo(actions.get(0).getId().intValue()))) - .andExpect(jsonPath("content.[0].type", equalTo("cancel"))) - .andExpect(jsonPath("content.[0].status", equalTo("pending"))) - .andExpect(jsonPath("content.[0]._links.self.href", - equalTo(generateActionSelfLink(knownTargetId, actions.get(0).getId())))) - .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) - .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) - .andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); - - if (withExternalRef) { - resultActions - .andExpect(jsonPath("content.[1].externalRef", equalTo(externalRefs.get(1)))) - .andExpect(jsonPath("content.[0].externalRef", equalTo(externalRefs.get(0)))); - } - } - @Test @Description("Ensures that the expected response of getting actions with maintenance window of a target is returned.") void getActionsWithMaintenanceWindow() throws Exception { @@ -1149,7 +1154,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { schedule, duration, timezone); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) + + MgmtRestConstants.TARGET_V1_ACTIONS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue()))) .andExpect(jsonPath("content.[1].type", equalTo("update"))) @@ -1188,8 +1193,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // sort is default descending order, latest status first mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" - + MgmtRestConstants.TARGET_V1_ACTION_STATUS)).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + + MgmtRestConstants.TARGET_V1_ACTION_STATUS)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) .andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(0).getId().intValue()))) .andExpect(jsonPath("content.[0].type", equalTo("canceling"))) @@ -1215,8 +1220,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // descending order mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" - + MgmtRestConstants.TARGET_V1_ACTION_STATUS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + + MgmtRestConstants.TARGET_V1_ACTION_STATUS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "REPORTEDAT:DESC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(1).getId().intValue()))) @@ -1233,8 +1238,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // ascending order mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" - + MgmtRestConstants.TARGET_V1_ACTION_STATUS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + + MgmtRestConstants.TARGET_V1_ACTION_STATUS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "REPORTEDAT:ASC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("content.[1].id", equalTo(actionStatus.get(1).getId().intValue()))) @@ -1262,8 +1267,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // Page 1 mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" - + MgmtRestConstants.TARGET_V1_ACTION_STATUS).param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + + MgmtRestConstants.TARGET_V1_ACTION_STATUS).param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("content.[0].id", equalTo(actionStatus.get(1).getId().intValue()))) @@ -1277,8 +1282,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // Page 2 mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" - + MgmtRestConstants.TARGET_V1_ACTION_STATUS) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId() + "/" + + MgmtRestConstants.TARGET_V1_ACTION_STATUS) .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) @@ -1298,7 +1303,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // page 1: one entry mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS) + + MgmtRestConstants.TARGET_V1_ACTIONS) .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) @@ -1313,7 +1318,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // page 2: one entry mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS) + + MgmtRestConstants.TARGET_V1_ACTIONS) .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(1)) .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)) .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(1)) @@ -1329,69 +1334,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); } - private String generateActionSelfLink(final String knownTargetId, final Long actionId) { - return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId; - } - - private String generateActionDsLink(final Long dsId) { - return "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + dsId; - } - - private String generateCanceledactionreferenceLink(final String knownTargetId, final Action action) { - return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId(); - } - - private String generateStatusreferenceLink(final String knownTargetId, final Long actionId) { - return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/" + MgmtRestConstants.TARGET_V1_ACTION_STATUS - + "?offset=0&limit=50&sort=id%3ADESC"; - } - - private List generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) { - return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null); - } - - private List generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId, - final String schedule, final String duration, final String timezone) { - final Target target = testdataFactory.createTarget(knownTargetId); - - final Iterator sets = testdataFactory.createDistributionSets(2).iterator(); - final DistributionSet one = sets.next(); - final DistributionSet two = sets.next(); - - // Update - if (schedule == null) { - final List updatedTargets = assignDistributionSet(one, Collections.singletonList(target)) - .getAssignedEntity().stream().map(Action::getTarget).collect(Collectors.toList()); - // 2nd update - // sleep 10ms to ensure that we can sort by reportedAt - Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L)); - assignDistributionSet(two, updatedTargets); - } else { - final List updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(), - target.getControllerId(), schedule, duration, timezone).getAssignedEntity().stream() - .map(Action::getTarget).collect(Collectors.toList()); - // 2nd update - // sleep 10ms to ensure that we can sort by reportedAt - Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) - .pollInterval(10, TimeUnit.MILLISECONDS) - .until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L)); - assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule, - duration, timezone); - } - - // two updates, one cancellation - final List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) - .getContent(); - - assertThat(actions).hasSize(2); - return actions; - } - @Test @Description("Verfies that an action is switched from soft to forced if requested by management API") void updateAction() throws Exception { @@ -1403,7 +1345,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final String body = new JSONObject().put("forceType", "forced").toString(); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId).content(body) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId).content(body) .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("id", equalTo(actionId.intValue()))).andExpect(jsonPath("type", equalTo("update"))) @@ -1426,7 +1368,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final DistributionSet set = testdataFactory.createDistributionSet("one"); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0))) .andExpect(jsonPath("total", equalTo(1))); @@ -1437,7 +1379,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // repeating DS assignment leads again to OK mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("assigned", equalTo(0))).andExpect(jsonPath("alreadyAssigned", equalTo(1))) .andExpect(jsonPath("total", equalTo(1))); @@ -1446,8 +1388,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assertThat(targetManagement.getByControllerID(target.getControllerId()).get()).isEqualTo(target); } - @Autowired - ActionRepository actionRepository; @ParameterizedTest @MethodSource("confirmationOptions") @Description("Ensures that confirmation option is considered in assignment request.") @@ -1467,7 +1407,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { } mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content(jsonPayload.toString()).contentType(MediaType.APPLICATION_JSON)) + .content(jsonPayload.toString()).contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0))) .andExpect(jsonPath("total", equalTo(1))); @@ -1488,11 +1428,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { }); } - private static Stream confirmationOptions() { - return Stream.of(Arguments.of(true, true), Arguments.of(true, false), Arguments.of(false, true), - Arguments.of(false, false), Arguments.of(true, null), Arguments.of(false, null)); - } - @Test @Description("Verfies that a DOWNLOAD_ONLY DS to target assignment is properly handled") void assignDownloadOnlyDistributionSetToTarget() throws Exception { @@ -1500,8 +1435,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final DistributionSet set = testdataFactory.createDistributionSet("one"); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content("{\"id\":" + set.getId() + ",\"type\": \"downloadonly\"}") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .content("{\"id\":" + set.getId() + ",\"type\": \"downloadonly\"}") + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0))) .andExpect(jsonPath("total", equalTo(1))); implicitLock(set); @@ -1520,7 +1455,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final DistributionSet set = testdataFactory.createDistributionSet("one"); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() - + "/assignedDS?offline=true").content("{\"id\":" + set.getId() + "}") + + "/assignedDS?offline=true").content("{\"id\":" + set.getId() + "}") .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("assigned", equalTo(1))).andExpect(jsonPath("alreadyAssigned", equalTo(0))) @@ -1534,7 +1469,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // repeating DS assignment leads again to OK mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() - + "/assignedDS?offline=true").content("{\"id\":" + set.getId() + "}") + + "/assignedDS?offline=true").content("{\"id\":" + set.getId() + "}") .contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("assigned", equalTo(0))).andExpect(jsonPath("alreadyAssigned", equalTo(1))) @@ -1554,7 +1489,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .put("forcetime", forceTime).toString(); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS").content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); implicitLock(set); @@ -1577,7 +1512,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .put("maintenanceWindow", new JSONObject().put("schedule", getTestSchedule(0))).toString(); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); } @@ -1592,7 +1527,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .put("maintenanceWindow", new JSONObject().put("duration", getTestDuration(10))).toString(); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content(body).contentType(MediaTypes.HAL_JSON_VALUE)).andDo(MockMvcResultPrinter.print()) + .content(body).contentType(MediaTypes.HAL_JSON_VALUE)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); } @@ -1609,7 +1544,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .toString(); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); } @@ -1622,16 +1557,16 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final long nextExecutionStart = System.currentTimeMillis(); final String body = new JSONObject().put("id", set.getId()).put("maintenanceWindow", - new JSONObject().put("schedule", getTestSchedule(10)).put("duration", getTestDuration(10)) - .put("timezone", getTestTimeZone()).put("nextStartAt", String.valueOf(nextExecutionStart))) + new JSONObject().put("schedule", getTestSchedule(10)).put("duration", getTestDuration(10)) + .put("timezone", getTestTimeZone()).put("nextStartAt", String.valueOf(nextExecutionStart))) .toString(); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS)).andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS)).andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) .andExpect(jsonPath("content.[0].maintenanceWindow.nextStartAt", not(nextExecutionStart))); } @@ -1648,7 +1583,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .toString(); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + target.getControllerId() + "/assignedDS") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); } @@ -1658,25 +1593,25 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final DistributionSet set = testdataFactory.createDistributionSet("one"); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); testdataFactory.createTarget("fsdfsd"); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS") - .content("{\"id\":12345678}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":12345678}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/fsdfsd/assignedDS") - .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed()); } @@ -1687,29 +1622,29 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // target does not exist mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS)).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNotFound()); final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); final Long actionId = actions.get(0).getId(); // should work now mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId)).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); // action does not exist mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/12321")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/12321")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNotFound()); // not allowed methods mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId)).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); // Invalid content mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId)).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnsupportedMediaType()); } @@ -1719,30 +1654,30 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // target does not exist mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/1/status")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/1/status")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNotFound()); final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); final Long actionId = actions.get(0).getId(); // should work now mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); // action does not exist mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/12321/status")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/12321/status")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNotFound()); // not allowed methods mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" - + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/status")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); } @@ -1792,52 +1727,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { verifyResettingRequestAttributesIsNotAllowed(knownTargetId); } - @Step - private void verifyAttributeUpdateCanBeRequested(final String knownTargetId) throws Exception { - final String body = new JSONObject().put("requestAttributes", true).toString(); - - mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - - assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isTrue(); - } - - @Step - private void verifyRequestAttributesAttributeIsOptional(final String knownTargetId) throws Exception { - final String body = new JSONObject().put("description", "verify attribute can be missing").toString(); - - mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - } - - @Step - private void verifyResettingRequestAttributesIsNotAllowed(final String knownTargetId) throws Exception { - final String body = new JSONObject().put("requestAttributes", false).toString(); - - mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isBadRequest()); - - assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isTrue(); - } - - @Test - @Description("Handles the GET request of retrieving all targets within SP..") - public void getTargets() throws Exception { - enableConfirmationFlow(); - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING)).andExpect(status().isOk()) - .andDo(MockMvcResultPrinter.print()); - } - - @Test - @Description("Handles the GET request of retrieving all targets within SP based by parameter.") - public void getTargetsWithParameters() throws Exception { - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "?limit=10&sort=name:ASC&offset=0&q=name==a")) - .andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()); - } - @Test void searchTargetsUsingRsqlQuery() throws Exception { final int amountTargets = 10; @@ -1851,52 +1740,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("content[1].controllerId", equalTo("b"))); } - private String getCreateTargetsListJsonString(final String controllerId, final String name, - final String description) { - return "[{\"name\":\"" + name + "\",\"controllerId\":\"" + controllerId + "\",\"description\":\"" + description - + "\"}]"; - } - - private Target createSingleTarget(final String controllerId, final String name) { - targetManagement.create(entityFactory.target().create().controllerId(controllerId).name(name) - .description(TARGET_DESCRIPTION_TEST)); - return controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST); - } - - /** - * Creating targets with the given amount by setting name, id etc from the - * alphabet [a-z] using ASCII. - * - * @param amount - * The number of targets to create - */ - private void createTargetsAlphabetical(final int amount) { - char character = 'a'; - for (int index = 0; index < amount; index++) { - final String str = String.valueOf(character); - targetManagement.create(entityFactory.target().create().controllerId(str).name(str).description(str)); - controllerManagement.findOrRegisterTargetIfItDoesNotExist(str, LOCALHOST); - character++; - } - } - - /** - * helper method to create a target and start an action on it. - * - * @return The targetid of the created target. - */ - private Target createTargetAndStartAction() { - // prepare test - final DistributionSet dsA = testdataFactory.createDistributionSet(""); - final Target tA = testdataFactory.createTarget("target-id-A"); - // assign a distribution set so we get an active update action - assignDistributionSet(dsA, Arrays.asList(tA)); - // verify active action - final Slice actionsByTarget = deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE); - assertThat(actionsByTarget.getContent()).hasSize(1); - return targetManagement.getByControllerID(tA.getControllerId()).get(); - } - @Test void getControllerTagReturnsTagsWithOk() throws Exception { // create target with attributes @@ -1942,7 +1785,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { metaData1.put(new JSONObject().put("key", knownKey2).put("value", knownValue2)); mvc.perform(post("/rest/v1/targets/{targetId}/metadata", knownControllerId).accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON).content(metaData1.toString())) + .contentType(MediaType.APPLICATION_JSON).content(metaData1.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("[0].key", equalTo(knownKey1))) @@ -1965,7 +1808,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { } mvc.perform(post("/rest/v1/targets/{targetId}/metadata", knownControllerId).accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON).content(metaData2.toString())) + .contentType(MediaType.APPLICATION_JSON).content(metaData2.toString())) .andDo(MockMvcResultPrinter.print()).andExpect(status().isForbidden()); // verify that the number of meta data entries has not changed @@ -1990,8 +1833,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final JSONObject jsonObject = new JSONObject().put("key", knownKey).put("value", updateValue); mvc.perform(put("/rest/v1/targets/{targetId}/metadata/{key}", knownControllerId, knownKey) - .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON) - .content(jsonObject.toString())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON) + .content(jsonObject.toString())).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(updateValue))); @@ -2001,13 +1844,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { } - private void setupTargetWithMetadata(final String knownControllerId, final String knownKey, - final String knownValue) { - testdataFactory.createTarget(knownControllerId); - targetManagement.createMetaData(knownControllerId, - Collections.singletonList(entityFactory.generateTargetMetadata(knownKey, knownValue))); - } - @Test @Description("Ensures that a metadata entry deletion through API is reflected by the repository.") void deleteMetadata() throws Exception { @@ -2061,24 +1897,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(knownValue))); } - @Test - @Description("Get a paged list of meta data for a target with standard page size.") - public void getMetadata() throws Exception { - final int totalMetadata = 4; - final String knownKeyPrefix = "knownKey"; - final String knownValuePrefix = "knownValue"; - final Target testTarget = testdataFactory.createTarget("targetId"); - for (int index = 0; index < totalMetadata; index++) { - targetManagement.createMetaData(testTarget.getControllerId(), List.of( - entityFactory.generateTargetMetadata(knownKeyPrefix + index, knownValuePrefix + index))); - } - - mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata", testTarget.getControllerId())) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)); - } - @Test @Description("Ensures that a metadata entry paged list selection through API reflectes the repository content.") void getPagedListOfMetadata() throws Exception { @@ -2093,25 +1911,13 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { setupTargetWithMetadata(knownControllerId, knownKeyPrefix, knownValuePrefix, totalMetadata); mvc.perform(get("/rest/v1/targets/{targetId}/metadata?offset=" + offsetParam + "&limit=" + limitParam, - knownControllerId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + knownControllerId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("size", equalTo(limitParam))).andExpect(jsonPath("total", equalTo(totalMetadata))) .andExpect(jsonPath("content[0].key", equalTo("knownKey0"))) .andExpect(jsonPath("content[0].value", equalTo("knownValue0"))); } - private void setupTargetWithMetadata(final String knownControllerId, final String knownKeyPrefix, - final String knownValuePrefix, final int totalMetadata) { - testdataFactory.createTarget(knownControllerId); - - final List targetMetadataEntries = new LinkedList<>(); - for (int index = 0; index < totalMetadata; index++) { - targetMetadataEntries - .add(entityFactory.generateTargetMetadata(knownKeyPrefix + index, knownValuePrefix + index)); - } - targetManagement.createMetaData(knownControllerId, targetMetadataEntries); - } - @Test @Description("Ensures that a target metadata filtered query with value==knownValue1 parameter returns only the metadata entries with that value.") void searchDistributionSetMetadataRsql() throws Exception { @@ -2142,7 +1948,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { 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()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); } @@ -2154,7 +1960,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { 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()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); } @@ -2168,7 +1974,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { 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()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(1))); } @@ -2184,7 +1990,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { enableMultiAssignments(); mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(body.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("total", equalTo(2))); } @@ -2200,11 +2006,11 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { enableMultiAssignments(); mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyInvalid.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .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()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); final List actions = deploymentManagement.findActionsAll(PAGE).get().collect(Collectors.toList()); @@ -2221,7 +2027,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { 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()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); } @@ -2236,7 +2042,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { enableMultiAssignments(); mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyValid.toString()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); final List actions = deploymentManagement.findActionsAll(PAGE).get().collect(Collectors.toList()); @@ -2257,7 +2063,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assignDistributionSet(dsId, targetId, customWeightLow); mvc.perform(get("/rest/v1/targets/{targetId}/actions", targetId) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "WEIGHT:ASC")) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "WEIGHT:ASC")) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("content.[0].weight", equalTo(customWeightLow))) .andExpect(jsonPath("content.[1].weight", equalTo(customWeightHigh))) @@ -2291,7 +2097,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { PageRequest.of(0, 100)); assertThat(action.getContent()).hasSize(1); mvc.perform(get("/rest/v1/targets/{targetId}/actions/{actionId}", target.getControllerId(), - action.getContent().get(0).getId())).andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) + action.getContent().get(0).getId())).andExpect(status().isOk()).andDo(MockMvcResultPrinter.print()) .andExpect(jsonPath("$.rollout", equalTo(rollout.getId().intValue()))) .andExpect(jsonPath("$.rolloutName", equalTo(rollout.getName()))).andExpect(jsonPath( "$._links.rollout.href", containsString("/rest/v1/rollouts/" + rollout.getId().intValue()))); @@ -2376,7 +2182,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // test query target over rest resource mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content(targetList) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isCreated()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isCreated()) .andExpect(jsonPath("[0].controllerId", equalTo("targetcontroller"))) .andExpect(jsonPath("[0].targetType", equalTo(targetTypes.get(0).getId().intValue()))); @@ -2401,7 +2207,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { final String body = new JSONObject().put("targetType", targetTypes.get(1).getId().intValue()).toString(); mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + controllerId).content(body) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()) .andExpect(jsonPath("controllerId", equalTo(controllerId))) .andExpect(jsonPath("targetType", equalTo(targetTypes.get(1).getId().intValue()))); } @@ -2423,7 +2229,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // post target over rest resource mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING).content(targetList) - .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isNotFound()) + .contentType(MediaType.APPLICATION_JSON)).andExpect(status().isNotFound()) .andExpect(jsonPath("message", Matchers.containsString(errorMsg))); } @@ -2441,7 +2247,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // assign target type over rest resource mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetControllerId + "/targettype") - .content("{\"id\":" + targetType.getId() + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + targetType.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); assertThat(targetManagement.getByControllerID(targetControllerId).get().getTargetType().getId()) @@ -2461,7 +2267,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // assign invalid target type over rest resource mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + targetControllerId + "/targettype") - .content("{\"id\":" + invalidTargetTypeId + "}").contentType(MediaType.APPLICATION_JSON)) + .content("{\"id\":" + invalidTargetTypeId + "}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); // verify response json exception message if body does not include id @@ -2517,12 +2323,12 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // POST does not exist with path parameter targettype mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING - + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING + "/123", knownTargetId)) + + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING + "/123", knownTargetId)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); // DELETE does not exist with path parameter targettype mvc.perform(delete(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING - + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING + "/123", knownTargetId)) + + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING + "/123", knownTargetId)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); // Invalid content @@ -2532,8 +2338,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // Bad request if id field is missing mvc.perform(post( - MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING, - knownTargetId).content("{\"unknownfield\":123}").contentType(MediaType.APPLICATION_JSON)) + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING, + knownTargetId).content("{\"unknownfield\":123}").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest()); } @@ -2546,7 +2352,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // GET with all possible responses mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/" + TARGET_V1_AUTO_CONFIRM, - knownTargetId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + knownTargetId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("active", equalTo(Boolean.TRUE))) .andExpect(initiator == null ? jsonPath("initiator").doesNotExist() : jsonPath("initiator", equalTo(initiator))) @@ -2590,7 +2396,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // GET for auto-confirm not active mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/" + TARGET_V1_AUTO_CONFIRM, - knownTargetId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + knownTargetId)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("active", equalTo(Boolean.FALSE))).andExpect(jsonPath("initiator").doesNotExist()) .andExpect(jsonPath("remark").doesNotExist()).andExpect(jsonPath("_links.activate").exists()); } @@ -2614,33 +2420,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("autoConfirmActive").exists()).andExpect(jsonPath("_links.autoConfirm").exists()); } - @Test - @Description("Handles the POST request to activate auto-confirm on a target. Payload can be provided to specify more details about the operation.") - public void postActivateAutoConfirm() throws Exception { - final Target testTarget = testdataFactory.createTarget("targetId"); - - final MgmtTargetAutoConfirmUpdate body = new MgmtTargetAutoConfirmUpdate("custom_initiator_value", - "custom_remark_value"); - - mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/" + TARGET_V1_AUTO_CONFIRM + "/" - + TARGET_V1_ACTIVATE_AUTO_CONFIRM, testTarget.getControllerId()) - .content(objectMapper.writeValueAsString(body)).contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - } - - @Test - @Description("Handles the POST request to deactivate auto-confirm on a target.") - public void postDeactivateAutoConfirm() throws Exception { - final Target testTarget = testdataFactory.createTarget("targetId"); - confirmationManagement.activateAutoConfirmation(testTarget.getControllerId(), null, null); - - mvc.perform(post(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/" + TARGET_V1_AUTO_CONFIRM + "/" - + TARGET_V1_DEACTIVATE_AUTO_CONFIRM, testTarget.getControllerId())) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - } - @Test @Description("Verifies that the status code that was reported in the last action status update is correctly exposed via the action.") void lastActionStatusCode() throws Exception { @@ -2652,31 +2431,250 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { // no status update yet -> no status code mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", - target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) + target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("lastStatusCode").doesNotExist()); // update action status with status code updateActionStatus(action, Status.RUNNING, 100); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", - target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) + target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("lastStatusCode", equalTo(100))) .andExpect(jsonPath("detailStatus", equalTo("running"))); // update action status without a status code updateActionStatus(action, Status.RUNNING, null); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", - target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) + target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("lastStatusCode").doesNotExist()) .andExpect(jsonPath("detailStatus", equalTo("running"))); // update action status with status code updateActionStatus(action, Status.ERROR, 432); mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", - target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) + target.getControllerId(), action.getId())).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(jsonPath("lastStatusCode", equalTo(432))) .andExpect(jsonPath("detailStatus", equalTo("error"))); } + private static Stream confirmationOptions() { + return Stream.of(Arguments.of(true, true), Arguments.of(true, false), Arguments.of(false, true), + Arguments.of(false, false), Arguments.of(true, null), Arguments.of(false, null)); + } + + private static Stream possibleActiveStates() { + return Stream.of(Arguments.of("someInitiator", "someRemark"), Arguments.of(null, "someRemark"), + Arguments.of("someInitiator", null), Arguments.of(null, null)); + } + + private void createTarget(final String controllerId) { + targetManagement.create(entityFactory.target().create().controllerId(controllerId) + .address(IpUtil.createHttpUri("127.0.0.1").toString())); + } + + private Target assertTarget(final String controllerId, final String name, final String description) { + final Optional target1 = targetManagement.getByControllerID(controllerId); + assertThat(target1).isPresent(); + final Target t = target1.get(); + assertThat(t.getName()).isEqualTo(name); + assertThat(t.getDescription()).isEqualTo(description); + return t; + } + + private void getActions(final boolean withExternalRef) throws Exception { + final String knownTargetId = "targetId"; + final List actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId); + + final List externalRefs = new ArrayList<>(2); + if (withExternalRef) { + externalRefs.add("extRef#123_0"); + externalRefs.add("extRef#123_1"); + controllerManagement.updateActionExternalRef(actions.get(0).getId(), externalRefs.get(0)); + controllerManagement.updateActionExternalRef(actions.get(1).getId(), externalRefs.get(1)); + } + + final ResultActions resultActions = + mvc.perform(get(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + + MgmtRestConstants.TARGET_V1_ACTIONS).param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "ID:ASC")) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(jsonPath("content.[1].id", equalTo(actions.get(1).getId().intValue()))) + .andExpect(jsonPath("content.[1].type", equalTo("update"))) + .andExpect(jsonPath("content.[1].status", equalTo("pending"))) + .andExpect(jsonPath("content.[1]._links.self.href", + equalTo(generateActionSelfLink(knownTargetId, actions.get(1).getId())))) + .andExpect(jsonPath("content.[0].id", equalTo(actions.get(0).getId().intValue()))) + .andExpect(jsonPath("content.[0].type", equalTo("cancel"))) + .andExpect(jsonPath("content.[0].status", equalTo("pending"))) + .andExpect(jsonPath("content.[0]._links.self.href", + equalTo(generateActionSelfLink(knownTargetId, actions.get(0).getId())))) + .andExpect(jsonPath(JSON_PATH_PAGED_LIST_TOTAL, equalTo(2))) + .andExpect(jsonPath(JSON_PATH_PAGED_LIST_SIZE, equalTo(2))) + .andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(2))); + + if (withExternalRef) { + resultActions + .andExpect(jsonPath("content.[1].externalRef", equalTo(externalRefs.get(1)))) + .andExpect(jsonPath("content.[0].externalRef", equalTo(externalRefs.get(0)))); + } + } + + private String generateActionSelfLink(final String knownTargetId, final Long actionId) { + return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId; + } + + private String generateActionDsLink(final Long dsId) { + return "http://localhost" + MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/" + dsId; + } + + private String generateCanceledactionreferenceLink(final String knownTargetId, final Action action) { + return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + action.getId(); + } + + private String generateStatusreferenceLink(final String knownTargetId, final Long actionId) { + return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/" + MgmtRestConstants.TARGET_V1_ACTION_STATUS + + "?offset=0&limit=50&sort=id%3ADESC"; + } + + private List generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) { + return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null); + } + + private List generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId, + final String schedule, final String duration, final String timezone) { + final Target target = testdataFactory.createTarget(knownTargetId); + + final Iterator sets = testdataFactory.createDistributionSets(2).iterator(); + final DistributionSet one = sets.next(); + final DistributionSet two = sets.next(); + + // Update + if (schedule == null) { + final List updatedTargets = assignDistributionSet(one, Collections.singletonList(target)) + .getAssignedEntity().stream().map(Action::getTarget).collect(Collectors.toList()); + // 2nd update + // sleep 10ms to ensure that we can sort by reportedAt + Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) + .pollInterval(10, TimeUnit.MILLISECONDS) + .until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L)); + assignDistributionSet(two, updatedTargets); + } else { + final List updatedTargets = assignDistributionSetWithMaintenanceWindow(one.getId(), + target.getControllerId(), schedule, duration, timezone).getAssignedEntity().stream() + .map(Action::getTarget).collect(Collectors.toList()); + // 2nd update + // sleep 10ms to ensure that we can sort by reportedAt + Awaitility.await().atMost(Duration.ofMillis(100)).atLeast(5, TimeUnit.MILLISECONDS) + .pollInterval(10, TimeUnit.MILLISECONDS) + .until(() -> updatedTargets.stream().allMatch(t -> t.getLastModifiedAt() > 0L)); + assignDistributionSetWithMaintenanceWindow(two.getId(), updatedTargets.get(0).getControllerId(), schedule, + duration, timezone); + } + + // two updates, one cancellation + final List actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) + .getContent(); + + assertThat(actions).hasSize(2); + return actions; + } + + @Step + private void verifyAttributeUpdateCanBeRequested(final String knownTargetId) throws Exception { + final String body = new JSONObject().put("requestAttributes", true).toString(); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + + assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isTrue(); + } + + @Step + private void verifyRequestAttributesAttributeIsOptional(final String knownTargetId) throws Exception { + final String body = new JSONObject().put("description", "verify attribute can be missing").toString(); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); + } + + @Step + private void verifyResettingRequestAttributesIsNotAllowed(final String knownTargetId) throws Exception { + final String body = new JSONObject().put("requestAttributes", false).toString(); + + mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId).content(body) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isBadRequest()); + + assertThat(targetManagement.isControllerAttributesRequested(knownTargetId)).isTrue(); + } + + private String getCreateTargetsListJsonString(final String controllerId, final String name, + final String description) { + return "[{\"name\":\"" + name + "\",\"controllerId\":\"" + controllerId + "\",\"description\":\"" + description + + "\"}]"; + } + + private Target createSingleTarget(final String controllerId, final String name) { + targetManagement.create(entityFactory.target().create().controllerId(controllerId).name(name) + .description(TARGET_DESCRIPTION_TEST)); + return controllerManagement.findOrRegisterTargetIfItDoesNotExist(controllerId, LOCALHOST); + } + + /** + * Creating targets with the given amount by setting name, id etc from the + * alphabet [a-z] using ASCII. + * + * @param amount The number of targets to create + */ + private void createTargetsAlphabetical(final int amount) { + char character = 'a'; + for (int index = 0; index < amount; index++) { + final String str = String.valueOf(character); + targetManagement.create(entityFactory.target().create().controllerId(str).name(str).description(str)); + controllerManagement.findOrRegisterTargetIfItDoesNotExist(str, LOCALHOST); + character++; + } + } + + /** + * helper method to create a target and start an action on it. + * + * @return The targetid of the created target. + */ + private Target createTargetAndStartAction() { + // prepare test + final DistributionSet dsA = testdataFactory.createDistributionSet(""); + final Target tA = testdataFactory.createTarget("target-id-A"); + // assign a distribution set so we get an active update action + assignDistributionSet(dsA, Arrays.asList(tA)); + // verify active action + final Slice actionsByTarget = deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE); + assertThat(actionsByTarget.getContent()).hasSize(1); + return targetManagement.getByControllerID(tA.getControllerId()).get(); + } + + private void setupTargetWithMetadata(final String knownControllerId, final String knownKey, + final String knownValue) { + testdataFactory.createTarget(knownControllerId); + targetManagement.createMetaData(knownControllerId, + Collections.singletonList(entityFactory.generateTargetMetadata(knownKey, knownValue))); + } + + private void setupTargetWithMetadata(final String knownControllerId, final String knownKeyPrefix, + final String knownValuePrefix, final int totalMetadata) { + testdataFactory.createTarget(knownControllerId); + + final List targetMetadataEntries = new LinkedList<>(); + for (int index = 0; index < totalMetadata; index++) { + targetMetadataEntries + .add(entityFactory.generateTargetMetadata(knownKeyPrefix + index, knownValuePrefix + index)); + } + targetManagement.createMetaData(knownControllerId, targetMetadataEntries); + } + private Action updateActionStatus(final Action action, final Status status, final Integer statusCode) { return updateActionStatus(action, status, statusCode, null); } @@ -2698,9 +2696,4 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { return controllerManagement.addUpdateActionStatus(actionStatus); } - - private static Stream possibleActiveStates() { - return Stream.of(Arguments.of("someInitiator", "someRemark"), Arguments.of(null, "someRemark"), - Arguments.of("someInitiator", null), Arguments.of(null, null)); - } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java index 88f478048..ae990e495 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java @@ -29,6 +29,9 @@ import java.util.Map; import java.util.Random; import java.util.stream.Collectors; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Story; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi; import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent; @@ -52,19 +55,15 @@ import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Story; - /** * Spring MVC Tests against the MgmtTargetTagResource. - * */ @Feature("Component Tests - Management API") @Story("Target Tag Resource") public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationTest { private static final String TARGETTAGS_ROOT = "http://localhost" + MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/"; + private static final Random RND = new Random(); @Test @Description("Verfies that a paged result list of target tags reflects the content on the repository side.") @@ -114,15 +113,15 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT // pass here q directly as a pure string because .queryParam method delimiters the parameters in q with , // which is logical OR, we want AND here mvc.perform(get(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + - "?" + MgmtRestConstants.REQUEST_PARAMETER_SEARCH + "=colour==" + tag2.getColour()) - .accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(applyTagMatcherOnPagedResult(tag2)) - .andExpect(applySelfLinkMatcherOnPagedResult(tag2, TARGETTAGS_ROOT + tag2.getId())) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(1))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(1))) - .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); + "?" + MgmtRestConstants.REQUEST_PARAMETER_SEARCH + "=colour==" + tag2.getColour()) + .accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(applyTagMatcherOnPagedResult(tag2)) + .andExpect(applySelfLinkMatcherOnPagedResult(tag2, TARGETTAGS_ROOT + tag2.getId())) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(1))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(1))) + .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); } @Test @@ -133,7 +132,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT final TargetTag assigned = tags.get(0); mvc.perform(get(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + assigned.getId()) - .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(applyTagMatcherOnSingleResult(assigned)) .andExpect(applySelfLinkMatcherOnSingleResult(TARGETTAGS_ROOT + assigned.getId())) @@ -239,7 +238,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT targetManagement.assignTag(targets.stream().map(Target::getControllerId).collect(Collectors.toList()), tag.getId()); mvc.perform(get(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(targetsAssigned))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize))) @@ -260,13 +259,14 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT targetManagement.assignTag(targets.stream().map(Target::getControllerId).collect(Collectors.toList()), tag.getId()); mvc.perform(get(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(targetsAssigned))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(targetsAssigned))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(targetsAssigned))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize))); } + @Test @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @ExpectEvents({ @@ -295,7 +295,8 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2); final Target assigned0 = targets.get(0); - final Target assigned1 = targets.get(1);; + final Target assigned1 = targets.get(1); + ; mvc.perform(put(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") .content(JsonBuilder.toArray(Arrays.asList(assigned0.getControllerId(), assigned1.getControllerId()))) @@ -307,12 +308,11 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT .containsOnly(assigned0.getControllerId(), assigned1.getControllerId()); } - private static final Random RND = new Random(); @Test @Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.") @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), - @Expect(type = TargetCreatedEvent.class, count = 2)}) + @Expect(type = TargetCreatedEvent.class, count = 2) }) public void assignTargetsNotFound() throws Exception { final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); @@ -352,7 +352,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 2)}) + @Expect(type = TargetUpdatedEvent.class, count = 2) }) public void assignTargetsNotFoundTagAndFail() throws Exception { final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); @@ -394,7 +394,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 2)}) + @Expect(type = TargetUpdatedEvent.class, count = 2) }) public void assignTargetsNotFoundTagAndSuccess() throws Exception { final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); @@ -475,7 +475,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 2)}) + @Expect(type = TargetUpdatedEvent.class, count = 2) }) public void unassignTargetsNotFound() throws Exception { final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); @@ -518,7 +518,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 4)}) + @Expect(type = TargetUpdatedEvent.class, count = 4) }) public void unassignTargetsNotFoundUntagAndFail() throws Exception { final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); @@ -561,7 +561,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 4)}) + @Expect(type = TargetUpdatedEvent.class, count = 4) }) public void unassignTargetsNotFoundUntagAndSuccess() throws Exception { final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final List targets = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); @@ -620,17 +620,6 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT assertThat(targetManagement.findByTag(PAGE, tag.getId())).isEmpty(); } - private ResultActions toggle(final TargetTag tag, final List targets) throws Exception { - return mvc - .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() - + "/assigned/toggleTagAssignment") - .content(controllerIdsOld( - targets.stream().map(Target::getControllerId).collect(Collectors.toList()))) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); - } - @Test @Description("Verfies that tag assignments done through tag API command are correctly stored in the repository.") @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @@ -656,6 +645,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0))) .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1))); } + private static String controllerIdsOld(final Collection ids) throws JSONException { final JSONArray list = new JSONArray(); for (final String smID : ids) { @@ -664,4 +654,15 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT return list.toString(); } + + private ResultActions toggle(final TargetTag tag, final List targets) throws Exception { + return mvc + .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + + "/assigned/toggleTagAssignment") + .content(controllerIdsOld( + targets.stream().map(Target::getControllerId).collect(Collectors.toList()))) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); + } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java index 70c0e504c..27b1707aa 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeResourceTest.java @@ -9,6 +9,21 @@ */ package org.eclipse.hawkbit.mgmt.rest.resource; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.hasToString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.startsWith; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -20,7 +35,6 @@ import io.qameta.allure.Feature; import io.qameta.allure.Step; import io.qameta.allure.Story; import org.apache.commons.lang3.RandomStringUtils; -import org.assertj.core.util.Lists; import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; @@ -38,24 +52,8 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultActions; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.hasToString; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.startsWith; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - /** * Spring MVC Tests against the MgmtTargetTypeResource. - * */ @Feature("Component Tests - Management API") @Story("Target Type Resource") @@ -70,7 +68,6 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { private final static String TEST_USER = "targetTypeTester"; - @Test @WithUser(principal = "targetTypeTester", allSpPermissions = true, removeFromAllPermission = { SpPermission.READ_TARGET }) @Description("GET targettypes returns Forbidden when permission is missing") @@ -169,7 +166,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { // descending mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "name:DESC")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "name:DESC")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[0].id", equalTo(testTypeC.getId().intValue()))) .andExpect(jsonPath("$.content.[0].name", equalTo(typeNameC))) @@ -190,7 +187,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { // ascending mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON) - .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "name:ASC")).andDo(MockMvcResultPrinter.print()) + .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "name:ASC")).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.content.[0].id", equalTo(testTypeA.getId().intValue()))) .andExpect(jsonPath("$.content.[0].name", equalTo(typeNameA))) @@ -221,7 +218,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { createTestTargetTypesInDB(typePrefix, count); mvc.perform(get(TARGETTYPES_ENDPOINT).param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, - String.valueOf(limit))).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + String.valueOf(limit))).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(count))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limit))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(limit))); @@ -238,8 +235,8 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { createTestTargetTypesInDB(typePrefix, count); mvc.perform(get(TARGETTYPES_ENDPOINT) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offset)) - .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(count))) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offset)) + .param(MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(count))) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(count))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) @@ -256,7 +253,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { .put("name", "TestTypePUTupdated").put("colour", "#ffffff").toString(); mvc.perform( - put(TARGETTYPE_SINGLE_ENDPOINT, testType.getId()).content(body).contentType(MediaType.APPLICATION_JSON)) + put(TARGETTYPE_SINGLE_ENDPOINT, testType.getId()).content(body).contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.description", equalTo("updated description"))) @@ -307,7 +304,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { assertThat(testType.getOptLockRevision()).isEqualTo(1); mvc.perform(post(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()) - .content("[{\"id\":" + standardDsType.getId() + "}]").contentType(MediaType.APPLICATION_JSON)) + .content("[{\"id\":" + standardDsType.getId() + "}]").contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); testType = targetTypeManagement.get(testType.getId()).get(); @@ -341,7 +338,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { final TargetType testType = createTestTargetTypeInDB(typeName); mvc.perform(get(TARGETTYPE_DSTYPE_SINGLE_ENDPOINT, testType.getId(), standardDsType.getId()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); } @@ -354,7 +351,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { TargetType testType = createTestTargetTypeInDB(typeName, Collections.singletonList(standardDsType)); mvc.perform(delete(TARGETTYPE_DSTYPE_SINGLE_ENDPOINT, testType.getId(), standardDsType.getId()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); testType = targetTypeManagement.get(testType.getId()).get(); @@ -435,7 +432,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { final String body = new JSONObject().put("id", testType.getId()).put("deleted", true).toString(); mvc.perform( - put(TARGETTYPE_SINGLE_ENDPOINT, testType.getId()).content(body).contentType(MediaType.APPLICATION_JSON)) + put(TARGETTYPE_SINGLE_ENDPOINT, testType.getId()).content(body).contentType(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) .andExpect(jsonPath("$.id", equalTo(testType.getId().intValue()))) .andExpect(jsonPath("$.deleted", equalTo(false))); // don't delete with update @@ -460,7 +457,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { Collections.singletonList(standardDsType)); mvc.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypes(Collections.singletonList(testNewType))) - .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_OCTET_STREAM)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isUnsupportedMediaType()); // bad request - no content @@ -469,18 +466,18 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { // bad request - bad content mvc.perform(post(TARGETTYPES_ENDPOINT).content("sdfjsdlkjfskdjf".getBytes()) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); // Missing mandatory field name mvc.perform(post(TARGETTYPES_ENDPOINT).content("[{\"description\":\"Desc123\"}]") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); final TargetType tooLongName = entityFactory.targetType().create() .name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1)).build(); mvc.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypes(Collections.singletonList(tooLongName))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); // ds types @@ -491,11 +488,11 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { .andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound()); mvc.perform(post(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()).content("{\"id\":1}") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()); mvc.perform(post(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()).content("[{\"id\":44456}]") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isNotFound()); // not allowed methods @@ -515,7 +512,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { .andDo(MockMvcResultPrinter.print()).andExpect(status().isMethodNotAllowed()); mvc.perform(post(TARGETTYPE_DSTYPE_SINGLE_ENDPOINT, testType.getId(), 565765) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isMethodNotAllowed()); mvc.perform(get(TARGETTYPE_DSTYPE_SINGLE_ENDPOINT, testType.getId(), 565765)) @@ -553,13 +550,13 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { // verify quota enforcement for distribution set types mvc.perform(post(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()) - .content(JsonBuilder.ids(dsTypeIds.subList(0, dsTypeIds.size() - 1))) - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(JsonBuilder.ids(dsTypeIds.subList(0, dsTypeIds.size() - 1))) + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); mvc.perform(post(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()) - .content("[{\"id\":" + dsTypeIds.get(dsTypeIds.size() - 1) + "}]") - .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content("[{\"id\":" + dsTypeIds.get(dsTypeIds.size() - 1) + "}]") + .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()) .andExpect(jsonPath("$.exceptionClass", equalTo(AssignmentQuotaExceededException.class.getName()))) .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); @@ -641,8 +638,8 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest { assertThat(JsonPath.compile("$[ ?(@.name=='" + name + "') ].id") .read(mvcResult.getResponse().getContentAsString()).toString()).contains(String.valueOf(created.getId())); assertThat(JsonPath.compile("$[ ?(@.name=='" + name + "') ]._links.self.href") - .read(mvcResult.getResponse().getContentAsString()).toString()).contains("/"+created.getId()); - } + .read(mvcResult.getResponse().getContentAsString()).toString()).contains("/" + created.getId()); + } assertThat(targetTypeManagement.count()).isEqualTo(size); } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java index 6e7a3426a..b71bd87f2 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java @@ -18,6 +18,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.fasterxml.jackson.databind.ObjectMapper; +import io.qameta.allure.Description; +import io.qameta.allure.Feature; +import io.qameta.allure.Story; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; @@ -28,15 +31,10 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.json.JSONObject; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; - -import io.qameta.allure.Description; -import io.qameta.allure.Feature; -import io.qameta.allure.Story; import org.springframework.test.web.servlet.ResultMatcher; /** * Spring MVC Tests against the MgmtTenantManagementResource. - * */ @Feature("Component Tests - Management API") @Story("Tenant Management Resource") @@ -64,37 +62,6 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg } - @Test - @Description("Handles GET request for receiving all tenant specific configurations depending on read gateway token permissions.") - void getTenantConfigurationReadGWToken() throws Exception { - SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_admin", SpPermission.TENANT_CONFIGURATION), () -> { - tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, - "123"); - return null; - }); - - // TODO - should be able to read with TENANT_CONFIGURATION but somehow here the role hierarchy doesn't play - // checked in mgmt / update server runtime PreAuthorizeEnabledTest - SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_admin", SpPermission.READ_TENANT_CONFIGURATION, SpPermission.READ_GATEWAY_SEC_TOKEN), () -> { - mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) - .andDo(MockMvcResultPrinter.print()) - .andDo(m -> System.out.println("-> 1: " + m.getResponse().getContentAsString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "']").exists()) - .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "'].value", equalTo("123"))); - return null; - }); - - SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_read", SpPermission.READ_TENANT_CONFIGURATION), () -> { - mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) - .andDo(MockMvcResultPrinter.print()) - .andDo(m -> System.out.println("-> 2: " + m.getResponse().getContentAsString())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "']").doesNotExist()); - return null; - }); - } - @Test @Description("Handles GET request for receiving a tenant specific configuration.") public void getTenantConfiguration() throws Exception { @@ -110,10 +77,10 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg public void getTenantMetadata() throws Exception { //Test TenantMetadata property mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", - DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.value", equalTo(getActualDefaultDsType().intValue()))); + DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.value", equalTo(getActualDefaultDsType().intValue()))); } @Test @@ -143,26 +110,19 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg final String json = mapper.writeValueAsString(bodyPut); mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", - DEFAULT_DISTRIBUTION_SET_TYPE_KEY).content(json) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); + DEFAULT_DISTRIBUTION_SET_TYPE_KEY).content(json) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); //check if after Rest success, value is really changed in TenantMetadata - assertEquals(updatedTestDefaultDsType, getActualDefaultDsType(), "Rest endpoint for updating the Default DistributionSetType completed successfully, but the actual value was not changed."); - } - - private Long createTestDistributionSetType() { - DistributionSetType testDefaultDsType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create() - .key("test123").name("TestName123").description("TestDefaultDsType")); - testDefaultDsType = distributionSetTypeManagement - .update(entityFactory.distributionSetType().update(testDefaultDsType.getId()).description("TestDefaultDsType")); - return testDefaultDsType.getId(); + assertEquals(updatedTestDefaultDsType, getActualDefaultDsType(), + "Rest endpoint for updating the Default DistributionSetType completed successfully, but the actual value was not changed."); } @Test @Description("Update DefaultDistributionSetType Fails if given DistributionSetType ID does not exist.") - public void putTenantMetadataFails() throws Exception{ + public void putTenantMetadataFails() throws Exception { long oldDefaultDsType = getActualDefaultDsType(); //try an invalid input String newDefaultDsType = new JSONObject().put("value", true).toString(); @@ -175,15 +135,6 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg assertDefaultDsTypeUpdateBadRequestFails(newDefaultDsType, oldDefaultDsType, status().isNotFound()); } - private void assertDefaultDsTypeUpdateBadRequestFails(String newDefaultDsType, long oldDefaultDsType, ResultMatcher resultMatchers) throws Exception { - mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", - DEFAULT_DISTRIBUTION_SET_TYPE_KEY).content(newDefaultDsType) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(resultMatchers); - assertEquals(oldDefaultDsType, getActualDefaultDsType(), "Rest endpoint for updating DefaultDistributionType failed, but actual value changed unexpectedly."); - } - @Test @Description("The 'multi.assignments.enabled' property must not be changed to false.") public void deactivateMultiAssignment() throws Exception { @@ -191,11 +142,11 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg final String bodyDeactivate = new JSONObject().put("value", false).toString(); mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", KEY_MULTI_ASSIGNMENTS) - .content(bodyActivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(bodyActivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", KEY_MULTI_ASSIGNMENTS) - .content(bodyDeactivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(bodyDeactivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()); } @@ -206,11 +157,12 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg // some TenantConfiguration are not valid, // TenantMetadata - DefaultDSType ID is valid, //in the end batch configuration update must fail, and thus, not a single config should be actually changed - long testValidDistributionSetType = createTestDistributionSetType(); + long testValidDistributionSetType = createTestDistributionSetType(); boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); //test TenantConfiguration with invalid config value, and a valid TenantMetadata - Default DistributionSetType id - assertBatchConfigurationFails(!oldRolloutApprovalConfig, "invalid-config-value", oldAuthGatewayToken + "randomSuffix0", testValidDistributionSetType, status().isBadRequest()); + assertBatchConfigurationFails(!oldRolloutApprovalConfig, "invalid-config-value", oldAuthGatewayToken + "randomSuffix0", + testValidDistributionSetType, status().isBadRequest()); } @Test @@ -221,52 +173,33 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg // TenantMetadata - DefaultDSType ID is invalid //in the end batch configuration update must fail, and thus, not a single config should be actually changed. boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); - boolean oldAuthGatewayTokenEnabled = (Boolean) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(); + boolean oldAuthGatewayTokenEnabled = (Boolean) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED) + .getValue(); String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); //invalid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing invalid type - string //not a single configuration should be changed after the failure - Object testInvalidDistributionSetType = "someInvalidInput"; - assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix1", testInvalidDistributionSetType, status().isBadRequest()); + Object testInvalidDistributionSetType = "someInvalidInput"; + assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix1", + testInvalidDistributionSetType, status().isBadRequest()); //invalid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing invalid type - bool //not a single configuration should be changed after the failure testInvalidDistributionSetType = true; - assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", testInvalidDistributionSetType, status().isBadRequest()); + assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", + testInvalidDistributionSetType, status().isBadRequest()); //Valid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing valid type - but given DistributionSetType Id does not exist. //not a single configuration should be changed after the failure testInvalidDistributionSetType = 9999; - assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", testInvalidDistributionSetType, status().isNotFound()); - } - - private void assertBatchConfigurationFails(Object newRolloutApprovalEnabled, Object newAuthGatewayTokenEnabled, Object newGatewayToken, Object newDistributionSetTypeId, ResultMatcher resultMatchers) throws Exception { - long oldDefaultDsType = getActualDefaultDsType(); - boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); - boolean oldAuthGatewayTokenEnabled = (Boolean) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(); - String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); - - JSONObject configuration = new JSONObject(); - configuration.put(ROLLOUT_APPROVAL_ENABLED, newRolloutApprovalEnabled); - configuration.put(AUTHENTICATION_GATEWAYTOKEN_ENABLED, newAuthGatewayTokenEnabled); - configuration.put(AUTHENTICATION_GATEWAYTOKEN_KEY, newGatewayToken); - configuration.put(DEFAULT_DISTRIBUTION_SET_TYPE_KEY, newDistributionSetTypeId); - String body = configuration.toString(); - - mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(resultMatchers); - //Check if TenantMetadata and TenantConfiguration is not changed as Batch config failed - assertEquals(oldDefaultDsType, getActualDefaultDsType(), "Batch configuration update Failed, but TenantMetadata - DistributionSetType was actually changed."); - assertEquals(oldRolloutApprovalConfig, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), "Batch configuration update Failed, but TenantConfiguration was actually changed."); - assertEquals(oldAuthGatewayTokenEnabled, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), "Batch configuration update Failed, but TenantConfiguration was actually changed."); - assertEquals(oldAuthGatewayToken, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), "Batch configuration update Failed, but TenantConfiguration was actually changed."); + assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", + testInvalidDistributionSetType, status().isNotFound()); } @Test @Description("The Batch configuration should be applied") public void changeBatchConfiguration() throws Exception { - long updatedDistributionSetType = createTestDistributionSetType(); + long updatedDistributionSetType = createTestDistributionSetType(); boolean updatedRolloutApprovalEnabled = true; boolean updatedAuthGatewayTokenEnabled = true; String updatedAuthGatewayTokenKey = "54321"; @@ -279,14 +212,20 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg String body = configuration.toString(); mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs") - .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()); //assert all changes were applied after Rest Success - assertEquals(updatedDistributionSetType, getActualDefaultDsType(), "Change BatchConfiguration was successful but TenantMetadata - Default DistributionSetType was not actually changed."); - assertEquals(updatedRolloutApprovalEnabled, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); - assertEquals(updatedAuthGatewayTokenEnabled, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); - assertEquals(updatedAuthGatewayTokenKey, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); + assertEquals(updatedDistributionSetType, getActualDefaultDsType(), + "Change BatchConfiguration was successful but TenantMetadata - Default DistributionSetType was not actually changed."); + assertEquals(updatedRolloutApprovalEnabled, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), + "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); + assertEquals(updatedAuthGatewayTokenEnabled, + tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), + "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); + assertEquals(updatedAuthGatewayTokenKey, + tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), + "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); } @Test @@ -297,17 +236,17 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg // enable Multi-Assignments mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", KEY_MULTI_ASSIGNMENTS) - .content(bodyActivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(bodyActivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); // try to enable Auto-Close mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", KEY_AUTO_CLOSE) - .content(bodyActivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(bodyActivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()); // try to disable Auto-Close mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", KEY_AUTO_CLOSE) - .content(bodyDeactivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .content(bodyDeactivate).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .andExpect(status().isForbidden()); } @@ -324,9 +263,92 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg @Description("Tests DELETE request must Fail for TenantMetadata properties.") public void deleteTenantMetadataFail() throws Exception { mvc.perform(delete(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", - DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isBadRequest()); + DEFAULT_DISTRIBUTION_SET_TYPE_KEY)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isBadRequest()); + } + + @Test + @Description("Handles GET request for receiving all tenant specific configurations depending on read gateway token permissions.") + void getTenantConfigurationReadGWToken() throws Exception { + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_admin", SpPermission.TENANT_CONFIGURATION), () -> { + tenantConfigurationManagement.addOrUpdateConfiguration( + TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, + "123"); + return null; + }); + + // TODO - should be able to read with TENANT_CONFIGURATION but somehow here the role hierarchy doesn't play + // checked in mgmt / update server runtime PreAuthorizeEnabledTest + SecurityContextSwitch.runAs( + SecurityContextSwitch.withUser("tenant_admin", SpPermission.READ_TENANT_CONFIGURATION, SpPermission.READ_GATEWAY_SEC_TOKEN), + () -> { + mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) + .andDo(MockMvcResultPrinter.print()) + .andDo(m -> System.out.println("-> 1: " + m.getResponse().getContentAsString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "']").exists()) + .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "'].value", equalTo("123"))); + return null; + }); + + SecurityContextSwitch.runAs(SecurityContextSwitch.withUser("tenant_read", SpPermission.READ_TENANT_CONFIGURATION), () -> { + mvc.perform(get(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs")) + .andDo(MockMvcResultPrinter.print()) + .andDo(m -> System.out.println("-> 2: " + m.getResponse().getContentAsString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.['" + AUTHENTICATION_GATEWAYTOKEN_KEY + "']").doesNotExist()); + return null; + }); + } + + private Long createTestDistributionSetType() { + DistributionSetType testDefaultDsType = distributionSetTypeManagement.create(entityFactory.distributionSetType().create() + .key("test123").name("TestName123").description("TestDefaultDsType")); + testDefaultDsType = distributionSetTypeManagement + .update(entityFactory.distributionSetType().update(testDefaultDsType.getId()).description("TestDefaultDsType")); + return testDefaultDsType.getId(); + } + + private void assertDefaultDsTypeUpdateBadRequestFails(String newDefaultDsType, long oldDefaultDsType, ResultMatcher resultMatchers) + throws Exception { + mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", + DEFAULT_DISTRIBUTION_SET_TYPE_KEY).content(newDefaultDsType) + .contentType(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(resultMatchers); + assertEquals(oldDefaultDsType, getActualDefaultDsType(), + "Rest endpoint for updating DefaultDistributionType failed, but actual value changed unexpectedly."); + } + + private void assertBatchConfigurationFails(Object newRolloutApprovalEnabled, Object newAuthGatewayTokenEnabled, Object newGatewayToken, + Object newDistributionSetTypeId, ResultMatcher resultMatchers) throws Exception { + long oldDefaultDsType = getActualDefaultDsType(); + boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); + boolean oldAuthGatewayTokenEnabled = (Boolean) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED) + .getValue(); + String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); + + JSONObject configuration = new JSONObject(); + configuration.put(ROLLOUT_APPROVAL_ENABLED, newRolloutApprovalEnabled); + configuration.put(AUTHENTICATION_GATEWAYTOKEN_ENABLED, newAuthGatewayTokenEnabled); + configuration.put(AUTHENTICATION_GATEWAYTOKEN_KEY, newGatewayToken); + configuration.put(DEFAULT_DISTRIBUTION_SET_TYPE_KEY, newDistributionSetTypeId); + String body = configuration.toString(); + + mvc.perform(put(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs") + .content(body).contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) + .andExpect(resultMatchers); + //Check if TenantMetadata and TenantConfiguration is not changed as Batch config failed + assertEquals(oldDefaultDsType, getActualDefaultDsType(), + "Batch configuration update Failed, but TenantMetadata - DistributionSetType was actually changed."); + assertEquals(oldRolloutApprovalConfig, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), + "Batch configuration update Failed, but TenantConfiguration was actually changed."); + assertEquals(oldAuthGatewayTokenEnabled, + tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), + "Batch configuration update Failed, but TenantConfiguration was actually changed."); + assertEquals(oldAuthGatewayToken, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), + "Batch configuration update Failed, but TenantConfiguration was actually changed."); } private Long getActualDefaultDsType() { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/ResourceUtility.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/ResourceUtility.java index 6f225e60c..7153a281c 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/ResourceUtility.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/ResourceUtility.java @@ -11,18 +11,18 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import java.io.IOException; -import org.eclipse.hawkbit.mgmt.json.model.PagedList; -import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact; -import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; - import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.hawkbit.mgmt.json.model.PagedList; +import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact; +import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; /** * Utility additions for the REST API tests. */ public final class ResourceUtility { + private static final ObjectMapper mapper = new ObjectMapper(); static ExceptionInfo convertException(final String jsonExceptionResponse)