diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtDistributionSetRequestBodyPost.java b/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtDistributionSetRequestBodyPost.java index c6fabd66c7..0450270c9c 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtDistributionSetRequestBodyPost.java +++ b/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtDistributionSetRequestBodyPost.java @@ -33,7 +33,7 @@ @JsonIgnoreProperties(ignoreUnknown = true) public class MgmtDistributionSetRequestBodyPost extends MgmtDistributionSetRequestBodyPut { - // deprecated format from the time where os, application and runtime where statically defined + // deprecated format from the times where os, application and runtime where statically defined @JsonProperty @Schema(hidden = true) private MgmtSoftwareModuleAssignment os; @@ -45,8 +45,8 @@ public class MgmtDistributionSetRequestBodyPost extends MgmtDistributionSetReque @JsonProperty @Schema(hidden = true) private MgmtSoftwareModuleAssignment application; - // deprecated format - END + @JsonProperty private List modules; diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java b/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java index b2312c572c..ed7b4e8e40 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java +++ b/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java @@ -19,8 +19,6 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedDistributionSetRequestBody; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtDistributionSetTagAssigmentResult; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTagRequestBodyPut; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; @@ -457,90 +455,4 @@ ResponseEntity unassignDistributionSet( ResponseEntity unassignDistributionSets( @PathVariable("distributionsetTagId") Long distributionsetTagId, @RequestBody List distributionsetIds); - - /** - * Handles the POST request to toggle the assignment of distribution sets by - * the given tag id. - * - * @param distributionsetTagId the ID of the distribution set tag to retrieve - * @param assignedDSRequestBodies list of distribution set ids to be toggled - * @return the list of assigned distribution sets and unassigned distribution sets. - * @deprecated since 0.6.0 with toggle assignment deprecation - */ - @Operation(summary = "[DEPRECATED] Toggle the assignment of distribution sets by the given tag id", - description = "Handles the POST request of toggle distribution assignment. The request body must " + - "always be a list of distribution set ids.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully retrieved"), - @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), - @ApiResponse(responseCode = "401", description = "The request requires user authentication.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", - description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " + - "data volume restriction applies.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + - "user in another request at the same time. You may retry your modification request.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + - "supported by the server for this resource.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + - "and the client has to wait another second.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) - }) - @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + - MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING + "/toggleTagAssignment") - @Deprecated(forRemoval = true, since = "0.6.0") - ResponseEntity toggleTagAssignment( - @PathVariable("distributionsetTagId") Long distributionsetTagId, - @RequestBody List assignedDSRequestBodies); - - /** - * Handles the POST request to assign distribution sets to the given tag id. - * - * @param distributionsetTagId the ID of the distribution set tag to retrieve - * @param assignedDSRequestBodies list of distribution sets ids to be assigned - * @return the list of assigned distribution set. - * @deprecated since 0.6.0 in favor or assign by ds ids - */ - @Operation(summary = "[DEPRECATED] Assign distribution sets to the given tag id", - description = "Handles the POST request of distribution assignment. Already assigned distribution will " + - "be ignored.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully retrieved"), - @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), - @ApiResponse(responseCode = "401", description = "The request requires user authentication.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "403", - description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " + - "data volume restriction applies.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + - "user in another request at the same time. You may retry your modification request.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + - "supported by the server for this resource.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), - @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + - "and the client has to wait another second.", - content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) - }) - @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING, - consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, - produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) - @Deprecated(forRemoval = true, since = "0.6.0") - ResponseEntity> assignDistributionSetsByRequestBody( - @PathVariable("distributionsetTagId") Long distributionsetTagId, - @RequestBody List assignedDSRequestBodies); } \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java b/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java index bfbe26d674..60121e8cda 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java +++ b/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java @@ -18,10 +18,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.eclipse.hawkbit.mgmt.json.model.PagedList; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedTargetRequestBody; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTagRequestBodyPut; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTargetTagAssigmentResult; import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.springframework.hateoas.MediaTypes; @@ -388,74 +386,6 @@ ResponseEntity unassignTargets( @Schema(description = "List of controller ids to be unassigned", example = "[\"controllerId1\", \"controllerId2\"]") @RequestBody List controllerId); - /** - * Handles the POST request to toggle the assignment of targets by the given tag id. - * - * @param targetTagId the ID of the target tag to retrieve - * @param assignedTargetRequestBodies list of controller ids to be toggled - * @return the list of assigned targets and unassigned targets. - * @deprecated since 0.6.0 - not very usable with very unclear logic - */ - @Operation(summary = "[DEPRECATED] Toggles target tag assignment", description = "Handles the POST request of toggle target " + - "assignment. The request body must always be a list of controller ids.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully retrieved"), - @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), - @ApiResponse(responseCode = "401", description = "The request requires user authentication."), - @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " + - "changed (i.e. read-only) or data volume restriction applies."), - @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."), - @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json."), - @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + - "user in another request at the same time. You may retry your modification request."), - @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + - "supported by the server for this resource."), - @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts and the client has to wait another second.") - }) - @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + - MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING + "/toggleTagAssignment", - consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, - produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) - @Deprecated(forRemoval = true, since = "0.6.0") - ResponseEntity toggleTagAssignment( - @PathVariable("targetTagId") Long targetTagId, - @RequestBody List assignedTargetRequestBodies); - - /** - * Handles the POST request to assign targets to the given tag id. - * - * @param targetTagId the ID of the target tag to retrieve - * @param assignedTargetRequestBodies list of controller ids to be assigned - * @return the list of assigned targets. - * @deprecated since 0.6.0 in favour of {@link #assignTargets} - */ - @Operation(summary = "[DEPRECATED] Assign target(s) to given tagId and return targets", - description = "Handles the POST request of target assignment. Already assigned target will be ignored.") - @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Successfully assigned"), - @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), - @ApiResponse(responseCode = "401", description = "The request requires user authentication."), - @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " + - "changed (i.e. read-only) or data volume restriction applies."), - @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."), - @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json."), - @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + - "user in another request at the same time. You may retry your modification request."), - @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + - "supported by the server for this resource."), - @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + - "and the client has to wait another second.") - }) - @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING, - consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, - produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) - @Deprecated(forRemoval = true, since = "0.6.0") - ResponseEntity> assignTargetsByRequestBody( - @PathVariable("targetTagId") Long targetTagId, - @RequestBody List assignedTargetRequestBodies); - enum OnNotFoundPolicy { FAIL, // default ON_WHAT_FOUND_AND_FAIL, diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/pom.xml b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/pom.xml new file mode 100644 index 0000000000..25d36be47d --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/pom.xml @@ -0,0 +1,79 @@ + + + 4.0.0 + + org.eclipse.hawkbit + hawkbit-mgmt-parent + ${revision} + + + hawkbit-mgmt-resource-deprecated + hawkBit :: Management :: REST Resources (DEPRECATED) + + + + org.eclipse.hawkbit + hawkbit-repository-jpa + ${project.version} + + + org.eclipse.hawkbit + hawkbit-mgmt-resource + ${project.version} + + + + + org.eclipse.hawkbit + hawkbit-repository-test + ${project.version} + test + + + org.eclipse.hawkbit + hawkbit-rest-core + ${project.version} + tests + test + + + org.eclipse.hawkbit + hawkbit-mgmt-resource + ${project.version} + tests + test + + + javax.el + javax.el-api + test + + + org.springframework.boot + spring-boot-starter-json + test + + + org.springframework.security + spring-security-aspects + test + + + org.springframework + spring-context-support + test + + + \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtResource.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtResource.java new file mode 100644 index 0000000000..45846dca2f --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtResource.java @@ -0,0 +1,251 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import jakarta.persistence.EntityManager; + +import lombok.extern.slf4j.Slf4j; +import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; +import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; +import org.eclipse.hawkbit.mgmt.rest.resource.MgmtDistributionSetMapper; +import org.eclipse.hawkbit.mgmt.rest.resource.MgmtTargetMapper; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtAssignedDistributionSetRequestBody; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtAssignedTargetRequestBody; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtDistributionSetTagAssigmentResult; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtTargetTagAssigmentResult; +import org.eclipse.hawkbit.repository.DistributionSetManagement; +import org.eclipse.hawkbit.repository.DistributionSetTagManagement; +import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.TargetTagManagement; +import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; +import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetRepository; +import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository; +import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository; +import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; +import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.security.SystemSecurityContext; +import org.eclipse.hawkbit.utils.TenantConfigHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.web.bind.annotation.RestController; + +/** + * REST Resource handling for {@link DistributionSetTag} CRUD operations. + */ +@Slf4j +@RestController +public class DeprecatedMgmtResource implements DeprecatedMgmtRestApi { + + @Autowired + private DistributionSetRepository distributionSetRepository; + @Autowired + private DistributionSetTagManagement distributionSetTagManagement; + @Autowired + private DistributionSetManagement distributionSetManagement; + @Autowired + private TargetRepository targetRepository; + @Autowired + private TargetTagRepository targetTagRepository; + @Autowired + private TargetManagement targetManagement; + @Autowired + private TargetTagManagement targetTagManagement; + @Autowired + private PlatformTransactionManager txManager; + @Autowired + private EntityManager entityManager; + + private final TenantConfigHelper tenantConfigHelper; + + DeprecatedMgmtResource(final SystemSecurityContext securityContext, final TenantConfigurationManagement configurationManagement) { + tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement); + } + + @Override + public ResponseEntity toggleDistributionSetTagAssignment( + final Long distributionsetTagId, + final List assignedDSRequestBodies) { + log.debug("Toggle distribution set assignment {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId); + + final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); + + final DistributionSetTagAssignmentResult assigmentResult = + DeploymentHelper.runInNewTransaction( + txManager, + "toggleDistributionSetTagAssignment", + status -> toggleDistributionSetTagAssignment(findDistributionSetIds(assignedDSRequestBodies), tag.getName())); + + final MgmtDistributionSetTagAssigmentResult tagAssigmentResultRest = new MgmtDistributionSetTagAssigmentResult(); + tagAssigmentResultRest.setAssignedDistributionSets( + MgmtDistributionSetMapper.toResponseDistributionSets(assigmentResult.getAssignedEntity())); + tagAssigmentResultRest.setUnassignedDistributionSets( + MgmtDistributionSetMapper.toResponseDistributionSets(assigmentResult.getUnassignedEntity())); + + log.debug("Toggled assignedDS {} and unassignedDS{}", assigmentResult.getAssigned(), assigmentResult.getUnassigned()); + + return ResponseEntity.ok(tagAssigmentResultRest); + } + private DistributionSetTagAssignmentResult toggleDistributionSetTagAssignment(final Collection ids, final String tagName) { + return updateTag( + ids, + () -> distributionSetTagManagement + .findByName(tagName) + .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName)), + (allDs, distributionSetTag) -> { + final List toBeChangedDSs = allDs.stream().filter(set -> set.addTag(distributionSetTag)) + .collect(Collectors.toList()); + + final DistributionSetTagAssignmentResult result; + // un-assignment case + if (toBeChangedDSs.isEmpty()) { + for (final JpaDistributionSet set : allDs) { + if (set.removeTag(distributionSetTag)) { + toBeChangedDSs.add(set); + } + } + result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(), + Collections.emptyList(), + Collections.unmodifiableList( + toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())), + distributionSetTag); + } else { + result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(), + Collections.unmodifiableList( + toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())), + Collections.emptyList(), distributionSetTag); + } + return result; + }); + } + private T updateTag( + final Collection dsIds, final Supplier tagSupplier, + final BiFunction, DistributionSetTag, T> updater) { + final List allDs = dsIds.size() == 1 ? + distributionSetRepository.findById(dsIds.iterator().next()).map(List::of).orElseGet(Collections::emptyList) : + distributionSetRepository.findAll(DistributionSetSpecification.byIdsFetch(dsIds)); + if (allDs.size() < dsIds.size()) { + throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).toList()); + } + + final DistributionSetTag distributionSetTag = tagSupplier.get(); + try { + return updater.apply(allDs, distributionSetTag); + } finally { + // No reason to save the tag + entityManager.detach(distributionSetTag); + } + } + + @Override + public ResponseEntity> assignDistributionSetsByRequestBody( + final Long distributionsetTagId, + final List assignedDSRequestBodies) { + log.debug("Assign DistributionSet {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId); + final List assignedDs = this.distributionSetManagement + .assignTag(findDistributionSetIds(assignedDSRequestBodies), distributionsetTagId); + log.debug("Assigned DistributionSet {}", assignedDs.size()); + return ResponseEntity.ok(MgmtDistributionSetMapper.toResponseDistributionSets(assignedDs)); + } + + @Override + public ResponseEntity toggleTargetTagAssignment( + final Long targetTagId, final List assignedTargetRequestBodies) { + log.debug("Toggle Target assignment {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId); + + final TargetTag targetTag = targetTagManagement.get(targetTagId) + .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId)); + final TargetTagAssignmentResult assigmentResult = + DeploymentHelper.runInNewTransaction( + txManager, + "toggleDistributionSetTagAssignment", + status -> toggleTargetTagAssignment(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); + } + private TargetTagAssignmentResult toggleTargetTagAssignment(final Collection controllerIds, final String tagName) { + final TargetTag tag = targetTagRepository + .findByNameEquals(tagName) + .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagName)); + final List allTargets = targetRepository + .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds)); + if (allTargets.size() < controllerIds.size()) { + throw new EntityNotFoundException(Target.class, controllerIds, + allTargets.stream().map(Target::getControllerId).toList()); + } + + final List alreadyAssignedTargets = targetRepository.findAll( + TargetSpecifications.hasTagName(tagName).and(TargetSpecifications.hasControllerIdIn(controllerIds))); + + // all are already assigned -> unassign + if (alreadyAssignedTargets.size() == allTargets.size()) { + + alreadyAssignedTargets.forEach(target -> target.removeTag(tag)); + return new TargetTagAssignmentResult(0, Collections.emptyList(), + Collections.unmodifiableList(alreadyAssignedTargets), tag); + } + + allTargets.removeAll(alreadyAssignedTargets); + // some or none are assigned -> assign + allTargets.forEach(target -> target.addTag(tag)); + final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(), + targetRepository.saveAll(allTargets), Collections.emptyList(), tag); + + // no reason to persist the tag + entityManager.detach(tag); + return result; + } + + @Override + public ResponseEntity> assignTargetsByRequestBody( + final Long targetTagId, final List assignedTargetRequestBodies) { + log.debug("Assign targets {} for target tag {}", assignedTargetRequestBodies, targetTagId); + final List assignedTarget = targetManagement + .assignTag(findTargetControllerIds(assignedTargetRequestBodies), targetTagId); + return ResponseEntity.ok(MgmtTargetMapper.toResponse(assignedTarget, tenantConfigHelper)); + } + + private static List findDistributionSetIds( + final List assignedDistributionSetRequestBodies) { + return assignedDistributionSetRequestBodies.stream() + .map(MgmtAssignedDistributionSetRequestBody::getDistributionSetId).collect(Collectors.toList()); + } + + private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) { + return distributionSetTagManagement.get(distributionsetTagId) + .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, distributionsetTagId)); + } + + private List findTargetControllerIds( + final List assignedTargetRequestBodies) { + return assignedTargetRequestBodies.stream().map(MgmtAssignedTargetRequestBody::getControllerId) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtRestApi.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtRestApi.java new file mode 100644 index 0000000000..5023296970 --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtRestApi.java @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated; + +import java.util.List; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; +import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; +import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtAssignedDistributionSetRequestBody; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtAssignedTargetRequestBody; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtDistributionSetTagAssigmentResult; +import org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model.MgmtTargetTagAssigmentResult; +import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; +import org.springframework.hateoas.MediaTypes; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +/** + * REST Resource handling for DistributionSetTag CRUD operations. + */ +// no request mapping specified here to avoid CVE-2021-22044 in Feign client +@Tag(name = "Deprecated Management API", description = "Deprecated REST operations.") +public interface DeprecatedMgmtRestApi { + + /** + * Handles the POST request to toggle the assignment of distribution sets by + * the given tag id.
+ * From {@link org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetTagRestApi} + * + * @param distributionsetTagId the ID of the distribution set tag to retrieve + * @param assignedDSRequestBodies list of distribution set ids to be toggled + * @return the list of assigned distribution sets and unassigned distribution sets. + * @deprecated since 0.6.0 with toggle assignment deprecation + */ + @Operation(summary = "[DEPRECATED] Toggle the assignment of distribution sets by the given tag id", + description = "Handles the POST request of toggle distribution assignment. The request body must " + + "always be a list of distribution set ids.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved"), + @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), + @ApiResponse(responseCode = "401", description = "The request requires user authentication.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", + description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " + + "data volume restriction applies.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + + "user in another request at the same time. You may retry your modification request.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + + "supported by the server for this resource.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + + "and the client has to wait another second.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) + }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING + "/toggleTagAssignment") + @Deprecated(forRemoval = true, since = "0.6.0") + ResponseEntity toggleDistributionSetTagAssignment( + @PathVariable("distributionsetTagId") Long distributionsetTagId, + @RequestBody List assignedDSRequestBodies); + + /** + * Handles the POST request to assign distribution sets to the given tag id..
+ * From {@link org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetTagRestApi} + * + * @param distributionsetTagId the ID of the distribution set tag to retrieve + * @param assignedDSRequestBodies list of distribution sets ids to be assigned + * @return the list of assigned distribution set. + * @deprecated since 0.6.0 in favor or assign by ds ids + */ + @Operation(summary = "[DEPRECATED] Assign distribution sets to the given tag id", + description = "Handles the POST request of distribution assignment. Already assigned distribution will " + + "be ignored.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved"), + @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), + @ApiResponse(responseCode = "401", description = "The request requires user authentication.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "403", + description = "Insufficient permissions, entity is not allowed to be changed (i.e. read-only) or " + + "data volume restriction applies.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + + "user in another request at the same time. You may retry your modification request.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + + "supported by the server for this resource.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))), + @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + + "and the client has to wait another second.", + content = @Content(mediaType = "application/json", schema = @Schema(hidden = true))) + }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING, + consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, + produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @Deprecated(forRemoval = true, since = "0.6.0") + ResponseEntity> assignDistributionSetsByRequestBody( + @PathVariable("distributionsetTagId") Long distributionsetTagId, + @RequestBody List assignedDSRequestBodies); + + /** + * Handles the POST request to toggle the assignment of targets by the given tag id.
+ * From {@link org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi} + * + * @param targetTagId the ID of the target tag to retrieve + * @param assignedTargetRequestBodies list of controller ids to be toggled + * @return the list of assigned targets and unassigned targets. + * @deprecated since 0.6.0 - not very usable with very unclear logic + */ + @Operation(summary = "[DEPRECATED] Toggles target tag assignment", description = "Handles the POST request of toggle target " + + "assignment. The request body must always be a list of controller ids.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved"), + @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), + @ApiResponse(responseCode = "401", description = "The request requires user authentication."), + @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " + + "changed (i.e. read-only) or data volume restriction applies."), + @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."), + @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json."), + @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + + "user in another request at the same time. You may retry your modification request."), + @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + + "supported by the server for this resource."), + @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts and the client has to wait another second.") + }) + @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING + "/toggleTagAssignment", + consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, + produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @Deprecated(forRemoval = true, since = "0.6.0") + ResponseEntity toggleTargetTagAssignment( + @PathVariable("targetTagId") Long targetTagId, + @RequestBody List assignedTargetRequestBodies); + + /** + * Handles the POST request to assign targets to the given tag id.
+ * From {@link org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi} + * + * @param targetTagId the ID of the target tag to retrieve + * @param assignedTargetRequestBodies list of controller ids to be assigned + * @return the list of assigned targets. + * @deprecated since 0.6.0 in favour of {@link org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi#assignTargets} + */ + @Operation(summary = "[DEPRECATED] Assign target(s) to given tagId and return targets", + description = "Handles the POST request of target assignment. Already assigned target will be ignored.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully assigned"), + @ApiResponse(responseCode = "400", description = "Bad Request - e.g. invalid parameters", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionInfo.class))), + @ApiResponse(responseCode = "401", description = "The request requires user authentication."), + @ApiResponse(responseCode = "403", description = "Insufficient permissions, entity is not allowed to be " + + "changed (i.e. read-only) or data volume restriction applies."), + @ApiResponse(responseCode = "405", description = "The http request method is not allowed on the resource."), + @ApiResponse(responseCode = "406", description = "In case accept header is specified and not application/json."), + @ApiResponse(responseCode = "409", description = "E.g. in case an entity is created or modified by another " + + "user in another request at the same time. You may retry your modification request."), + @ApiResponse(responseCode = "415", description = "The request was attempt with a media-type which is not " + + "supported by the server for this resource."), + @ApiResponse(responseCode = "429", description = "Too many requests. The server will refuse further attempts " + + "and the client has to wait another second.") + }) + @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING, + consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, + produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @Deprecated(forRemoval = true, since = "0.6.0") + ResponseEntity> assignTargetsByRequestBody( + @PathVariable("targetTagId") Long targetTagId, + @RequestBody List assignedTargetRequestBodies); +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DistributionSetTagAssignmentResult.java similarity index 78% rename from hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java rename to hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DistributionSetTagAssignmentResult.java index 7e17133738..085fc16186 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DistributionSetTagAssignmentResult.java @@ -7,13 +7,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated; import java.util.List; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; +import org.eclipse.hawkbit.repository.model.AbstractAssignmentResult; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; /** * Result object for {@link DistributionSetTag} assignments. @@ -28,14 +31,6 @@ public class DistributionSetTagAssignmentResult extends AbstractAssignmentResult private final DistributionSetTag distributionSetTag; - /** - * Constructor. - * - * @param alreadyAssigned number of already assigned/ignored elements - * @param assigned newly assigned elements - * @param unassigned unassigned elements - * @param distributionSetTag the assigned or unassigned tag - */ public DistributionSetTagAssignmentResult(final int alreadyAssigned, final List assigned, final List unassigned, final DistributionSetTag distributionSetTag) { diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/TargetTagAssignmentResult.java similarity index 61% rename from hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java rename to hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/TargetTagAssignmentResult.java index 4bda16c22d..2bf307a4db 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/TargetTagAssignmentResult.java @@ -7,13 +7,16 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.repository.model; +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated; import java.util.List; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.ToString; +import org.eclipse.hawkbit.repository.model.AbstractAssignmentResult; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetTag; /** * Result object for {@link TargetTag} assignments. @@ -28,16 +31,9 @@ public class TargetTagAssignmentResult extends AbstractAssignmentResult private final TargetTag targetTag; - /** - * Constructor. - * - * @param alreadyAssigned count of already assigned (ignored) elements - * @param assigned {@link List} of assigned {@link Target}s. - * @param unassigned {@link List} of unassigned {@link Target}s. - * @param targetTag the assigned or unassigned tag - */ - public TargetTagAssignmentResult(final int alreadyAssigned, final List assigned, - final List unassigned, final TargetTag targetTag) { + public TargetTagAssignmentResult( + final int alreadyAssigned, final List assigned, final List unassigned, + final TargetTag targetTag) { super(alreadyAssigned, assigned, unassigned); this.targetTag = targetTag; } diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtAssignedDistributionSetRequestBody.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtAssignedDistributionSetRequestBody.java similarity index 93% rename from hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtAssignedDistributionSetRequestBody.java rename to hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtAssignedDistributionSetRequestBody.java index 5cd246c39c..e708f83708 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtAssignedDistributionSetRequestBody.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtAssignedDistributionSetRequestBody.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.mgmt.json.model.tag; +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtAssignedTargetRequestBody.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtAssignedTargetRequestBody.java similarity index 93% rename from hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtAssignedTargetRequestBody.java rename to hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtAssignedTargetRequestBody.java index c7d80afb61..c7451b2b0a 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtAssignedTargetRequestBody.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtAssignedTargetRequestBody.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.mgmt.json.model.tag; +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtDistributionSetTagAssigmentResult.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtDistributionSetTagAssigmentResult.java similarity index 95% rename from hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtDistributionSetTagAssigmentResult.java rename to hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtDistributionSetTagAssigmentResult.java index 32ce5521aa..8d25dd6c1d 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtDistributionSetTagAssigmentResult.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtDistributionSetTagAssigmentResult.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.mgmt.json.model.tag; +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model; import java.util.List; diff --git a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtTargetTagAssigmentResult.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtTargetTagAssigmentResult.java similarity index 95% rename from hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtTargetTagAssigmentResult.java rename to hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtTargetTagAssigmentResult.java index 63e52880a1..57722cf592 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag/MgmtTargetTagAssigmentResult.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model/MgmtTargetTagAssigmentResult.java @@ -7,7 +7,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -package org.eclipse.hawkbit.mgmt.json.model.tag; +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated.json.model; import java.util.List; diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/MgmtDeprecatedResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/MgmtDeprecatedResourceTest.java new file mode 100644 index 0000000000..b5b372812c --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/MgmtDeprecatedResourceTest.java @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.mgmt.rest.resource.deprecated; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.Collection; +import java.util.List; +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.resource.AbstractManagementApiIntegrationTest; +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.DistributionSetUpdatedEvent; +import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagCreatedEvent; +import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.repository.test.matcher.Expect; +import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents; +import org.eclipse.hawkbit.rest.util.JsonBuilder; +import org.eclipse.hawkbit.rest.util.MockMvcResultPrinter; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.ResultActions; + +@Feature("Component Tests - Management API") +@Story("Distribution Set Tag Resource") +public class MgmtDeprecatedResourceTest extends AbstractManagementApiIntegrationTest { + + @Test + @Description("Verifies that tag assignments done through toggle API command are correctly assigned or unassigned.") + @ExpectEvents({ + @Expect(type = DistributionSetTagCreatedEvent.class, count = 1), + @Expect(type = DistributionSetCreatedEvent.class, count = 2), + @Expect(type = DistributionSetUpdatedEvent.class, count = 4) }) + public void toggleDistributionSetTagAssignment() throws Exception { + final DistributionSetTag tag = testdataFactory.createDistributionSetTags(1).get(0); + final int setsAssigned = 2; + final List sets = testdataFactory.createDistributionSetsWithoutModules(setsAssigned); + + // 2 DistributionSetUpdateEvent + ResultActions result = toggle(tag, sets); + + List updated = distributionSetManagement.findByTag(tag.getId(), PAGE).getContent(); + + assertThat(updated.stream().map(DistributionSet::getId).collect(Collectors.toList())) + .containsAll(sets.stream().map(DistributionSet::getId).collect(Collectors.toList())); + + result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0), "assignedDistributionSets")) + .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1), "assignedDistributionSets")); + + // 2 DistributionSetUpdateEvent + result = toggle(tag, sets); + + updated = distributionSetManagement.findAll(PAGE).getContent(); + + result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0), "unassignedDistributionSets")) + .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1), "unassignedDistributionSets")); + + assertThat(distributionSetManagement.findByTag(tag.getId(), PAGE)).isEmpty(); + } + + private ResultActions toggle(final DistributionSetTag tag, final List sets) throws Exception { + return mvc + .perform(post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + + "/assigned/toggleTagAssignment").content( + JsonBuilder.ids(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()))) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); + } + + @Test + @Description("Verifes that tag assignments done through toggle API command are correctly assigned or unassigned.") + @ExpectEvents({ + @Expect(type = TargetTagCreatedEvent.class, count = 1), + @Expect(type = TargetCreatedEvent.class, count = 2), + @Expect(type = TargetUpdatedEvent.class, count = 4) }) + public void toggleTargetTagAssignment() throws Exception { + final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); + final int targetsAssigned = 2; + final List targets = testdataFactory.createTargets(targetsAssigned); + + ResultActions result = toggle(tag, targets); + + List updated = targetManagement.findByTag(PAGE, tag.getId()).getContent(); + + assertThat(updated.stream().map(Target::getControllerId).collect(Collectors.toList())) + .containsAll(targets.stream().map(Target::getControllerId).collect(Collectors.toList())); + + result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0), "assignedTargets")) + .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1), "assignedTargets")); + + result = toggle(tag, targets); + + updated = targetManagement.findAll(PAGE).getContent(); + + result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0), "unassignedTargets")) + .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1), "unassignedTargets")); + + assertThat(targetManagement.findByTag(PAGE, tag.getId())).isEmpty(); + } + + @Test + @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") + @ExpectEvents({ + @Expect(type = TargetTagCreatedEvent.class, count = 1), + @Expect(type = TargetCreatedEvent.class, count = 2), + @Expect(type = TargetUpdatedEvent.class, count = 2) }) + public void assignTargetsByRequestBody() throws Exception { + final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); + final int targetsAssigned = 2; + final List targets = testdataFactory.createTargets(targetsAssigned); + + final ResultActions result = mvc + .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") + .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)); + + final List updated = targetManagement.findByTag(PAGE, tag.getId()).getContent(); + + assertThat(updated.stream().map(Target::getControllerId).collect(Collectors.toList())) + .containsAll(targets.stream().map(Target::getControllerId).collect(Collectors.toList())); + + result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0))) + .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1))); + } + + private static String controllerIdsOld(final Collection ids) throws JSONException { + final JSONArray list = new JSONArray(); + for (final String smID : ids) { + list.put(new JSONObject().put("controllerId", smID)); + } + + return list.toString(); + } + + private ResultActions toggle(final TargetTag tag, final List targets) throws Exception { + return mvc + .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + + "/assigned/toggleTagAssignment") + .content(controllerIdsOld( + targets.stream().map(Target::getControllerId).collect(Collectors.toList()))) + .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) + .andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); + } +} \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml b/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml index 4cfc4d3fe1..1b4c4dd082 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml @@ -99,4 +99,21 @@ test + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java index e105ef24a9..9310c261d2 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java @@ -129,7 +129,8 @@ static MgmtTargetAssignmentResponseBody toResponse( return result; } - static List toResponseDistributionSets(final Collection sets) { + // TODO - to be made package visible when hawkbit-mgmt-rest-deprecated is removed + public static List toResponseDistributionSets(final Collection sets) { if (sets == null) { return Collections.emptyList(); } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java index b84891ec68..54fecb2c3e 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResource.java @@ -10,13 +10,10 @@ package org.eclipse.hawkbit.mgmt.rest.resource; import java.util.List; -import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedDistributionSetRequestBody; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtDistributionSetTagAssigmentResult; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTagRequestBodyPut; import org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetTagRestApi; @@ -28,7 +25,6 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; @@ -182,45 +178,6 @@ public ResponseEntity unassignDistributionSets( return ResponseEntity.ok().build(); } - @Override - public ResponseEntity toggleTagAssignment( - final Long distributionsetTagId, - final List assignedDSRequestBodies) { - log.debug("Toggle distribution set assignment {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId); - - final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); - - final DistributionSetTagAssignmentResult assigmentResult = this.distributionSetManagement - .toggleTagAssignment(findDistributionSetIds(assignedDSRequestBodies), tag.getName()); - - final MgmtDistributionSetTagAssigmentResult tagAssigmentResultRest = new MgmtDistributionSetTagAssigmentResult(); - tagAssigmentResultRest.setAssignedDistributionSets( - MgmtDistributionSetMapper.toResponseDistributionSets(assigmentResult.getAssignedEntity())); - tagAssigmentResultRest.setUnassignedDistributionSets( - MgmtDistributionSetMapper.toResponseDistributionSets(assigmentResult.getUnassignedEntity())); - - log.debug("Toggled assignedDS {} and unassignedDS{}", assigmentResult.getAssigned(), assigmentResult.getUnassigned()); - - return ResponseEntity.ok(tagAssigmentResultRest); - } - - @Override - public ResponseEntity> assignDistributionSetsByRequestBody( - final Long distributionsetTagId, - final List assignedDSRequestBodies) { - log.debug("Assign DistributionSet {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId); - final List assignedDs = this.distributionSetManagement - .assignTag(findDistributionSetIds(assignedDSRequestBodies), distributionsetTagId); - log.debug("Assigned DistributionSet {}", assignedDs.size()); - return ResponseEntity.ok(MgmtDistributionSetMapper.toResponseDistributionSets(assignedDs)); - } - - private static List findDistributionSetIds( - final List assignedDistributionSetRequestBodies) { - return assignedDistributionSetRequestBodies.stream() - .map(MgmtAssignedDistributionSetRequestBody::getDistributionSetId).collect(Collectors.toList()); - } - private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) { return distributionSetTagManagement.get(distributionsetTagId) .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, distributionsetTagId)); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java index 506c9b60db..0c0e1a41b4 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResource.java @@ -12,14 +12,11 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.mgmt.json.model.PagedList; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedTargetRequestBody; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag; import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTagRequestBodyPut; -import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTargetTagAssigmentResult; import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi; import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility; @@ -31,7 +28,6 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.utils.TenantConfigHelper; import org.springframework.data.domain.Page; @@ -55,12 +51,12 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi { MgmtTargetTagResource( final TargetTagManagement tagManagement, final TargetManagement targetManagement, - final EntityFactory entityFactory, final SystemSecurityContext securityContext, - final TenantConfigurationManagement configurationManagement) { + final EntityFactory entityFactory, + final SystemSecurityContext securityContext, final TenantConfigurationManagement configurationManagement) { this.tagManagement = tagManagement; this.targetManagement = targetManagement; this.entityFactory = entityFactory; - this.tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement); + tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement); } @Override @@ -174,7 +170,7 @@ public ResponseEntity assignTargets( @Override public ResponseEntity unassignTarget(final Long targetTagId, final String controllerId) { log.debug("Unassign target {} for target tag {}", controllerId, targetTagId); - this.targetManagement.unassignTag(controllerId, targetTagId); + this.targetManagement.unassignTag(List.of(controllerId), targetTagId); return ResponseEntity.ok().build(); } @@ -197,40 +193,8 @@ public ResponseEntity unassignTargets( return ResponseEntity.ok().build(); } - @Override - public ResponseEntity toggleTagAssignment( - final Long targetTagId, final List assignedTargetRequestBodies) { - log.debug("Toggle Target assignment {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId); - - final TargetTag targetTag = findTargetTagById(targetTagId); - final TargetTagAssignmentResult assigmentResult = this.targetManagement - .toggleTagAssignment(findTargetControllerIds(assignedTargetRequestBodies), targetTag.getName()); - - final MgmtTargetTagAssigmentResult tagAssigmentResultRest = new MgmtTargetTagAssigmentResult(); - tagAssigmentResultRest.setAssignedTargets( - MgmtTargetMapper.toResponse(assigmentResult.getAssignedEntity(), tenantConfigHelper)); - tagAssigmentResultRest.setUnassignedTargets( - MgmtTargetMapper.toResponse(assigmentResult.getUnassignedEntity(), tenantConfigHelper)); - return ResponseEntity.ok(tagAssigmentResultRest); - } - - @Override - public ResponseEntity> assignTargetsByRequestBody( - final Long targetTagId, final List assignedTargetRequestBodies) { - log.debug("Assign targets {} for target tag {}", assignedTargetRequestBodies, targetTagId); - final List assignedTarget = this.targetManagement - .assignTag(findTargetControllerIds(assignedTargetRequestBodies), targetTagId); - return ResponseEntity.ok(MgmtTargetMapper.toResponse(assignedTarget, tenantConfigHelper)); - } - private TargetTag findTargetTagById(final Long targetTagId) { return tagManagement.get(targetTagId) .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId)); } - - private List findTargetControllerIds( - final List assignedTargetRequestBodies) { - return assignedTargetRequestBodies.stream().map(MgmtAssignedTargetRequestBody::getControllerId) - .collect(Collectors.toList()); - } } \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java index 09bde1f41d..c9e44a5ecf 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java @@ -319,39 +319,6 @@ public void getAssignedDistributionSetsWithPagingLimitAndOffsetRequestParameter( .andExpect(jsonPath(MgmtTargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize))); } - @Test - @Description("Verifies that tag assignments done through toggle API command are correctly assigned or unassigned.") - @ExpectEvents({ - @Expect(type = DistributionSetTagCreatedEvent.class, count = 1), - @Expect(type = DistributionSetCreatedEvent.class, count = 2), - @Expect(type = DistributionSetUpdatedEvent.class, count = 4) }) - public void toggleTagAssignment() throws Exception { - final DistributionSetTag tag = testdataFactory.createDistributionSetTags(1).get(0); - final int setsAssigned = 2; - final List sets = testdataFactory.createDistributionSetsWithoutModules(setsAssigned); - - // 2 DistributionSetUpdateEvent - ResultActions result = toggle(tag, sets); - - List updated = distributionSetManagement.findByTag(tag.getId(), PAGE).getContent(); - - assertThat(updated.stream().map(DistributionSet::getId).collect(Collectors.toList())) - .containsAll(sets.stream().map(DistributionSet::getId).collect(Collectors.toList())); - - result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0), "assignedDistributionSets")) - .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1), "assignedDistributionSets")); - - // 2 DistributionSetUpdateEvent - result = toggle(tag, sets); - - updated = distributionSetManagement.findAll(PAGE).getContent(); - - result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0), "unassignedDistributionSets")) - .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1), "unassignedDistributionSets")); - - assertThat(distributionSetManagement.findByTag(tag.getId(), PAGE)).isEmpty(); - } - @Test @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") @ExpectEvents({ @@ -513,17 +480,4 @@ public void assignDistributionSetsWithRequestBody() throws Exception { result.andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(0))) .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1))); } - - // DEPRECATED flows - - private ResultActions toggle(final DistributionSetTag tag, final List sets) throws Exception { - return mvc - .perform(post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() - + "/assigned/toggleTagAssignment").content( - JsonBuilder.ids(sets.stream().map(DistributionSet::getId).collect(Collectors.toList()))) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); - } } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java index 0a1cbcd31b..f54ed57cc2 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java @@ -616,86 +616,4 @@ public void unassignTargetsNotFoundUntagAndSuccess() throws Exception { .andExpect(status().isOk()); assertThat(targetManagement.findByTag(PAGE, tag.getId()).getContent()).isEmpty(); } - - // DEPRECATED scenarios - @Test - @Description("Verifes that tag assignments done through toggle API command are correctly assigned or unassigned.") - @ExpectEvents({ - @Expect(type = TargetTagCreatedEvent.class, count = 1), - @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 4) }) - public void toggleTagAssignment() throws Exception { - final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); - final int targetsAssigned = 2; - final List targets = testdataFactory.createTargets(targetsAssigned); - - ResultActions result = toggle(tag, targets); - - List updated = targetManagement.findByTag(PAGE, tag.getId()).getContent(); - - assertThat(updated.stream().map(Target::getControllerId).collect(Collectors.toList())) - .containsAll(targets.stream().map(Target::getControllerId).collect(Collectors.toList())); - - result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0), "assignedTargets")) - .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1), "assignedTargets")); - - result = toggle(tag, targets); - - updated = targetManagement.findAll(PAGE).getContent(); - - result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0), "unassignedTargets")) - .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1), "unassignedTargets")); - - assertThat(targetManagement.findByTag(PAGE, tag.getId())).isEmpty(); - } - - @Test - @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") - @ExpectEvents({ - @Expect(type = TargetTagCreatedEvent.class, count = 1), - @Expect(type = TargetCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 2) }) - public void assignTargetsByRequestBody() throws Exception { - final TargetTag tag = testdataFactory.createTargetTags(1, "").get(0); - final int targetsAssigned = 2; - final List targets = testdataFactory.createTargets(targetsAssigned); - - final ResultActions result = mvc - .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .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)); - - final List updated = targetManagement.findByTag(PAGE, tag.getId()).getContent(); - - assertThat(updated.stream().map(Target::getControllerId).collect(Collectors.toList())) - .containsAll(targets.stream().map(Target::getControllerId).collect(Collectors.toList())); - - result.andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(0))) - .andExpect(applyTargetEntityMatcherOnArrayResult(updated.get(1))); - } - - private static String controllerIdsOld(final Collection ids) throws JSONException { - final JSONArray list = new JSONArray(); - for (final String smID : ids) { - list.put(new JSONObject().put("controllerId", smID)); - } - - return list.toString(); - } - - private ResultActions toggle(final TargetTag tag, final List targets) throws Exception { - return mvc - .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() - + "/assigned/toggleTagAssignment") - .content(controllerIdsOld( - targets.stream().map(Target::getControllerId).collect(Collectors.toList()))) - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)); - } -} +} \ No newline at end of file diff --git a/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml b/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml index f89391022d..06c397f0f9 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml +++ b/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml @@ -53,6 +53,13 @@ hawkbit-autoconfigure ${project.version} + + + + org.eclipse.hawkbit + hawkbit-mgmt-resource-deprecated + ${project.version} + diff --git a/hawkbit-mgmt/pom.xml b/hawkbit-mgmt/pom.xml index 1cc5059557..a13b2fc6f1 100644 --- a/hawkbit-mgmt/pom.xml +++ b/hawkbit-mgmt/pom.xml @@ -27,5 +27,8 @@ hawkbit-mgmt-resource hawkbit-mgmt-starter hawkbit-mgmt-server + + + hawkbit-mgmt-resource-deprecated \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index 399119f116..6d198d09de 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -32,7 +32,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetFilter; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Statistic; @@ -384,33 +383,4 @@ public interface DistributionSetManagement extends RepositoryManagement ids, @NotNull String tagName); - - /** - * Unassign a {@link DistributionSetTag} assignment to given {@link DistributionSet}. - * - * @param id to unassign for - * @param tagId to unassign - * @return the unassigned ds or if no ds is unassigned - * @throws EntityNotFoundException if set or tag with given ID does not exist - * @deprecated since 0.6.0 in favor of unassignTag(List, long) - */ - @Deprecated(forRemoval = true) - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unassignTag(long id, long tagId); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java index dde94197ad..7a43a9428d 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/TargetManagement.java @@ -33,12 +33,10 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetMetadata; import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; @@ -756,33 +754,4 @@ Page findMetaDataByControllerIdAndRsql(@NotNull Pageable pageabl */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) TargetMetadata updateMetadata(@NotEmpty String controllerId, @NotNull MetaData metadata); - - /** - * Toggles {@link TargetTag} assignment to given {@link Target}s by means that - * if some (or all) of the targets in the list have the {@link Tag} not yet - * assigned, they will be. Only if all of them have the tag already assigned - * they will be removed instead. - * - * @param controllerIds to toggle for - * @param tagName to toggle - * @return TagAssigmentResult with all metadata of the assignment outcome. - * @throws EntityNotFoundException if tag with given name does not exist - * @deprecated since 0.6.0 - not very usable with very unclear logic - */ - @Deprecated(forRemoval = true, since = "0.6.0") - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) - TargetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection controllerIds, @NotEmpty String tagName); - - /** - * Un-assign a {@link TargetTag} assignment to given {@link Target}. - * - * @param controllerId to un-assign for - * @param targetTagId to un-assign - * @return the unassigned target or if no target is unassigned - * @throws EntityNotFoundException if TAG with given ID does not exist - * @deprecated since 0.6.0 - use {@link #unassignTag(Collection, long)} (List, long)} instead - */ - @Deprecated(forRemoval = true, since = "0.6.0") - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) - Target unassignTag(@NotEmpty String controllerId, long targetTagId); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/AbstractAssignmentResult.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/AbstractAssignmentResult.java index 4fff715036..f900e1bbae 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/AbstractAssignmentResult.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/AbstractAssignmentResult.java @@ -12,6 +12,8 @@ import java.util.Collections; import java.util.List; +import lombok.Getter; + /** * Generic assignment result bean. * @@ -19,71 +21,35 @@ */ public abstract class AbstractAssignmentResult { + @Getter private final int alreadyAssigned; private final List assignedEntity; private final List unassignedEntity; - /** - * Constructor. - * - * @param alreadyAssigned count of already assigned entities - * @param assignedEntity {@link List} of assigned entity. - * @param unassignedEntity {@link List} of unassigned entity. - */ - protected AbstractAssignmentResult(final int alreadyAssigned, final List assignedEntity, - final List unassignedEntity) { + protected AbstractAssignmentResult( + final int alreadyAssigned, final List assignedEntity, final List unassignedEntity) { this.alreadyAssigned = alreadyAssigned; this.assignedEntity = assignedEntity; this.unassignedEntity = unassignedEntity; } - /** - * @return number of newly assigned elements. - */ public int getAssigned() { return getAssignedEntity().size(); } - /** - * @return total number (assigned and already assigned). - */ public int getTotal() { return getAssigned() + alreadyAssigned; } - /** - * @return number of already assigned/ignored elements. - */ - public int getAlreadyAssigned() { - return alreadyAssigned; - } - - /** - * @return number of unsassigned elements - */ public int getUnassigned() { return getUnassignedEntity().size(); } - /** - * @return {@link List} of assigned entity. - */ public List getAssignedEntity() { - if (assignedEntity == null) { - return Collections.emptyList(); - } - - return Collections.unmodifiableList(assignedEntity); + return assignedEntity == null ? Collections.emptyList() : Collections.unmodifiableList(assignedEntity); } - /** - * @return {@link List} of unassigned entity. - */ public List getUnassignedEntity() { - if (unassignedEntity == null) { - return Collections.emptyList(); - } - - return Collections.unmodifiableList(unassignedEntity); + return unassignedEntity == null ? Collections.emptyList() : Collections.unmodifiableList(unassignedEntity); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java index ee0cedf171..80137490d2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDistributionSetManagement.java @@ -21,7 +21,6 @@ import java.util.Set; import java.util.function.BiFunction; import java.util.function.Function; -import java.util.function.Supplier; import java.util.stream.Collectors; import jakarta.persistence.EntityManager; @@ -72,7 +71,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetFilter; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.MetaData; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -625,62 +623,6 @@ public Long countAutoAssignmentsForDistributionSet(final Long id) { return distributionSetRepository.countAutoAssignmentsForDistributionSet(id); } - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, - backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public DistributionSetTagAssignmentResult toggleTagAssignment(final Collection ids, final String tagName) { - return updateTag( - ids, - () -> distributionSetTagManagement - .findByName(tagName) - .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, tagName)), - (allDs, distributionSetTag) -> { - final List toBeChangedDSs = allDs.stream().filter(set -> set.addTag(distributionSetTag)) - .collect(Collectors.toList()); - - final DistributionSetTagAssignmentResult result; - // un-assignment case - if (toBeChangedDSs.isEmpty()) { - for (final JpaDistributionSet set : allDs) { - if (set.removeTag(distributionSetTag)) { - toBeChangedDSs.add(set); - } - } - result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(), - Collections.emptyList(), - Collections.unmodifiableList( - toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())), - distributionSetTag); - } else { - result = new DistributionSetTagAssignmentResult(ids.size() - toBeChangedDSs.size(), - Collections.unmodifiableList( - toBeChangedDSs.stream().map(distributionSetRepository::save).collect(Collectors.toList())), - Collections.emptyList(), distributionSetTag); - } - return result; - }); - } - - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, - backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public DistributionSet unassignTag(final long id, final long dsTagId) { - final JpaDistributionSet set = (JpaDistributionSet) getWithDetails(id) - .orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, id)); - - final DistributionSetTag distributionSetTag = distributionSetTagManagement.get(dsTagId) - .orElseThrow(() -> new EntityNotFoundException(DistributionSetTag.class, dsTagId)); - set.removeTag(distributionSetTag); - - final JpaDistributionSet result = distributionSetRepository.save(set); - - // No reason to save the tag - entityManager.detach(distributionSetTag); - return result; - } - // check if shall implicitly lock a distribution set boolean isImplicitLockApplicable(final DistributionSet distributionSet) { final JpaDistributionSet jpaDistributionSet = (JpaDistributionSet) distributionSet; @@ -876,23 +818,4 @@ private void assertDsTagExists(final Long tagId) { throw new EntityNotFoundException(DistributionSetTag.class, tagId); } } - - private T updateTag( - final Collection dsIds, final Supplier tagSupplier, - final BiFunction, DistributionSetTag, T> updater) { - final List allDs = dsIds.size() == 1 ? - distributionSetRepository.findById(dsIds.iterator().next()).map(List::of).orElseGet(Collections::emptyList) : - distributionSetRepository.findAll(DistributionSetSpecification.byIdsFetch(dsIds)); - if (allDs.size() < dsIds.size()) { - throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).toList()); - } - - final DistributionSetTag distributionSetTag = tagSupplier.get(); - try { - return updater.apply(allDs, distributionSetTag); - } finally { - // No reason to save the tag - entityManager.detach(distributionSetTag); - } - } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java index b2f37e9c8d..3b4e7cef9d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTargetManagement.java @@ -78,7 +78,6 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetMetadata; import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetTypeAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; @@ -830,62 +829,6 @@ public TargetMetadata updateMetadata(final String controllerId, final MetaData m return metadata; } - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, - backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public TargetTagAssignmentResult toggleTagAssignment(final Collection controllerIds, final String tagName) { - final TargetTag tag = targetTagRepository - .findByNameEquals(tagName) - .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, tagName)); - final List allTargets = targetRepository - .findAll(TargetSpecifications.byControllerIdWithTagsInJoin(controllerIds)); - if (allTargets.size() < controllerIds.size()) { - throw new EntityNotFoundException(Target.class, controllerIds, - allTargets.stream().map(Target::getControllerId).toList()); - } - - final List alreadyAssignedTargets = targetRepository.findAll( - TargetSpecifications.hasTagName(tagName).and(TargetSpecifications.hasControllerIdIn(controllerIds))); - - // all are already assigned -> unassign - if (alreadyAssignedTargets.size() == allTargets.size()) { - - alreadyAssignedTargets.forEach(target -> target.removeTag(tag)); - return new TargetTagAssignmentResult(0, Collections.emptyList(), - Collections.unmodifiableList(alreadyAssignedTargets), tag); - } - - allTargets.removeAll(alreadyAssignedTargets); - // some or none are assigned -> assign - allTargets.forEach(target -> target.addTag(tag)); - final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(), - targetRepository.saveAll(allTargets), Collections.emptyList(), tag); - - // no reason to persist the tag - entityManager.detach(tag); - return result; - } - - @Override - @Transactional - @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, - backoff = @Backoff(delay = Constants.TX_RT_DELAY)) - public Target unassignTag(final String controllerId, final long targetTagId) { - final JpaTarget target = getByControllerIdAndThrowIfNotFound(controllerId); - - final TargetTag tag = targetTagRepository.findById(targetTagId) - .orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagId)); - - target.removeTag(tag); - - final Target result = targetRepository.save(target); - - // No reason to save the tag - entityManager.detach(tag); - return result; - } - private static boolean hasTagsFilterActive(final FilterParams filterParams) { final boolean isNoTagActive = Boolean.TRUE.equals(filterParams.getSelectTargetWithNoTag()); final boolean isAtLeastOneTagActive = filterParams.getFilterByTagNames() != null diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java index 7eb160638d..5601dc1b52 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/AbstractJpaIntegrationTest.java @@ -204,7 +204,7 @@ protected List assignTag(final Collection sets protected List unassignTag(final Collection sets, final DistributionSetTag tag) { return distributionSetManagement.unassignTag( - sets.stream().map(DistributionSet::getId).collect(Collectors.toList()), tag.getId()); + sets.stream().map(DistributionSet::getId).toList(), tag.getId()); } protected TargetTypeAssignmentResult initiateTypeAssignment(final Collection targets, final TargetType type) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/DistributionSetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/DistributionSetAccessControllerTest.java index af3e8f38ab..c9921f9e63 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/DistributionSetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/DistributionSetAccessControllerTest.java @@ -249,7 +249,7 @@ void verifyTagFilteringAndManagement() { // assignment is denied for hiddenTarget since it's hidden assertThatThrownBy(() -> { - distributionSetManagement.unassignTag(hidden.getId(), dsTag.getId()); + distributionSetManagement.unassignTag(List.of(hidden.getId()), dsTag.getId()); }).as("Missing update permissions for target to toggle tag assignment.") .isInstanceOf(EntityNotFoundException.class); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/TargetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/TargetAccessControllerTest.java index e8275d9a80..9072e2340f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/TargetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/controller/TargetAccessControllerTest.java @@ -195,7 +195,7 @@ void verifyTagFilteringAndManagement() { .isInstanceOf(InsufficientPermissionException.class); // assignment is denied for hiddenTarget since it's hidden - assertThatThrownBy(() -> targetManagement.unassignTag(hiddenTarget.getControllerId(), myTag.getId())) + assertThatThrownBy(() -> targetManagement.unassignTag(List.of(hiddenTarget.getControllerId()), myTag.getId())) .as("Missing update permissions for target to toggle tag assignment.") .isInstanceOf(InsufficientPermissionException.class); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java index a62e314a71..239370af22 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DistributionSetManagementTest.java @@ -132,9 +132,9 @@ void entityQueriesReferringToNotExistingEntitiesThrowsException() { verifyThrownExceptionBy(() -> distributionSetManagement.assignTag(singletonList(set.getId()), Long.parseLong(NOT_EXIST_ID)), "DistributionSetTag"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(set.getId(), NOT_EXIST_IDL), "DistributionSetTag"); + verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(singletonList(set.getId()), NOT_EXIST_IDL), "DistributionSetTag"); - verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(NOT_EXIST_IDL, dsTag.getId()), "DistributionSet"); + verifyThrownExceptionBy(() -> distributionSetManagement.unassignTag(singletonList(NOT_EXIST_IDL), dsTag.getId()), "DistributionSet"); verifyThrownExceptionBy(() -> distributionSetManagement.create( entityFactory.distributionSet().create().name("xxx").type(NOT_EXIST_ID)), "DistributionSetType"); @@ -331,7 +331,7 @@ void assignAndUnassignDistributionSetToTag() { .isEqualTo(distributionSetManagement.findByTag(tag.getId(), PAGE).getNumberOfElements()); final JpaDistributionSet unAssignDS = (JpaDistributionSet) distributionSetManagement - .unassignTag(assignDS.get(0), findDistributionSetTag.getId()); + .unassignTag(List.of(assignDS.get(0)), findDistributionSetTag.getId()).get(0); assertThat(unAssignDS.getId()).as("unassigned ds is wrong").isEqualTo(assignDS.get(0)); assertThat(unAssignDS.getTags().size()).as("unassigned ds has wrong tag size").isZero(); assertThat(distributionSetTagManagement.findByName(TAG1_NAME)).isPresent();