From d2799f4bbcda654b4e6a04903947ad660d43e88d Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Thu, 9 Jan 2025 11:04:39 +0200 Subject: [PATCH] Move deprecated repository and mgmt rest methods in separate module (#2177) Some already deprecated management REST methods are moved in separate module (together with used only for them repository api and impl) in order to have cleanly separate deprecatd REST API. The new module is hawkbit-mgmt-resource-deprecated. It is inculded, by default, in hawkbit-mgmt-stater. * when we decide to remove the deprecated REST API implementation completely - will be easily remved - just module and refs * deprecated REST API could be excluded (by removing the module from runtime) even before that for the runtimes. * after removal, for some time (untill the usad management and repository APIs are compatible) it will be possible to refer (and include) the deprecated method implementation together with the next hawkBit versions. The deprecated methods are: * POST /rest/v1/distributionsettags/{distributionsetTagId}/assigned/toggleTagAssignment * POST /rest/v1/distributionsettags/{distributionsetTagId}/assigned * POST /rest/v1/targettags/{targetTagId}/assigned/toggleTagAssignment * POST /rest/v1/targettags/{targetTagId}/assigned Signed-off-by: Avgustin Marinov --- .../MgmtDistributionSetRequestBodyPost.java | 4 +- .../api/MgmtDistributionSetTagRestApi.java | 88 ------ .../mgmt/rest/api/MgmtTargetTagRestApi.java | 70 ----- .../hawkbit-mgmt-resource-deprecated/pom.xml | 79 ++++++ .../deprecated/DeprecatedMgmtResource.java | 263 ++++++++++++++++++ .../deprecated/DeprecatedMgmtRestApi.java | 203 ++++++++++++++ .../DistributionSetTagAssignmentResult.java | 13 +- .../TargetTagAssignmentResult.java | 18 +- ...gmtAssignedDistributionSetRequestBody.java | 2 +- .../model}/MgmtAssignedTargetRequestBody.java | 2 +- ...MgmtDistributionSetTagAssigmentResult.java | 2 +- .../model}/MgmtTargetTagAssigmentResult.java | 2 +- .../MgmtDeprecatedResourceTest.java | 205 ++++++++++++++ hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml | 17 ++ .../resource/MgmtDistributionSetMapper.java | 3 +- .../MgmtDistributionSetTagResource.java | 43 --- .../resource/MgmtOpenApiConfiguration.java | 2 +- .../rest/resource/MgmtTargetTagResource.java | 44 +-- .../MgmtDistributionSetTagResourceTest.java | 78 +----- .../resource/MgmtTargetTagResourceTest.java | 84 +----- hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml | 7 + hawkbit-mgmt/pom.xml | 3 + .../repository/DistributionSetManagement.java | 30 -- .../hawkbit/repository/TargetManagement.java | 31 --- .../model/AbstractAssignmentResult.java | 48 +--- .../JpaDistributionSetManagement.java | 77 ----- .../jpa/management/JpaTargetManagement.java | 57 ---- .../jpa/AbstractJpaIntegrationTest.java | 2 +- .../DistributionSetAccessControllerTest.java | 2 +- .../TargetAccessControllerTest.java | 2 +- .../DistributionSetManagementTest.java | 6 +- 31 files changed, 816 insertions(+), 671 deletions(-) create mode 100644 hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/pom.xml create mode 100644 hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtResource.java create mode 100644 hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtRestApi.java rename {hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model => hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated}/DistributionSetTagAssignmentResult.java (78%) rename {hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model => hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated}/TargetTagAssignmentResult.java (61%) rename hawkbit-mgmt/{hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag => hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model}/MgmtAssignedDistributionSetRequestBody.java (93%) rename hawkbit-mgmt/{hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag => hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model}/MgmtAssignedTargetRequestBody.java (93%) rename hawkbit-mgmt/{hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag => hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model}/MgmtDistributionSetTagAssigmentResult.java (95%) rename hawkbit-mgmt/{hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/tag => hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/json/model}/MgmtTargetTagAssigmentResult.java (95%) create mode 100644 hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/MgmtDeprecatedResourceTest.java 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 c6fabd66c..0450270c9 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 @@ import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleAssi @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 b2312c572..ed7b4e8e4 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.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.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 @@ public interface MgmtDistributionSetTagRestApi { 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 bfbe26d67..60121e8cd 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.ApiResponse; 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 @@ public interface MgmtTargetTagRestApi { @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 000000000..25d36be47 --- /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 000000000..a8e07036c --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtResource.java @@ -0,0 +1,263 @@ +/** + * 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.slf4j.Logger; +import org.slf4j.LoggerFactory; +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 { + + // logger that logs usage of deprecated API + private static final Logger DEPRECATED_USAGE_LOGGER = LoggerFactory.getLogger("DEPRECATED_USAGE"); + + @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) { + DEPRECATED_USAGE_LOGGER.debug("[DEPRECATED] Deprecated POST /rest/v1/distributionsettags/{distributionsetTagId}/assigned/toggleTagAssignment called"); + 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); + } + + @Override + public ResponseEntity> assignDistributionSetsByRequestBody( + final Long distributionsetTagId, + final List assignedDSRequestBodies) { + DEPRECATED_USAGE_LOGGER.debug("[DEPRECATED] Deprecated POST /rest/v1/distributionsettags/{distributionsetTagId}/assigned called"); + 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) { + DEPRECATED_USAGE_LOGGER.debug("[DEPRECATED] Deprecated POST /rest/v1/targettags/{targetTagId}/assigned/toggleTagAssignment called"); + 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); + } + + @Override + public ResponseEntity> assignTargetsByRequestBody( + final Long targetTagId, final List assignedTargetRequestBodies) { + DEPRECATED_USAGE_LOGGER.debug("[DEPRECATED] Deprecated POST /rest/v1/targettags/{targetTagId}/assigned called"); + 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 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); + } + } + + 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; + } + + 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 000000000..66e2663e2 --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/DeprecatedMgmtRestApi.java @@ -0,0 +1,203 @@ +/** + * 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 +@Deprecated(forRemoval = true) +@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.", + deprecated = true) + @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.", + deprecated = true) + @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.", + deprecated = true) + @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.", + deprecated = true) + @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 7e1713373..085fc1618 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 4bda16c22..2bf307a4d 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 5cd246c39..e708f8370 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 c7d80afb6..c7451b2b0 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 32ce5521a..8d25dd6c1 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 63e52880a..57722cf59 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 000000000..d4da0e223 --- /dev/null +++ b/hawkbit-mgmt/hawkbit-mgmt-resource-deprecated/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/deprecated/MgmtDeprecatedResourceTest.java @@ -0,0 +1,205 @@ +/** + * 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(); + } + + @Test + @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") + @ExpectEvents({ + @Expect(type = DistributionSetTagCreatedEvent.class, count = 1), + @Expect(type = DistributionSetCreatedEvent.class, count = 2), + @Expect(type = DistributionSetUpdatedEvent.class, count = 2) }) + public void assignDistributionSetsWithRequestBody() throws Exception { + final DistributionSetTag tag = testdataFactory.createDistributionSetTags(1).get(0); + final int setsAssigned = 2; + final List sets = testdataFactory.createDistributionSetsWithoutModules(setsAssigned); + + final ResultActions result = mvc + .perform( + post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") + .content(JsonBuilder + .ids(sets.stream().map(DistributionSet::getId).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 = 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))) + .andExpect(applyBaseEntityMatcherOnArrayResult(updated.get(1))); + } + + @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 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)); + } + + 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 4cfc4d3fe..1b4c4dd08 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 e105ef24a..9310c261d 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 @@ public final class MgmtDistributionSetMapper { 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 b84891ec6..54fecb2c3 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.OffsetBasedPageRequest; 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 class MgmtDistributionSetTagResource implements MgmtDistributionSetTagRes 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/MgmtOpenApiConfiguration.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtOpenApiConfiguration.java index 3410f2972..188090532 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtOpenApiConfiguration.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtOpenApiConfiguration.java @@ -36,7 +36,7 @@ public class MgmtOpenApiConfiguration { return GroupedOpenApi .builder() .group("Management API") - .pathsToMatch("/rest/v1/**") + .pathsToMatch("/rest/v*/**") .addOpenApiCustomizer(openApi -> openApi .addSecurityItem(new SecurityRequirement() 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 506c9b60d..0c0e1a41b 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 @@ package org.eclipse.hawkbit.mgmt.rest.resource; 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.TenantConfigurationManagement; 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 class MgmtTargetTagResource implements MgmtTargetTagRestApi { @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 class MgmtTargetTagResource implements MgmtTargetTagRestApi { 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 09bde1f41..1b89e4e60 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 class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt .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({ @@ -483,47 +450,4 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt assertThat(notFound).isEqualTo(missing); }); } - - @Test - @Description("Verifies that tag assignments done through tag API command are correctly stored in the repository.") - @ExpectEvents({ - @Expect(type = DistributionSetTagCreatedEvent.class, count = 1), - @Expect(type = DistributionSetCreatedEvent.class, count = 2), - @Expect(type = DistributionSetUpdatedEvent.class, count = 2) }) - public void assignDistributionSetsWithRequestBody() throws Exception { - final DistributionSetTag tag = testdataFactory.createDistributionSetTags(1).get(0); - final int setsAssigned = 2; - final List sets = testdataFactory.createDistributionSetsWithoutModules(setsAssigned); - - final ResultActions result = mvc - .perform( - post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + tag.getId() + "/assigned") - .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)); - - final 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))) - .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)); - } -} +} \ No newline at end of file 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 0a1cbcd31..f54ed57cc 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 class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT .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 f89391022..06c397f0f 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 1cc505955..a13b2fc6f 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 399119f11..6d198d09d 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.DistributionSet; 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 dde94197a..7a43a9428 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.DistributionSet; 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 @@ public interface TargetManagement { */ @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 4fff71503..f900e1bba 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 @@ package org.eclipse.hawkbit.repository.model; import java.util.Collections; import java.util.List; +import lombok.Getter; + /** * Generic assignment result bean. * @@ -19,71 +21,35 @@ import java.util.List; */ 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 ee0cedf17..80137490d 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.Optional; 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.DistributionSet; 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 class JpaDistributionSetManagement implements DistributionSetManagement { 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 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { 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 b2f37e9c8..3b4e7cef9 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.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; @@ -830,62 +829,6 @@ public class JpaTargetManagement implements TargetManagement { 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 7eb160638..5601dc1b5 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 @@ public abstract class AbstractJpaIntegrationTest extends AbstractIntegrationTest 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 af3e8f38a..c9921f9e6 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 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest { // 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 e8275d9a8..9072e2340 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 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest { .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 a62e314a7..239370af2 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 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { 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 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest { .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();