Implement target tag management using common RepositoryManagement (and abstract JPA impl) (#2580)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-08-01 13:41:20 +03:00
committed by GitHub
parent 5d75c9b0cc
commit fd9c0fc50d
28 changed files with 235 additions and 539 deletions

View File

@@ -38,6 +38,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
@@ -49,18 +50,15 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class MgmtTargetTagResource implements MgmtTargetTagRestApi { public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
private final TargetTagManagement tagManagement; private final TargetTagManagement<? extends TargetTag> tagManagement;
private final TargetManagement targetManagement; private final TargetManagement targetManagement;
private final EntityFactory entityFactory;
private final TenantConfigHelper tenantConfigHelper; private final TenantConfigHelper tenantConfigHelper;
MgmtTargetTagResource( MgmtTargetTagResource(
final TargetTagManagement tagManagement, final TargetManagement targetManagement, final TargetTagManagement<? extends TargetTag> tagManagement, final TargetManagement targetManagement,
final EntityFactory entityFactory,
final SystemSecurityContext securityContext, final TenantConfigurationManagement configurationManagement) { final SystemSecurityContext securityContext, final TenantConfigurationManagement configurationManagement) {
this.tagManagement = tagManagement; this.tagManagement = tagManagement;
this.targetManagement = targetManagement; this.targetManagement = targetManagement;
this.entityFactory = entityFactory;
tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement); tenantConfigHelper = TenantConfigHelper.usingContext(securityContext, configurationManagement);
} }
@@ -68,7 +66,7 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
public ResponseEntity<PagedList<MgmtTag>> getTargetTags( public ResponseEntity<PagedList<MgmtTag>> getTargetTags(
final String rsqlParam, final int pagingOffsetParam, final int pagingLimitParam, final String sortParam) { final String rsqlParam, final int pagingOffsetParam, final int pagingLimitParam, final String sortParam) {
final Pageable pageable = PagingUtility.toPageable(pagingOffsetParam, pagingLimitParam, sanitizeTagSortParam(sortParam)); final Pageable pageable = PagingUtility.toPageable(pagingOffsetParam, pagingLimitParam, sanitizeTagSortParam(sortParam));
final Page<TargetTag> findTargetsAll; final Page<? extends TargetTag> findTargetsAll;
if (rsqlParam == null) { if (rsqlParam == null) {
findTargetsAll = this.tagManagement.findAll(pageable); findTargetsAll = this.tagManagement.findAll(pageable);
} else { } else {
@@ -92,7 +90,7 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
@Override @Override
public ResponseEntity<List<MgmtTag>> createTargetTags(final List<MgmtTagRequestBodyPut> tags) { public ResponseEntity<List<MgmtTag>> createTargetTags(final List<MgmtTagRequestBodyPut> tags) {
log.debug("creating {} target tags", tags.size()); log.debug("creating {} target tags", tags.size());
final List<TargetTag> createdTargetTags = tagManagement.create(MgmtTagMapper.mapTagFromRequest(entityFactory, tags)); final List<? extends TargetTag> createdTargetTags = tagManagement.create(MgmtTagMapper.mapTagFromRequest(tags));
return new ResponseEntity<>(MgmtTagMapper.toResponse(createdTargetTags), HttpStatus.CREATED); return new ResponseEntity<>(MgmtTagMapper.toResponse(createdTargetTags), HttpStatus.CREATED);
} }
@@ -101,8 +99,8 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
log.debug("update {} target tag", restTargetTagRest); log.debug("update {} target tag", restTargetTagRest);
final TargetTag updateTargetTag = tagManagement final TargetTag updateTargetTag = tagManagement
.update(entityFactory.tag().update(targetTagId).name(restTargetTagRest.getName()) .update(TargetTagManagement.Update.builder().id(targetTagId).name(restTargetTagRest.getName())
.description(restTargetTagRest.getDescription()).colour(restTargetTagRest.getColour())); .description(restTargetTagRest.getDescription()).colour(restTargetTagRest.getColour()).build());
log.debug("target tag updated"); log.debug("target tag updated");
@@ -118,7 +116,7 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
log.debug("Delete {} target tag", targetTagId); log.debug("Delete {} target tag", targetTagId);
final TargetTag targetTag = findTargetTagById(targetTagId); final TargetTag targetTag = findTargetTagById(targetTagId);
this.tagManagement.delete(targetTag.getName()); this.tagManagement.delete(targetTag.getId());
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }

View File

@@ -24,7 +24,7 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetTagRestApi;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.builder.TagCreate; import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
@@ -36,7 +36,7 @@ import org.eclipse.hawkbit.rest.json.model.ResponseList;
@NoArgsConstructor(access = AccessLevel.PRIVATE) @NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class MgmtTagMapper { public final class MgmtTagMapper {
public static List<MgmtTag> toResponse(final List<TargetTag> targetTags) { public static List<MgmtTag> toResponse(final List<? extends TargetTag> targetTags) {
final List<MgmtTag> tagsRest = new ArrayList<>(); final List<MgmtTag> tagsRest = new ArrayList<>();
if (targetTags == null) { if (targetTags == null) {
return tagsRest; return tagsRest;
@@ -106,10 +106,14 @@ public final class MgmtTagMapper {
.withRel("assignedDistributionSets").expand()); .withRel("assignedDistributionSets").expand());
} }
public static List<TagCreate<Tag>> mapTagFromRequest(final EntityFactory entityFactory, final Collection<MgmtTagRequestBodyPut> tags) { public static List<TargetTagManagement.Create> mapTagFromRequest(final Collection<MgmtTagRequestBodyPut> tags) {
return tags.stream() return tags.stream()
.map(tagRest -> entityFactory.tag().create().name(tagRest.getName()) .map(tagRest -> TargetTagManagement.Create.builder()
.description(tagRest.getDescription()).colour(tagRest.getColour())) .name(tagRest.getName())
.description(tagRest.getDescription())
.colour(tagRest.getColour())
.build())
.map(TargetTagManagement.Create.class::cast)
.toList(); .toList();
} }

View File

@@ -21,7 +21,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -29,6 +28,7 @@ import java.util.Random;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.resource.util.ResourceUtility; import org.eclipse.hawkbit.mgmt.rest.resource.util.ResourceUtility;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagCreatedEvent;
@@ -188,14 +188,16 @@ class MgmtDistributionSetTagResourceTest extends AbstractManagementApiIntegratio
@Test @Test
@ExpectEvents({ @Expect(type = DistributionSetTagCreatedEvent.class, count = 2) }) @ExpectEvents({ @Expect(type = DistributionSetTagCreatedEvent.class, count = 2) })
void createDistributionSetTags() throws Exception { void createDistributionSetTags() throws Exception {
final Tag tagOne = entityFactory.tag().create().colour("testcol1").description("its a test1").name("thetest1") final DistributionSetTagManagement.Create tagOne = DistributionSetTagManagement.Create.builder()
.colour("testcol1").description("its a test1").name("thetest1")
.build(); .build();
final Tag tagTwo = entityFactory.tag().create().colour("testcol2").description("its a test2").name("thetest2") final DistributionSetTagManagement.Create tagTwo = DistributionSetTagManagement.Create.builder()
.colour("testcol2").description("its a test2").name("thetest2")
.build(); .build();
final ResultActions result = mvc final ResultActions result = mvc
.perform(post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) .perform(post(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING)
.content(JsonBuilder.tags(Arrays.asList(tagOne, tagTwo))) .content(JsonBuilder.dsTags(List.of(tagOne, tagTwo)))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isCreated()) .andExpect(status().isCreated())
@@ -210,8 +212,7 @@ class MgmtDistributionSetTagResourceTest extends AbstractManagementApiIntegratio
assertThat(createdTwo.getDescription()).isEqualTo(tagTwo.getDescription()); assertThat(createdTwo.getDescription()).isEqualTo(tagTwo.getDescription());
assertThat(createdTwo.getColour()).isEqualTo(tagTwo.getColour()); assertThat(createdTwo.getColour()).isEqualTo(tagTwo.getColour());
result.andExpect(applyTagMatcherOnArrayResult(createdOne)) result.andExpect(applyTagMatcherOnArrayResult(createdOne)).andExpect(applyTagMatcherOnArrayResult(createdTwo));
.andExpect(applyTagMatcherOnArrayResult(createdTwo));
} }
/** /**
@@ -225,12 +226,13 @@ class MgmtDistributionSetTagResourceTest extends AbstractManagementApiIntegratio
final List<DistributionSetTag> tags = testdataFactory.createDistributionSetTags(1); final List<DistributionSetTag> tags = testdataFactory.createDistributionSetTags(1);
final DistributionSetTag original = tags.get(0); final DistributionSetTag original = tags.get(0);
final Tag update = entityFactory.tag().create().name("updatedName").colour("updatedCol") final DistributionSetTagManagement.Update update = DistributionSetTagManagement.Update.builder()
.description("updatedDesc").build(); .name("updatedName").colour("updatedCol").description("updatedDesc")
.build();
final ResultActions result = mvc final ResultActions result = mvc
.perform(put(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + original.getId()) .perform(put(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/" + original.getId())
.content(JsonBuilder.tag(update)).contentType(MediaType.APPLICATION_JSON) .content(JsonBuilder.dsTag(update)).contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)) .accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())

View File

@@ -30,6 +30,7 @@ import java.util.Random;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi;
import org.eclipse.hawkbit.mgmt.rest.resource.util.ResourceUtility; import org.eclipse.hawkbit.mgmt.rest.resource.util.ResourceUtility;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; 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.TargetTagCreatedEvent;
@@ -153,14 +154,16 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Test @Test
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) }) @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) })
public void createTargetTags() throws Exception { public void createTargetTags() throws Exception {
final Tag tagOne = entityFactory.tag().create().colour("testcol1").description("its a test1").name("thetest1") final TargetTagManagement.Create tagOne = TargetTagManagement.Create.builder()
.colour("testcol1").description("its a test1").name("thetest1")
.build(); .build();
final Tag tagTwo = entityFactory.tag().create().colour("testcol2").description("its a test2").name("thetest2") final TargetTagManagement.Create tagTwo = TargetTagManagement.Create.builder()
.colour("testcol2").description("its a test2").name("thetest2")
.build(); .build();
final ResultActions result = mvc final ResultActions result = mvc
.perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING) .perform(post(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING)
.content(JsonBuilder.tags(Arrays.asList(tagOne, tagTwo))) .content(JsonBuilder.targetTags(List.of(tagOne, tagTwo)))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isCreated()) .andExpect(status().isCreated())
@@ -190,12 +193,13 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
final List<TargetTag> tags = testdataFactory.createTargetTags(1, ""); final List<TargetTag> tags = testdataFactory.createTargetTags(1, "");
final TargetTag original = tags.get(0); final TargetTag original = tags.get(0);
final Tag update = entityFactory.tag().create().name("updatedName").colour("updatedCol") final TargetTagManagement.Update update = TargetTagManagement.Update.builder()
.description("updatedDesc").build(); .name("updatedName").colour("updatedCol").description("updatedDesc")
.build();
final ResultActions result = mvc final ResultActions result = mvc
.perform(put(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + original.getId()) .perform(put(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + original.getId())
.content(JsonBuilder.tag(update)).contentType(MediaType.APPLICATION_JSON) .content(JsonBuilder.targetTag(update)).contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)) .accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isOk()) .andExpect(status().isOk())

View File

@@ -12,16 +12,13 @@ package org.eclipse.hawkbit.repository;
import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder; import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder; import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder; import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder;
import org.eclipse.hawkbit.repository.builder.TagBuilder;
import org.eclipse.hawkbit.repository.builder.TargetBuilder; import org.eclipse.hawkbit.repository.builder.TargetBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder; import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.builder.TargetTypeBuilder; import org.eclipse.hawkbit.repository.builder.TargetTypeBuilder;
import org.eclipse.hawkbit.repository.model.BaseEntity; import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.Tag;
/** /**
* central {@link BaseEntity} generation service. Objects are created but not * Central {@link BaseEntity} generation service. Objects are created but not persisted.
* persisted.
*/ */
public interface EntityFactory { public interface EntityFactory {
@@ -30,11 +27,6 @@ public interface EntityFactory {
*/ */
ActionStatusBuilder actionStatus(); ActionStatusBuilder actionStatus();
/**
* @return {@link TagBuilder} object
*/
TagBuilder<Tag> tag();
/** /**
* @return {@link RolloutGroupBuilder} object * @return {@link RolloutGroupBuilder} object
*/ */

View File

@@ -83,7 +83,7 @@ public interface RepositoryManagement<T extends BaseEntity, C, U extends Identif
* @return all {@link BaseEntity}s in the repository. * @return all {@link BaseEntity}s in the repository.
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
Slice<T> findAll(@NotNull Pageable pageable); Page<T> findAll(@NotNull Pageable pageable);
/** /**
* Retrieves all {@link BaseEntity}s with a given specification. * Retrieves all {@link BaseEntity}s with a given specification.

View File

@@ -9,129 +9,67 @@
*/ */
package org.eclipse.hawkbit.repository; package org.eclipse.hawkbit.repository;
import java.util.Collection;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.TagCreate; import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.builder.TagUpdate;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
/** /**
* Management service for {@link TargetTag}s. * Management service for {@link TargetTag}s.
*/ */
public interface TargetTagManagement { public interface TargetTagManagement<T extends TargetTag>
extends RepositoryManagement<T, TargetTagManagement.Create, TargetTagManagement.Update> {
/** @Override
* Count {@link TargetTag}s. default String permissionGroup() {
* return "TARGET";
* @return size of {@link TargetTag}s }
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long count();
/** @PreAuthorize(SpringEvalExpressions.HAS_READ_REPOSITORY)
* Creates a new {@link TargetTag}.
*
* @param create to be created
* @return the new created {@link TargetTag}
* @throws EntityAlreadyExistsException if given object already exists
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link TagCreate} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
TargetTag create(@NotNull @Valid TagCreate<Tag> create);
/**
* Created multiple {@link TargetTag}s.
*
* @param creates to be created
* @return the new created {@link TargetTag}s
* @throws EntityAlreadyExistsException if given object has already an ID.
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link TagCreate} for field constraints.
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
List<TargetTag> create(@NotNull @Valid Collection<TagCreate<Tag>> creates);
/**
* Deletes {@link TargetTag} with given name.
*
* @param targetTagName tag name of the {@link TargetTag} to be deleted
* @throws EntityNotFoundException if tag with given name does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET)
void delete(@NotEmpty String targetTagName);
/**
* returns all {@link TargetTag}s.
*
* @param pageable page parameter
* @return all {@link TargetTag}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetTag> findAll(@NotNull Pageable pageable);
/**
* Retrieves all target tags based on the given specification.
*
* @param rsql rsql query string
* @param pageable pagination parameter
* @return the found {@link Target}s, never {@code null}
* @throws RSQLParameterUnsupportedFieldException if a field in the RSQL string is used but not provided by the given {@code fieldNameProvider}
* @throws RSQLParameterSyntaxException if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetTag> findByRsql(@NotNull String rsql, @NotNull Pageable pageable);
/**
* Find {@link TargetTag} based on given Name.
*
* @param name to look for.
* @return {@link TargetTag}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Optional<TargetTag> getByName(@NotEmpty String name); Optional<TargetTag> getByName(@NotEmpty String name);
/** @SuperBuilder
* Finds {@link TargetTag} by given id. @Getter
* @EqualsAndHashCode(callSuper = true)
* @param id to search for @ToString(callSuper = true)
* @return the found {@link TargetTag} final class Create extends DistributionSetTagManagement.UpdateCreate {}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Optional<TargetTag> get(long id);
/** @SuperBuilder
* Finds {@link TargetTag} by given ids. @Getter
* @EqualsAndHashCode(callSuper = true)
* @param ids the ids to for @ToString(callSuper = true)
* @return the found {@link TargetTag}s final class Update extends DistributionSetTagManagement.UpdateCreate implements Identifiable<Long> {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
List<TargetTag> get(@NotEmpty Collection<Long> ids);
/** @NotNull
* Updates the {@link TargetTag}. private Long id;
* }
* @param update the {@link TargetTag} with updated values
* @return the updated {@link TargetTag} @SuperBuilder
* @throws EntityNotFoundException in case the {@link TargetTag} does not exist and cannot be updated @Getter
* @throws ConstraintViolationException if fields are not filled as specified. Check {@link TagUpdate} for field constraints. class UpdateCreate {
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) @ValidString
TargetTag update(@NotNull @Valid TagUpdate update); @Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull(groups = DistributionSetTagManagement.Create.class)
private String name;
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@ValidString
@Size(max = Tag.COLOUR_MAX_SIZE)
private String colour;
}
} }

View File

@@ -1,29 +0,0 @@
/**
* 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.repository.builder;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* Builder for {@link Tag}.
*/
public interface TagBuilder<T extends Tag> {
/**
* @param id of the updatable entity
* @return builder instance
*/
TagUpdate update(long id);
/**
* @return builder instance
*/
TagCreate<T> create();
}

View File

@@ -1,48 +0,0 @@
/**
* 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.repository.builder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* Builder to create a new {@link Tag} entry. Defines all fields that can be set
* at creation time. Other fields are set by the repository automatically, e.g.
* {@link BaseEntity#getCreatedAt()}.
*/
public interface TagCreate<T extends Tag> {
/**
* @param name for {@link Tag#getName()}
* @return updated builder instance
*/
TagCreate<T> name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param description for {@link Tag#getDescription()}
* @return updated builder instance
*/
TagCreate<T> description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link Tag#getColour()}
* @return updated builder instance
*/
TagCreate<T> colour(@Size(max = Tag.COLOUR_MAX_SIZE) String colour);
/**
* @return peek on current state of {@link Tag} in the builder
*/
T build();
}

View File

@@ -1,41 +0,0 @@
/**
* 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.repository.builder;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* Builder to update an existing {@link Tag} entry. Defines all fields that can
* be updated.
*/
public interface TagUpdate {
/**
* @param name for {@link Tag#getName()}
* @return updated builder instance
*/
TagUpdate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotNull String name);
/**
* @param description for {@link Tag#getDescription()}
* @return updated builder instance
*/
TagUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link Tag#getColour()}
* @return updated builder instance
*/
TagUpdate colour(@Size(max = Tag.COLOUR_MAX_SIZE) String colour);
}

View File

@@ -1,20 +0,0 @@
/**
* 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.repository.builder;
/**
* Update implementation.
*/
public class GenericTagUpdate extends AbstractTagUpdateCreate<TagUpdate> implements TagUpdate {
public GenericTagUpdate(final Long id) {
super.id = id;
}
}

View File

@@ -13,14 +13,11 @@ import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder; import org.eclipse.hawkbit.repository.builder.ActionStatusBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder; import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder; import org.eclipse.hawkbit.repository.builder.RolloutGroupBuilder;
import org.eclipse.hawkbit.repository.builder.TagBuilder;
import org.eclipse.hawkbit.repository.builder.TargetBuilder; import org.eclipse.hawkbit.repository.builder.TargetBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder; import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.builder.TargetTypeBuilder; import org.eclipse.hawkbit.repository.builder.TargetTypeBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusBuilder; import org.eclipse.hawkbit.repository.jpa.builder.JpaActionStatusBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupBuilder; import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagBuilder;
import org.eclipse.hawkbit.repository.model.Tag;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
/** /**
@@ -49,12 +46,6 @@ public class JpaEntityFactory implements EntityFactory {
return new JpaActionStatusBuilder(); return new JpaActionStatusBuilder();
} }
@Override
public TagBuilder<Tag> tag() {
return (TagBuilder)new JpaTagBuilder();
}
@Override @Override
public RolloutGroupBuilder rolloutGroup() { public RolloutGroupBuilder rolloutGroup() {
return new JpaRolloutGroupBuilder(); return new JpaRolloutGroupBuilder();

View File

@@ -453,8 +453,7 @@ public class JpaRepositoryConfiguration {
final TargetBuilder targetBuilder, final TargetTypeBuilder targetTypeBuilder, final TargetBuilder targetBuilder, final TargetTypeBuilder targetTypeBuilder,
final TargetFilterQueryBuilder targetFilterQueryBuilder, final TargetFilterQueryBuilder targetFilterQueryBuilder,
final RolloutBuilder rolloutBuilder) { final RolloutBuilder rolloutBuilder) {
return new JpaEntityFactory( return new JpaEntityFactory(targetBuilder, targetTypeBuilder, targetFilterQueryBuilder, rolloutBuilder);
targetBuilder, targetTypeBuilder, targetFilterQueryBuilder, rolloutBuilder);
} }
/** /**

View File

@@ -1,33 +0,0 @@
/**
* 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.repository.jpa.builder;
import org.eclipse.hawkbit.repository.builder.GenericTagUpdate;
import org.eclipse.hawkbit.repository.builder.TagBuilder;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TagUpdate;
import org.eclipse.hawkbit.repository.jpa.model.JpaTag;
import org.eclipse.hawkbit.repository.model.Tag;
/**
* Builder implementation for {@link Tag}.
*/
public class JpaTagBuilder implements TagBuilder<JpaTag> {
@Override
public TagUpdate update(final long id) {
return new GenericTagUpdate(id);
}
@Override
public TagCreate<JpaTag> create() {
return new JpaTagCreate();
}
}

View File

@@ -1,33 +0,0 @@
/**
* 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.repository.jpa.builder;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.repository.builder.AbstractTagUpdateCreate;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaTag;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
/**
* Create/build implementation.
*/
@NoArgsConstructor(access = AccessLevel.PACKAGE)
public class JpaTagCreate extends AbstractTagUpdateCreate<TagCreate<JpaTag>> implements TagCreate<JpaTag> {
public JpaTargetTag buildTargetTag() {
return new JpaTargetTag(name, description, colour);
}
@Override
public JpaTag build() {
return new JpaTag(name, description, colour);
}
}

View File

@@ -142,8 +142,8 @@ abstract class AbstractJpaRepositoryManagement<T extends AbstractJpaBaseEntity,
} }
@Override @Override
public Slice<T> findAll(final Pageable pageable) { public Page<T> findAll(final Pageable pageable) {
return JpaManagementHelper.findAllWithoutCountBySpec( return JpaManagementHelper.findAllWithCountBySpec(
jpaRepository, isNotDeleted().map(List::of).orElseGet(Collections::emptyList), pageable); jpaRepository, isNotDeleted().map(List::of).orElseGet(Collections::emptyList), pageable);
} }

View File

@@ -9,33 +9,16 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.management; package org.eclipse.hawkbit.repository.jpa.management;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import jakarta.persistence.EntityManager;
import org.eclipse.hawkbit.repository.TargetTagFields; import org.eclipse.hawkbit.repository.TargetTagFields;
import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.builder.GenericTagUpdate;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TagUpdate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTagCreate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaNamedEntity_;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetTagRepository;
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -47,91 +30,19 @@ import org.springframework.validation.annotation.Validated;
@Validated @Validated
@Service @Service
@ConditionalOnBooleanProperty(prefix = "hawkbit.jpa", name = { "enabled", "target-tag-management" }, matchIfMissing = true) @ConditionalOnBooleanProperty(prefix = "hawkbit.jpa", name = { "enabled", "target-tag-management" }, matchIfMissing = true)
public class JpaTargetTagManagement implements TargetTagManagement { public class JpaTargetTagManagement
extends AbstractJpaRepositoryManagement<JpaTargetTag, TargetTagManagement.Create, TargetTagManagement.Update, TargetTagRepository, TargetTagFields>
implements TargetTagManagement<JpaTargetTag> {
private final TargetTagRepository targetTagRepository; protected JpaTargetTagManagement(
final TargetTagRepository targetTagRepository,
protected JpaTargetTagManagement(final TargetTagRepository targetTagRepository) { final EntityManager entityManager) {
this.targetTagRepository = targetTagRepository; super(targetTagRepository, entityManager);
} }
@Override
public long count() {
return targetTagRepository.count();
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public TargetTag create(final TagCreate c) {
final JpaTagCreate create = (JpaTagCreate) c;
return targetTagRepository.save(AccessController.Operation.CREATE, create.buildTargetTag());
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<TargetTag> create(final Collection<TagCreate<Tag>> tt) {
final List<JpaTargetTag> targetTagList = tt.stream().map(JpaTagCreate.class::cast)
.map(JpaTagCreate::buildTargetTag).toList();
return Collections.unmodifiableList(
targetTagRepository.saveAll(AccessController.Operation.CREATE, targetTagList));
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public void delete(final String targetTagName) {
targetTagRepository.delete(
targetTagRepository
.findOne(((root, query, cb) -> cb.equal(root.get(AbstractJpaNamedEntity_.name), targetTagName)))
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, targetTagName)));
}
@Override
public Page<TargetTag> findAll(final Pageable pageable) {
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, null, pageable);
}
@Override
public Page<TargetTag> findByRsql(final String rsql, final Pageable pageable) {
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, Collections.singletonList(
RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetTagFields.class)), pageable);
}
@Override @Override
public Optional<TargetTag> getByName(final String name) { public Optional<TargetTag> getByName(final String name) {
return targetTagRepository.findByNameEquals(name); return jpaRepository.findByNameEquals(name);
}
@Override
public Optional<TargetTag> get(final long id) {
return targetTagRepository.findById(id).map(TargetTag.class::cast);
}
@Override
public List<TargetTag> get(final Collection<Long> ids) {
return Collections.unmodifiableList(targetTagRepository.findAllById(ids));
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public TargetTag update(final TagUpdate u) {
final GenericTagUpdate update = (GenericTagUpdate) u;
final JpaTargetTag tag = targetTagRepository.findById(update.getId())
.orElseThrow(() -> new EntityNotFoundException(TargetTag.class, update.getId()));
update.getName().ifPresent(tag::setName);
update.getDescription().ifPresent(tag::setDescription);
update.getColour().ifPresent(tag::setColour);
return targetTagRepository.save(tag);
} }
} }

View File

@@ -9,6 +9,7 @@
*/ */
package org.eclipse.hawkbit.repository.event.remote.entity; package org.eclipse.hawkbit.repository.event.remote.entity;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -32,12 +33,12 @@ class TargetTagEventTest extends AbstractRemoteEntityEventTest<TargetTag> {
* Verifies that the target tag entity reloading by remote updated event works * Verifies that the target tag entity reloading by remote updated event works
*/ */
@Test @Test
void testTargetTagUpdateEventt() { void testTargetTagUpdateEvent() {
assertAndCreateRemoteEvent(TargetTagUpdatedEvent.class); assertAndCreateRemoteEvent(TargetTagUpdatedEvent.class);
} }
@Override @Override
protected TargetTag createEntity() { protected TargetTag createEntity() {
return targetTagManagement.create(entityFactory.tag().create().name("tag1")); return targetTagManagement.create(TargetTagManagement.Create.builder().name("tag1").build());
} }
} }

View File

@@ -25,6 +25,7 @@ import java.util.List;
import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.Identifiable; import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker; import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
@@ -127,11 +128,11 @@ class TargetAccessControllerTest extends AbstractJpaIntegrationTest {
final Target hiddenTarget = targetManagement final Target hiddenTarget = targetManagement
.create(entityFactory.target().create().controllerId("device03").status(TargetUpdateStatus.REGISTERED)); .create(entityFactory.target().create().controllerId("device03").status(TargetUpdateStatus.REGISTERED));
final Long myTagId = targetTagManagement.create(entityFactory.tag().create().name("myTag")).getId(); final Long myTagId = targetTagManagement.create(TargetTagManagement.Create.builder().name("myTag").build()).getId();
// perform tag assignment before setting access rules // perform tag assignment before setting access rules
targetManagement.assignTag( targetManagement.assignTag(
Arrays.asList(permittedTarget.getControllerId(), readOnlyTargetControllerId, hiddenTarget.getControllerId()), myTagId); List.of(permittedTarget.getControllerId(), readOnlyTargetControllerId, hiddenTarget.getControllerId()), myTagId);
runAs(withUser("user", runAs(withUser("user",
READ_TARGET + "/controllerId==" + permittedTarget.getControllerId() + " or controllerId==" + readOnlyTargetControllerId, READ_TARGET + "/controllerId==" + permittedTarget.getControllerId() + " or controllerId==" + readOnlyTargetControllerId,

View File

@@ -18,6 +18,7 @@ import java.util.List;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -67,10 +68,10 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void targetSearchWithVariousFilterCombinations() { void targetSearchWithVariousFilterCombinations() {
final TargetTag targTagX = targetTagManagement.create(entityFactory.tag().create().name("TargTag-X")); final TargetTag targTagX = targetTagManagement.create(TargetTagManagement.Create.builder().name("TargTag-X").build());
final TargetTag targTagY = targetTagManagement.create(entityFactory.tag().create().name("TargTag-Y")); final TargetTag targTagY = targetTagManagement.create(TargetTagManagement.Create.builder().name("TargTag-Y").build());
final TargetTag targTagZ = targetTagManagement.create(entityFactory.tag().create().name("TargTag-Z")); final TargetTag targTagZ = targetTagManagement.create(TargetTagManagement.Create.builder().name("TargTag-Z").build());
final TargetTag targTagW = targetTagManagement.create(entityFactory.tag().create().name("TargTag-W")); final TargetTag targTagW = targetTagManagement.create(TargetTagManagement.Create.builder().name("TargTag-W").build());
final DistributionSet setA = testdataFactory.createDistributionSet("A"); final DistributionSet setA = testdataFactory.createDistributionSet("A");
final DistributionSet setB = testdataFactory.createDistributionSet("B"); final DistributionSet setB = testdataFactory.createDistributionSet("B");

View File

@@ -32,6 +32,7 @@ import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.SpRole; import org.eclipse.hawkbit.im.authentication.SpRole;
import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.Identifiable; import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.builder.TargetCreate; import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate; import org.eclipse.hawkbit.repository.builder.TargetUpdate;
import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent;
@@ -108,7 +109,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetTagCreatedEvent.class, count = 1) }) @Expect(type = TargetTagCreatedEvent.class, count = 1) })
void entityQueriesReferringToNotExistingEntitiesThrowsException() { void entityQueriesReferringToNotExistingEntitiesThrowsException() {
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("A")); final TargetTag tag = targetTagManagement.create(TargetTagManagement.Create.builder().name("A").build());
final Target target = testdataFactory.createTarget(); final Target target = testdataFactory.createTarget();
verifyThrownExceptionBy( verifyThrownExceptionBy(
@@ -240,7 +241,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
assignTarget.add(targetManagement.create(entityFactory.target().create().controllerId("targetId1235")).getControllerId()); assignTarget.add(targetManagement.create(entityFactory.target().create().controllerId("targetId1235")).getControllerId());
assignTarget.add(targetManagement.create(entityFactory.target().create().controllerId("targetId1236")).getControllerId()); assignTarget.add(targetManagement.create(entityFactory.target().create().controllerId("targetId1236")).getControllerId());
final TargetTag targetTag = targetTagManagement.create(entityFactory.tag().create().name("Tag1")); final TargetTag targetTag = targetTagManagement.create(TargetTagManagement.Create.builder().name("Tag1").build());
final List<Target> assignedTargets = targetManagement.assignTag(assignTarget, targetTag.getId()); final List<Target> assignedTargets = targetManagement.assignTag(assignTarget, targetTag.getId());
assertThat(assignedTargets).as("Assigned targets are wrong").hasSize(4); assertThat(assignedTargets).as("Assigned targets are wrong").hasSize(4);
@@ -554,10 +555,10 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final List<Target> tagABCTargets = testdataFactory.createTargets(10, "tagABCTargets", "first description"); final List<Target> tagABCTargets = testdataFactory.createTargets(10, "tagABCTargets", "first description");
final TargetTag tagA = targetTagManagement.create(entityFactory.tag().create().name("A")); final TargetTag tagA = targetTagManagement.create(TargetTagManagement.Create.builder().name("A").build());
final TargetTag tagB = targetTagManagement.create(entityFactory.tag().create().name("B")); final TargetTag tagB = targetTagManagement.create(TargetTagManagement.Create.builder().name("B").build());
final TargetTag tagC = targetTagManagement.create(entityFactory.tag().create().name("C")); final TargetTag tagC = targetTagManagement.create(TargetTagManagement.Create.builder().name("C").build());
targetTagManagement.create(entityFactory.tag().create().name("X")); targetTagManagement.create(TargetTagManagement.Create.builder().name("X").build());
// doing different assignments // doing different assignments
assignTag(tagATargets, tagA); assignTag(tagATargets, tagA);
@@ -618,9 +619,9 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetCreatedEvent.class, count = 109), @Expect(type = TargetCreatedEvent.class, count = 109),
@Expect(type = TargetUpdatedEvent.class, count = 227) }) @Expect(type = TargetUpdatedEvent.class, count = 227) })
void targetTagBulkUnassignments() { void targetTagBulkUnassignments() {
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag")); final TargetTag targTagA = targetTagManagement.create(TargetTagManagement.Create.builder().name("Targ-A-Tag").build());
final TargetTag targTagB = targetTagManagement.create(entityFactory.tag().create().name("Targ-B-Tag")); final TargetTag targTagB = targetTagManagement.create(TargetTagManagement.Create.builder().name("Targ-B-Tag").build());
final TargetTag targTagC = targetTagManagement.create(entityFactory.tag().create().name("Targ-C-Tag")); final TargetTag targTagC = targetTagManagement.create(TargetTagManagement.Create.builder().name("Targ-C-Tag").build());
final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description"); final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description");
final List<Target> targBs = testdataFactory.createTargets(20, "target-id-B", "first description"); final List<Target> targBs = testdataFactory.createTargets(20, "target-id-B", "first description");
@@ -679,7 +680,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = TargetCreatedEvent.class, count = 50), @Expect(type = TargetCreatedEvent.class, count = 50),
@Expect(type = TargetUpdatedEvent.class, count = 25) }) @Expect(type = TargetUpdatedEvent.class, count = 25) })
void findTargetsWithNoTag() { void findTargetsWithNoTag() {
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag")); final TargetTag targTagA = targetTagManagement.create(TargetTagManagement.Create.builder().name("Targ-A-Tag").build());
final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description"); final List<Target> targAs = testdataFactory.createTargets(25, "target-id-A", "first description");
assignTag(targAs, targTagA); assignTag(targAs, targTagA);
@@ -721,7 +722,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void findTargetsWithTagOrId() { void findTargetsWithTagOrId() {
final String rsqlFilter = "tag==Targ-A-Tag,id==target-id-B-00001,id==target-id-B-00008"; final String rsqlFilter = "tag==Targ-A-Tag,id==target-id-B-00001,id==target-id-B-00008";
final TargetTag targTagA = targetTagManagement.create(entityFactory.tag().create().name("Targ-A-Tag")); final TargetTag targTagA = targetTagManagement.create(TargetTagManagement.Create.builder().name("Targ-A-Tag").build());
final List<String> targAs = testdataFactory.createTargets(25, "target-id-A", "first description").stream() final List<String> targAs = testdataFactory.createTargets(25, "target-id-A", "first description").stream()
.map(Target::getControllerId).toList(); .map(Target::getControllerId).toList();
targetManagement.assignTag(targAs, targTagA.getId()); targetManagement.assignTag(targAs, targTagA.getId());

View File

@@ -13,6 +13,7 @@ import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -36,7 +37,9 @@ class TargetTagManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createPermissionsCheck() { void createPermissionsCheck() {
assertPermissions(() -> targetTagManagement.create(entityFactory.tag().create().name("name")), List.of(SpPermission.CREATE_TARGET)); assertPermissions(
() -> targetTagManagement.create(TargetTagManagement.Create.builder().name("name").build()),
List.of(SpPermission.CREATE_TARGET));
} }
/** /**
@@ -44,7 +47,8 @@ class TargetTagManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createCollectionPermissionsCheck() { void createCollectionPermissionsCheck() {
assertPermissions(() -> targetTagManagement.create(List.of(entityFactory.tag().create().name("name"))), assertPermissions(
() -> targetTagManagement.create(List.of(TargetTagManagement.Create.builder().name("name").build())),
List.of(SpPermission.CREATE_TARGET)); List.of(SpPermission.CREATE_TARGET));
} }
@@ -54,7 +58,7 @@ class TargetTagManagementSecurityTest extends AbstractJpaIntegrationTest {
@Test @Test
void deletePermissionsCheck() { void deletePermissionsCheck() {
assertPermissions(() -> { assertPermissions(() -> {
targetTagManagement.delete("tag"); targetTagManagement.delete(1);
return null; return null;
}, List.of(SpPermission.DELETE_TARGET)); }, List.of(SpPermission.DELETE_TARGET));
} }
@@ -104,6 +108,6 @@ class TargetTagManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void updatePermissionsCheck() { void updatePermissionsCheck() {
assertPermissions(() -> targetTagManagement.update(entityFactory.tag().update(1L)), List.of(SpPermission.UPDATE_TARGET)); assertPermissions(() -> targetTagManagement.update(TargetTagManagement.Update.builder().id(1L).build()), List.of(SpPermission.UPDATE_TARGET));
} }
} }

View File

@@ -23,8 +23,8 @@ import java.util.Random;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.builder.TagCreate; import org.eclipse.hawkbit.repository.TargetTagManagement.Create;
import org.eclipse.hawkbit.repository.builder.TagUpdate; import org.eclipse.hawkbit.repository.TargetTagManagement.Update;
import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetTagUpdatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetTagUpdatedEvent;
@@ -59,7 +59,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
final Collection<String> group = testdataFactory.createTargets(5).stream() final Collection<String> group = testdataFactory.createTargets(5).stream()
.map(Target::getControllerId) .map(Target::getControllerId)
.toList(); .toList();
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1")); final TargetTag tag = targetTagManagement.create(Create.builder().name("tag1").description("tagdesc1").build());
final List<String> missing = new ArrayList<>(); final List<String> missing = new ArrayList<>();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
@@ -77,7 +77,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
.matches(e -> { .matches(e -> {
if (e instanceof EntityNotFoundException enfe if (e instanceof EntityNotFoundException enfe
&& enfe.getInfo().get(EntityNotFoundException.TYPE).equals(Target.class.getSimpleName()) && enfe.getInfo().get(EntityNotFoundException.TYPE).equals(Target.class.getSimpleName())
&& enfe.getInfo().get(EntityNotFoundException.ENTITY_ID) instanceof Collection entityId) { && enfe.getInfo().get(EntityNotFoundException.ENTITY_ID) instanceof Collection<?> entityId) {
return entityId.stream().sorted().toList().equals(missing); return entityId.stream().sorted().toList().equals(missing);
} }
return false; return false;
@@ -104,8 +104,8 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = DistributionSetTagUpdatedEvent.class), @Expect(type = DistributionSetTagUpdatedEvent.class),
@Expect(type = TargetTagUpdatedEvent.class) }) @Expect(type = TargetTagUpdatedEvent.class) })
void entityQueriesReferringToNotExistingEntitiesThrowsException() { void entityQueriesReferringToNotExistingEntitiesThrowsException() {
verifyThrownExceptionBy(() -> targetTagManagement.delete(NOT_EXIST_ID), "TargetTag"); verifyThrownExceptionBy(() -> targetTagManagement.delete(NOT_EXIST_IDL), "TargetTag");
verifyThrownExceptionBy(() -> targetTagManagement.update(entityFactory.tag().update(NOT_EXIST_IDL)), "TargetTag"); verifyThrownExceptionBy(() -> targetTagManagement.update(Update.builder().id(NOT_EXIST_IDL).build()), "TargetTag");
verifyThrownExceptionBy(() -> getTargetTags(NOT_EXIST_ID), "Target"); verifyThrownExceptionBy(() -> getTargetTags(NOT_EXIST_ID), "Target");
} }
@@ -114,7 +114,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createAndUpdateTagWithInvalidFields() { void createAndUpdateTagWithInvalidFields() {
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1")); final TargetTag tag = targetTagManagement.create(Create.builder().name("tag1").description("tagdesc1").build());
createAndUpdateTagWithInvalidDescription(tag); createAndUpdateTagWithInvalidDescription(tag);
createAndUpdateTagWithInvalidColour(tag); createAndUpdateTagWithInvalidColour(tag);
createAndUpdateTagWithInvalidName(tag); createAndUpdateTagWithInvalidName(tag);
@@ -128,7 +128,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
final List<Target> groupA = testdataFactory.createTargets(20); final List<Target> groupA = testdataFactory.createTargets(20);
final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb"); final List<Target> groupB = testdataFactory.createTargets(20, "groupb", "groupb");
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("tag1").description("tagdesc1")); final TargetTag tag = targetTagManagement.create(Create.builder().name("tag1").description("tagdesc1").build());
// toggle A only -> A is now assigned // toggle A only -> A is now assigned
List<Target> result = assignTag(groupA, tag); List<Target> result = assignTag(groupA, tag);
@@ -175,13 +175,10 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createTargetTag() { void createTargetTag() {
final Tag tag = targetTagManagement final Tag tag = targetTagManagement.create(Create.builder().name("k1").description("k2").colour("colour").build());
.create(entityFactory.tag().create().name("kai1").description("kai2").colour("colour")); assertThat(targetTagRepository.findByNameEquals("k1").orElseThrow().getDescription()).as("wrong tag ed").isEqualTo("k2");
assertThat(targetTagManagement.getByName("k1").orElseThrow().getColour()).as("wrong tag found").isEqualTo("colour");
assertThat(targetTagRepository.findByNameEquals("kai1").get().getDescription()).as("wrong tag ed") assertThat(targetTagManagement.get(tag.getId()).orElseThrow().getColour()).as("wrong tag found").isEqualTo("colour");
.isEqualTo("kai2");
assertThat(targetTagManagement.getByName("kai1").get().getColour()).as("wrong tag found").isEqualTo("colour");
assertThat(targetTagManagement.get(tag.getId()).get().getColour()).as("wrong tag found").isEqualTo("colour");
} }
/** /**
@@ -198,7 +195,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
} }
// delete // delete
targetTagManagement.delete(toDelete.getName()); targetTagManagement.delete(toDelete.getId());
// check // check
for (final Target target : targetRepository.findAll()) { for (final Target target : targetRepository.findAll()) {
@@ -220,13 +217,13 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
final TargetTag savedAssigned = tags.iterator().next(); final TargetTag savedAssigned = tags.iterator().next();
// persist // persist
targetTagManagement.update(entityFactory.tag().update(savedAssigned.getId()).name("test123")); targetTagManagement.update(Update.builder().id(savedAssigned.getId()).name("test123").build());
// check data // check data
assertThat(targetTagRepository.findAll()).as("Wrong target tag size").hasSize(tags.size()); assertThat(targetTagRepository.findAll()).as("Wrong target tag size").hasSize(tags.size());
assertThat(targetTagRepository.findById(savedAssigned.getId()).get().getName()).as("wrong target tag is saved") assertThat(targetTagRepository.findById(savedAssigned.getId()).orElseThrow().getName()).as("wrong target tag is saved")
.isEqualTo("test123"); .isEqualTo("test123");
assertThat(targetTagRepository.findById(savedAssigned.getId()).get().getOptLockRevision()) assertThat(targetTagRepository.findById(savedAssigned.getId()).orElseThrow().getOptLockRevision())
.as("wrong target tag is saved") .as("wrong target tag is saved")
.isEqualTo(2); .isEqualTo(2);
} }
@@ -236,7 +233,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void failedDuplicateTargetTagNameException() { void failedDuplicateTargetTagNameException() {
final TagCreate tagCreate = entityFactory.tag().create().name("A"); final Create tagCreate = Create.builder().name("A").build();
targetTagManagement.create(tagCreate); targetTagManagement.create(tagCreate);
assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> targetTagManagement.create(tagCreate)); assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> targetTagManagement.create(tagCreate));
} }
@@ -246,69 +243,68 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void failedDuplicateTargetTagNameExceptionAfterUpdate() { void failedDuplicateTargetTagNameExceptionAfterUpdate() {
targetTagManagement.create(entityFactory.tag().create().name("A")); targetTagManagement.create(Create.builder().name("A").build());
final TargetTag tag = targetTagManagement.create(entityFactory.tag().create().name("B")); final TargetTag tag = targetTagManagement.create(Create.builder().name("B").build());
final TagUpdate tagUpdate = entityFactory.tag().update(tag.getId()).name("A"); final Update tagUpdate = Update.builder().id(tag.getId()).name("A").build();
assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> targetTagManagement.update(tagUpdate)); assertThatExceptionOfType(EntityAlreadyExistsException.class).isThrownBy(() -> targetTagManagement.update(tagUpdate));
} }
private void createAndUpdateTagWithInvalidDescription(final Tag tag) { private void createAndUpdateTagWithInvalidDescription(final Tag tag) {
final TagCreate tagCraeteTooLong = entityFactory.tag().create().name("a").description(randomString(513)); final Create tagCreateTooLong = Create.builder().name("a").description(randomString(513)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too long description should not be created") .as("tag with too long description should not be created")
.isThrownBy(() -> targetTagManagement.create(tagCraeteTooLong)); .isThrownBy(() -> targetTagManagement.create(tagCreateTooLong));
final TagCreate tagCreateInvalidHtml = entityFactory.tag().create().name("a").description(INVALID_TEXT_HTML); final Create tagCreateInvalidHtml = Create.builder().name("a").description(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with invalid description should not be created") .as("tag with invalid description should not be created")
.isThrownBy(() -> targetTagManagement.create(tagCreateInvalidHtml)); .isThrownBy(() -> targetTagManagement.create(tagCreateInvalidHtml));
final TagUpdate tagUpdateTooLong = entityFactory.tag().update(tag.getId()).description(randomString(513)); final Update tagUpdateTooLong = Update.builder().id(tag.getId()).description(randomString(513)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too long description should not be updated") .as("tag with too long description should not be updated")
.isThrownBy(() -> targetTagManagement.update(tagUpdateTooLong)); .isThrownBy(() -> targetTagManagement.update(tagUpdateTooLong));
final TagUpdate tagUpdateInvalidHtml = entityFactory.tag().update(tag.getId()).description(INVALID_TEXT_HTML); final Update tagUpdateInvalidHtml = Update.builder().id(tag.getId()).description(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with invalid description should not be updated") .as("tag with invalid description should not be updated")
.isThrownBy(() -> targetTagManagement.update(tagUpdateInvalidHtml)); .isThrownBy(() -> targetTagManagement.update(tagUpdateInvalidHtml));
} }
private void createAndUpdateTagWithInvalidColour(final Tag tag) { private void createAndUpdateTagWithInvalidColour(final Tag tag) {
final TagCreate tagCreateTooLong = entityFactory.tag().create().name("a").colour(randomString(17)); final Create tagCreateTooLong = Create.builder().name("a").colour(randomString(17)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too long colour should not be created") .as("tag with too long colour should not be created")
.isThrownBy(() -> targetTagManagement.create(tagCreateTooLong)); .isThrownBy(() -> targetTagManagement.create(tagCreateTooLong));
final TagCreate tagCraeteInvalidHtml = entityFactory.tag().create().name("a").colour(INVALID_TEXT_HTML); final Create tagCreateInvalidHtml = Create.builder().name("a").colour(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with invalid colour should not be created") .as("tag with invalid colour should not be created")
.isThrownBy(() -> targetTagManagement.create(tagCraeteInvalidHtml)); .isThrownBy(() -> targetTagManagement.create(tagCreateInvalidHtml));
final TagUpdate tagUpdateTooLong = entityFactory.tag().update(tag.getId()).colour(randomString(17)); final Update tagUpdateTooLong = Update.builder().id(tag.getId()).colour(randomString(17)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too long colour should not be updated") .as("tag with too long colour should not be updated")
.isThrownBy(() -> targetTagManagement.update(tagUpdateTooLong)); .isThrownBy(() -> targetTagManagement.update(tagUpdateTooLong));
final TagUpdate tagUpdateInvalidHtml = entityFactory.tag().update(tag.getId()).colour(INVALID_TEXT_HTML); final Update tagUpdateInvalidHtml = Update.builder().id(tag.getId()).colour(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with invalid colour should not be updated") .as("tag with invalid colour should not be updated")
.isThrownBy(() -> targetTagManagement .isThrownBy(() -> targetTagManagement.update(tagUpdateInvalidHtml));
.update(tagUpdateInvalidHtml));
} }
private void createAndUpdateTagWithInvalidName(final Tag tag) { private void createAndUpdateTagWithInvalidName(final Tag tag) {
final TagCreate tagCreateTooLong = entityFactory.tag().create().name(randomString(NamedEntity.NAME_MAX_SIZE + 1)); final Create tagCreateTooLong = Create.builder().name(randomString(NamedEntity.NAME_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too long name should not be created") .as("tag with too long name should not be created")
.isThrownBy(() -> targetTagManagement.create(tagCreateTooLong)); .isThrownBy(() -> targetTagManagement.create(tagCreateTooLong));
final TagCreate tagCreateInvalidHtml = entityFactory.tag().create().name(INVALID_TEXT_HTML); final Create tagCreateInvalidHtml = Create.builder().name(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with invalid name should not be created") .as("tag with invalid name should not be created")
.isThrownBy(() -> targetTagManagement.create(tagCreateInvalidHtml)); .isThrownBy(() -> targetTagManagement.create(tagCreateInvalidHtml));
final TagUpdate tagUpdateTooLong = entityFactory.tag().update(tag.getId()).name(randomString(NamedEntity.NAME_MAX_SIZE + 1)); final Update tagUpdateTooLong = Update.builder().id(tag.getId()).name(randomString(NamedEntity.NAME_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too long name should not be updated") .as("tag with too long name should not be updated")
.isThrownBy(() -> targetTagManagement.update(tagUpdateTooLong)); .isThrownBy(() -> targetTagManagement.update(tagUpdateTooLong));
final TagUpdate tagUpdateInvalidHtml = entityFactory.tag().update(tag.getId()).name(INVALID_TEXT_HTML); final Update tagUpdateInvalidHtml = Update.builder().id(tag.getId()).name(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class).as("tag with invalid name should not be updated") assertThatExceptionOfType(ConstraintViolationException.class).as("tag with invalid name should not be updated")
.isThrownBy(() -> targetTagManagement.update(tagUpdateInvalidHtml)); .isThrownBy(() -> targetTagManagement.update(tagUpdateInvalidHtml));
final TagUpdate tagUpdateEmpty = entityFactory.tag().update(tag.getId()).name(""); final Update tagUpdateEmpty = Update.builder().id(tag.getId()).name("").build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("tag with too short name should not be updated") .as("tag with too short name should not be updated")
.isThrownBy(() -> targetTagManagement.update(tagUpdateEmpty)); .isThrownBy(() -> targetTagManagement.update(tagUpdateEmpty));

View File

@@ -13,6 +13,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.TagFields; import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
@@ -30,8 +31,8 @@ class RsqlTagFieldsTest extends AbstractJpaIntegrationTest {
@BeforeEach @BeforeEach
void seuptBeforeTest() { void seuptBeforeTest() {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
targetTagManagement.create(entityFactory.tag().create() targetTagManagement.create(TargetTagManagement.Create.builder()
.name(Integer.toString(i)).description(Integer.toString(i)).colour(i % 2 == 0 ? "red" : "blue")); .name(Integer.toString(i)).description(Integer.toString(i)).colour(i % 2 == 0 ? "red" : "blue").build());
distributionSetTagManagement.create(DistributionSetTagManagement.Create.builder() distributionSetTagManagement.create(DistributionSetTagManagement.Create.builder()
.name(Integer.toString(i)).description(Integer.toString(i)).colour(i % 2 == 0 ? "red" : "blue").build()); .name(Integer.toString(i)).description(Integer.toString(i)).colour(i % 2 == 0 ? "red" : "blue").build());
} }
@@ -135,7 +136,7 @@ class RsqlTagFieldsTest extends AbstractJpaIntegrationTest {
} }
private void assertRSQLQueryTarget(final String rsql, final long expectedEntities) { private void assertRSQLQueryTarget(final String rsql, final long expectedEntities) {
final Page<TargetTag> findEntity = targetTagManagement.findByRsql(rsql, PageRequest.of(0, 100)); final Page<? extends TargetTag> findEntity = targetTagManagement.findByRsql(rsql, PageRequest.of(0, 100));
final long countAllEntities = findEntity.getTotalElements(); final long countAllEntities = findEntity.getTotalElements();
assertThat(findEntity).isNotNull(); assertThat(findEntity).isNotNull();
assertThat(countAllEntities).isEqualTo(expectedEntities); assertThat(countAllEntities).isEqualTo(expectedEntities);

View File

@@ -18,6 +18,7 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetFields;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.TargetTypeFields; import org.eclipse.hawkbit.repository.TargetTypeFields;
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
@@ -59,10 +60,10 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest {
final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs"); final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs");
final TargetTag targetTag = targetTagManagement.create(entityFactory.tag().create().name("Tag1")); final TargetTag targetTag = targetTagManagement.create(TargetTagManagement.Create.builder().name("Tag1").build());
final TargetTag targetTag2 = targetTagManagement.create(entityFactory.tag().create().name("Tag2")); final TargetTag targetTag2 = targetTagManagement.create(TargetTagManagement.Create.builder().name("Tag2").build());
final TargetTag targetTag3 = targetTagManagement.create(entityFactory.tag().create().name("Tag3")); final TargetTag targetTag3 = targetTagManagement.create(TargetTagManagement.Create.builder().name("Tag3").build());
targetTagManagement.create(entityFactory.tag().create().name("Tag4")); targetTagManagement.create(TargetTagManagement.Create.builder().name("Tag4").build());
target = targetManagement.create( target = targetManagement.create(
entityFactory.target().create() entityFactory.target().create()

View File

@@ -66,6 +66,7 @@ import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.test.TestConfiguration; import org.eclipse.hawkbit.repository.test.TestConfiguration;
import org.eclipse.hawkbit.repository.test.matcher.EventVerifier; import org.eclipse.hawkbit.repository.test.matcher.EventVerifier;
import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.security.SystemSecurityContext;
@@ -144,7 +145,7 @@ public abstract class AbstractIntegrationTest {
@Autowired @Autowired
protected TargetFilterQueryManagement targetFilterQueryManagement; protected TargetFilterQueryManagement targetFilterQueryManagement;
@Autowired @Autowired
protected TargetTagManagement targetTagManagement; protected TargetTagManagement<? extends TargetTag> targetTagManagement;
@Autowired @Autowired
protected DeploymentManagement deploymentManagement; protected DeploymentManagement deploymentManagement;
@Autowired @Autowired

View File

@@ -49,7 +49,6 @@ import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement; import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.TargetTypeManagement; import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.builder.DynamicRolloutGroupTemplate; import org.eclipse.hawkbit.repository.builder.DynamicRolloutGroupTemplate;
import org.eclipse.hawkbit.repository.builder.TagCreate;
import org.eclipse.hawkbit.repository.builder.TargetCreate; import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.builder.TargetTypeCreate;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
@@ -914,9 +913,9 @@ public class TestdataFactory {
* @return the created set of {@link TargetTag}s * @return the created set of {@link TargetTag}s
*/ */
public List<TargetTag> createTargetTags(final int number, final String tagPrefix) { public List<TargetTag> createTargetTags(final int number, final String tagPrefix) {
final List<TagCreate<Tag>> result = new ArrayList<>(number); final List<TargetTagManagement.Create> result = new ArrayList<>(number);
for (int i = 0; i < number; i++) { for (int i = 0; i < number; i++) {
result.add(entityFactory.tag().create().name(tagPrefix + i).description(tagPrefix + i).colour(String.valueOf(i))); result.add(TargetTagManagement.Create.builder().name(tagPrefix + i).description(tagPrefix + i).colour(String.valueOf(i)).build());
} }
return targetTagManagement.create(result); return targetTagManagement.create(result);
} }

View File

@@ -19,9 +19,11 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement; import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement; import org.eclipse.hawkbit.repository.SoftwareModuleTypeManagement;
import org.eclipse.hawkbit.repository.TargetTagManagement;
import org.eclipse.hawkbit.repository.model.RolloutGroup; import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder; import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions; import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
@@ -72,6 +74,59 @@ public class JsonBuilder {
return builder.toString(); return builder.toString();
} }
public static String targetTag(final TargetTagManagement.Update dsTagUpdate) throws JSONException {
final StringBuilder builder = new StringBuilder();
builder.append(new JSONObject()
.put("name", dsTagUpdate.getName()).put("description", dsTagUpdate.getDescription())
.put("colour", dsTagUpdate.getColour()).toString());
return builder.toString();
}
public static String targetTags(final List<TargetTagManagement.Create> dsTagsCreate) throws JSONException {
final StringBuilder builder = new StringBuilder();
builder.append("[");
int i = 0;
for (final TargetTagManagement.Create tag : dsTagsCreate) {
builder.append(new JSONObject()
.put("name", tag.getName()).put("description", tag.getDescription())
.put("colour", tag.getColour()).toString());
if (++i < dsTagsCreate.size()) {
builder.append(",");
}
}
builder.append("]");
return builder.toString();
}
public static String dsTag(final DistributionSetTagManagement.Update dsTagUpdate) throws JSONException {
final StringBuilder builder = new StringBuilder();
builder.append(new JSONObject()
.put("name", dsTagUpdate.getName()).put("description", dsTagUpdate.getDescription())
.put("colour", dsTagUpdate.getColour()).toString());
return builder.toString();
}
public static String dsTags(final List<DistributionSetTagManagement.Create> dsTagsCreate) throws JSONException {
final StringBuilder builder = new StringBuilder();
builder.append("[");
int i = 0;
for (final DistributionSetTagManagement.Create tag : dsTagsCreate) {
builder.append(new JSONObject()
.put("name", tag.getName()).put("description", tag.getDescription())
.put("colour", tag.getColour()).toString());
if (++i < dsTagsCreate.size()) {
builder.append(",");
}
}
builder.append("]");
return builder.toString();
}
public static String tag(final Tag tag) throws JSONException { public static String tag(final Tag tag) throws JSONException {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();