Code format hawkbit-mgmt-resource (#1943)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-11-05 11:31:47 +02:00
committed by GitHub
parent fd933ed61d
commit b863fdb337
46 changed files with 2738 additions and 2756 deletions

View File

@@ -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 # Compile

View File

@@ -9,8 +9,8 @@
SPDX-License-Identifier: EPL-2.0 SPDX-License-Identifier: EPL-2.0
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>

View File

@@ -31,11 +31,8 @@ public final class MgmtActionMapper {
/** /**
* Create a response for actions. * Create a response for actions.
* *
* @param actions * @param actions list of actions
* list of actions * @param repMode the representation mode
* @param repMode
* the representation mode
*
* @return the response * @return the response
*/ */
public static List<MgmtAction> toResponse(final Collection<Action> actions, final MgmtRepresentationMode repMode) { public static List<MgmtAction> toResponse(final Collection<Action> actions, final MgmtRepresentationMode repMode) {

View File

@@ -26,8 +26,7 @@ public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi {
/** /**
* Default constructor * Default constructor
* *
* @param tenantAware * @param tenantAware tenantAware
* tenantAware
*/ */
public MgmtBasicAuthResource(TenantAware tenantAware) { public MgmtBasicAuthResource(TenantAware tenantAware) {
this.tenantAware = tenantAware; this.tenantAware = tenantAware;

View File

@@ -21,6 +21,7 @@ import org.eclipse.hawkbit.repository.model.DeploymentRequestBuilder;
* A mapper for assignment requests * A mapper for assignment requests
*/ */
public final class MgmtDeploymentRequestMapper { public final class MgmtDeploymentRequestMapper {
private MgmtDeploymentRequestMapper() { private MgmtDeploymentRequestMapper() {
// Utility class // Utility class
} }
@@ -28,10 +29,8 @@ public final class MgmtDeploymentRequestMapper {
/** /**
* Convert assignment information to an {@link DeploymentRequestBuilder} * Convert assignment information to an {@link DeploymentRequestBuilder}
* *
* @param dsAssignment * @param dsAssignment DS assignment information
* DS assignment information * @param targetId target to assign the DS to
* @param targetId
* target to assign the DS to
* @return resulting {@link DeploymentRequestBuilder} * @return resulting {@link DeploymentRequestBuilder}
*/ */
public static DeploymentRequestBuilder createAssignmentRequestBuilder( public static DeploymentRequestBuilder createAssignmentRequestBuilder(
@@ -44,10 +43,8 @@ public final class MgmtDeploymentRequestMapper {
/** /**
* Convert assignment information to an {@link DeploymentRequestBuilder} * Convert assignment information to an {@link DeploymentRequestBuilder}
* *
* @param targetAssignment * @param targetAssignment target assignment information
* target assignment information * @param dsId DS to assign the target to
* @param dsId
* DS to assign the target to
* @return resulting {@link DeploymentRequestBuilder} * @return resulting {@link DeploymentRequestBuilder}
*/ */
public static DeploymentRequestBuilder createAssignmentRequestBuilder( public static DeploymentRequestBuilder createAssignmentRequestBuilder(

View File

@@ -54,32 +54,6 @@ public final class MgmtDistributionSetMapper {
return sets.stream().map(dsRest -> fromRequest(dsRest, entityFactory)).collect(Collectors.toList()); 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<Long> 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<MetaData> fromRequestDsMetadata(final List<MgmtMetadata> metadata, final EntityFactory entityFactory) { static List<MetaData> fromRequestDsMetadata(final List<MgmtMetadata> metadata, final EntityFactory entityFactory) {
if (metadata == null) { if (metadata == null) {
return Collections.emptyList(); return Collections.emptyList();
@@ -186,4 +160,30 @@ public final class MgmtDistributionSetMapper {
return sets.stream().map(MgmtDistributionSetMapper::toResponse).collect(Collectors.toList()); 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<Long> 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());
}
} }

View File

@@ -52,10 +52,10 @@ import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DeploymentRequest; import org.eclipse.hawkbit.repository.model.DeploymentRequest;
import org.eclipse.hawkbit.repository.model.DistributionSet; 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.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation; import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; 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.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery;

View File

@@ -202,17 +202,6 @@ public class MgmtDistributionSetTagResource implements MgmtDistributionSetTagRes
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) {
return distributionSetTagManagement.get(distributionsetTagId)
.orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, distributionsetTagId));
}
private static List<Long> findDistributionSetIds(
final List<MgmtAssignedDistributionSetRequestBody> assignedDistributionSetRequestBodies) {
return assignedDistributionSetRequestBodies.stream()
.map(MgmtAssignedDistributionSetRequestBody::getDistributionSetId).collect(Collectors.toList());
}
@Override @Override
public ResponseEntity<MgmtDistributionSetTagAssigmentResult> toggleTagAssignment( public ResponseEntity<MgmtDistributionSetTagAssigmentResult> toggleTagAssignment(
@PathVariable("distributionsetTagId") final Long distributionsetTagId, @PathVariable("distributionsetTagId") final Long distributionsetTagId,
@@ -247,4 +236,15 @@ public class MgmtDistributionSetTagResource implements MgmtDistributionSetTagRes
log.debug("Assigned DistributionSet {}", assignedDs.size()); log.debug("Assigned DistributionSet {}", assignedDs.size());
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponseDistributionSets(assignedDs)); return ResponseEntity.ok(MgmtDistributionSetMapper.toResponseDistributionSets(assignedDs));
} }
private static List<Long> findDistributionSetIds(
final List<MgmtAssignedDistributionSetRequestBody> 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));
}
} }

View File

@@ -31,7 +31,6 @@ import org.eclipse.hawkbit.rest.data.ResponseList;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*/ */
final class MgmtDistributionSetTypeMapper { final class MgmtDistributionSetTypeMapper {
@@ -49,25 +48,6 @@ final class MgmtDistributionSetTypeMapper {
return smTypesRest.stream().map(smRest -> fromRequest(entityFactory, smRest)).collect(Collectors.toList()); 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<Long> 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<Long> getOptionalmodules(final MgmtDistributionSetTypeRequestBodyPost smsRest) {
return Optional.ofNullable(smsRest.getOptionalmodules()).map(
modules -> modules.stream().map(MgmtSoftwareModuleTypeAssigment::getId).collect(Collectors.toList()))
.orElse(Collections.emptyList());
}
static List<MgmtDistributionSetType> toListResponse(final Collection<DistributionSetType> types) { static List<MgmtDistributionSetType> toListResponse(final Collection<DistributionSetType> types) {
if (types == null) { if (types == null) {
return Collections.emptyList(); return Collections.emptyList();
@@ -98,4 +78,23 @@ final class MgmtDistributionSetTypeMapper {
.withRel(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULES).expand()); .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<Long> 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<Long> getOptionalmodules(final MgmtDistributionSetTypeRequestBodyPost smsRest) {
return Optional.ofNullable(smsRest.getOptionalmodules()).map(
modules -> modules.stream().map(MgmtSoftwareModuleTypeAssigment::getId).collect(Collectors.toList()))
.orElse(Collections.emptyList());
}
} }

View File

@@ -131,11 +131,6 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
.body(MgmtDistributionSetTypeMapper.toListResponse(createdSoftwareModules)); .body(MgmtDistributionSetTypeMapper.toListResponse(createdSoftwareModules));
} }
private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final Long distributionSetTypeId) {
return distributionSetTypeManagement.get(distributionSetTypeId)
.orElseThrow(() -> new EntityNotFoundException(DistributionSetType.class, distributionSetTypeId));
}
@Override @Override
public ResponseEntity<List<MgmtSoftwareModuleType>> getMandatoryModules( public ResponseEntity<List<MgmtSoftwareModuleType>> getMandatoryModules(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId) {
@@ -219,6 +214,11 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
return ResponseEntity.ok().build(); 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) { private SoftwareModuleType findSoftwareModuleTypeWithExceptionIfNotFound(final Long softwareModuleTypeId) {
return softwareModuleTypeManagement.get(softwareModuleTypeId) return softwareModuleTypeManagement.get(softwareModuleTypeId)

View File

@@ -40,6 +40,7 @@ import org.springframework.web.context.WebApplicationContext;
@RestController @RestController
@Scope(value = WebApplicationContext.SCOPE_REQUEST) @Scope(value = WebApplicationContext.SCOPE_REQUEST)
public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi { public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi {
@Autowired @Autowired
private SoftwareModuleManagement softwareModuleManagement; private SoftwareModuleManagement softwareModuleManagement;
@@ -49,11 +50,8 @@ public class MgmtDownloadArtifactResource implements MgmtDownloadArtifactRestApi
/** /**
* Handles the GET request for downloading an artifact. * Handles the GET request for downloading an artifact.
* *
* @param softwareModuleId * @param softwareModuleId of the parent SoftwareModule
* of the parent SoftwareModule * @param artifactId of the related Artifact
* @param artifactId
* of the related Artifact
*
* @return responseEntity with status ok if successful * @return responseEntity with status ok if successful
*/ */
@Override @Override

View File

@@ -23,7 +23,6 @@ import org.eclipse.hawkbit.repository.model.Type;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*/ */
public final class MgmtRestModelMapper { 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 <null> 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 <null> 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 <null> 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) { static void mapBaseToBase(final MgmtBaseEntity response, final TenantAwareBaseEntity base) {
response.setCreatedBy(base.getCreatedBy()); response.setCreatedBy(base.getCreatedBy());
response.setLastModifiedBy(base.getLastModifiedBy()); response.setLastModifiedBy(base.getLastModifiedBy());
@@ -57,86 +132,4 @@ public final class MgmtRestModelMapper {
response.setColour(base.getColour()); response.setColour(base.getColour());
response.setDeleted(base.isDeleted()); 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 <null> 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 <null> 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 <null> 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");
}
}
} }

View File

@@ -52,8 +52,6 @@ import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*
*/ */
final class MgmtRolloutMapper { final class MgmtRolloutMapper {

View File

@@ -174,15 +174,6 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
return ResponseEntity.status(HttpStatus.CREATED).body(MgmtRolloutMapper.toResponseRollout(rollout, true)); return ResponseEntity.status(HttpStatus.CREATED).body(MgmtRolloutMapper.toResponseRollout(rollout, true));
} }
private Optional<Boolean> 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 @Override
public ResponseEntity<MgmtRolloutResponseBody> update( public ResponseEntity<MgmtRolloutResponseBody> update(
@@ -282,12 +273,6 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
tenantConfigHelper.isConfirmationFlowEnabled())); tenantConfigHelper.isConfirmationFlowEnabled()));
} }
private void findRolloutOrThrowException(final Long rolloutId) {
if (!rolloutManagement.exists(rolloutId)) {
throw new EntityNotFoundException(Rollout.class, rolloutId);
}
}
@Override @Override
public ResponseEntity<PagedList<MgmtTarget>> getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId, public ResponseEntity<PagedList<MgmtTarget>> getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId,
@PathVariable("groupId") final Long groupId, @PathVariable("groupId") final Long groupId,
@@ -349,4 +334,20 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
}); });
} }
private Optional<Boolean> 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);
}
}
} }

View File

@@ -48,13 +48,6 @@ import org.springframework.hateoas.Link;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class MgmtSoftwareModuleMapper { 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<SoftwareModuleMetadataCreate> fromRequestSwMetadata(final EntityFactory entityFactory, static List<SoftwareModuleMetadataCreate> fromRequestSwMetadata(final EntityFactory entityFactory,
final Long softwareModuleId, final Collection<MgmtSoftwareModuleMetadata> metadata) { final Long softwareModuleId, final Collection<MgmtSoftwareModuleMetadata> metadata) {
if (metadata == null) { if (metadata == null) {
@@ -170,4 +163,11 @@ public final class MgmtSoftwareModuleMapper {
artifact.getId(), artifact.getSha1Hash())), ApiType.MGMT, null); artifact.getId(), artifact.getSha1Hash())), ApiType.MGMT, null);
urls.forEach(entry -> response.add(Link.of(entry.getRef()).withRel(entry.getRel()).expand())); 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());
}
} }

View File

@@ -136,14 +136,6 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
return ResponseEntity.ok(new ResponseList<>(response)); 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 @Override
@ResponseBody @ResponseBody
// Exception squid:S3655 - Optional access is checked in // 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)); 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, private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId,
final Long artifactId) { final Long artifactId) {

View File

@@ -28,7 +28,6 @@ import org.eclipse.hawkbit.rest.data.ResponseList;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*/ */
final class MgmtSoftwareModuleTypeMapper { final class MgmtSoftwareModuleTypeMapper {
@@ -46,13 +45,6 @@ final class MgmtSoftwareModuleTypeMapper {
return smTypesRest.stream().map(smRest -> fromRequest(entityFactory, smRest)).collect(Collectors.toList()); 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<MgmtSoftwareModuleType> toTypesResponse(final Collection<SoftwareModuleType> types) { static List<MgmtSoftwareModuleType> toTypesResponse(final Collection<SoftwareModuleType> types) {
if (types == null) { if (types == null) {
return Collections.emptyList(); return Collections.emptyList();
@@ -75,4 +67,11 @@ final class MgmtSoftwareModuleTypeMapper {
return result; 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());
}
} }

View File

@@ -21,8 +21,6 @@ import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest; import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; 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.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; 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. * REST Resource handling for {@link SoftwareModuleType} CRUD operations.
*
*/ */
@RestController @RestController
public class MgmtSoftwareModuleTypeResource implements MgmtSoftwareModuleTypeRestApi { public class MgmtSoftwareModuleTypeResource implements MgmtSoftwareModuleTypeRestApi {

View File

@@ -48,8 +48,7 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi
/** /**
* Deletes the tenant data of a given tenant. USE WITH CARE! * Deletes the tenant data of a given tenant. USE WITH CARE!
* *
* @param tenant * @param tenant to delete
* to delete
* @return HttpStatus.OK * @return HttpStatus.OK
*/ */
@Override @Override
@@ -79,19 +78,6 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi
return ResponseEntity.ok(result); 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. * Returns a list of all caches.
* *
@@ -121,4 +107,17 @@ public class MgmtSystemManagementResource implements MgmtSystemManagementRestApi
cacheNames.forEach(cacheName -> cacheManager.getCache(cacheName).clear()); cacheNames.forEach(cacheName -> cacheManager.getCache(cacheName).clear());
return ResponseEntity.ok(cacheNames); 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;
}
} }

View File

@@ -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.MgmtTargetFilterQuery;
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody; import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetRestApi; 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.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetFilterQueryRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetFilterQueryRestApi;
import org.eclipse.hawkbit.repository.EntityFactory; 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.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.springframework.hateoas.Link;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*/ */
public final class MgmtTargetFilterQueryMapper { public final class MgmtTargetFilterQueryMapper {
@@ -78,7 +75,8 @@ public final class MgmtTargetFilterQueryMapper {
linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withSelfRel().expand()); linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withSelfRel().expand());
if (isReprentationFull && distributionSet != null) { if (isReprentationFull && distributionSet != null) {
targetRest.add( targetRest.add(
linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSets(Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET), linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSets(
Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET),
Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null,
"name==" + distributionSet.getName() + ";version==" + distributionSet.getVersion())).withRel("DS").expand()); "name==" + distributionSet.getName() + ";version==" + distributionSet.getVersion())).withRel("DS").expand());
} }

View File

@@ -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_SEARCH, required = false) final String rsqlParam,
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE_DEFAULT) String representationModeParam) { @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE_DEFAULT) String representationModeParam) {
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
final Sort sorting = PagingUtility.sanitizeTargetFilterQuerySortParam(sortParam); final Sort sorting = PagingUtility.sanitizeTargetFilterQuerySortParam(sortParam);
@@ -141,6 +140,22 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@Override
public ResponseEntity<MgmtDistributionSet> 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 @Override
public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet( public ResponseEntity<MgmtTargetFilterQuery> postAssignedDistributionSet(
@PathVariable("filterId") final Long filterId, @PathVariable("filterId") final Long filterId,
@@ -162,22 +177,6 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
return ResponseEntity.ok(response); return ResponseEntity.ok(response);
} }
@Override
public ResponseEntity<MgmtDistributionSet> 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 @Override
public ResponseEntity<Void> deleteAssignedDistributionSet(@PathVariable("filterId") final Long filterId) { public ResponseEntity<Void> deleteAssignedDistributionSet(@PathVariable("filterId") final Long filterId) {
filterManagement.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(null)); filterManagement.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(filterId).ds(null));
@@ -185,11 +184,6 @@ public class MgmtTargetFilterQueryResource implements MgmtTargetFilterQueryRestA
return ResponseEntity.noContent().build(); 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) { private static MgmtRepresentationMode parseRepresentationMode(final String representationModeParam) {
return MgmtRepresentationMode.fromValue(representationModeParam).orElseGet(() -> { return MgmtRepresentationMode.fromValue(representationModeParam).orElseGet(() -> {
// no need for a 400, just apply a safe fallback // 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));
}
} }

View File

@@ -59,7 +59,6 @@ import org.springframework.util.ObjectUtils;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*/ */
public final class MgmtTargetMapper { public final class MgmtTargetMapper {
@@ -70,8 +69,7 @@ public final class MgmtTargetMapper {
/** /**
* Add links to a target response. * Add links to a target response.
* *
* @param response * @param response the target response
* the target response
*/ */
public static void addTargetLinks(final MgmtTarget response) { public static void addTargetLinks(final MgmtTarget response) {
response.add(linkTo(methodOn(MgmtTargetRestApi.class).getAssignedDistributionSet(response.getControllerId())) response.add(linkTo(methodOn(MgmtTargetRestApi.class).getAssignedDistributionSet(response.getControllerId()))
@@ -115,24 +113,10 @@ public final class MgmtTargetMapper {
return response; return response;
} }
private static void addPollStatus(final Target target, final MgmtTarget targetRest, final Function<Target, PollStatus> 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. * Create a response for targets.
* *
* @param targets * @param targets list of targets
* list of targets
* @return the response * @return the response
*/ */
public static List<MgmtTarget> toResponse(final Collection<Target> targets, final TenantConfigHelper configHelper) { public static List<MgmtTarget> toResponse(final Collection<Target> targets, final TenantConfigHelper configHelper) {
@@ -148,11 +132,11 @@ public final class MgmtTargetMapper {
/** /**
* Create a response for target. * Create a response for target.
* *
* @param target * @param target the target
* the target
* @return the response * @return the response
*/ */
public static MgmtTarget toResponse(final Target target, final TenantConfigHelper configHelper, final Function<Target, PollStatus> pollStatusResolver) { public static MgmtTarget toResponse(final Target target, final TenantConfigHelper configHelper,
final Function<Target, PollStatus> pollStatusResolver) {
if (target == null) { if (target == null) {
return null; return null;
} }
@@ -215,12 +199,6 @@ public final class MgmtTargetMapper {
.collect(Collectors.toList()); .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<MetaData> fromRequestTargetMetadata(final List<MgmtMetadata> metadata, static List<MetaData> fromRequestTargetMetadata(final List<MgmtMetadata> metadata,
final EntityFactory entityFactory) { final EntityFactory entityFactory) {
if (metadata == null) { if (metadata == null) {
@@ -336,6 +314,36 @@ public final class MgmtTargetMapper {
return actions.stream().map(action -> toResponse(targetId, action)).collect(Collectors.toList()); 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<MgmtMetadata> toResponseTargetMetadata(final List<TargetMetadata> metadata) {
return metadata.stream().map(MgmtTargetMapper::toResponseTargetMetadata).collect(Collectors.toList());
}
private static void addPollStatus(final Target target, final MgmtTarget targetRest, final Function<Target, PollStatus> 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) { private static String getType(final Action action) {
if (!action.isCancelingOrCanceled()) { if (!action.isCancelingOrCanceled()) {
return MgmtAction.ACTION_UPDATE; return MgmtAction.ACTION_UPDATE;
@@ -357,15 +365,4 @@ public final class MgmtTargetMapper {
return result; 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<MgmtMetadata> toResponseTargetMetadata(final List<TargetMetadata> metadata) {
return metadata.stream().map(MgmtTargetMapper::toResponseTargetMetadata).collect(Collectors.toList());
}
} }

View File

@@ -169,7 +169,8 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
} else { } else {
updateTarget = this.targetManagement.update( updateTarget = this.targetManagement.update(
entityFactory.target().update(targetId).name(targetRest.getName()).description(targetRest.getDescription()) entityFactory.target().update(targetId).name(targetRest.getName()).description(targetRest.getDescription())
.address(targetRest.getAddress()).targetType(targetRest.getTargetType()).securityToken(targetRest.getSecurityToken()) .address(targetRest.getAddress()).targetType(targetRest.getTargetType())
.securityToken(targetRest.getSecurityToken())
.requestAttributes(targetRest.getRequestAttributes())); .requestAttributes(targetRest.getRequestAttributes()));
} }
@@ -278,6 +279,26 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
return ResponseEntity.noContent().build(); return ResponseEntity.noContent().build();
} }
@Override
public ResponseEntity<MgmtAction> 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 @Override
public ResponseEntity<PagedList<MgmtActionStatus>> getActionStatusList( public ResponseEntity<PagedList<MgmtActionStatus>> getActionStatusList(
@PathVariable("targetId") final String targetId, @PathVariable("actionId") final Long actionId, @PathVariable("targetId") final String targetId, @PathVariable("actionId") final Long actionId,
@@ -370,31 +391,6 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
return ResponseEntity.ok(distributionSetRest); return ResponseEntity.ok(distributionSetRest);
} }
private Target findTargetWithExceptionIfNotFound(final String targetId) {
return targetManagement.getByControllerID(targetId)
.orElseThrow(() -> new EntityNotFoundException(Target.class, targetId));
}
@Override
public ResponseEntity<MgmtAction> 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 @Override
public ResponseEntity<List<MgmtTag>> getTags(@PathVariable("targetId") String targetId) { public ResponseEntity<List<MgmtTag>> getTags(@PathVariable("targetId") String targetId) {
final Set<TargetTag> tags = targetManagement.getTagsByControllerId(targetId); final Set<TargetTag> tags = targetManagement.getTagsByControllerId(targetId);
@@ -473,14 +469,19 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
private <T, R> R getNullIfEmpty(final T object, final Function<T, R> extractMethod) {
return object == null ? null : extractMethod.apply(object);
}
@Override @Override
public ResponseEntity<Void> deactivateAutoConfirm(@PathVariable("targetId") final String targetId) { public ResponseEntity<Void> deactivateAutoConfirm(@PathVariable("targetId") final String targetId) {
confirmationManagement.deactivateAutoConfirmation(targetId); confirmationManagement.deactivateAutoConfirmation(targetId);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
private Target findTargetWithExceptionIfNotFound(final String targetId) {
return targetManagement.getByControllerID(targetId)
.orElseThrow(() -> new EntityNotFoundException(Target.class, targetId));
}
private <T, R> R getNullIfEmpty(final T object, final Function<T, R> extractMethod) {
return object == null ? null : extractMethod.apply(object);
}
} }

View File

@@ -161,24 +161,6 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements())); return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements()));
} }
@Override
public ResponseEntity<MgmtTargetTagAssigmentResult> toggleTagAssignment(
@PathVariable("targetTagId") final Long targetTagId,
@RequestBody final List<MgmtAssignedTargetRequestBody> 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 @Override
public ResponseEntity<Void> assignTarget(final Long targetTagId, final String controllerId) { public ResponseEntity<Void> assignTarget(final Long targetTagId, final String controllerId) {
log.debug("Assign target {} for target tag {}", controllerId, targetTagId); log.debug("Assign target {} for target tag {}", controllerId, targetTagId);
@@ -187,7 +169,8 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
} }
@Override @Override
public ResponseEntity<Void> assignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, final List<String> controllerIds) { public ResponseEntity<Void> assignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy,
final List<String> controllerIds) {
log.debug("Assign {} targets for target tag {}", controllerIds.size(), targetTagId); log.debug("Assign {} targets for target tag {}", controllerIds.size(), targetTagId);
if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) { if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) {
this.targetManagement.assignTag(controllerIds, targetTagId); this.targetManagement.assignTag(controllerIds, targetTagId);
@@ -213,7 +196,8 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
} }
@Override @Override
public ResponseEntity<Void> unassignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy, final List<String> controllerIds) { public ResponseEntity<Void> unassignTargets(final Long targetTagId, final OnNotFoundPolicy onNotFoundPolicy,
final List<String> controllerIds) {
log.debug("Unassign {} targets for target tag {}", controllerIds.size(), targetTagId); log.debug("Unassign {} targets for target tag {}", controllerIds.size(), targetTagId);
if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) { if (onNotFoundPolicy == OnNotFoundPolicy.FAIL) {
this.targetManagement.unassignTag(controllerIds, targetTagId); this.targetManagement.unassignTag(controllerIds, targetTagId);
@@ -230,6 +214,24 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@Override
public ResponseEntity<MgmtTargetTagAssigmentResult> toggleTagAssignment(
@PathVariable("targetTagId") final Long targetTagId,
@RequestBody final List<MgmtAssignedTargetRequestBody> 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 @Override
public ResponseEntity<List<MgmtTarget>> assignTargetsByRequestBody(@PathVariable("targetTagId") final Long targetTagId, public ResponseEntity<List<MgmtTarget>> assignTargetsByRequestBody(@PathVariable("targetTagId") final Long targetTagId,
@RequestBody final List<MgmtAssignedTargetRequestBody> assignedTargetRequestBodies) { @RequestBody final List<MgmtAssignedTargetRequestBody> assignedTargetRequestBodies) {

View File

@@ -46,20 +46,6 @@ public final class MgmtTargetTypeMapper {
.collect(Collectors.toList()); .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<Long> getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) {
return Optional.ofNullable(targetTypesRest.getCompatibledistributionsettypes())
.map(ds -> ds.stream().map(MgmtDistributionSetTypeAssignment::getId).collect(Collectors.toList()))
.orElse(Collections.emptyList());
}
static List<MgmtTargetType> toListResponse(final List<TargetType> types) { static List<MgmtTargetType> toListResponse(final List<TargetType> types) {
if (types == null) { if (types == null) {
return Collections.emptyList(); return Collections.emptyList();
@@ -81,4 +67,18 @@ public final class MgmtTargetTypeMapper {
result.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getCompatibleDistributionSets(result.getTypeId())) result.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getCompatibleDistributionSets(result.getTypeId()))
.withRel(MgmtRestConstants.TARGETTYPE_V1_DS_TYPES).expand()); .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<Long> getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) {
return Optional.ofNullable(targetTypesRest.getCompatibledistributionsettypes())
.map(ds -> ds.stream().map(MgmtDistributionSetTypeAssignment::getId).collect(Collectors.toList()))
.orElse(Collections.emptyList());
}
} }

View File

@@ -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.linkTo;
import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn;
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
@@ -19,6 +20,7 @@ import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
* back. * back.
*/ */
public final class MgmtTenantManagementMapper { public final class MgmtTenantManagementMapper {
public static String DEFAULT_DISTRIBUTION_SET_TYPE_KEY = "default.ds.type"; public static String DEFAULT_DISTRIBUTION_SET_TYPE_KEY = "default.ds.type";
private MgmtTenantManagementMapper() { private MgmtTenantManagementMapper() {

View File

@@ -14,7 +14,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValue;
@@ -64,7 +63,8 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
}); });
// Load and Add Default DistributionSetType // 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); tenantConfigurationValueMap.put(MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY, defaultDsTypeId);
// return combined TenantConfiguration and TenantMetadata // return combined TenantConfiguration and TenantMetadata
@@ -72,24 +72,6 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
return ResponseEntity.ok(tenantConfigurationValueMap); return ResponseEntity.ok(tenantConfigurationValueMap);
} }
@Override
public ResponseEntity<MgmtSystemTenantConfigurationValue> 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 @Override
public ResponseEntity<Void> deleteTenantConfigurationValue(@PathVariable("keyName") final String keyName) { public ResponseEntity<Void> deleteTenantConfigurationValue(@PathVariable("keyName") final String keyName) {
@@ -104,6 +86,12 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@Override
public ResponseEntity<MgmtSystemTenantConfigurationValue> getTenantConfigurationValue(
@PathVariable("keyName") final String keyName) {
return ResponseEntity.ok(loadTenantConfigurationValueBy(keyName));
}
@Override @Override
public ResponseEntity<MgmtSystemTenantConfigurationValue> updateTenantConfigurationValue( public ResponseEntity<MgmtSystemTenantConfigurationValue> updateTenantConfigurationValue(
@PathVariable("keyName") final String keyName, @PathVariable("keyName") final String keyName,
@@ -152,15 +140,34 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
throw ex; throw ex;
} }
List<MgmtSystemTenantConfigurationValue> tenantConfigurationListUpdated = new java.util.ArrayList<>(tenantConfigurationValues.entrySet().stream() List<MgmtSystemTenantConfigurationValue> tenantConfigurationListUpdated = new java.util.ArrayList<>(
.map(entry -> MgmtTenantManagementMapper.toResponseTenantConfigurationValue(entry.getKey(), entry.getValue())).toList()); tenantConfigurationValues.entrySet().stream()
.map(entry -> MgmtTenantManagementMapper.toResponseTenantConfigurationValue(entry.getKey(), entry.getValue()))
.toList());
if (updatedDefaultDsType != null) { if (updatedDefaultDsType != null) {
tenantConfigurationListUpdated.add(updatedDefaultDsType); tenantConfigurationListUpdated.add(updatedDefaultDsType);
} }
return ResponseEntity.ok(tenantConfigurationListUpdated); return ResponseEntity.ok(tenantConfigurationListUpdated);
} }
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) { private MgmtSystemTenantConfigurationValue updateDefaultDsType(Serializable defaultDsType) {
long updateDefaultDsType; long updateDefaultDsType;
try { try {
@@ -173,9 +180,4 @@ public class MgmtTenantManagementResource implements MgmtTenantManagementRestApi
return MgmtTenantManagementMapper.toResponseDefaultDsType(updateDefaultDsType); return MgmtTenantManagementMapper.toResponseDefaultDsType(updateDefaultDsType);
} }
private static boolean isDefaultDistributionSetTypeKey(String keyName) {
return MgmtTenantManagementMapper.DEFAULT_DISTRIBUTION_SET_TYPE_KEY.equals(keyName);
}
} }

View File

@@ -30,9 +30,9 @@ import org.springframework.data.domain.Sort.Direction;
/** /**
* Utility class for for paged body generation. * Utility class for for paged body generation.
*
*/ */
public final class PagingUtility { public final class PagingUtility {
/* /*
* utility constructor private. * utility constructor private.
*/ */

View File

@@ -27,6 +27,10 @@ import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; 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.awaitility.Awaitility;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtActionRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtActionRestApi;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRepresentationMode; 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.repository.model.Target;
import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter;
import org.junit.jupiter.api.Test; 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; 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; 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 @Test
@Description("Verifies that actions can be filtered based on action status.") @Description("Verifies that actions can be filtered based on action status.")
void filterActionsByStatus() throws Exception { void filterActionsByStatus() throws Exception {
@@ -292,18 +303,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
verifyResultsByTargetPropertyFilter(target, ds, rsqlTargetAddress); 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 @Test
@Description("Verifies that all available actions are returned if the complete collection is requested.") @Description("Verifies that all available actions are returned if the complete collection is requested.")
void getActions() throws Exception { void getActions() throws Exception {
@@ -316,55 +315,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
getActions(true); getActions(true);
} }
private void getActions(final boolean withExternalRef ) throws Exception {
final String knownTargetId = "targetId";
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
final Action action0 = actions.get(0);
final Action action1 = actions.get(1);
final List<String> 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 @Test
@Description("Verifies that a full representation of all actions is returned if the collection is requested for representation mode 'full'.") @Description("Verifies that a full representation of all actions is returned if the collection is requested for representation mode 'full'.")
void getActionsFullRepresentation() throws Exception { void getActionsFullRepresentation() throws Exception {
@@ -414,47 +364,6 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("content", hasSize(0))).andExpect(jsonPath("total", equalTo(0))); .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<Action> 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 @Test
@Description("Verifies paging is respected as expected.") @Description("Verifies paging is respected as expected.")
void getMultipleActionsWithPagingLimitRequestParameter() throws Exception { void getMultipleActionsWithPagingLimitRequestParameter() throws Exception {
@@ -541,6 +450,110 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isNotFound()); .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<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
final Action action0 = actions.get(0);
final Action action1 = actions.get(1);
final List<String> 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<Action> 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<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) { private List<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) {
return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null); return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null);
} }
@@ -583,18 +596,4 @@ class MgmtActionResourceTest extends AbstractManagementApiIntegrationTest {
assertThat(actions).hasSize(2); assertThat(actions).hasSize(2);
return actions; 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();
}
} }

View File

@@ -9,6 +9,12 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; 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.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Story; 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.util.Base64Utils;
import org.springframework.web.context.WebApplicationContext; 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}. * Test for {@link MgmtBasicAuthResource}.
*/ */
@@ -75,14 +75,12 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@Story("Basic auth Userinfo Resource") @Story("Basic auth Userinfo Resource")
public class MgmtBasicAuthResourceTest { public class MgmtBasicAuthResourceTest {
private static final String TEST_USER = "testUser";
private static final String DEFAULT = "default";
@Autowired
MockMvc defaultMock;
@Autowired @Autowired
protected WebApplicationContext webApplicationContext; protected WebApplicationContext webApplicationContext;
@Autowired
MockMvc defaultMock;
private static final String TEST_USER = "testUser";
private static final String DEFAULT = "default";
@Test @Test
@Description("Test of userinfo api with basic auth validation") @Description("Test of userinfo api with basic auth validation")

View File

@@ -9,6 +9,15 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; 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.Description;
import io.qameta.allure.Feature; import io.qameta.allure.Feature;
import io.qameta.allure.Story; import io.qameta.allure.Story;
@@ -26,15 +35,6 @@ import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; 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 * 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 * 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") @Story("Response Content-Type")
public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest { public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
private DistributionSet ds;
private final String dsName = "DS-ö"; private final String dsName = "DS-ö";
private DistributionSet ds;
@BeforeEach @BeforeEach
public void setupBeforeTest() { public void setupBeforeTest() {
@@ -58,7 +58,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("The response of a POST request shall contain charset=utf-8") @Description("The response of a POST request shall contain charset=utf-8")
public void postDistributionSet_ContentTypeJsonUtf8_woAccept() throws Exception { public void postDistributionSet_ContentTypeJsonUtf8_woAccept() throws Exception {
final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) 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()) .contentType(MediaType.APPLICATION_JSON_UTF8)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isCreated()).andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); .andExpect(status().isCreated()).andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn();
@@ -68,7 +69,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("The response of a POST request shall contain charset=utf-8") @Description("The response of a POST request shall contain charset=utf-8")
public void postDistributionSet_ContentTypeJsonUtf8_wAcceptJson() throws Exception { public void postDistributionSet_ContentTypeJsonUtf8_wAcceptJson() throws Exception {
final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) 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)) .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn();
@@ -79,7 +81,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("The response of a POST request shall contain charset=utf-8") @Description("The response of a POST request shall contain charset=utf-8")
public void postDistributionSet_ContentTypeJsonUtf8_wAcceptJsonUtf8() throws Exception { public void postDistributionSet_ContentTypeJsonUtf8_wAcceptJsonUtf8() throws Exception {
final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) 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)) .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON_UTF8))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn();
@@ -90,7 +93,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("The response of a POST request shall contain charset=utf-8") @Description("The response of a POST request shall contain charset=utf-8")
public void postDistributionSet_ContentTypeJsonUtf8_wAcceptHalJson() throws Exception { public void postDistributionSet_ContentTypeJsonUtf8_wAcceptHalJson() throws Exception {
final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) 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)) .contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaTypes.HAL_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn();
@@ -101,7 +105,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("The response of a POST request shall contain charset=utf-8") @Description("The response of a POST request shall contain charset=utf-8")
public void postDistributionSet_ContentTypeJson_woAccept() throws Exception { public void postDistributionSet_ContentTypeJson_woAccept() throws Exception {
final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) final MvcResult result = mvc.perform(
post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds)))
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isCreated()) .andExpect(status().isCreated())
.andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn();
@@ -112,7 +117,8 @@ public class MgmtContentTypeTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@Description("The response of a POST request shall contain charset=utf-8") @Description("The response of a POST request shall contain charset=utf-8")
public void postDistributionSet_ContentTypeJson_wAcceptJson() throws Exception { public void postDistributionSet_ContentTypeJson_wAcceptJson() throws Exception {
final MvcResult result = mvc.perform(post(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING).content(JsonBuilder.distributionSets(Arrays.asList(ds))) 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)) .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated()) .andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
.andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn(); .andExpect(jsonPath("[0]name", equalTo(dsName))).andReturn();

View File

@@ -36,6 +36,11 @@ import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import java.util.stream.Stream; 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.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType; 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.hateoas.MediaTypes;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; 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; import org.springframework.util.Assert;
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Distribution Set Resource") @Story("Distribution Set Resource")
public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTest { public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegrationTest {
@Autowired
ActionRepository actionRepository;
@Test @Test
@Description("This test verifies the call of all Software Modules that are assigned to a Distribution Set through the RESTful API.") @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 { public void getSoftwareModules() throws Exception {
@@ -330,7 +330,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
final DistributionSetType type = testdataFactory.findOrCreateDistributionSetType( final DistributionSetType type = testdataFactory.findOrCreateDistributionSetType(
"testKey", "testType", Collections.singletonList(softwareModule.getType()), "testKey", "testType", Collections.singletonList(softwareModule.getType()),
Collections.singletonList(softwareModule.getType())); Collections.singletonList(softwareModule.getType()));
final DistributionSet ds = testdataFactory.createDistributionSet("dsName", "dsVersion", type, Collections.singletonList(softwareModule)); final DistributionSet ds = testdataFactory.createDistributionSet("dsName", "dsVersion", type,
Collections.singletonList(softwareModule));
final Target target = testdataFactory.createTarget("exampleControllerId"); final Target target = testdataFactory.createTarget("exampleControllerId");
assignDistributionSet(ds, target); assignDistributionSet(ds, target);
@@ -552,39 +553,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(jsonPath("$.assigned", equalTo(2))).andExpect(jsonPath("$.total", equalTo(3))); .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 @Test
@Description("Ensures that assigned targets of DS are returned as reflected by the repository.") @Description("Ensures that assigned targets of DS are returned as reflected by the repository.")
public void getAssignedTargetsOfDistributionSet() throws Exception { public void getAssignedTargetsOfDistributionSet() throws Exception {
@@ -743,19 +711,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(status().isOk()).andExpect(jsonPath("$.size", equalTo(0))); .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 @Test
@Description("Ensures that DS in repository are listed with proper paging properties.") @Description("Ensures that DS in repository are listed with proper paging properties.")
public void getDistributionSetsWithoutAdditionalRequestParameters() throws Exception { public void getDistributionSetsWithoutAdditionalRequestParameters() throws Exception {
@@ -932,56 +887,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
assertThat(three.getCreatedAt()).isGreaterThanOrEqualTo(current); 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 @Test
@Description("Ensures that DS deletion request to API is reflected by the repository.") @Description("Ensures that DS deletion request to API is reflected by the repository.")
public void deleteUnassignedistributionSet() throws Exception { public void deleteUnassignedistributionSet() throws Exception {
@@ -1061,54 +966,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
assertThat(setupdated.isDeleted()).isEqualTo(false); 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 @Test
@Description("Ensures that DS property update on requiredMigrationStep fails if DS is assigned to a target.") @Description("Ensures that DS property update on requiredMigrationStep fails if DS is assigned to a target.")
public void updateRequiredMigrationStepFailsIfDistributionSetisInUse() throws Exception { public void updateRequiredMigrationStepFailsIfDistributionSetisInUse() throws Exception {
@@ -1318,7 +1175,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
final String knownValuePrefix = "knownValue"; final String knownValuePrefix = "knownValue";
final DistributionSet testDS = testdataFactory.createDistributionSet("one"); final DistributionSet testDS = testdataFactory.createDistributionSet("one");
for (int index = 0; index < totalMetadata; index++) { 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", mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}/metadata",
@@ -1427,17 +1285,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(jsonPath("content[0].value", equalTo("knownValue1"))); .andExpect(jsonPath("content[0].value", equalTo("knownValue1")));
} }
private Set<DistributionSet> createDistributionSetsAlphabetical(final int amount) {
char character = 'a';
final Set<DistributionSet> 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 @Test
@Description("Ensures that multi target assignment through API is reflected by the repository in the case of " @Description("Ensures that multi target assignment through API is reflected by the repository in the case of "
+ "DOWNLOAD_ONLY.") + "DOWNLOAD_ONLY.")
@@ -1460,8 +1307,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.as("Five targets in repository have DS assigned").hasSize(5); .as("Five targets in repository have DS assigned").hasSize(5);
} }
@Autowired
ActionRepository actionRepository;
@ParameterizedTest @ParameterizedTest
@MethodSource("confirmationOptions") @MethodSource("confirmationOptions")
@Description("Ensures that confirmation option is considered in assignment request.") @Description("Ensures that confirmation option is considered in assignment request.")
@@ -1495,11 +1340,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
}); });
} }
private static Stream<Arguments> 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 @Test
@Description("A request for assigning a target multiple times results in a Bad Request when multiassignment is disabled.") @Description("A request for assigning a target multiple times results in a Bad Request when multiassignment is disabled.")
public void multiAssignmentRequestNotAllowedIfDisabled() throws Exception { public void multiAssignmentRequestNotAllowedIfDisabled() throws Exception {
@@ -1591,7 +1431,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutHandler.handleAll(); 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()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("rollouts.READY", equalTo(1))) .andExpect(jsonPath("rollouts.READY", equalTo(1)))
@@ -1600,7 +1441,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(jsonPath("actions").doesNotExist()) .andExpect(jsonPath("actions").doesNotExist())
.andExpect(jsonPath("totalAutoAssignments").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()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("rollouts").doesNotExist())
@@ -1621,7 +1463,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutHandler.handleAll(); 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()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("actions.RUNNING", equalTo(4))) .andExpect(jsonPath("actions.RUNNING", equalTo(4)))
@@ -1629,7 +1472,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("rollouts").doesNotExist())
.andExpect(jsonPath("totalAutoAssignments").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()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("rollouts").doesNotExist())
@@ -1645,19 +1489,23 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
DistributionSet ds2 = testdataFactory.createDistributionSet("DS2"); DistributionSet ds2 = testdataFactory.createDistributionSet("DS2");
targetFilterQueryManagement.create( 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( 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()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("totalAutoAssignments", equalTo(2))) .andExpect(jsonPath("totalAutoAssignments", equalTo(2)))
.andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("rollouts").doesNotExist())
.andExpect(jsonPath("actions").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()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("rollouts").doesNotExist())
@@ -1674,15 +1522,16 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
DistributionSet ds2 = testdataFactory.createDistributionSet("DS2"); DistributionSet ds2 = testdataFactory.createDistributionSet("DS2");
targetFilterQueryManagement.create( 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", Rollout rollout = testdataFactory.createRolloutByVariables("rollout", "description",
1, "name==targets*", ds1, "50", "5", false); 1, "name==targets*", ds1, "50", "5", false);
rolloutManagement.start(rollout.getId()); rolloutManagement.start(rollout.getId());
rolloutHandler.handleAll(); rolloutHandler.handleAll();
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics", ds1.getId()).contentType(
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics", ds1.getId()).contentType(MediaType.APPLICATION_JSON)) MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("totalAutoAssignments", equalTo(1))) .andExpect(jsonPath("totalAutoAssignments", equalTo(1)))
@@ -1691,8 +1540,8 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(jsonPath("rollouts.RUNNING", equalTo(1))) .andExpect(jsonPath("rollouts.RUNNING", equalTo(1)))
.andExpect(jsonPath("rollouts.total", equalTo(1))); .andExpect(jsonPath("rollouts.total", equalTo(1)));
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType(
mvc.perform(get(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{ds}/statistics/autoassignments", ds2.getId()).contentType(MediaType.APPLICATION_JSON)) MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("rollouts").doesNotExist()) .andExpect(jsonPath("rollouts").doesNotExist())
@@ -1700,7 +1549,6 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.andExpect(jsonPath("totalAutoAssignments").doesNotExist()); .andExpect(jsonPath("totalAutoAssignments").doesNotExist());
} }
@Test @Test
@Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments, stops rollouts and cancels assignments") @Description("Verify invalidation of distribution sets that removes distribution sets from auto assignments, stops rollouts and cancels assignments")
public void invalidateDistributionSet() throws Exception { public void invalidateDistributionSet() throws Exception {
@@ -1733,4 +1581,164 @@ public class MgmtDistributionSetResourceTest extends AbstractManagementApiIntegr
.getContent().get(0).getStatus()).isEqualTo(Status.CANCELING); .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<Arguments> 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<DistributionSet> createDistributionSetsAlphabetical(final int amount) {
char character = 'a';
final Set<DistributionSet> 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;
}
} }

View File

@@ -28,21 +28,20 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.stream.Collectors; 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.MgmtRestConstants;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent; 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.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent; 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.DistributionSetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetUpdatedEvent; 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.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.Tag; 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.Expect;
import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents; import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; 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.http.MediaType;
import org.springframework.test.web.servlet.ResultActions; 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") @Feature("Component Tests - Management API")
@Story("Distribution Set Tag Resource") @Story("Distribution Set Tag Resource")
public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiIntegrationTest { public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiIntegrationTest {
private static final String DISTRIBUTIONSETTAGS_ROOT = "http://localhost" private static final String DISTRIBUTIONSETTAGS_ROOT = "http://localhost"
+ MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/"; + MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/";
private static final Random RND = new Random();
@Test @Test
@Description("Verfies that a paged result list of DS tags reflects the content on the repository side.") @Description("Verfies that a paged result list of DS tags reflects the content on the repository side.")
@@ -337,16 +333,6 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
assertThat(distributionSetManagement.findByTag(PAGE, tag.getId())).isEmpty(); assertThat(distributionSetManagement.findByTag(PAGE, tag.getId())).isEmpty();
} }
private ResultActions toggle(final DistributionSetTag tag, final List<DistributionSet> 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 @Test
@Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.")
@ExpectEvents({ @ExpectEvents({
@@ -435,7 +421,6 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
.containsOnly(assigned.getId()); .containsOnly(assigned.getId());
} }
private static final Random RND = new Random();
@Test @Test
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.") @Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
@ExpectEvents({ @ExpectEvents({
@@ -475,8 +460,6 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
}); });
} }
// DEPRECATED flows
@Test @Test
@Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.")
@ExpectEvents({ @ExpectEvents({
@@ -505,4 +488,16 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt
result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0))) result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0)))
.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1))); .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1)));
} }
// DEPRECATED flows
private ResultActions toggle(final DistributionSetTag tag, final List<DistributionSet> 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));
}
} }

View File

@@ -28,8 +28,12 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; 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.apache.commons.lang3.RandomStringUtils;
import org.assertj.core.util.Lists;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleTypeCreate; 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.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; 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}. * Test for {@link MgmtDistributionSetTypeResource}.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Distribution Set Type Resource") @Story("Distribution Set Type Resource")
@@ -149,68 +145,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
verifyCreatedDistributionSetTypes(mvcResult); 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<DistributionSetType> 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<DistributionSetType> 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 @Test
@WithUser(principal = "uploadTester", allSpPermissions = true) @WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes POST requests.") @Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/mandatorymoduletypes POST requests.")
@@ -350,16 +284,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
.andExpect(jsonPath("$.lastModifiedAt", equalTo(osType.getLastModifiedAt()))); .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 @Test
@WithUser(principal = "uploadTester", allSpPermissions = true) @WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes/{ID} GET requests.") @Description("Checks the correct behaviour of /rest/v1/distributionsettypes/{ID}/optionalmoduletypes/{ID} GET requests.")
@@ -685,6 +609,78 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractManagementApiIn
.andExpect(jsonPath("content[1].name", equalTo("TestName1234"))); .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<DistributionSetType> 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<DistributionSetType> 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) { private void createSoftwareModulesAlphabetical(final int amount) {
char character = 'a'; char character = 'a';
for (int index = 0; index < amount; index++) { for (int index = 0; index < amount; index++) {

View File

@@ -37,6 +37,10 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.TimeUnit; 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.io.IOUtils;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
@@ -79,12 +83,6 @@ import org.springframework.test.web.servlet.ResultActions;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RestController; 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}. * 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(); 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<SoftwareModuleType> 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 @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).") @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) @WithUser(principal = "smUpdateTester", allSpPermissions = true)
@@ -335,35 +446,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
.andExpect(jsonPath("$.message", containsString("Invalid characters in string"))); .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 @Test
@Description("Verifies that the system does not accept empty artifact uploads. Expected response: BAD REQUEST") @Description("Verifies that the system does not accept empty artifact uploads. Expected response: BAD REQUEST")
void emptyUploadArtifact() throws Exception { void emptyUploadArtifact() throws Exception {
@@ -430,43 +512,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
assertThat(artifactManagement.getByFilename("customFilename")).as("Local artifact is wrong").isPresent(); 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<SoftwareModuleType> 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 @Test
@Description("Verifies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST") @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 { void uploadArtifactWithHashCheck() throws Exception {
@@ -624,17 +669,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
assertThat(artifactManagement.count()).isEqualTo(2); 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 @Test
@Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.") @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 { void getArtifact() throws Exception {
@@ -760,24 +794,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
"http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artifact2.getId()))); "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 @ParameterizedTest
@ValueSource(booleans = { true, false }) @ValueSource(booleans = { true, false })
@Description("Verifies the listing of all artifacts assigned to a software module. That includes the artifact metadata and download links.") @Description("Verifies the listing of all artifacts assigned to a software module. That includes the artifact metadata and download links.")
@@ -1327,64 +1343,6 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
} }
@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 @Test
@Description("Verifies the successful update of metadata based on given key.") @Description("Verifies the successful update of metadata based on given key.")
void updateMetadataKey() throws Exception { void updateMetadataKey() throws Exception {
@@ -1485,6 +1443,50 @@ class MgmtSoftwareModuleResourceTest extends AbstractManagementApiIntegrationTes
.andExpect(jsonPath("content[0].value", equalTo("knownValue1"))); .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) { private void createSoftwareModulesAlphabetical(final int amount) {
char character = 'a'; char character = 'a';
for (int index = 0; index < amount; index++) { 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();
}
} }

View File

@@ -26,6 +26,10 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; 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.apache.commons.lang3.RandomStringUtils;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.model.NamedEntity; 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.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; 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}. * Test for {@link MgmtSoftwareModuleTypeResource}.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Software Module Type Resource") @Story("Software Module Type Resource")
@@ -109,14 +106,6 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractManagementApiInt
.andExpect(status().isOk()); .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 @Test
@WithUser(principal = "uploadTester", allSpPermissions = true) @WithUser(principal = "uploadTester", allSpPermissions = true)
@Description("Checks the correct behaviour of /rest/v1/softwaremoduletypes GET requests with sorting by MAXASSIGNMENTS field.") @Description("Checks the correct behaviour of /rest/v1/softwaremoduletypes GET requests with sorting by MAXASSIGNMENTS field.")
@@ -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) { private void createSoftwareModulesAlphabetical(final int amount) {
char character = 'a'; char character = 'a';
for (int index = 0; index < amount; index++) { for (int index = 0; index < amount; index++) {

View File

@@ -26,6 +26,10 @@ import java.nio.charset.StandardCharsets;
import java.util.List; import java.util.List;
import java.util.stream.Stream; 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.exception.SpServerError;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
@@ -49,16 +53,10 @@ import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; 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; import org.springframework.web.util.UriUtils;
/** /**
* Spring MVC Tests against the MgmtTargetResource. * Spring MVC Tests against the MgmtTargetResource.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Target Filter Query Resource") @Story("Target Filter Query Resource")
@@ -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_QUERY = ".query";
private static final String JSON_PATH_FIELD_CONFIRMATION_REQUIRED = ".confirmationRequired"; private static final String JSON_PATH_FIELD_CONFIRMATION_REQUIRED = ".confirmationRequired";
private static final String JSON_PATH_FIELD_CONTENT = ".content"; 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"; 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"; 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_DS = ".autoAssignDistributionSet";
private static final String JSON_PATH_FIELD_AUTO_ASSIGN_ACTION_TYPE = ".autoAssignActionType"; 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_EXCEPTION_CLASS = ".exceptionClass";
private static final String JSON_PATH_FIELD_ERROR_CODE = ".errorCode"; 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_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_ID = JSON_PATH_ROOT + JSON_PATH_FIELD_ID;
private static final String JSON_PATH_QUERY = JSON_PATH_ROOT + JSON_PATH_FIELD_QUERY; private static final String JSON_PATH_QUERY = JSON_PATH_ROOT + JSON_PATH_FIELD_QUERY;
@@ -413,7 +409,6 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
final DistributionSet set = testdataFactory.createDistributionSet(); final DistributionSet set = testdataFactory.createDistributionSet();
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target*"); final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("1", "controllerId==target*");
mvc.perform( mvc.perform(
post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS") post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + filterQuery.getId() + "/autoAssignDS")
.content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON)) .content("{\"id\":" + set.getId() + "}").contentType(MediaType.APPLICATION_JSON))
@@ -485,6 +480,114 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
verifyAutoAssignmentWithSoftDeletedDs(tfq); verifyAutoAssignmentWithSoftDeletedDs(tfq);
} }
@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 {
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("filter_01", "name==test_01");
final DistributionSet ds = testdataFactory.createDistributionSet("ds");
targetFilterQueryManagement
.updateAutoAssignDS(entityFactory.targetFilterQuery()
.updateAutoAssign(filterQuery.getId()).ds(ds.getId()));
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterQuery.getId()))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
}
@Test
@Description("Handles the POST request of setting a distribution set for auto assignment within SP.")
public void createAutoAssignDS() throws Exception {
enableMultiAssignments();
enableConfirmationFlow();
final String filterName = "filter_01";
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery(filterName, "name==test_01");
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds");
final String autoAssignBody = new JSONObject().put("id", distributionSet.getId())
.put("type", MgmtActionType.SOFT.getName()).put("weight", 200).toString();
mvc
.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterQuery.getId()).contentType(MediaType.APPLICATION_JSON).content(autoAssignBody.toString()))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
}
@Test
@Description("Handles the DELETE request of deleting the auto assign distribution set from a target filter query within SP.")
public void deleteAutoAssignDS() throws Exception {
final String filterName = "filter_01";
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery(filterName, "name==test_01");
mvc
.perform(delete(
MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterQuery.getId()))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isNoContent());
}
@Test
@Description("Ensures that the deletion of auto-assignment distribution set works as intended, deleting the auto-assignment action type as well")
public void deleteAutoAssignDistributionSetOfTargetFilterQuery() throws Exception {
final String knownQuery = "name==test06";
final String knownName = "filter06";
final String dsName = "testDS";
final DistributionSet set = testdataFactory.createDistributionSet(dsName);
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
targetFilterQueryManagement
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(tfq.getId()).ds(set.getId()));
implicitLock(set);
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get();
assertThat(updatedFilterQuery.getAutoAssignDistributionSet()).isEqualTo(set);
assertThat(updatedFilterQuery.getAutoAssignActionType()).isEqualTo(ActionType.FORCED);
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isOk()).andExpect(jsonPath(JSON_PATH_NAME, equalTo(dsName)));
mvc.perform(delete(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isNoContent());
final TargetFilterQuery filterQueryWithDeletedDs = targetFilterQueryManagement.get(tfq.getId()).get();
assertThat(filterQueryWithDeletedDs.getAutoAssignDistributionSet()).isNull();
assertThat(filterQueryWithDeletedDs.getAutoAssignActionType()).isNull();
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isNoContent());
}
@Test
@Description("An auto assignment containing a weight is only accepted when weight is valide and multi assignment is on.")
public void weightValidation() throws Exception {
final Long filterId = createSingleTargetFilterQuery("filter1", "name==*").getId();
final Long dsId = testdataFactory.createDistributionSet().getId();
final String invalideWeightRequest = new JSONObject().put("id", dsId).put("weight", Action.WEIGHT_MIN - 1)
.toString();
final String valideWeightRequest = new JSONObject().put("id", dsId).put("weight", 45).toString();
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isOk());
enableMultiAssignments();
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterId).content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation")));
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isOk());
final List<TargetFilterQuery> filters = targetFilterQueryManagement.findAll(PAGE).getContent();
assertThat(filters).hasSize(1);
assertThat(filters.get(0).getAutoAssignWeight().get()).isEqualTo(45);
}
@ParameterizedTest @ParameterizedTest
@ValueSource(booleans = { true, false }) @ValueSource(booleans = { true, false })
@Description("Verify the confirmation required flag will be set based on the feature state") @Description("Verify the confirmation required flag will be set based on the feature state")
@@ -624,114 +727,6 @@ public class MgmtTargetFilterQueryResourceTest extends AbstractManagementApiInt
.andExpect(jsonPath(JSON_PATH_ERROR_CODE, equalTo(SpServerError.SP_DELETED.getKey()))); .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 {
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery("filter_01", "name==test_01");
final DistributionSet ds = testdataFactory.createDistributionSet("ds");
targetFilterQueryManagement
.updateAutoAssignDS(entityFactory.targetFilterQuery()
.updateAutoAssign(filterQuery.getId()).ds(ds.getId()));
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterQuery.getId()))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
}
@Test
@Description("Handles the POST request of setting a distribution set for auto assignment within SP.")
public void createAutoAssignDS() throws Exception {
enableMultiAssignments();
enableConfirmationFlow();
final String filterName = "filter_01";
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery(filterName, "name==test_01");
final DistributionSet distributionSet = testdataFactory.createDistributionSet("ds");
final String autoAssignBody = new JSONObject().put("id", distributionSet.getId())
.put("type", MgmtActionType.SOFT.getName()).put("weight", 200).toString();
mvc
.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterQuery.getId()).contentType(MediaType.APPLICATION_JSON).content(autoAssignBody.toString()))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk());
}
@Test
@Description("Handles the DELETE request of deleting the auto assign distribution set from a target filter query within SP.")
public void deleteAutoAssignDS() throws Exception {
final String filterName = "filter_01";
final TargetFilterQuery filterQuery = createSingleTargetFilterQuery(filterName, "name==test_01");
mvc
.perform(delete(
MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterQuery.getId()))
.andDo(MockMvcResultPrinter.print())
.andExpect(status().isNoContent());
}
@Test
@Description("Ensures that the deletion of auto-assignment distribution set works as intended, deleting the auto-assignment action type as well")
public void deleteAutoAssignDistributionSetOfTargetFilterQuery() throws Exception {
final String knownQuery = "name==test06";
final String knownName = "filter06";
final String dsName = "testDS";
final DistributionSet set = testdataFactory.createDistributionSet(dsName);
final TargetFilterQuery tfq = createSingleTargetFilterQuery(knownName, knownQuery);
targetFilterQueryManagement
.updateAutoAssignDS(entityFactory.targetFilterQuery().updateAutoAssign(tfq.getId()).ds(set.getId()));
implicitLock(set);
final TargetFilterQuery updatedFilterQuery = targetFilterQueryManagement.get(tfq.getId()).get();
assertThat(updatedFilterQuery.getAutoAssignDistributionSet()).isEqualTo(set);
assertThat(updatedFilterQuery.getAutoAssignActionType()).isEqualTo(ActionType.FORCED);
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isOk()).andExpect(jsonPath(JSON_PATH_NAME, equalTo(dsName)));
mvc.perform(delete(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isNoContent());
final TargetFilterQuery filterQueryWithDeletedDs = targetFilterQueryManagement.get(tfq.getId()).get();
assertThat(filterQueryWithDeletedDs.getAutoAssignDistributionSet()).isNull();
assertThat(filterQueryWithDeletedDs.getAutoAssignActionType()).isNull();
mvc.perform(get(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/" + tfq.getId() + "/autoAssignDS"))
.andExpect(status().isNoContent());
}
@Test
@Description("An auto assignment containing a weight is only accepted when weight is valide and multi assignment is on.")
public void weightValidation() throws Exception {
final Long filterId = createSingleTargetFilterQuery("filter1", "name==*").getId();
final Long dsId = testdataFactory.createDistributionSet().getId();
final String invalideWeightRequest = new JSONObject().put("id", dsId).put("weight", Action.WEIGHT_MIN - 1)
.toString();
final String valideWeightRequest = new JSONObject().put("id", dsId).put("weight", 45).toString();
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isOk());
enableMultiAssignments();
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterId).content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation")));
mvc.perform(post(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{targetFilterQueryId}/autoAssignDS",
filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)).andDo(print())
.andExpect(status().isOk());
final List<TargetFilterQuery> filters = targetFilterQueryManagement.findAll(PAGE).getContent();
assertThat(filters).hasSize(1);
assertThat(filters.get(0).getAutoAssignWeight().get()).isEqualTo(45);
}
private TargetFilterQuery createSingleTargetFilterQuery(final String name, final String query) { private TargetFilterQuery createSingleTargetFilterQuery(final String name, final String query) {
return targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(name).query(query)); return targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name(name).query(query));
} }

View File

@@ -10,7 +10,9 @@
package org.eclipse.hawkbit.mgmt.rest.resource; package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.assertj.core.api.Assertions.assertThat; 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.containsString;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.not;
@@ -46,6 +48,11 @@ import java.util.stream.Stream;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
import com.fasterxml.jackson.databind.ObjectMapper; 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.apache.commons.lang3.RandomStringUtils;
import org.awaitility.Awaitility; import org.awaitility.Awaitility;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
@@ -96,56 +103,174 @@ import org.springframework.hateoas.MediaTypes;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult; 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; import org.springframework.test.web.servlet.ResultActions;
/** /**
* Spring MVC Tests against the MgmtTargetResource. * Spring MVC Tests against the MgmtTargetResource.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Target Resource") @Story("Target Resource")
class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Autowired
ActionRepository actionRepository;
private static final String TARGET_DESCRIPTION_TEST = "created in test"; private static final String TARGET_DESCRIPTION_TEST = "created in test";
private static final String JSON_PATH_ROOT = "$"; private static final String JSON_PATH_ROOT = "$";
// fields, attributes // fields, attributes
private static final String JSON_PATH_FIELD_ID = ".id"; 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_CONTROLLERID = ".controllerId";
private static final String JSON_PATH_FIELD_NAME = ".name"; 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_DESCRIPTION = ".description";
private static final String JSON_PATH_FIELD_CONTENT = ".content"; 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 // target
// $.field // $.field
static final String JSON_PATH_PAGED_LIST_CONTENT = JSON_PATH_ROOT + JSON_PATH_FIELD_CONTENT; 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; 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; 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_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_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_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_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_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; private static final String JSON_PATH_TYPE = JSON_PATH_ROOT + JSON_PATH_FIELD_TARGET_TYPE;
@Autowired @Autowired
private ObjectMapper objectMapper; private ObjectMapper objectMapper;
@Autowired @Autowired
private JpaProperties jpaProperties; 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 @Test
@Description("Ensures that actions list is in expected order.") @Description("Ensures that actions list is in expected order.")
void getActionStatusReturnsCorrectType() throws Exception { void getActionStatusReturnsCorrectType() throws Exception {
@@ -225,11 +350,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
contains(IpUtil.createHttpUri("127.0.0.1").toString()))); 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 @Test
@Description("Ensures that actions history is returned as defined by filter status==pending,status==finished.") @Description("Ensures that actions history is returned as defined by filter status==pending,status==finished.")
void searchActionsRsql() throws Exception { void searchActionsRsql() throws Exception {
@@ -464,75 +584,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModify); 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 @Test
@Description("Ensures that target query returns list of targets in defined format.") @Description("Ensures that target query returns list of targets in defined format.")
void getTargetWithoutAdditionalRequestParameters() throws Exception { void getTargetWithoutAdditionalRequestParameters() throws Exception {
@@ -918,15 +969,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
assertTarget("id3", "testname3", "testid3"); assertTarget("id3", "testname3", "testid3");
} }
private Target assertTarget(final String controllerId, final String name, final String description) {
final Optional<Target> 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 @Test
@Description("Ensures that a post request for creating one target within a list works.") @Description("Ensures that a post request for creating one target within a list works.")
void createTargetsSingleEntryListReturnsSuccessful() throws Exception { void createTargetsSingleEntryListReturnsSuccessful() throws Exception {
@@ -1101,43 +1143,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
getActions(true); getActions(true);
} }
private void getActions(final boolean withExternalRef) throws Exception {
final String knownTargetId = "targetId";
final List<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
final List<String> 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 @Test
@Description("Ensures that the expected response of getting actions with maintenance window of a target is returned.") @Description("Ensures that the expected response of getting actions with maintenance window of a target is returned.")
void getActionsWithMaintenanceWindow() throws Exception { void getActionsWithMaintenanceWindow() throws Exception {
@@ -1329,69 +1334,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath(JSON_PATH_PAGED_LIST_CONTENT, hasSize(1))); .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<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) {
return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null);
}
private List<Action> generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId,
final String schedule, final String duration, final String timezone) {
final Target target = testdataFactory.createTarget(knownTargetId);
final Iterator<DistributionSet> sets = testdataFactory.createDistributionSets(2).iterator();
final DistributionSet one = sets.next();
final DistributionSet two = sets.next();
// Update
if (schedule == null) {
final List<Target> 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<Target> 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<Action> actions = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE)
.getContent();
assertThat(actions).hasSize(2);
return actions;
}
@Test @Test
@Description("Verfies that an action is switched from soft to forced if requested by management API") @Description("Verfies that an action is switched from soft to forced if requested by management API")
void updateAction() throws Exception { void updateAction() throws Exception {
@@ -1446,8 +1388,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
assertThat(targetManagement.getByControllerID(target.getControllerId()).get()).isEqualTo(target); assertThat(targetManagement.getByControllerID(target.getControllerId()).get()).isEqualTo(target);
} }
@Autowired
ActionRepository actionRepository;
@ParameterizedTest @ParameterizedTest
@MethodSource("confirmationOptions") @MethodSource("confirmationOptions")
@Description("Ensures that confirmation option is considered in assignment request.") @Description("Ensures that confirmation option is considered in assignment request.")
@@ -1488,11 +1428,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
}); });
} }
private static Stream<Arguments> 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 @Test
@Description("Verfies that a DOWNLOAD_ONLY DS to target assignment is properly handled") @Description("Verfies that a DOWNLOAD_ONLY DS to target assignment is properly handled")
void assignDownloadOnlyDistributionSetToTarget() throws Exception { void assignDownloadOnlyDistributionSetToTarget() throws Exception {
@@ -1792,52 +1727,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
verifyResettingRequestAttributesIsNotAllowed(knownTargetId); 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 @Test
void searchTargetsUsingRsqlQuery() throws Exception { void searchTargetsUsingRsqlQuery() throws Exception {
final int amountTargets = 10; final int amountTargets = 10;
@@ -1851,52 +1740,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("content[1].controllerId", equalTo("b"))); .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<Action> actionsByTarget = deploymentManagement.findActionsByTarget(tA.getControllerId(), PAGE);
assertThat(actionsByTarget.getContent()).hasSize(1);
return targetManagement.getByControllerID(tA.getControllerId()).get();
}
@Test @Test
void getControllerTagReturnsTagsWithOk() throws Exception { void getControllerTagReturnsTagsWithOk() throws Exception {
// create target with attributes // create target with attributes
@@ -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 @Test
@Description("Ensures that a metadata entry deletion through API is reflected by the repository.") @Description("Ensures that a metadata entry deletion through API is reflected by the repository.")
void deleteMetadata() throws Exception { void deleteMetadata() throws Exception {
@@ -2061,24 +1897,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(knownValue))); .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 @Test
@Description("Ensures that a metadata entry paged list selection through API reflectes the repository content.") @Description("Ensures that a metadata entry paged list selection through API reflectes the repository content.")
void getPagedListOfMetadata() throws Exception { void getPagedListOfMetadata() throws Exception {
@@ -2100,18 +1918,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
} }
private void setupTargetWithMetadata(final String knownControllerId, final String knownKeyPrefix,
final String knownValuePrefix, final int totalMetadata) {
testdataFactory.createTarget(knownControllerId);
final List<MetaData> targetMetadataEntries = new LinkedList<>();
for (int index = 0; index < totalMetadata; index++) {
targetMetadataEntries
.add(entityFactory.generateTargetMetadata(knownKeyPrefix + index, knownValuePrefix + index));
}
targetManagement.createMetaData(knownControllerId, targetMetadataEntries);
}
@Test @Test
@Description("Ensures that a target metadata filtered query with value==knownValue1 parameter returns only the metadata entries with that value.") @Description("Ensures that a target metadata filtered query with value==knownValue1 parameter returns only the metadata entries with that value.")
void searchDistributionSetMetadataRsql() throws Exception { void searchDistributionSetMetadataRsql() throws Exception {
@@ -2614,33 +2420,6 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("autoConfirmActive").exists()).andExpect(jsonPath("_links.autoConfirm").exists()); .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 @Test
@Description("Verifies that the status code that was reported in the last action status update is correctly exposed via the action.") @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 { void lastActionStatusCode() throws Exception {
@@ -2677,6 +2456,225 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("detailStatus", equalTo("error"))); .andExpect(jsonPath("detailStatus", equalTo("error")));
} }
private static Stream<Arguments> 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<Arguments> 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<Target> 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<Action> actions = generateTargetWithTwoUpdatesWithOneOverride(knownTargetId);
final List<String> 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<Action> generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) {
return generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(knownTargetId, null, null, null);
}
private List<Action> generateTargetWithTwoUpdatesWithOneOverrideWithMaintenanceWindow(final String knownTargetId,
final String schedule, final String duration, final String timezone) {
final Target target = testdataFactory.createTarget(knownTargetId);
final Iterator<DistributionSet> sets = testdataFactory.createDistributionSets(2).iterator();
final DistributionSet one = sets.next();
final DistributionSet two = sets.next();
// Update
if (schedule == null) {
final List<Target> 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<Target> 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<Action> 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<Action> 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<MetaData> 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) { private Action updateActionStatus(final Action action, final Status status, final Integer statusCode) {
return updateActionStatus(action, status, statusCode, null); return updateActionStatus(action, status, statusCode, null);
} }
@@ -2698,9 +2696,4 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
return controllerManagement.addUpdateActionStatus(actionStatus); return controllerManagement.addUpdateActionStatus(actionStatus);
} }
private static Stream<Arguments> possibleActiveStates() {
return Stream.of(Arguments.of("someInitiator", "someRemark"), Arguments.of(null, "someRemark"),
Arguments.of("someInitiator", null), Arguments.of(null, null));
}
} }

View File

@@ -29,6 +29,9 @@ import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.stream.Collectors; 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.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi;
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent; 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.http.MediaType;
import org.springframework.test.web.servlet.ResultActions; 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. * Spring MVC Tests against the MgmtTargetTagResource.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Target Tag Resource") @Story("Target Tag Resource")
public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationTest { public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationTest {
private static final String TARGETTAGS_ROOT = "http://localhost" + MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/"; private static final String TARGETTAGS_ROOT = "http://localhost" + MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/";
private static final Random RND = new Random();
@Test @Test
@Description("Verfies that a paged result list of target tags reflects the content on the repository side.") @Description("Verfies that a paged result list of target tags reflects the content on the repository side.")
@@ -267,6 +266,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize))) .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize)))
.andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize))); .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize)));
} }
@Test @Test
@Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.")
@ExpectEvents({ @ExpectEvents({
@@ -295,7 +295,8 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0);
final List<Target> targets = testdataFactory.createTargets(2); final List<Target> targets = testdataFactory.createTargets(2);
final Target assigned0 = targets.get(0); 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") mvc.perform(put(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned")
.content(JsonBuilder.toArray(Arrays.asList(assigned0.getControllerId(), assigned1.getControllerId()))) .content(JsonBuilder.toArray(Arrays.asList(assigned0.getControllerId(), assigned1.getControllerId())))
@@ -307,7 +308,6 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
.containsOnly(assigned0.getControllerId(), assigned1.getControllerId()); .containsOnly(assigned0.getControllerId(), assigned1.getControllerId());
} }
private static final Random RND = new Random();
@Test @Test
@Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.") @Description("Verifies that tag assignments (multi targets) done through tag API command are correctly stored in the repository.")
@ExpectEvents({ @ExpectEvents({
@@ -620,17 +620,6 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
assertThat(targetManagement.findByTag(PAGE, tag.getId())).isEmpty(); assertThat(targetManagement.findByTag(PAGE, tag.getId())).isEmpty();
} }
private ResultActions toggle(final TargetTag tag, final List<Target> 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 @Test
@Description("Verfies that tag assignments done through tag API command are correctly stored in the repository.") @Description("Verfies that tag assignments done through tag API command are correctly stored in the repository.")
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1), @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 1),
@@ -656,6 +645,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0))) result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0)))
.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1))); .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1)));
} }
private static String controllerIdsOld(final Collection<String> ids) throws JSONException { private static String controllerIdsOld(final Collection<String> ids) throws JSONException {
final JSONArray list = new JSONArray(); final JSONArray list = new JSONArray();
for (final String smID : ids) { for (final String smID : ids) {
@@ -664,4 +654,15 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
return list.toString(); return list.toString();
} }
private ResultActions toggle(final TargetTag tag, final List<Target> 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));
}
} }

View File

@@ -9,6 +9,21 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; 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.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@@ -20,7 +35,6 @@ import io.qameta.allure.Feature;
import io.qameta.allure.Step; import io.qameta.allure.Step;
import io.qameta.allure.Story; import io.qameta.allure.Story;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.assertj.core.util.Lists;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; 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.MvcResult;
import org.springframework.test.web.servlet.ResultActions; 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. * Spring MVC Tests against the MgmtTargetTypeResource.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Target Type Resource") @Story("Target Type Resource")
@@ -70,7 +68,6 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
private final static String TEST_USER = "targetTypeTester"; private final static String TEST_USER = "targetTypeTester";
@Test @Test
@WithUser(principal = "targetTypeTester", allSpPermissions = true, removeFromAllPermission = { SpPermission.READ_TARGET }) @WithUser(principal = "targetTypeTester", allSpPermissions = true, removeFromAllPermission = { SpPermission.READ_TARGET })
@Description("GET targettypes returns Forbidden when permission is missing") @Description("GET targettypes returns Forbidden when permission is missing")

View File

@@ -18,6 +18,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import com.fasterxml.jackson.databind.ObjectMapper; 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.im.authentication.SpPermission;
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest; import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; 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.json.JSONObject;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType; 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; import org.springframework.test.web.servlet.ResultMatcher;
/** /**
* Spring MVC Tests against the MgmtTenantManagementResource. * Spring MVC Tests against the MgmtTenantManagementResource.
*
*/ */
@Feature("Component Tests - Management API") @Feature("Component Tests - Management API")
@Story("Tenant Management Resource") @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 @Test
@Description("Handles GET request for receiving a tenant specific configuration.") @Description("Handles GET request for receiving a tenant specific configuration.")
public void getTenantConfiguration() throws Exception { public void getTenantConfiguration() throws Exception {
@@ -149,15 +116,8 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg
.andExpect(status().isOk()); .andExpect(status().isOk());
//check if after Rest success, value is really changed in TenantMetadata //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."); 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();
} }
@Test @Test
@@ -175,15 +135,6 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg
assertDefaultDsTypeUpdateBadRequestFails(newDefaultDsType, oldDefaultDsType, status().isNotFound()); 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 @Test
@Description("The 'multi.assignments.enabled' property must not be changed to false.") @Description("The 'multi.assignments.enabled' property must not be changed to false.")
public void deactivateMultiAssignment() throws Exception { public void deactivateMultiAssignment() throws Exception {
@@ -210,7 +161,8 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg
boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(); boolean oldRolloutApprovalConfig = (Boolean) tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue();
String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(); String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue();
//test TenantConfiguration with invalid config value, and a valid TenantMetadata - Default DistributionSetType id //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 @Test
@@ -221,46 +173,27 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg
// TenantMetadata - DefaultDSType ID is invalid // TenantMetadata - DefaultDSType ID is invalid
//in the end batch configuration update must fail, and thus, not a single config should be actually changed. //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 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(); String oldAuthGatewayToken = (String) tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue();
//invalid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing invalid type - string //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 //not a single configuration should be changed after the failure
Object testInvalidDistributionSetType = "someInvalidInput"; Object testInvalidDistributionSetType = "someInvalidInput";
assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix1", testInvalidDistributionSetType, status().isBadRequest()); assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix1",
testInvalidDistributionSetType, status().isBadRequest());
//invalid TenantMetadata Default DistributionSetType, it is expected to be a number. Testing invalid type - bool //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 //not a single configuration should be changed after the failure
testInvalidDistributionSetType = true; 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. //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 //not a single configuration should be changed after the failure
testInvalidDistributionSetType = 9999; testInvalidDistributionSetType = 9999;
assertBatchConfigurationFails(!oldRolloutApprovalConfig, !oldAuthGatewayTokenEnabled, oldAuthGatewayToken + "randomSuffix2", testInvalidDistributionSetType, status().isNotFound()); 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.");
} }
@Test @Test
@@ -283,10 +216,16 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg
.andExpect(status().isOk()); .andExpect(status().isOk());
//assert all changes were applied after Rest Success //assert all changes were applied after Rest Success
assertEquals(updatedDistributionSetType, getActualDefaultDsType(), "Change BatchConfiguration was successful but TenantMetadata - Default DistributionSetType was not actually changed."); assertEquals(updatedDistributionSetType, getActualDefaultDsType(),
assertEquals(updatedRolloutApprovalEnabled, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); "Change BatchConfiguration was successful but TenantMetadata - Default DistributionSetType was not actually changed.");
assertEquals(updatedAuthGatewayTokenEnabled, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_ENABLED).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); assertEquals(updatedRolloutApprovalEnabled, tenantConfigurationManagement.getConfigurationValue(ROLLOUT_APPROVAL_ENABLED).getValue(),
assertEquals(updatedAuthGatewayTokenKey, tenantConfigurationManagement.getConfigurationValue(AUTHENTICATION_GATEWAYTOKEN_KEY).getValue(), "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); "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 @Test
@@ -329,6 +268,89 @@ public class MgmtTenantManagementResourceTest extends AbstractManagementApiInteg
.andExpect(status().isBadRequest()); .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() { private Long getActualDefaultDsType() {
return systemManagement.getTenantMetadata().getDefaultDsType().getId(); return systemManagement.getTenantMetadata().getDefaultDsType().getId();
} }

View File

@@ -11,18 +11,18 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import java.io.IOException; 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.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; 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. * Utility additions for the REST API tests.
*/ */
public final class ResourceUtility { public final class ResourceUtility {
private static final ObjectMapper mapper = new ObjectMapper(); private static final ObjectMapper mapper = new ObjectMapper();
static ExceptionInfo convertException(final String jsonExceptionResponse) static ExceptionInfo convertException(final String jsonExceptionResponse)