TargetType management over common RepositoryManagement (#2581)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-08-01 19:24:49 +03:00
committed by GitHub
parent c79e35b9de
commit a689733d4c
40 changed files with 435 additions and 762 deletions

View File

@@ -25,13 +25,12 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtDistributionSetTypeMapper; import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtDistributionSetTypeMapper;
import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTargetTypeMapper; import org.eclipse.hawkbit.mgmt.rest.resource.mapper.MgmtTargetTypeMapper;
import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility; import org.eclipse.hawkbit.mgmt.rest.resource.util.PagingUtility;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.TargetTypeManagement; import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.TargetTypeManagement.Update;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetType;
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;
@@ -43,30 +42,28 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi { public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi {
private final TargetTypeManagement targetTypeManagement; private final TargetTypeManagement<? extends TargetType> targetTypeManagement;
private final EntityFactory entityFactory; private final MgmtTargetTypeMapper mgmtTargetTypeMapper;
public MgmtTargetTypeResource(final TargetTypeManagement targetTypeManagement, final EntityFactory entityFactory) { public MgmtTargetTypeResource(
final TargetTypeManagement<? extends TargetType> targetTypeManagement, final MgmtTargetTypeMapper mgmtTargetTypeMapper) {
this.targetTypeManagement = targetTypeManagement; this.targetTypeManagement = targetTypeManagement;
this.entityFactory = entityFactory; this.mgmtTargetTypeMapper = mgmtTargetTypeMapper;
} }
@Override @Override
public ResponseEntity<PagedList<MgmtTargetType>> getTargetTypes( public ResponseEntity<PagedList<MgmtTargetType>> getTargetTypes(
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, sanitizeTargetTypeSortParam(sortParam)); final Pageable pageable = PagingUtility.toPageable(pagingOffsetParam, pagingLimitParam, sanitizeTargetTypeSortParam(sortParam));
final Slice<TargetType> findTargetTypesAll; final Page<? extends TargetType> findTargetTypesAll;
long countTargetTypesAll;
if (rsqlParam != null) { if (rsqlParam != null) {
findTargetTypesAll = targetTypeManagement.findByRsql(rsqlParam, pageable); findTargetTypesAll = targetTypeManagement.findByRsql(rsqlParam, pageable);
countTargetTypesAll = ((Page<TargetType>) findTargetTypesAll).getTotalElements();
} else { } else {
findTargetTypesAll = targetTypeManagement.findAll(pageable); findTargetTypesAll = targetTypeManagement.findAll(pageable);
countTargetTypesAll = targetTypeManagement.count();
} }
final List<MgmtTargetType> rest = MgmtTargetTypeMapper.toListResponse(findTargetTypesAll.getContent()); final List<MgmtTargetType> rest = MgmtTargetTypeMapper.toListResponse(findTargetTypesAll.getContent());
return ResponseEntity.ok(new PagedList<>(rest, countTargetTypesAll)); return ResponseEntity.ok(new PagedList<>(rest, targetTypeManagement.count()));
} }
@Override @Override
@@ -88,8 +85,9 @@ public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi {
@Override @Override
public ResponseEntity<MgmtTargetType> updateTargetType(final Long targetTypeId, final MgmtTargetTypeRequestBodyPut restTargetType) { public ResponseEntity<MgmtTargetType> updateTargetType(final Long targetTypeId, final MgmtTargetTypeRequestBodyPut restTargetType) {
final TargetType updated = targetTypeManagement final TargetType updated = targetTypeManagement
.update(entityFactory.targetType().update(targetTypeId).name(restTargetType.getName()) .update(Update.builder().id(targetTypeId)
.description(restTargetType.getDescription()).colour(restTargetType.getColour())); .name(restTargetType.getName()).description(restTargetType.getDescription()).colour(restTargetType.getColour())
.build());
final MgmtTargetType response = MgmtTargetTypeMapper.toResponse(updated); final MgmtTargetType response = MgmtTargetTypeMapper.toResponse(updated);
MgmtTargetTypeMapper.addLinks(response); MgmtTargetTypeMapper.addLinks(response);
return ResponseEntity.ok(response); return ResponseEntity.ok(response);
@@ -97,15 +95,14 @@ public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi {
@Override @Override
public ResponseEntity<List<MgmtTargetType>> createTargetTypes(final List<MgmtTargetTypeRequestBodyPost> targetTypes) { public ResponseEntity<List<MgmtTargetType>> createTargetTypes(final List<MgmtTargetTypeRequestBodyPost> targetTypes) {
final List<TargetType> createdTargetTypes = targetTypeManagement final List<? extends TargetType> createdTargetTypes = targetTypeManagement.create(mgmtTargetTypeMapper.targetFromRequest(targetTypes));
.create(MgmtTargetTypeMapper.targetFromRequest(entityFactory, targetTypes));
return ResponseEntity.status(HttpStatus.CREATED).body(MgmtTargetTypeMapper.toListResponse(createdTargetTypes)); return ResponseEntity.status(HttpStatus.CREATED).body(MgmtTargetTypeMapper.toListResponse(createdTargetTypes));
} }
@Override @Override
public ResponseEntity<List<MgmtDistributionSetType>> getCompatibleDistributionSets(final Long targetTypeId) { public ResponseEntity<List<MgmtDistributionSetType>> getCompatibleDistributionSets(final Long targetTypeId) {
final TargetType foundType = findTargetTypeWithExceptionIfNotFound(targetTypeId); final TargetType foundType = findTargetTypeWithExceptionIfNotFound(targetTypeId);
return ResponseEntity.ok(MgmtDistributionSetTypeMapper.toListResponse(foundType.getCompatibleDistributionSetTypes())); return ResponseEntity.ok(MgmtDistributionSetTypeMapper.toListResponse(foundType.getDistributionSetTypes()));
} }
@Override @Override

View File

@@ -16,36 +16,46 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetTypeAssignment; import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetTypeAssignment;
import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetType; import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetType;
import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetTypeRequestBodyPost; import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetTypeRequestBodyPost;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi; import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.rest.json.model.ResponseList; import org.eclipse.hawkbit.rest.json.model.ResponseList;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
/** /**
* A mapper which maps repository model to RESTful model representation and back. * A mapper which maps repository model to RESTful model representation and back.
*/ */
@NoArgsConstructor(access = AccessLevel.PRIVATE) @Service
public final class MgmtTargetTypeMapper { public final class MgmtTargetTypeMapper {
public static List<TargetTypeCreate> targetFromRequest( private final DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement;
final EntityFactory entityFactory, final Collection<MgmtTargetTypeRequestBodyPost> targetTypesRest) {
public MgmtTargetTypeMapper(final DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement) {
this.distributionSetTypeManagement = distributionSetTypeManagement;
}
public List<TargetTypeManagement.Create> targetFromRequest(final Collection<MgmtTargetTypeRequestBodyPost> targetTypesRest) {
if (targetTypesRest == null) { if (targetTypesRest == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
return targetTypesRest.stream() return targetTypesRest.stream()
.map(targetRest -> fromRequest(entityFactory, targetRest)) .map(this::fromRequest)
.toList(); .toList();
} }
public static List<MgmtTargetType> toListResponse(final List<TargetType> types) { public static List<MgmtTargetType> toListResponse(final List<? extends TargetType> types) {
if (types == null) { if (types == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -67,17 +77,31 @@ public final class MgmtTargetTypeMapper {
.withRel(MgmtRestConstants.TARGETTYPE_V1_DS_TYPES).expand()); .withRel(MgmtRestConstants.TARGETTYPE_V1_DS_TYPES).expand());
} }
private static TargetTypeCreate fromRequest(final EntityFactory entityFactory, private TargetTypeManagement.Create fromRequest(final MgmtTargetTypeRequestBodyPost targetTypesRest) {
final MgmtTargetTypeRequestBodyPost targetTypesRest) { return TargetTypeManagement.Create.builder()
return entityFactory.targetType().create()
.name(targetTypesRest.getName()).description(targetTypesRest.getDescription()) .name(targetTypesRest.getName()).description(targetTypesRest.getDescription())
.key(targetTypesRest.getKey()).colour(targetTypesRest.getColour()) .key(targetTypesRest.getKey()).colour(targetTypesRest.getColour())
.compatible(getDistributionSets(targetTypesRest)); .distributionSetTypes(getDistributionSets(targetTypesRest))
.build();
} }
private static Collection<Long> getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) { private Set<DistributionSetType> getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) {
return Optional.ofNullable(targetTypesRest.getCompatibledistributionsettypes()) return Optional.ofNullable(targetTypesRest.getCompatibledistributionsettypes())
.map(ds -> ds.stream().map(MgmtDistributionSetTypeAssignment::getId).toList()) .map(compatibleDs -> compatibleDs.stream().map(MgmtDistributionSetTypeAssignment::getId).toList())
.orElse(Collections.emptyList()); .map(this::getDistributionSetTypes)
.orElse(Collections.emptySet());
}
private Set<DistributionSetType> getDistributionSetTypes(final Collection<Long> distributionSetTypeId) {
if (CollectionUtils.isEmpty(distributionSetTypeId)) {
return Collections.emptySet();
}
final Collection<? extends DistributionSetType> type = distributionSetTypeManagement.get(distributionSetTypeId);
if (type.size() < distributionSetTypeId.size()) {
throw new EntityNotFoundException(SoftwareModuleType.class, distributionSetTypeId);
}
return type.stream().map(DistributionSetType.class::cast).collect(Collectors.toSet());
} }
} }

View File

@@ -39,6 +39,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
@@ -54,6 +55,8 @@ 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.ActionFields; import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.Identifiable; import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.TargetTypeManagement.Create;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate; import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
@@ -152,8 +155,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
final String knownNameNotModify = "controllerName"; final String knownNameNotModify = "controllerName";
final Long unassignTargetTypeValue = -1L; final Long unassignTargetTypeValue = -1L;
final TargetType targetType = targetTypeManagement.create( final TargetType targetType = targetTypeManagement.create(Create.builder().name("targettype1").description("targettypedes1").build());
entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
final String body = new JSONObject().put("targetType", unassignTargetTypeValue).toString(); final String body = new JSONObject().put("targetType", unassignTargetTypeValue).toString();
@@ -192,8 +194,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
final Long unassignTargetTypeValue = -1L; final Long unassignTargetTypeValue = -1L;
final String controllerNewName = "controllerNewName"; final String controllerNewName = "controllerNewName";
final TargetType targetType = targetTypeManagement.create( final TargetType targetType = targetTypeManagement.create(Create.builder().name("targettype1").description("targettypedes1").build());
entityFactory.targetType().create().name("targettype1").description("targettypedes1"));
final String body = new JSONObject() final String body = new JSONObject()
.put("targetType", unassignTargetTypeValue).put("name", "controllerNewName") .put("targetType", unassignTargetTypeValue).put("name", "controllerNewName")
@@ -2077,7 +2078,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.hasSize(0))); .andExpect(jsonPath("$", Matchers.hasSize(0)));
final List<TargetTag> targetTags = testdataFactory.createTargetTags(2, "tag_getControllerTagReturnsTagWithOk"); final List<? extends TargetTag> targetTags = testdataFactory.createTargetTags(2, "tag_getControllerTagReturnsTagWithOk");
final List<String> tagNames = new ArrayList<>(); final List<String> tagNames = new ArrayList<>();
for (final TargetTag targetTag : targetTags) { for (final TargetTag targetTag : targetTags) {
targetManagement.assignTag(Collections.singletonList(target.getControllerId()), targetTag.getId()); targetManagement.assignTag(Collections.singletonList(target.getControllerId()), targetTag.getId());
@@ -2459,10 +2460,8 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
*/ */
@Test @Test
void createTargetsWithTargetType() throws Exception { void createTargetsWithTargetType() throws Exception {
final TargetType type1 = testdataFactory.createTargetType("typeWithDs", final TargetType type1 = testdataFactory.createTargetType("typeWithDs", Set.of(standardDsType));
Collections.singletonList(standardDsType)); final TargetType type2 = testdataFactory.createTargetType("typeWithOutDs", Set.of(standardDsType));
final TargetType type2 = testdataFactory.createTargetType("typeWithOutDs",
Collections.singletonList(standardDsType));
final Target test1 = entityFactory.target().create().controllerId("id1").name("targetWithoutType") final Target test1 = entityFactory.target().create().controllerId("id1").name("targetWithoutType")
.securityToken("token").address("amqp://test123/foobar").description("testid1").build(); .securityToken("token").address("amqp://test123/foobar").description("testid1").build();
@@ -2531,7 +2530,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
void createTargetWithExistingTargetType() throws Exception { void createTargetWithExistingTargetType() throws Exception {
// create target type // create target type
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 1); final List<? extends TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 1);
assertThat(targetTypes).hasSize(1); assertThat(targetTypes).hasSize(1);
final Target target = entityFactory.target().create().controllerId("targetcontroller").name("testtarget") final Target target = entityFactory.target().create().controllerId("targetcontroller").name("testtarget")
@@ -2556,7 +2555,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
void updateTargetTypeInTarget() throws Exception { void updateTargetTypeInTarget() throws Exception {
// create target type // create target type
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2); final List<? extends TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2);
assertThat(targetTypes).hasSize(2); assertThat(targetTypes).hasSize(2);
final String controllerId = "targetcontroller"; final String controllerId = "targetcontroller";
@@ -2581,10 +2580,9 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
void addingNonExistingTargetTypeInTargetShouldFail() throws Exception { void addingNonExistingTargetTypeInTargetShouldFail() throws Exception {
final long unknownTargetTypeId = 999; final long unknownTargetTypeId = 999;
final String errorMsg = String.format("TargetType with given identifier {%s} does not exist.", final String errorMsg = String.format("TargetType with given identifier {%s} does not exist.", unknownTargetTypeId);
unknownTargetTypeId);
final Optional<TargetType> targetType = targetTypeManagement.get(unknownTargetTypeId); final Optional<? extends TargetType> targetType = targetTypeManagement.get(unknownTargetTypeId);
assertThat(targetType).isNotPresent(); assertThat(targetType).isNotPresent();
final String controllerId = "targetcontroller"; final String controllerId = "targetcontroller";
@@ -2664,7 +2662,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
void unassignTargetTypeFromTarget() throws Exception { void unassignTargetTypeFromTarget() throws Exception {
// create target type // create target type
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 1); final List<? extends TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 1);
assertThat(targetTypes).hasSize(1); assertThat(targetTypes).hasSize(1);
final String targetControllerId = "targetcontroller"; final String targetControllerId = "targetcontroller";
@@ -2686,7 +2684,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest {
void invalidRequestsOnTargetTypeResource() throws Exception { void invalidRequestsOnTargetTypeResource() throws Exception {
final String knownTargetId = "targetId"; final String knownTargetId = "targetId";
testdataFactory.createTarget(knownTargetId); testdataFactory.createTarget(knownTargetId);
testdataFactory.createTargetType("targettype", Collections.emptyList()); testdataFactory.createTargetType("targettype", Set.of());
// GET is not allowed // GET is not allowed
mvc.perform(get( mvc.perform(get(

View File

@@ -66,7 +66,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Test @Test
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) }) @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) })
public void getTargetTags() throws Exception { public void getTargetTags() throws Exception {
final List<TargetTag> tags = testdataFactory.createTargetTags(2, ""); final List<? extends TargetTag> tags = testdataFactory.createTargetTags(2, "");
final TargetTag assigned = tags.get(0); final TargetTag assigned = tags.get(0);
final TargetTag unassigned = tags.get(1); final TargetTag unassigned = tags.get(1);
@@ -105,7 +105,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
testdataFactory.createTarget(controllerId1); testdataFactory.createTarget(controllerId1);
testdataFactory.createTarget(controllerId2); testdataFactory.createTarget(controllerId2);
final List<TargetTag> tags = testdataFactory.createTargetTags(2, ""); final List<? extends TargetTag> tags = testdataFactory.createTargetTags(2, "");
final TargetTag tag1 = tags.get(0); final TargetTag tag1 = tags.get(0);
final TargetTag tag2 = tags.get(1); final TargetTag tag2 = tags.get(1);
@@ -133,7 +133,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Test @Test
@ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) }) @ExpectEvents({ @Expect(type = TargetTagCreatedEvent.class, count = 2) })
public void getTargetTag() throws Exception { public void getTargetTag() throws Exception {
final List<TargetTag> tags = testdataFactory.createTargetTags(2, ""); final List<? extends TargetTag> tags = testdataFactory.createTargetTags(2, "");
final TargetTag assigned = tags.get(0); final TargetTag assigned = tags.get(0);
mvc.perform(get(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + assigned.getId()) mvc.perform(get(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + assigned.getId())
@@ -190,7 +190,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetTagCreatedEvent.class, count = 1),
@Expect(type = TargetTagUpdatedEvent.class, count = 1) }) @Expect(type = TargetTagUpdatedEvent.class, count = 1) })
public void updateTargetTag() throws Exception { public void updateTargetTag() throws Exception {
final List<TargetTag> tags = testdataFactory.createTargetTags(1, ""); final List<? extends TargetTag> tags = testdataFactory.createTargetTags(1, "");
final TargetTag original = tags.get(0); final TargetTag original = tags.get(0);
final TargetTagManagement.Update update = TargetTagManagement.Update.builder() final TargetTagManagement.Update update = TargetTagManagement.Update.builder()
@@ -222,7 +222,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT
@Expect(type = TargetTagCreatedEvent.class, count = 1), @Expect(type = TargetTagCreatedEvent.class, count = 1),
@Expect(type = TargetTagDeletedEvent.class, count = 1) }) @Expect(type = TargetTagDeletedEvent.class, count = 1) })
public void deleteTargetTag() throws Exception { public void deleteTargetTag() throws Exception {
final List<TargetTag> tags = testdataFactory.createTargetTags(1, ""); final List<? extends TargetTag> tags = testdataFactory.createTargetTags(1, "");
final TargetTag original = tags.get(0); final TargetTag original = tags.get(0);
mvc.perform(delete(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + original.getId())) mvc.perform(delete(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/" + original.getId()))

View File

@@ -28,12 +28,14 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.JsonPath;
import org.eclipse.hawkbit.exception.SpServerError; import org.eclipse.hawkbit.exception.SpServerError;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.TargetTypeManagement.Create;
import org.eclipse.hawkbit.repository.TargetTypeManagement.Update;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity; import org.eclipse.hawkbit.repository.model.NamedEntity;
@@ -115,7 +117,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
void getTargetTypes() throws Exception { void getTargetTypes() throws Exception {
String typeName = "TestTypeGET"; String typeName = "TestTypeGET";
int count = 5; int count = 5;
List<TargetType> testTypes = createTestTargetTypesInDB(typeName, count); final List<? extends TargetType> testTypes = createTestTargetTypesInDB(typeName, count);
ResultActions resultActions = mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON)) ResultActions resultActions = mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()); .andDo(MockMvcResultPrinter.print());
@@ -178,7 +180,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
TargetType testTypeA = createTestTargetTypeInDB(typeNameA); TargetType testTypeA = createTestTargetTypeInDB(typeNameA);
testTypeA = targetTypeManagement testTypeA = targetTypeManagement
.update(entityFactory.targetType().update(testTypeA.getId()).description("Updated description")); .update(Update.builder().id(testTypeA.getId()).description("Updated description").build());
// descending // descending
mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON) mvc.perform(get(TARGETTYPES_ENDPOINT).accept(MediaType.APPLICATION_JSON)
@@ -303,8 +305,9 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
final String initialTypeName = "TestTypeGET"; final String initialTypeName = "TestTypeGET";
TargetType testType = createTestTargetTypeInDB(initialTypeName); TargetType testType = createTestTargetTypeInDB(initialTypeName);
final String typeNameUpdated = "TestTypeGETupdated"; final String typeNameUpdated = "TestTypeGETupdated";
testType = targetTypeManagement.update(entityFactory.targetType().update(testType.getId()).name(typeNameUpdated) testType = targetTypeManagement.update(Update.builder().id(testType.getId())
.description("Updated Description").colour("#ffffff")); .name(typeNameUpdated).description("Updated Description").colour("#ffffff")
.build());
mvc.perform(get(TARGETTYPE_SINGLE_ENDPOINT, testType.getId()).accept(MediaType.APPLICATION_JSON)) mvc.perform(get(TARGETTYPE_SINGLE_ENDPOINT, testType.getId()).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
@@ -328,7 +331,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
@WithUser(principal = TEST_USER, allSpPermissions = true) @WithUser(principal = TEST_USER, allSpPermissions = true)
void createTargetTypes() throws Exception { void createTargetTypes() throws Exception {
String typeName = "TestTypePOST"; String typeName = "TestTypePOST";
final List<TargetType> types = buildTestTargetTypesWithoutDsTypes(typeName, 5); final List<Create> types = buildTestTargetTypesWithoutDsTypes(typeName, 5);
runPostTargetTypeAndVerify(types); runPostTargetTypeAndVerify(types);
} }
@@ -351,7 +354,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
testType = targetTypeManagement.get(testType.getId()).get(); testType = targetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo(TEST_USER); assertThat(testType.getLastModifiedBy()).isEqualTo(TEST_USER);
assertThat(testType.getOptLockRevision()).isEqualTo(2); assertThat(testType.getOptLockRevision()).isEqualTo(2);
assertThat(testType.getCompatibleDistributionSetTypes()).containsExactly(standardDsType); assertThat(testType.getDistributionSetTypes()).containsExactly(standardDsType);
} }
/** /**
@@ -361,7 +364,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
@WithUser(principal = TEST_USER, allSpPermissions = true) @WithUser(principal = TEST_USER, allSpPermissions = true)
void getDistributionSetsOfTargetType() throws Exception { void getDistributionSetsOfTargetType() throws Exception {
String typeName = "TestTypeGetDs"; String typeName = "TestTypeGetDs";
final TargetType testType = createTestTargetTypeInDB(typeName, Collections.singletonList(standardDsType)); final TargetType testType = createTestTargetTypeInDB(typeName, Set.of(standardDsType));
mvc.perform(get(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()).accept(MediaType.APPLICATION_JSON)) mvc.perform(get(TARGETTYPE_DSTYPES_ENDPOINT, testType.getId()).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
@@ -397,7 +400,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
@WithUser(principal = TEST_USER, allSpPermissions = true) @WithUser(principal = TEST_USER, allSpPermissions = true)
void removeDsTypeFromTargetType() throws Exception { void removeDsTypeFromTargetType() throws Exception {
String typeName = "TestTypeRemoveDs"; String typeName = "TestTypeRemoveDs";
TargetType testType = createTestTargetTypeInDB(typeName, Collections.singletonList(standardDsType)); TargetType testType = createTestTargetTypeInDB(typeName, Set.of(standardDsType));
mvc.perform(delete(TARGETTYPE_DSTYPE_SINGLE_ENDPOINT, testType.getId(), standardDsType.getId()) mvc.perform(delete(TARGETTYPE_DSTYPE_SINGLE_ENDPOINT, testType.getId(), standardDsType.getId())
.contentType(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON))
@@ -407,7 +410,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
testType = targetTypeManagement.get(testType.getId()).get(); testType = targetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo(TEST_USER); assertThat(testType.getLastModifiedBy()).isEqualTo(TEST_USER);
assertThat(testType.getOptLockRevision()).isEqualTo(2); assertThat(testType.getOptLockRevision()).isEqualTo(2);
assertThat(testType.getCompatibleDistributionSetTypes()).isEmpty(); assertThat(testType.getDistributionSetTypes()).isEmpty();
} }
/** /**
@@ -416,8 +419,8 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
@WithUser(principal = TEST_USER, allSpPermissions = true) @WithUser(principal = TEST_USER, allSpPermissions = true)
void deletingDsTypeRemovesAssignmentFromTargetType() throws Exception { void deletingDsTypeRemovesAssignmentFromTargetType() throws Exception {
TargetType testType = createTestTargetTypeInDB("TestTypeRemoveDs", Collections.singletonList(standardDsType)); TargetType testType = createTestTargetTypeInDB("TestTypeRemoveDs", Set.of(standardDsType));
assertThat(testType.getCompatibleDistributionSetTypes()).hasSize(1); assertThat(testType.getDistributionSetTypes()).hasSize(1);
assertThat(distributionSetTypeManagement.findByKey(standardDsType.getKey())).isNotEmpty(); assertThat(distributionSetTypeManagement.findByKey(standardDsType.getKey())).isNotEmpty();
mvc.perform(delete(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/" + standardDsType.getId())) mvc.perform(delete(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/" + standardDsType.getId()))
@@ -427,7 +430,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
testType = targetTypeManagement.get(testType.getId()).get(); testType = targetTypeManagement.get(testType.getId()).get();
assertThat(testType.getLastModifiedBy()).isEqualTo(TEST_USER); assertThat(testType.getLastModifiedBy()).isEqualTo(TEST_USER);
assertThat(testType.getOptLockRevision()).isEqualTo(2); assertThat(testType.getOptLockRevision()).isEqualTo(2);
assertThat(testType.getCompatibleDistributionSetTypes()).isEmpty(); assertThat(testType.getDistributionSetTypes()).isEmpty();
assertThat(distributionSetTypeManagement.findByKey(standardDsType.getKey())).isEmpty(); assertThat(distributionSetTypeManagement.findByKey(standardDsType.getKey())).isEmpty();
} }
@@ -508,7 +511,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
@Test @Test
void invalidRequestsOnTargetTypesResource() throws Exception { void invalidRequestsOnTargetTypesResource() throws Exception {
String typeName = "TestTypeInvalidReq"; String typeName = "TestTypeInvalidReq";
final TargetType testType = createTestTargetTypeInDB(typeName, Collections.singletonList(standardDsType)); final TargetType testType = createTestTargetTypeInDB(typeName, Set.of(standardDsType));
// target type does not exist // target type does not exist
mvc.perform(get(TARGETTYPE_SINGLE_ENDPOINT, 12345678)) mvc.perform(get(TARGETTYPE_SINGLE_ENDPOINT, 12345678))
@@ -522,8 +525,7 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
// target types at creation time invalid // target types at creation time invalid
final TargetType testNewType = createTestTargetTypeInDB(typeName + "Another", final TargetType testNewType = createTestTargetTypeInDB(typeName + "Another", Set.of(standardDsType));
Collections.singletonList(standardDsType));
mvc.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypes(Collections.singletonList(testNewType))) mvc.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypes(Collections.singletonList(testNewType)))
.contentType(MediaType.APPLICATION_OCTET_STREAM)) .contentType(MediaType.APPLICATION_OCTET_STREAM))
@@ -547,9 +549,8 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
final TargetType tooLongName = entityFactory.targetType().create() final Create tooLongName = Create.builder().name(randomString(NamedEntity.NAME_MAX_SIZE + 1)).build();
.name(randomString(NamedEntity.NAME_MAX_SIZE + 1)).build(); mvc.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypesCreate(List.of(tooLongName)))
mvc.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypes(Collections.singletonList(tooLongName)))
.contentType(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()) .andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
@@ -609,8 +610,8 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
*/ */
@Test @Test
void searchTargetTypeRsql() throws Exception { void searchTargetTypeRsql() throws Exception {
targetTypeManagement.create(entityFactory.targetType().create().name("TestName123")); targetTypeManagement.create(Create.builder().name("TestName123").build());
targetTypeManagement.create(entityFactory.targetType().create().name("TestName1234")); targetTypeManagement.create(Create.builder().name("TestName1234").build());
final String rsqlFindLikeDs1OrDs2 = "name==TestName123,name==TestName1234"; final String rsqlFindLikeDs1OrDs2 = "name==TestName123,name==TestName1234";
@@ -656,45 +657,46 @@ class MgmtTargetTypeResourceTest extends AbstractManagementApiIntegrationTest {
.andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey()))); .andExpect(jsonPath("$.errorCode", equalTo(SpServerError.SP_QUOTA_EXCEEDED.getKey())));
} }
private TargetType buildTestTargetTypeBody(String name) { private Create buildTestTargetTypeBody(final String name) {
return prepareTestTargetType(name, null).build(); return prepareTestTargetType(name, null);
} }
private TargetTypeCreate prepareTestTargetType(String name, Collection<DistributionSetType> dsTypes) { @SuppressWarnings({ "rawtypes", "unchecked" })
TargetTypeCreate create = entityFactory.targetType().create().name(name) private Create prepareTestTargetType(final String name, final Collection<DistributionSetType> dsTypes) {
final Create.CreateBuilder create = Create.builder().name(name)
.description("Description of the test type").colour("#aaaaaa"); .description("Description of the test type").colour("#aaaaaa");
if (dsTypes != null && !dsTypes.isEmpty()) { if (dsTypes != null && !dsTypes.isEmpty()) {
create.compatible(Collections.singletonList(standardDsType.getId())); create.distributionSetTypes(Set.of(standardDsType.getId()));
} }
return create; return create.build();
} }
private List<TargetType> createTestTargetTypesInDB(String namePrefix, int count) { private List<? extends TargetType> createTestTargetTypesInDB(final String namePrefix, final int count) {
return testdataFactory.createTargetTypes(namePrefix, count); return testdataFactory.createTargetTypes(namePrefix, count);
} }
private TargetType createTestTargetTypeInDB(String name) { private TargetType createTestTargetTypeInDB(final String name) {
return testdataFactory.findOrCreateTargetType(name); return testdataFactory.findOrCreateTargetType(name);
} }
private TargetType createTestTargetTypeInDB(String name, List<DistributionSetType> dsTypes) { private TargetType createTestTargetTypeInDB(final String name, final Set<DistributionSetType> dsTypes) {
TargetType targetType = testdataFactory.createTargetType(name, dsTypes); TargetType targetType = testdataFactory.createTargetType(name, dsTypes);
assertThat(targetType.getOptLockRevision()).isEqualTo(1); assertThat(targetType.getOptLockRevision()).isEqualTo(1);
return targetType; return targetType;
} }
private List<TargetType> buildTestTargetTypesWithoutDsTypes(String namePrefix, int count) { private List<Create> buildTestTargetTypesWithoutDsTypes(final String namePrefix, final int count) {
final List<TargetType> types = new ArrayList<>(); final List<Create> types = new ArrayList<>();
for (int index = 0; index < count; index++) { for (int index = 0; index < count; index++) {
types.add(buildTestTargetTypeBody(namePrefix + index)); types.add(buildTestTargetTypeBody(namePrefix + index));
} }
return types; return types;
} }
private void runPostTargetTypeAndVerify(final List<TargetType> types) throws Exception { private void runPostTargetTypeAndVerify(final List<Create> types) throws Exception {
int size = types.size(); int size = types.size();
ResultActions resultActions = mvc ResultActions resultActions = mvc
.perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypes(types)) .perform(post(TARGETTYPES_ENDPOINT).content(JsonBuilder.targetTypesCreate(types))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON)) .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultPrinter.print()); .andDo(MockMvcResultPrinter.print());

View File

@@ -58,4 +58,18 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<doclint>syntax</doclint>
<!-- javadoc fail on TargetTypeManagement.Create because of lombok CreateBuildaer-->
<failOnError>false</failOnError>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View File

@@ -92,10 +92,12 @@ public interface DistributionSetTypeManagement<T extends DistributionSetType>
@ToString(callSuper = true) @ToString(callSuper = true)
final class Create extends UpdateCreate { final class Create extends UpdateCreate {
@ValidString
@Size(min = 1, max = Type.KEY_MAX_SIZE) @Size(min = 1, max = Type.KEY_MAX_SIZE)
@NotNull @NotNull
private String key; private String key;
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull @NotNull
private String name; private String name;

View File

@@ -14,7 +14,6 @@ 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.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.model.BaseEntity; import org.eclipse.hawkbit.repository.model.BaseEntity;
/** /**
@@ -42,11 +41,6 @@ public interface EntityFactory {
*/ */
TargetBuilder target(); TargetBuilder target();
/**
* @return {@link TargetTypeBuilder} object
*/
TargetTypeBuilder targetType();
/** /**
* @return {@link TargetFilterQueryBuilder} object * @return {@link TargetFilterQueryBuilder} object
*/ */

View File

@@ -52,10 +52,12 @@ public interface SoftwareModuleTypeManagement<T extends SoftwareModuleType>
@ToString(callSuper = true) @ToString(callSuper = true)
final class Create extends UpdateCreate { final class Create extends UpdateCreate {
@ValidString
@Size(min = 1, max = Type.KEY_MAX_SIZE) @Size(min = 1, max = Type.KEY_MAX_SIZE)
@NotNull @NotNull
private String key; private String key;
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull @NotNull
private String name; private String name;

View File

@@ -43,13 +43,13 @@ public interface TargetTagManagement<T extends TargetTag>
@Getter @Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
final class Create extends DistributionSetTagManagement.UpdateCreate {} final class Create extends UpdateCreate {}
@SuperBuilder @SuperBuilder
@Getter @Getter
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true) @ToString(callSuper = true)
final class Update extends DistributionSetTagManagement.UpdateCreate implements Identifiable<Long> { final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull @NotNull
private Long id; private Long id;

View File

@@ -12,26 +12,29 @@ package org.eclipse.hawkbit.repository;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_CLOSE;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_OPEN; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.BRACKET_OPEN;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_AND; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_AND;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_CREATE_TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_DELETE_TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_PREFIX; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_PREFIX;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_TARGET_TYPE; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_READ_TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_SUFFIX; import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_SUFFIX;
import static org.eclipse.hawkbit.im.authentication.SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET_TYPE;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.Collections;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
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.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.exception.TargetTypeKeyOrNameRequiredException;
import org.eclipse.hawkbit.repository.builder.TargetTypeUpdate; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetType;
import org.springframework.data.domain.Page; import org.eclipse.hawkbit.repository.model.Type;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -39,7 +42,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
/** /**
* Management service for {@link TargetType}s. * Management service for {@link TargetType}s.
*/ */
public interface TargetTypeManagement { public interface TargetTypeManagement<T extends TargetType>
extends RepositoryManagement<T, TargetTypeManagement.Create, TargetTypeManagement.Update> {
String HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE = BRACKET_OPEN + String HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE = BRACKET_OPEN +
HAS_AUTH_PREFIX + SpPermission.READ_DISTRIBUTION_SET + HAS_AUTH_SUFFIX + HAS_AUTH_PREFIX + SpPermission.READ_DISTRIBUTION_SET + HAS_AUTH_SUFFIX +
@@ -47,6 +51,11 @@ public interface TargetTypeManagement {
HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET_TYPE + HAS_AUTH_SUFFIX + HAS_AUTH_PREFIX + SpPermission.UPDATE_TARGET_TYPE + HAS_AUTH_SUFFIX +
BRACKET_CLOSE; BRACKET_CLOSE;
@Override
default String permissionGroup() {
return "TARGET_TYPE";
}
/** /**
* @param key as {@link TargetType#getKey()} * @param key as {@link TargetType#getKey()}
* @return {@link TargetType} * @return {@link TargetType}
@@ -61,12 +70,6 @@ public interface TargetTypeManagement {
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) @PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
Optional<TargetType> getByName(@NotEmpty String name); Optional<TargetType> getByName(@NotEmpty String name);
/**
* @return total count
*/
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
long count();
/** /**
* @param name as {@link TargetType#getName()} * @param name as {@link TargetType#getName()}
* @return total count by name * @return total count by name
@@ -74,41 +77,6 @@ public interface TargetTypeManagement {
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) @PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
long countByName(String name); long countByName(String name);
/**
* @param create TargetTypeCreate
* @return targetType
*/
@PreAuthorize(HAS_AUTH_CREATE_TARGET_TYPE)
TargetType create(@NotNull @Valid TargetTypeCreate create);
/**
* @param creates List of TargetTypeCreate
* @return List of targetType
*/
@PreAuthorize(HAS_AUTH_CREATE_TARGET_TYPE)
List<TargetType> create(@NotEmpty @Valid Collection<TargetTypeCreate> creates);
/**
* @param id targetTypeId
*/
@PreAuthorize(HAS_AUTH_DELETE_TARGET_TYPE)
void delete(@NotNull Long id);
/**
* @param pageable Page
* @return TargetType page
*/
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
Slice<TargetType> findAll(@NotNull Pageable pageable);
/**
* @param rsql query param
* @param pageable Page
* @return Target type
*/
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
Page<TargetType> findByRsql(@NotEmpty String rsql, @NotNull Pageable pageable);
/** /**
* Retrieves {@link TargetType}s by filtering on the given parameters. * Retrieves {@link TargetType}s by filtering on the given parameters.
* *
@@ -119,27 +87,6 @@ public interface TargetTypeManagement {
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE) @PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
Slice<TargetType> findByName(String name, @NotNull Pageable pageable); Slice<TargetType> findByName(String name, @NotNull Pageable pageable);
/**
* @param id Target type ID
* @return Target Type
*/
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
Optional<TargetType> get(long id);
/**
* @param ids List of Target type ID
* @return Target type list
*/
@PreAuthorize(HAS_AUTH_READ_TARGET_TYPE)
List<TargetType> get(@NotEmpty Collection<Long> ids);
/**
* @param update TargetTypeUpdate
* @return Target Type
*/
@PreAuthorize(HAS_AUTH_UPDATE_TARGET_TYPE)
TargetType update(@NotNull @Valid TargetTypeUpdate update);
/** /**
* @param id Target type ID * @param id Target type ID
* @param distributionSetTypeIds Distribution set ID * @param distributionSetTypeIds Distribution set ID
@@ -155,4 +102,60 @@ public interface TargetTypeManagement {
*/ */
@PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE) @PreAuthorize(HAS_AUTH_READ_DISTRIBUTION_SET_AND_UPDATE_TARGET_TYPE)
TargetType unassignDistributionSetType(long id, long distributionSetTypeIds); TargetType unassignDistributionSetType(long id, long distributionSetTypeIds);
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Create extends UpdateCreate {
@ValidString
@Size(min = 1, max = Type.KEY_MAX_SIZE)
@NotNull
private String key;
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
@NotNull
private String name;
private Set<DistributionSetType> distributionSetTypes;
private Create(final CreateBuilder<?, ?> builder) {
super(builder);
if (builder.key == null && builder.name == null) {
throw new TargetTypeKeyOrNameRequiredException("Key or name of the target type shall be specified!");
}
key = builder.key == null ? builder.name : builder.key;
name = builder.name == null ? builder.key : builder.name;
this.distributionSetTypes = builder.distributionSetTypes == null ? Collections.emptySet() : builder.distributionSetTypes;
}
}
@SuperBuilder
@Getter
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
final class Update extends UpdateCreate implements Identifiable<Long> {
@NotNull
private Long id;
@ValidString
@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE)
private String name;
}
@SuperBuilder
@Getter
class UpdateCreate {
@ValidString
@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE)
private String description;
@ValidString
@Size(max = Type.COLOUR_MAX_SIZE)
private String colour;
}
} }

View File

@@ -1,29 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO 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.TargetType;
/**
* Builder for {@link TargetType}.
*/
public interface TargetTypeBuilder {
/**
* @param id of the updatable entity
* @return builder instance
*/
TargetTypeUpdate update(long id);
/**
* @return builder instance
*/
TargetTypeCreate create();
}

View File

@@ -1,83 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO 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 java.util.Collection;
import java.util.Collections;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to create a new {@link TargetType} 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 TargetTypeCreate {
/**
* @param name for {@link TargetType#getName()}
* @return updated builder instance
*/
TargetTypeCreate name(@Size(min = 1, max = NamedEntity.NAME_MAX_SIZE) @NotEmpty String name);
/**
* @param description for {@link TargetType#getDescription()}
* @return updated builder instance
*/
TargetTypeCreate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param key for {@link TargetType#getName()}
* @return updated builder instance
*/
TargetTypeCreate key(@Size(min = 1, max = Type.KEY_MAX_SIZE) @NotEmpty String key);
/**
* @param colour for {@link TargetType#getColour()}
* @return updated builder instance
*/
TargetTypeCreate colour(@Size(max = Type.COLOUR_MAX_SIZE) String colour);
/**
* @param compatible for {@link TargetType#getCompatibleDistributionSetTypes()}
* @return updated builder instance
*/
TargetTypeCreate compatible(@NotEmpty Collection<Long> compatible);
/**
* @param compatible for {@link TargetType#getCompatibleDistributionSetTypes()}
* @return updated builder instance
*/
default TargetTypeCreate compatible(@NotNull final Long compatible) {
return compatible(Collections.singletonList(compatible));
}
/**
* @param compatible for {@link TargetType#getCompatibleDistributionSetTypes()}
* @return updated builder instance
*/
default TargetTypeCreate compatible(@NotNull final DistributionSetType compatible) {
return compatible(compatible.getId());
}
/**
* @return peek on current state of {@link TargetType} in the
* builder
*/
TargetType build();
}

View File

@@ -1,41 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO 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.Size;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.model.Type;
/**
* Builder to update an existing {@link TargetType} entry. Defines all
* fields that can be updated.
*/
public interface TargetTypeUpdate {
/**
* @param description for {@link TargetType#getDescription()}
* @return updated builder instance
*/
TargetTypeUpdate description(@Size(max = NamedEntity.DESCRIPTION_MAX_SIZE) String description);
/**
* @param colour for {@link TargetType#getColour()}
* @return updated builder instance
*/
TargetTypeUpdate colour(@Size(max = Type.COLOUR_MAX_SIZE) String colour);
/**
* @param name Name
* @return updated builder instance
*/
TargetTypeUpdate name(@Size(max = NamedEntity.NAME_MAX_SIZE) String name);
}

View File

@@ -28,20 +28,11 @@ public interface TargetType extends Type {
} }
/** /**
* Gets compatible distribution set types
*
* @return immutable set of optional {@link DistributionSetType}s * @return immutable set of optional {@link DistributionSetType}s
*/ */
Set<DistributionSetType> getCompatibleDistributionSetTypes(); Set<DistributionSetType> getDistributionSetTypes();
/**
* Checks if the given {@link DistributionSetType} is in
* {@link #getCompatibleDistributionSetTypes()}.
*
* @param distributionSetTypeId search by {@link DistributionSetType#getId()}
* @return <code>true</code> if found
*/
default boolean containsCompatibleDistributionSetType(final Long distributionSetTypeId) {
return getCompatibleDistributionSetTypes().stream().anyMatch(element -> element.getId().equals(distributionSetTypeId));
}
/** /**
* Unassigns a {@link DistributionSetType} from {@link TargetType} * Unassigns a {@link DistributionSetType} from {@link TargetType}
@@ -49,5 +40,5 @@ public interface TargetType extends Type {
* @param dsTypeId that will be removed from {@link TargetType} * @param dsTypeId that will be removed from {@link TargetType}
* @return the resulting target type * @return the resulting target type
*/ */
TargetType removeDistributionSetType(final Long dsTypeId); void removeDistributionSetType(final Long dsTypeId);
} }

View File

@@ -1,24 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO 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 GenericTargetTypeUpdate extends AbstractTargetTypeUpdateCreate<TargetTypeUpdate>
implements TargetTypeUpdate {
/**
* @param id Target type ID
*/
public GenericTargetTypeUpdate(final Long id) {
super.id = id;
}
}

View File

@@ -15,7 +15,6 @@ 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.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.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.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -27,17 +26,14 @@ import org.springframework.validation.annotation.Validated;
public class JpaEntityFactory implements EntityFactory { public class JpaEntityFactory implements EntityFactory {
private final TargetBuilder targetBuilder; private final TargetBuilder targetBuilder;
private final TargetTypeBuilder targetTypeBuilder;
private final TargetFilterQueryBuilder targetFilterQueryBuilder; private final TargetFilterQueryBuilder targetFilterQueryBuilder;
private final RolloutBuilder rolloutBuilder; private final RolloutBuilder rolloutBuilder;
@SuppressWarnings("java:S107") @SuppressWarnings("java:S107")
public JpaEntityFactory( public JpaEntityFactory(
final TargetBuilder targetBuilder, final TargetTypeBuilder targetTypeBuilder, final TargetBuilder targetBuilder, final TargetFilterQueryBuilder targetFilterQueryBuilder,
final TargetFilterQueryBuilder targetFilterQueryBuilder,
final RolloutBuilder rolloutBuilder) { final RolloutBuilder rolloutBuilder) {
this.targetBuilder = targetBuilder; this.targetBuilder = targetBuilder;
this.targetTypeBuilder = targetTypeBuilder;
this.targetFilterQueryBuilder = targetFilterQueryBuilder; this.targetFilterQueryBuilder = targetFilterQueryBuilder;
this.rolloutBuilder = rolloutBuilder; this.rolloutBuilder = rolloutBuilder;
} }
@@ -61,11 +57,6 @@ public class JpaEntityFactory implements EntityFactory {
return targetBuilder; return targetBuilder;
} }
@Override
public TargetTypeBuilder targetType() {
return targetTypeBuilder;
}
@Override @Override
public TargetFilterQueryBuilder targetFilterQuery() { public TargetFilterQueryBuilder targetFilterQuery() {
return targetFilterQueryBuilder; return targetFilterQueryBuilder;

View File

@@ -46,7 +46,6 @@ import org.eclipse.hawkbit.repository.autoassign.AutoAssignExecutor;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder; import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
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.event.ApplicationEventFilter; import org.eclipse.hawkbit.repository.event.ApplicationEventFilter;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager; import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder; import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
@@ -61,7 +60,6 @@ import org.eclipse.hawkbit.repository.jpa.autocleanup.CleanupTask;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutBuilder; import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetBuilder; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryBuilder; import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryBuilder;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetTypeBuilder;
import org.eclipse.hawkbit.repository.jpa.cluster.DistributedLockRepository; import org.eclipse.hawkbit.repository.jpa.cluster.DistributedLockRepository;
import org.eclipse.hawkbit.repository.jpa.cluster.LockProperties; import org.eclipse.hawkbit.repository.jpa.cluster.LockProperties;
import org.eclipse.hawkbit.repository.jpa.event.JpaEventEntityManager; import org.eclipse.hawkbit.repository.jpa.event.JpaEventEntityManager;
@@ -311,15 +309,6 @@ public class JpaRepositoryConfiguration {
return new JpaTargetBuilder(targetTypeManagement); return new JpaTargetBuilder(targetTypeManagement);
} }
/**
* @param dsTypeManagement for loading {@link TargetType#getCompatibleDistributionSetTypes()}
* @return TargetTypeBuilder bean
*/
@Bean
TargetTypeBuilder targetTypeBuilder(final DistributionSetTypeManagement<? extends DistributionSetType> dsTypeManagement) {
return new JpaTargetTypeBuilder(dsTypeManagement);
}
/** /**
* @param distributionSetManagement for loading {@link Rollout#getDistributionSet()} * @param distributionSetManagement for loading {@link Rollout#getDistributionSet()}
* @return RolloutBuilder bean * @return RolloutBuilder bean
@@ -450,10 +439,9 @@ public class JpaRepositoryConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
EntityFactory entityFactory( EntityFactory entityFactory(
final TargetBuilder targetBuilder, final TargetTypeBuilder targetTypeBuilder, final TargetBuilder targetBuilder, final TargetFilterQueryBuilder targetFilterQueryBuilder,
final TargetFilterQueryBuilder targetFilterQueryBuilder,
final RolloutBuilder rolloutBuilder) { final RolloutBuilder rolloutBuilder) {
return new JpaEntityFactory(targetBuilder, targetTypeBuilder, targetFilterQueryBuilder, rolloutBuilder); return new JpaEntityFactory(targetBuilder, targetFilterQueryBuilder, rolloutBuilder);
} }
/** /**

View File

@@ -23,9 +23,9 @@ import org.springframework.util.ObjectUtils;
*/ */
public class JpaTargetCreate extends AbstractTargetUpdateCreate<TargetCreate> implements TargetCreate { public class JpaTargetCreate extends AbstractTargetUpdateCreate<TargetCreate> implements TargetCreate {
private final TargetTypeManagement targetTypeManagement; private final TargetTypeManagement<? extends TargetType> targetTypeManagement;
JpaTargetCreate(final TargetTypeManagement targetTypeManagement) { JpaTargetCreate(final TargetTypeManagement<? extends TargetType> targetTypeManagement) {
super(null); super(null);
this.targetTypeManagement = targetTypeManagement; this.targetTypeManagement = targetTypeManagement;
} }

View File

@@ -1,40 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO 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.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.builder.GenericTargetTypeUpdate;
import org.eclipse.hawkbit.repository.builder.TargetTypeBuilder;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate;
import org.eclipse.hawkbit.repository.builder.TargetTypeUpdate;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.TargetType;
/**
* Builder implementation for {@link TargetType}.
*/
public class JpaTargetTypeBuilder implements TargetTypeBuilder {
private final DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement;
public JpaTargetTypeBuilder(DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement) {
this.distributionSetTypeManagement = distributionSetTypeManagement;
}
@Override
public TargetTypeUpdate update(long id) {
return new GenericTargetTypeUpdate(id);
}
@Override
public TargetTypeCreate create() {
return new JpaTargetTypeCreate(distributionSetTypeManagement);
}
}

View File

@@ -1,60 +0,0 @@
/**
* Copyright (c) 2021 Bosch.IO 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 java.util.Collection;
import java.util.Collections;
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.builder.AbstractTargetTypeUpdateCreate;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.TargetTypeKeyOrNameRequiredException;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.springframework.util.CollectionUtils;
/**
* Create/build implementation.
*/
public class JpaTargetTypeCreate extends AbstractTargetTypeUpdateCreate<TargetTypeCreate> implements TargetTypeCreate {
private final DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement;
JpaTargetTypeCreate(final DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement) {
this.distributionSetTypeManagement = distributionSetTypeManagement;
}
@Override
public JpaTargetType build() {
if (key == null && name == null) {
throw new TargetTypeKeyOrNameRequiredException("Key or name of the target type shall be specified!");
}
final JpaTargetType result = new JpaTargetType(key == null ? name : key, name == null ? key : name, description, colour);
findDistributionSetTypeWithExceptionIfNotFound(compatible).forEach(result::addCompatibleDistributionSetType);
return result;
}
private Collection<? extends DistributionSetType> findDistributionSetTypeWithExceptionIfNotFound(
final Collection<Long> distributionSetTypeId) {
if (CollectionUtils.isEmpty(distributionSetTypeId)) {
return Collections.emptyList();
}
final Collection<? extends DistributionSetType> type = distributionSetTypeManagement.get(distributionSetTypeId);
if (type.size() < distributionSetTypeId.size()) {
throw new EntityNotFoundException(SoftwareModuleType.class, distributionSetTypeId);
}
return type;
}
}

View File

@@ -719,7 +719,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
final Set<DistributionSetType> incompatibleDistSetTypes = distributionSetManagement.get(distSetIds).stream() final Set<DistributionSetType> incompatibleDistSetTypes = distributionSetManagement.get(distSetIds).stream()
.map(DistributionSet::getType) .map(DistributionSet::getType)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
incompatibleDistSetTypes.removeAll(target.getTargetType().getCompatibleDistributionSetTypes()); incompatibleDistSetTypes.removeAll(target.getTargetType().getDistributionSetTypes());
if (!incompatibleDistSetTypes.isEmpty()) { if (!incompatibleDistSetTypes.isEmpty()) {
final Set<String> distSetTypeNames = incompatibleDistSetTypes.stream() final Set<String> distSetTypeNames = incompatibleDistSetTypes.stream()

View File

@@ -10,37 +10,31 @@
package org.eclipse.hawkbit.repository.jpa.management; package org.eclipse.hawkbit.repository.jpa.management;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.ToLongFunction; import java.util.function.ToLongFunction;
import jakarta.persistence.EntityManager;
import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.TargetTypeFields; import org.eclipse.hawkbit.repository.TargetTypeFields;
import org.eclipse.hawkbit.repository.TargetTypeManagement; import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.builder.GenericTargetTypeUpdate;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate;
import org.eclipse.hawkbit.repository.builder.TargetTypeUpdate;
import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.TargetTypeInUseException; import org.eclipse.hawkbit.repository.exception.TargetTypeInUseException;
import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper; import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper;
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetTypeCreate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants; import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType; import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTypeRepository; import org.eclipse.hawkbit.repository.jpa.repository.DistributionSetTypeRepository;
import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetRepository;
import org.eclipse.hawkbit.repository.jpa.repository.TargetTypeRepository; import org.eclipse.hawkbit.repository.jpa.repository.TargetTypeRepository;
import org.eclipse.hawkbit.repository.jpa.rsql.RsqlUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetTypeSpecification; import org.eclipse.hawkbit.repository.jpa.specifications.TargetTypeSpecification;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper; import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.repository.model.TargetType;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
import org.springframework.dao.ConcurrencyFailureException; import org.springframework.dao.ConcurrencyFailureException;
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.data.domain.Slice;
import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Backoff;
@@ -56,119 +50,53 @@ import org.springframework.validation.annotation.Validated;
@Validated @Validated
@Service @Service
@ConditionalOnBooleanProperty(prefix = "hawkbit.jpa", name = { "enabled", "target-type-management" }, matchIfMissing = true) @ConditionalOnBooleanProperty(prefix = "hawkbit.jpa", name = { "enabled", "target-type-management" }, matchIfMissing = true)
public class JpaTargetTypeManagement implements TargetTypeManagement { public class JpaTargetTypeManagement
extends AbstractJpaRepositoryManagement<JpaTargetType, TargetTypeManagement.Create, TargetTypeManagement.Update, TargetTypeRepository, TargetTypeFields>
implements TargetTypeManagement<JpaTargetType>{
private final TargetTypeRepository targetTypeRepository;
private final TargetRepository targetRepository; private final TargetRepository targetRepository;
private final DistributionSetTypeRepository distributionSetTypeRepository; private final DistributionSetTypeRepository distributionSetTypeRepository;
private final QuotaManagement quotaManagement; private final QuotaManagement quotaManagement;
protected JpaTargetTypeManagement(final TargetTypeRepository targetTypeRepository, protected JpaTargetTypeManagement(
final TargetRepository targetRepository, final DistributionSetTypeRepository distributionSetTypeRepository, final TargetTypeRepository targetTypeRepository, final EntityManager entityManager,
final QuotaManagement quotaManagement) { final TargetRepository targetRepository,
this.targetTypeRepository = targetTypeRepository; final DistributionSetTypeRepository distributionSetTypeRepository, final QuotaManagement quotaManagement) {
super(targetTypeRepository, entityManager);
this.targetRepository = targetRepository; this.targetRepository = targetRepository;
this.distributionSetTypeRepository = distributionSetTypeRepository; this.distributionSetTypeRepository = distributionSetTypeRepository;
this.quotaManagement = quotaManagement; this.quotaManagement = quotaManagement;
} }
@Override
protected void delete0(final Collection<Long> ids) {
for (final Long id : ids) {
if (targetRepository.countByTargetTypeId(id) > 0) {
throw new TargetTypeInUseException("Cannot delete target type that is in use: " + id);
}
}
super.delete0(ids);
}
@Override @Override
public Optional<TargetType> getByKey(final String key) { public Optional<TargetType> getByKey(final String key) {
return targetTypeRepository.findOne(TargetTypeSpecification.hasKey(key)).map(TargetType.class::cast); return jpaRepository.findOne(TargetTypeSpecification.hasKey(key)).map(TargetType.class::cast);
} }
@Override @Override
public Optional<TargetType> getByName(final String name) { public Optional<TargetType> getByName(final String name) {
return targetTypeRepository.findOne(TargetTypeSpecification.hasName(name)).map(TargetType.class::cast); return jpaRepository.findOne(TargetTypeSpecification.hasName(name)).map(TargetType.class::cast);
}
@Override
public long count() {
return targetTypeRepository.count();
}
@Override
public long countByName(final String name) {
return targetTypeRepository.count(TargetTypeSpecification.hasName(name));
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public TargetType create(final TargetTypeCreate create) {
final JpaTargetType typeCreate = ((JpaTargetTypeCreate) create).build();
return targetTypeRepository.save(AccessController.Operation.CREATE, typeCreate);
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public List<TargetType> create(final Collection<TargetTypeCreate> creates) {
final List<JpaTargetType> typeCreate =
creates.stream().map(create -> ((JpaTargetTypeCreate) create).build()).toList();
return Collections.unmodifiableList(targetTypeRepository.saveAll(AccessController.Operation.CREATE, typeCreate));
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public void delete(final Long id) {
getByIdAndThrowIfNotFound(id);
if (targetRepository.countByTargetTypeId(id) > 0) {
throw new TargetTypeInUseException("Cannot delete target type that is in use");
}
targetTypeRepository.deleteById(id);
}
@Override
public Slice<TargetType> findAll(final Pageable pageable) {
return targetTypeRepository.findAllWithoutCount(pageable).map(TargetType.class::cast);
}
@Override
public Page<TargetType> findByRsql(final String rsql, final Pageable pageable) {
return JpaManagementHelper.findAllWithCountBySpec(
targetTypeRepository,
List.of(RsqlUtility.getInstance().buildRsqlSpecification(rsql, TargetTypeFields.class)),
pageable);
} }
@Override @Override
public Slice<TargetType> findByName(final String name, final Pageable pageable) { public Slice<TargetType> findByName(final String name, final Pageable pageable) {
return JpaManagementHelper.findAllWithoutCountBySpec(targetTypeRepository, List.of(TargetTypeSpecification.likeName(name)), pageable return JpaManagementHelper.findAllWithoutCountBySpec(jpaRepository, List.of(TargetTypeSpecification.likeName(name)), pageable);
);
} }
@Override @Override
public Optional<TargetType> get(final long id) { public long countByName(final String name) {
return targetTypeRepository.findById(id).map(TargetType.class::cast); return jpaRepository.count(TargetTypeSpecification.hasName(name));
}
@Override
public List<TargetType> get(final Collection<Long> ids) {
return Collections.unmodifiableList(targetTypeRepository.findAllById(ids));
}
@Override
@Transactional
@Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX,
backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public TargetType update(final TargetTypeUpdate update) {
final GenericTargetTypeUpdate typeUpdate = (GenericTargetTypeUpdate) update;
final JpaTargetType type = getByIdAndThrowIfNotFound(typeUpdate.getId());
typeUpdate.getName().ifPresent((type::setName));
typeUpdate.getDescription().ifPresent(type::setDescription);
typeUpdate.getColour().ifPresent(type::setColour);
return targetTypeRepository.save(type);
} }
@Override @Override
@@ -186,10 +114,10 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
} }
final JpaTargetType type = getByIdAndThrowIfNotFound(id); final JpaTargetType type = getByIdAndThrowIfNotFound(id);
assertDistributionSetTypeQuota(id, distributionSetTypeIds.size(), typeId -> type.getCompatibleDistributionSetTypes().size()); assertDistributionSetTypeQuota(id, distributionSetTypeIds.size(), typeId -> type.getDistributionSetTypes().size());
dsTypes.forEach(type::addCompatibleDistributionSetType); dsTypes.forEach(type::addCompatibleDistributionSetType);
return targetTypeRepository.save(type); return jpaRepository.save(type);
} }
@Override @Override
@@ -202,7 +130,7 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
type.removeDistributionSetType(distributionSetTypeId); type.removeDistributionSetType(distributionSetTypeId);
return targetTypeRepository.save(type); return jpaRepository.save(type);
} }
@SuppressWarnings("java:S2201") // the idea is just to check for distribution set type existence @SuppressWarnings("java:S2201") // the idea is just to check for distribution set type existence
@@ -213,7 +141,7 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
} }
private JpaTargetType getByIdAndThrowIfNotFound(final Long id) { private JpaTargetType getByIdAndThrowIfNotFound(final Long id) {
return targetTypeRepository return jpaRepository
.findById(id) .findById(id)
.orElseThrow(() -> new EntityNotFoundException(TargetType.class, id)); .orElseThrow(() -> new EntityNotFoundException(TargetType.class, id));
} }

View File

@@ -78,7 +78,7 @@ public class JpaTargetType extends AbstractJpaTypeEntity implements TargetType,
} }
@Override @Override
public Set<DistributionSetType> getCompatibleDistributionSetTypes() { public Set<DistributionSetType> getDistributionSetTypes() {
return Collections.unmodifiableSet(distributionSetTypes); return Collections.unmodifiableSet(distributionSetTypes);
} }
@@ -88,12 +88,11 @@ public class JpaTargetType extends AbstractJpaTypeEntity implements TargetType,
* @param dsTypeId Distribution set type ID * @param dsTypeId Distribution set type ID
* @return Target type * @return Target type
*/ */
public JpaTargetType removeDistributionSetType(final Long dsTypeId) { public void removeDistributionSetType(final Long dsTypeId) {
distributionSetTypes.stream() distributionSetTypes.stream()
.filter(element -> element.getId().equals(dsTypeId)) .filter(element -> element.getId().equals(dsTypeId))
.findAny() .findAny()
.ifPresent(distributionSetTypes::remove); .ifPresent(distributionSetTypes::remove);
return this;
} }
@Override @Override

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.repository.jpa.acm; package org.eclipse.hawkbit.repository.jpa.acm;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_TARGET_TYPE; import static org.eclipse.hawkbit.im.authentication.SpPermission.DELETE_TARGET_TYPE;
import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET_TYPE; import static org.eclipse.hawkbit.im.authentication.SpPermission.READ_TARGET_TYPE;
@@ -18,10 +19,11 @@ import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.run
import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withUser; import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withUser;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import org.eclipse.hawkbit.repository.Identifiable; import org.eclipse.hawkbit.repository.Identifiable;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.TargetTypeManagement.Create;
import org.eclipse.hawkbit.repository.builder.TargetTypeUpdate; import org.eclipse.hawkbit.repository.TargetTypeManagement.Update;
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
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;
@@ -42,8 +44,8 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void verifyTargetTypeReadOperations() { void verifyTargetTypeReadOperations() {
final TargetType permittedTargetType = targetTypeManagement.create(entityFactory.targetType().create().name("type1")); final TargetType permittedTargetType = targetTypeManagement.create(Create.builder().name("type1").build());
final TargetType hiddenTargetType = targetTypeManagement.create(entityFactory.targetType().create().name("type2")); final TargetType hiddenTargetType = targetTypeManagement.create(Create.builder().name("type2").build());
runAs(withUser("user", READ_TARGET_TYPE + "/id==" + permittedTargetType.getId()), () -> { runAs(withUser("user", READ_TARGET_TYPE + "/id==" + permittedTargetType.getId()), () -> {
// verify targetTypeManagement#findAll // verify targetTypeManagement#findAll
@@ -81,12 +83,13 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest {
assertThat(targetTypeManagement.getByName(hiddenTargetType.getName())).isEmpty(); assertThat(targetTypeManagement.getByName(hiddenTargetType.getName())).isEmpty();
// verify targetTypeManagement#get by ids // verify targetTypeManagement#get by ids
assertThat(targetTypeManagement.get(Arrays.asList(permittedTargetType.getId(), hiddenTargetTypeId)) final List<Long> allEntityIds = Arrays.asList(permittedTargetType.getId(), hiddenTargetTypeId);
.stream().map(Identifiable::getId).toList()).containsOnly(permittedTargetType.getId()); assertThatExceptionOfType(EntityNotFoundException.class).isThrownBy(() -> targetTypeManagement.get(allEntityIds));
// verify targetTypeManagement#update is not possible. Assert exception thrown. // verify targetTypeManagement#update is not possible. Assert exception thrown.
final TargetTypeUpdate targetTypeUpdate = entityFactory.targetType().update(hiddenTargetTypeId) final Update targetTypeUpdate = Update.builder()
.name(hiddenTargetType.getName() + "/new").description("newDesc"); .id(hiddenTargetTypeId).name(hiddenTargetType.getName() + "/new").description("newDesc")
.build();
assertThatThrownBy(() -> targetTypeManagement.update(targetTypeUpdate)) assertThatThrownBy(() -> targetTypeManagement.update(targetTypeUpdate))
.as("Target type update shouldn't be allowed since the target type is not visible.") .as("Target type update shouldn't be allowed since the target type is not visible.")
.isInstanceOf(InsufficientPermissionException.class); .isInstanceOf(InsufficientPermissionException.class);
@@ -103,8 +106,8 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void verifyTargetTypeDeleteOperations() { void verifyTargetTypeDeleteOperations() {
final TargetType manageableTargetType = targetTypeManagement.create(entityFactory.targetType().create().name("type1")); final TargetType manageableTargetType = targetTypeManagement.create(Create.builder().name("type1").build());
final TargetType readOnlyTargetType = targetTypeManagement.create(entityFactory.targetType().create().name("type2")); final TargetType readOnlyTargetType = targetTypeManagement.create(Create.builder().name("type2").build());
runAs(withUser("user", runAs(withUser("user",
READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(), READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(),
@@ -124,21 +127,21 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void verifyTargetTypeUpdateOperations() { void verifyTargetTypeUpdateOperations() {
final TargetType manageableTargetType = targetTypeManagement.create(entityFactory.targetType().create().name("type1")); final TargetType manageableTargetType = targetTypeManagement.create(Create.builder().name("type1").build());
final TargetType readOnlyTargetType = targetTypeManagement.create(entityFactory.targetType().create().name("type2")); final TargetType readOnlyTargetType = targetTypeManagement.create(Create.builder().name("type2").build());
runAs(withUser("user", runAs(withUser("user",
READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(), READ_TARGET_TYPE + "/id==" + manageableTargetType.getId() + " or id==" + readOnlyTargetType.getId(),
UPDATE_TARGET_TYPE + "/id==" + manageableTargetType.getId()), () -> { UPDATE_TARGET_TYPE + "/id==" + manageableTargetType.getId()), () -> {
// update the manageableTargetType // update the manageableTargetType
targetTypeManagement.update(entityFactory.targetType().update(manageableTargetType.getId()) targetTypeManagement.update(Update.builder().id(manageableTargetType.getId())
.name(manageableTargetType.getName() + "/new").description("newDesc")); .name(manageableTargetType.getName() + "/new").description("newDesc").build());
// verify targetTypeManagement#update for readOnlyTargetType is not possible // verify targetTypeManagement#update for readOnlyTargetType is not possible
final TargetTypeUpdate targetTypeUpdate = entityFactory.targetType().update(readOnlyTargetType.getId()) final Update targetTypeUpdate = Update.builder()
.name(readOnlyTargetType.getName() + "/new").description("newDesc"); .id(readOnlyTargetType.getId()).name(readOnlyTargetType.getName() + "/new").description("newDesc")
assertThatThrownBy(() -> targetTypeManagement.update(targetTypeUpdate)) .build();
.isInstanceOf(InsufficientPermissionException.class); assertThatThrownBy(() -> targetTypeManagement.update(targetTypeUpdate)).isInstanceOf(InsufficientPermissionException.class);
}); });
} }
@@ -149,7 +152,7 @@ class TargetTypeAccessControllerTest extends AbstractJpaIntegrationTest {
void verifyTargetTypeCreationBlockedByAccessController() { void verifyTargetTypeCreationBlockedByAccessController() {
runAs(withUser("user", READ_TARGET_TYPE, UPDATE_TARGET_TYPE), () -> { runAs(withUser("user", READ_TARGET_TYPE, UPDATE_TARGET_TYPE), () -> {
// verify targetTypeManagement#create for any type // verify targetTypeManagement#create for any type
final TargetTypeCreate targetTypeCreate = entityFactory.targetType().create().name("type1"); final Create targetTypeCreate = Create.builder().name("type1").build();
assertThatThrownBy(() -> targetTypeManagement.create(targetTypeCreate)) assertThatThrownBy(() -> targetTypeManagement.create(targetTypeCreate))
.as("Target type create shouldn't be allowed since the target type is not visible.") .as("Target type create shouldn't be allowed since the target type is not visible.")
.isInstanceOf(InsufficientPermissionException.class); .isInstanceOf(InsufficientPermissionException.class);

View File

@@ -385,16 +385,15 @@ class AutoAssignCheckerIntTest extends AbstractJpaIntegrationTest {
final TargetFilterQuery testFilter = targetFilterQueryManagement.create(entityFactory.targetFilterQuery() final TargetFilterQuery testFilter = targetFilterQueryManagement.create(entityFactory.targetFilterQuery()
.create().name("test-filter").query("name==*").autoAssignDistributionSet(testDs)); .create().name("test-filter").query("name==*").autoAssignDistributionSet(testDs));
final TargetType incompatibleEmptyType = testdataFactory.createTargetType("incompatibleEmptyType", final TargetType incompatibleEmptyType = testdataFactory.createTargetType("incompatibleEmptyType", Set.of());
Collections.emptyList()); final TargetType incompatibleSingleType = testdataFactory.createTargetType(
final TargetType incompatibleSingleType = testdataFactory.createTargetType("incompatibleSingleType", "incompatibleSingleType", Set.of(incompatibleDsType1));
Collections.singletonList(incompatibleDsType1)); final TargetType incompatibleMultiType = testdataFactory.createTargetType(
final TargetType incompatibleMultiType = testdataFactory.createTargetType("incompatibleMultiType", "incompatibleMultiType", Set.of(incompatibleDsType1, incompatibleDsType2));
Arrays.asList(incompatibleDsType1, incompatibleDsType2)); final TargetType compatibleSingleType = testdataFactory.createTargetType(
final TargetType compatibleSingleType = testdataFactory.createTargetType("compatibleSingleType", "compatibleSingleType", Set.of(testDs.getType()));
Collections.singletonList(testDs.getType())); final TargetType compatibleMultiType = testdataFactory.createTargetType(
final TargetType compatibleMultiType = testdataFactory.createTargetType("compatibleMultiType", "compatibleMultiType", Set.of(testDs.getType(), incompatibleDsType1));
Arrays.asList(testDs.getType(), incompatibleDsType1));
testdataFactory.createTargetsWithType(TARGET_COUNT, "incompatibleEmpty", incompatibleEmptyType); testdataFactory.createTargetsWithType(TARGET_COUNT, "incompatibleEmpty", incompatibleEmptyType);
testdataFactory.createTargetsWithType(TARGET_COUNT, "incompatibleSingle", incompatibleSingleType); testdataFactory.createTargetsWithType(TARGET_COUNT, "incompatibleSingle", incompatibleSingleType);

View File

@@ -17,6 +17,7 @@ import java.util.concurrent.TimeUnit;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.repository.SoftwareModuleManagement; import org.eclipse.hawkbit.repository.SoftwareModuleManagement;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.event.TenantAwareEvent; import org.eclipse.hawkbit.repository.event.TenantAwareEvent;
import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DistributionSetDeletedEvent;
import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent;
@@ -118,8 +119,7 @@ class RepositoryEntityEventTest extends AbstractJpaIntegrationTest {
@Test @Test
void targetTypeUpdatedEventIsPublished() throws InterruptedException { void targetTypeUpdatedEventIsPublished() throws InterruptedException {
final TargetType createdTargetType = testdataFactory.findOrCreateTargetType("targettype"); final TargetType createdTargetType = testdataFactory.findOrCreateTargetType("targettype");
targetTypeManagement targetTypeManagement.update(TargetTypeManagement.Update.builder().id(createdTargetType.getId()).name("updatedtargettype").build());
.update(entityFactory.targetType().update(createdTargetType.getId()).name("updatedtargettype"));
final TargetTypeUpdatedEvent targetTypeUpdatedEvent = eventListener.waitForEvent(TargetTypeUpdatedEvent.class); final TargetTypeUpdatedEvent targetTypeUpdatedEvent = eventListener.waitForEvent(TargetTypeUpdatedEvent.class);
assertThat(targetTypeUpdatedEvent).isNotNull(); assertThat(targetTypeUpdatedEvent).isNotNull();

View File

@@ -39,6 +39,7 @@ import jakarta.validation.ConstraintViolationException;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.UpdateMode; import org.eclipse.hawkbit.repository.UpdateMode;
import org.eclipse.hawkbit.repository.builder.ActionStatusCreate; import org.eclipse.hawkbit.repository.builder.ActionStatusCreate;
import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent;
@@ -1829,7 +1830,8 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest {
} }
private void createTargetType(String targetTypeName) { private void createTargetType(String targetTypeName) {
systemSecurityContext.runAsSystem(() -> targetTypeManagement.create(entityFactory.targetType().create().name(targetTypeName))); systemSecurityContext.runAsSystem(
() -> targetTypeManagement.create(TargetTypeManagement.Create.builder().name(targetTypeName).build()));
} }
private void addAttributeAndVerify(final String controllerId) { private void addAttributeAndVerify(final String controllerId) {

View File

@@ -1608,8 +1608,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void verifyDSAssignmentForMultipleTargetsWithSameTargetType() { void verifyDSAssignmentForMultipleTargetsWithSameTargetType() {
final DistributionSet ds = testdataFactory.createDistributionSet("test-ds"); final DistributionSet ds = testdataFactory.createDistributionSet("test-ds");
final TargetType targetType = testdataFactory.createTargetType("test-type", final TargetType targetType = testdataFactory.createTargetType("test-type", Set.of(ds.getType()));
Collections.singletonList(ds.getType()));
final List<DeploymentRequest> deploymentRequests = new ArrayList<>(); final List<DeploymentRequest> deploymentRequests = new ArrayList<>();
for (int i = 0; i < quotaManagement.getMaxTargetDistributionSetAssignmentsPerManualAssignment(); i++) { for (int i = 0; i < quotaManagement.getMaxTargetDistributionSetAssignmentsPerManualAssignment(); i++) {
@@ -1635,8 +1634,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void verifyDSAssignmentForMultipleTargetsWithDifferentTargetTypes() { void verifyDSAssignmentForMultipleTargetsWithDifferentTargetTypes() {
final DistributionSet ds = testdataFactory.createDistributionSet("test-ds"); final DistributionSet ds = testdataFactory.createDistributionSet("test-ds");
final TargetType targetType1 = testdataFactory.createTargetType("test-type1", Collections.singletonList(ds.getType())); final TargetType targetType1 = testdataFactory.createTargetType("test-type1", Set.of(ds.getType()));
final TargetType targetType2 = testdataFactory.createTargetType("test-type2", Collections.singletonList(ds.getType())); final TargetType targetType2 = testdataFactory.createTargetType("test-type2", Set.of(ds.getType()));
final Target target1 = testdataFactory.createTarget("test-target1", "test-target1", targetType1.getId()); final Target target1 = testdataFactory.createTarget("test-target1", "test-target1", targetType1.getId());
final Target target2 = testdataFactory.createTarget("test-target2", "test-target2", targetType2.getId()); final Target target2 = testdataFactory.createTarget("test-target2", "test-target2", targetType2.getId());
@@ -1663,13 +1662,11 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
void verifyDSAssignmentFailsForTargetsWithIncompatibleTargetTypes() { void verifyDSAssignmentFailsForTargetsWithIncompatibleTargetTypes() {
final DistributionSet ds = testdataFactory.createDistributionSet("test-ds"); final DistributionSet ds = testdataFactory.createDistributionSet("test-ds");
final DistributionSetType dsType = testdataFactory.findOrCreateDistributionSetType("test-ds-type", "dsType"); final DistributionSetType dsType = testdataFactory.findOrCreateDistributionSetType("test-ds-type", "dsType");
final TargetType targetType = testdataFactory.createTargetType("target-type", final TargetType targetType = testdataFactory.createTargetType("target-type", Set.of(dsType));
Collections.singletonList(dsType));
final Target target = testdataFactory.createTarget("test-target", "test-target", targetType.getId()); final Target target = testdataFactory.createTarget("test-target", "test-target", targetType.getId());
final DeploymentRequest deploymentRequest = DeploymentManagement final DeploymentRequest deploymentRequest = DeploymentManagement.deploymentRequest(target.getControllerId(), ds.getId()).build();
.deploymentRequest(target.getControllerId(), ds.getId()).build(); final List<DeploymentRequest> deploymentRequests = List.of(deploymentRequest);
final List<DeploymentRequest> deploymentRequests = Collections.singletonList(deploymentRequest);
assertThatExceptionOfType(IncompatibleTargetTypeException.class) assertThatExceptionOfType(IncompatibleTargetTypeException.class)
.isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests)); .isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests));
@@ -1681,9 +1678,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void verifyDSAssignmentFailsForTargetsWithTargetTypesThatAreNotCompatibleWithAnyDs() { void verifyDSAssignmentFailsForTargetsWithTargetTypesThatAreNotCompatibleWithAnyDs() {
final DistributionSet ds = testdataFactory.createDistributionSet("test-ds"); final DistributionSet ds = testdataFactory.createDistributionSet("test-ds");
final TargetType emptyTargetType = testdataFactory.createTargetType("target-type", Collections.emptyList()); final TargetType emptyTargetType = testdataFactory.createTargetType("target-type", Set.of());
final Target targetWithEmptyType = testdataFactory.createTarget("test-target", "test-target", final Target targetWithEmptyType = testdataFactory.createTarget("test-target", "test-target", emptyTargetType.getId());
emptyTargetType.getId());
final DeploymentRequest deploymentRequestWithEmptyType = DeploymentManagement final DeploymentRequest deploymentRequestWithEmptyType = DeploymentManagement
.deploymentRequest(targetWithEmptyType.getControllerId(), ds.getId()).build(); .deploymentRequest(targetWithEmptyType.getControllerId(), ds.getId()).build();

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -2147,21 +2148,17 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final String rolloutName = "rolloutTestCompatibility"; final String rolloutName = "rolloutTestCompatibility";
final DistributionSet testDs = testdataFactory.createDistributionSet("test-ds"); final DistributionSet testDs = testdataFactory.createDistributionSet("test-ds");
final TargetType incompatibleTargetType = testdataFactory.createTargetType("incompatible-type", final TargetType incompatibleTargetType = testdataFactory.createTargetType("incompatible-type", Set.of());
Collections.emptyList()); final TargetType compatibleTargetType = testdataFactory.createTargetType("compatible-type", Set.of(testDs.getType()));
final TargetType compatibleTargetType = testdataFactory.createTargetType("compatible-type",
Collections.singletonList(testDs.getType()));
final List<Target> incompatibleTargets = testdataFactory.createTargetsWithType(10, "incompatible", final List<Target> incompatibleTargets = testdataFactory.createTargetsWithType(10, "incompatible", incompatibleTargetType);
incompatibleTargetType);
final List<Target> targetsWithoutType = testdataFactory.createTargets(10, "testTarget-"); final List<Target> targetsWithoutType = testdataFactory.createTargets(10, "testTarget-");
final List<Target> targets = testdataFactory.createTargetsWithType(10, "compatibleTarget-", final List<Target> targets = testdataFactory.createTargetsWithType(10, "compatibleTarget-", compatibleTargetType);
compatibleTargetType);
targets.addAll(targetsWithoutType); targets.addAll(targetsWithoutType);
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build(); final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName) final RolloutCreate rolloutToCreate = entityFactory.rollout().create()
.targetFilterQuery("name==*").distributionSetId(testDs); .name(rolloutName).targetFilterQuery("name==*").distributionSetId(testDs);
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, false, conditions); final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, false, conditions);

View File

@@ -20,6 +20,7 @@ import jakarta.validation.ConstraintViolationException;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
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.SoftwareModuleTypeManagement.Create;
import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
@@ -67,11 +68,10 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void updateNothingResultsInUnchangedRepositoryForType() { void updateNothingResultsInUnchangedRepositoryForType() {
final SoftwareModuleType created = softwareModuleTypeManagement final SoftwareModuleType created = softwareModuleTypeManagement.create(Create.builder().key("test-key").name("test-name").build());
.create(SoftwareModuleTypeManagement.Create.builder().key("test-key").name("test-name").build());
final SoftwareModuleType updated = softwareModuleTypeManagement final SoftwareModuleType updated = softwareModuleTypeManagement.update(SoftwareModuleTypeManagement.Update.builder().id(created.getId())
.update(SoftwareModuleTypeManagement.Update.builder().id(created.getId()).build()); .build());
assertThat(updated.getOptLockRevision()) assertThat(updated.getOptLockRevision())
.as("Expected version number of updated entitity to be equal to created version") .as("Expected version number of updated entitity to be equal to created version")
@@ -84,7 +84,7 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void updateSoftwareModuleTypeFieldsToNewValue() { void updateSoftwareModuleTypeFieldsToNewValue() {
final SoftwareModuleType created = softwareModuleTypeManagement final SoftwareModuleType created = softwareModuleTypeManagement
.create(SoftwareModuleTypeManagement.Create.builder().key("test-key").name("test-name").build()); .create(Create.builder().key("test-key").name("test-name").build());
final SoftwareModuleType updated = softwareModuleTypeManagement.update( final SoftwareModuleType updated = softwareModuleTypeManagement.update(
SoftwareModuleTypeManagement.Update.builder().id(created.getId()).description("changed").colour("changed").build()); SoftwareModuleTypeManagement.Update.builder().id(created.getId()).description("changed").colour("changed").build());
@@ -100,9 +100,9 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createModuleTypesCallFailsForExistingTypes() { void createModuleTypesCallFailsForExistingTypes() {
final List<SoftwareModuleTypeManagement.Create> created = Arrays.asList( final List<Create> created = Arrays.asList(
SoftwareModuleTypeManagement.Create.builder().key("test-key").name("test-name").build(), Create.builder().key("test-key").name("test-name").build(),
SoftwareModuleTypeManagement.Create.builder().key("test-key2").name("test-name2").build()); Create.builder().key("test-key2").name("test-name2").build());
softwareModuleTypeManagement.create(created); softwareModuleTypeManagement.create(created);
assertThatExceptionOfType(EntityAlreadyExistsException.class) assertThatExceptionOfType(EntityAlreadyExistsException.class)
.as("should not have worked as module type already exists") .as("should not have worked as module type already exists")
@@ -117,7 +117,7 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(3).contains(osType, runtimeType, appType); Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(3).contains(osType, runtimeType, appType);
SoftwareModuleType type = softwareModuleTypeManagement SoftwareModuleType type = softwareModuleTypeManagement
.create(SoftwareModuleTypeManagement.Create.builder().key("bundle").name("OSGi Bundle").build()); .create(Create.builder().key("bundle").name("OSGi Bundle").build());
Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(4).contains(osType, runtimeType, appType, type); Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(4).contains(osType, runtimeType, appType, type);
@@ -127,7 +127,7 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeRepository.findAll()).hasSize(3).contains(osType, runtimeType, appType); Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeRepository.findAll()).hasSize(3).contains(osType, runtimeType, appType);
type = softwareModuleTypeManagement type = softwareModuleTypeManagement
.create(SoftwareModuleTypeManagement.Create.builder().key("bundle2").name("OSGi Bundle2").build()); .create(Create.builder().key("bundle2").name("OSGi Bundle2").build());
Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(4).contains(osType, runtimeType, appType, type); Assertions.<SoftwareModuleType>assertThat(softwareModuleTypeManagement.findAll(PAGE)).hasSize(4).contains(osType, runtimeType, appType, type);
@@ -152,9 +152,9 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
void findSoftwareModuleTypeByName() { void findSoftwareModuleTypeByName() {
testdataFactory.createSoftwareModuleOs(); testdataFactory.createSoftwareModuleOs();
final SoftwareModuleType found = softwareModuleTypeManagement final SoftwareModuleType found = softwareModuleTypeManagement
.create(SoftwareModuleTypeManagement.Create.builder().key("thetype").name("thename").build()); .create(Create.builder().key("thetype").name("thename").build());
softwareModuleTypeManagement softwareModuleTypeManagement
.create(SoftwareModuleTypeManagement.Create.builder().key("thetype2").name("anothername").build()); .create(Create.builder().key("thetype2").name("anothername").build());
Assertions.<SoftwareModuleType>assertThat(((SoftwareModuleTypeManagement<SoftwareModuleType>) softwareModuleTypeManagement).findByName("thename")) Assertions.<SoftwareModuleType>assertThat(((SoftwareModuleTypeManagement<SoftwareModuleType>) softwareModuleTypeManagement).findByName("thename"))
.as("Type with given name").contains(found); .as("Type with given name").contains(found);
@@ -165,7 +165,7 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createSoftwareModuleTypeFailsWithExistingEntity() { void createSoftwareModuleTypeFailsWithExistingEntity() {
final SoftwareModuleTypeManagement.Create create = SoftwareModuleTypeManagement.Create.builder().key("thetype").name("thename").build(); final Create create = Create.builder().key("thetype").name("thename").build();
softwareModuleTypeManagement.create(create); softwareModuleTypeManagement.create(create);
assertThatExceptionOfType(EntityAlreadyExistsException.class) assertThatExceptionOfType(EntityAlreadyExistsException.class)
.as("should not have worked as module type already exists") .as("should not have worked as module type already exists")
@@ -177,10 +177,10 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createSoftwareModuleTypesFailsWithExistingEntity() { void createSoftwareModuleTypesFailsWithExistingEntity() {
softwareModuleTypeManagement.create(SoftwareModuleTypeManagement.Create.builder().key("thetype").name("thename").build()); softwareModuleTypeManagement.create(Create.builder().key("thetype").name("thename").build());
final List<SoftwareModuleTypeManagement.Create> creates = List.of( final List<Create> creates = List.of(
SoftwareModuleTypeManagement.Create.builder().key("thetype").name("thename").build(), Create.builder().key("thetype").name("thename").build(),
SoftwareModuleTypeManagement.Create.builder().key("anothertype").name("anothername").build()); Create.builder().key("anothertype").name("anothername").build());
assertThatExceptionOfType(EntityAlreadyExistsException.class) assertThatExceptionOfType(EntityAlreadyExistsException.class)
.as("should not have worked as module type already exists") .as("should not have worked as module type already exists")
.isThrownBy(() -> softwareModuleTypeManagement.create(creates)); .isThrownBy(() -> softwareModuleTypeManagement.create(creates));
@@ -191,8 +191,8 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createSoftwareModuleTypesFailsWithInvalidMaxAssignment() { void createSoftwareModuleTypesFailsWithInvalidMaxAssignment() {
final SoftwareModuleTypeManagement.Create create = final Create create =
SoftwareModuleTypeManagement.Create.builder().key("type").name("name").maxAssignments(0).build(); Create.builder().key("type").name("name").maxAssignments(0).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("should not have worked as max assignment is invalid. Should be greater than 0") .as("should not have worked as max assignment is invalid. Should be greater than 0")
.isThrownBy(() -> softwareModuleTypeManagement.create(create)); .isThrownBy(() -> softwareModuleTypeManagement.create(create));
@@ -205,8 +205,8 @@ class SoftwareModuleTypeManagementTest extends AbstractJpaIntegrationTest {
void createMultipleSoftwareModuleTypes() { void createMultipleSoftwareModuleTypes() {
final List<? extends SoftwareModuleType> created = softwareModuleTypeManagement final List<? extends SoftwareModuleType> created = softwareModuleTypeManagement
.create(List.of( .create(List.of(
SoftwareModuleTypeManagement.Create.builder().key("thetype").name("thename").build(), Create.builder().key("thetype").name("thename").build(),
SoftwareModuleTypeManagement.Create.builder().key("thetype2").name("thename2").build())); Create.builder().key("thetype2").name("thename2").build()));
assertThat(created).as("Number of created types").hasSize(2); assertThat(created).as("Number of created types").hasSize(2);
assertThat(softwareModuleTypeManagement.count()).as("Number of types in repository").isEqualTo(5); assertThat(softwareModuleTypeManagement.count()).as("Number of types in repository").isEqualTo(5);

View File

@@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.FilterParams;
@@ -43,8 +44,7 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void findTargetByTargetType() { void findTargetByTargetType() {
final TargetType testType = testdataFactory.createTargetType("testType", final TargetType testType = testdataFactory.createTargetType("testType", Set.of(standardDsType));
Collections.singletonList(standardDsType));
final List<Target> unassigned = testdataFactory.createTargets(9, "unassigned"); final List<Target> unassigned = testdataFactory.createTargets(9, "unassigned");
final List<Target> assigned = testdataFactory.createTargetsWithType(11, "assigned", testType); final List<Target> assigned = testdataFactory.createTargetsWithType(11, "assigned", testType);
@@ -76,8 +76,7 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
final DistributionSet setA = testdataFactory.createDistributionSet("A"); final DistributionSet setA = testdataFactory.createDistributionSet("A");
final DistributionSet setB = testdataFactory.createDistributionSet("B"); final DistributionSet setB = testdataFactory.createDistributionSet("B");
final TargetType targetTypeX = testdataFactory.createTargetType("TargetTypeX", final TargetType targetTypeX = testdataFactory.createTargetType("TargetTypeX", Set.of(setB.getType()));
Collections.singletonList(setB.getType()));
final DistributionSet installedSet = testdataFactory.createDistributionSet("another"); final DistributionSet installedSet = testdataFactory.createDistributionSet("another");
@@ -259,8 +258,7 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
@Test @Test
void shouldFindAllTargetsCompatibleWithDS() { void shouldFindAllTargetsCompatibleWithDS() {
final DistributionSet testDs = testdataFactory.createDistributionSet(); final DistributionSet testDs = testdataFactory.createDistributionSet();
final TargetType targetType = testdataFactory.createTargetType("testType", final TargetType targetType = testdataFactory.createTargetType("testType", Set.of(testDs.getType()));
Collections.singletonList(testDs.getType()));
final TargetFilterQuery tfq = targetFilterQueryManagement final TargetFilterQuery tfq = targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name("test-filter").query("name==*")); .create(entityFactory.targetFilterQuery().create().name("test-filter").query("name==*"));
final List<Target> targets = testdataFactory.createTargets(20, "withOutType"); final List<Target> targets = testdataFactory.createTargets(20, "withOutType");
@@ -282,9 +280,9 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
final DistributionSetType dsType = testdataFactory.findOrCreateDistributionSetType("test-ds-type", "test-ds-type"); final DistributionSetType dsType = testdataFactory.findOrCreateDistributionSetType("test-ds-type", "test-ds-type");
final DistributionSet testDs = distributionSetManagement.create(DistributionSetManagement.Create.builder() final DistributionSet testDs = distributionSetManagement.create(DistributionSetManagement.Create.builder()
.type(dsType).name("test-ds").version("1.0").build()); .type(dsType).name("test-ds").version("1.0").build());
final TargetType compatibleTargetType = testdataFactory.createTargetType("compTestType", List.of(dsType)); final TargetType compatibleTargetType = testdataFactory.createTargetType("compTestType", Set.of(dsType));
final TargetType incompatibleTargetType = testdataFactory.createTargetType( final TargetType incompatibleTargetType = testdataFactory.createTargetType(
"incompTestType", List.of(testdataFactory.createDistributionSet().getType())); "incompTestType", Set.of(testdataFactory.createDistributionSet().getType()));
final TargetFilterQuery tfq = targetFilterQueryManagement final TargetFilterQuery tfq = targetFilterQueryManagement
.create(entityFactory.targetFilterQuery().create().name("test-filter").query("name==*")); .create(entityFactory.targetFilterQuery().create().name("test-filter").query("name==*"));

View File

@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
@@ -515,12 +516,12 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final Target t1 = testdataFactory.createTarget("id-1"); final Target t1 = testdataFactory.createTarget("id-1");
final int noT2Tags = 4; final int noT2Tags = 4;
final int noT1Tags = 3; final int noT1Tags = 3;
final List<TargetTag> t1Tags = testdataFactory.createTargetTags(noT1Tags, "tag1"); final List<? extends TargetTag> t1Tags = testdataFactory.createTargetTags(noT1Tags, "tag1");
t1Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t1.getControllerId()), tag.getId())); t1Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t1.getControllerId()), tag.getId()));
final Target t2 = testdataFactory.createTarget("id-2"); final Target t2 = testdataFactory.createTarget("id-2");
final List<TargetTag> t2Tags = testdataFactory.createTargetTags(noT2Tags, "tag2"); final List<? extends TargetTag> t2Tags = testdataFactory.createTargetTags(noT2Tags, "tag2");
t2Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t2.getControllerId()), tag.getId())); t2Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t2.getControllerId()), tag.getId()));
final Target t11 = targetManagement.getByControllerID(t1.getControllerId()) final Target t11 = targetManagement.getByControllerID(t1.getControllerId())
@@ -889,7 +890,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@WithUser(allSpPermissions = true) @WithUser(allSpPermissions = true)
void createAndUpdateTargetTypeInTarget() { void createAndUpdateTargetTypeInTarget() {
// create a target type // create a target type
final List<TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2); final List<? extends TargetType> targetTypes = testdataFactory.createTargetTypes("targettype", 2);
assertThat(targetTypes).hasSize(2); assertThat(targetTypes).hasSize(2);
// create a target // create a target
final Target target = testdataFactory.createTarget("target1", "testtarget", targetTypes.get(0).getId()); final Target target = testdataFactory.createTarget("target1", "testtarget", targetTypes.get(0).getId());
@@ -963,8 +964,8 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final List<Target> typeBTargets = testdataFactory.createTargets(10, "typeBTargets", "first description"); final List<Target> typeBTargets = testdataFactory.createTargets(10, "typeBTargets", "first description");
// create a target type // create a target type
final TargetType typeA = testdataFactory.createTargetType("A", Collections.singletonList(standardDsType)); final TargetType typeA = testdataFactory.createTargetType("A", Set.of(standardDsType));
final TargetType typeB = testdataFactory.createTargetType("B", Collections.singletonList(standardDsType)); final TargetType typeB = testdataFactory.createTargetType("B", Set.of(standardDsType));
// assign target type to target // assign target type to target
TargetTypeAssignmentResult resultA = initiateTypeAssignment(typeATargets, typeA); TargetTypeAssignmentResult resultA = initiateTypeAssignment(typeATargets, typeA);
@@ -1088,7 +1089,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final String controllerId1 = "target1"; final String controllerId1 = "target1";
final String controllerId2 = "target2"; final String controllerId2 = "target2";
createTargetWithMetadata(controllerId1, 2); createTargetWithMetadata(controllerId1, 2);
final TargetType type = testdataFactory.createTargetType("type1", Collections.emptyList()); final TargetType type = testdataFactory.createTargetType("type1", Set.of());
createTargetWithTargetTypeAndMetadata(controllerId2, type.getId(), 2); createTargetWithTargetTypeAndMetadata(controllerId2, type.getId(), 2);
assertThat(targetManagement.count()).as("Total targets").isEqualTo(2); assertThat(targetManagement.count()).as("Total targets").isEqualTo(2);
@@ -1147,7 +1148,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void matchesFilterWrongType() { void matchesFilterWrongType() {
final TargetType type = testdataFactory.createTargetType("type", Collections.emptyList()); final TargetType type = testdataFactory.createTargetType("type", Set.of());
final Target target = testdataFactory.createTarget("target", "target", type.getId()); final Target target = testdataFactory.createTarget("target", "target", type.getId());
final DistributionSet ds = testdataFactory.createDistributionSet(); final DistributionSet ds = testdataFactory.createDistributionSet();

View File

@@ -319,7 +319,7 @@ class TargetTagManagementTest extends AbstractJpaIntegrationTest {
private List<JpaTargetTag> createTargetsWithTags() { private List<JpaTargetTag> createTargetsWithTags() {
final List<Target> targets = testdataFactory.createTargets(20); final List<Target> targets = testdataFactory.createTargets(20);
final Iterable<TargetTag> tags = testdataFactory.createTargetTags(20, ""); final Iterable<? extends TargetTag> tags = testdataFactory.createTargetTags(20, "");
tags.forEach(tag -> assignTag(targets, tag)); tags.forEach(tag -> assignTag(targets, tag));

View File

@@ -13,6 +13,9 @@ 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.TargetTypeManagement;
import org.eclipse.hawkbit.repository.TargetTypeManagement.Create;
import org.eclipse.hawkbit.repository.TargetTypeManagement.Update;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
import org.eclipse.hawkbit.repository.test.util.WithUser; import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@@ -61,7 +64,7 @@ class TargetTypeManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createPermissionsCheck() { void createPermissionsCheck() {
assertPermissions(() -> targetTypeManagement.create(entityFactory.targetType().create().name("name")), assertPermissions(() -> targetTypeManagement.create(Create.builder().name("name").build()),
List.of(SpPermission.CREATE_TARGET)); List.of(SpPermission.CREATE_TARGET));
} }
@@ -70,7 +73,7 @@ class TargetTypeManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void createCollectionPermissionsCheck() { void createCollectionPermissionsCheck() {
assertPermissions(() -> targetTypeManagement.create(List.of(entityFactory.targetType().create().name("name"))), assertPermissions(() -> targetTypeManagement.create(List.of(Create.builder().name("name").build())),
List.of(SpPermission.CREATE_TARGET)); List.of(SpPermission.CREATE_TARGET));
} }
@@ -130,7 +133,7 @@ class TargetTypeManagementSecurityTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void updatePermissionsCheck() { void updatePermissionsCheck() {
assertPermissions(() -> targetTypeManagement.update(entityFactory.targetType().update(1L)), List.of(SpPermission.UPDATE_TARGET)); assertPermissions(() -> targetTypeManagement.update(Update.builder().id(1L).build()), List.of(SpPermission.UPDATE_TARGET));
} }
/** /**

View File

@@ -18,8 +18,8 @@ import java.util.Optional;
import jakarta.validation.ConstraintViolationException; import jakarta.validation.ConstraintViolationException;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.TargetTypeManagement.Create;
import org.eclipse.hawkbit.repository.builder.TargetTypeUpdate; import org.eclipse.hawkbit.repository.TargetTypeManagement.Update;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeCreatedEvent;
import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetTypeUpdatedEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
@@ -58,8 +58,7 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
@ExpectEvents({ @Expect(type = TargetTypeUpdatedEvent.class) }) @ExpectEvents({ @Expect(type = TargetTypeUpdatedEvent.class) })
void entityQueriesReferringToNotExistingEntitiesThrowsException() { void entityQueriesReferringToNotExistingEntitiesThrowsException() {
verifyThrownExceptionBy(() -> targetTypeManagement.delete(NOT_EXIST_IDL), "TargetType"); verifyThrownExceptionBy(() -> targetTypeManagement.delete(NOT_EXIST_IDL), "TargetType");
verifyThrownExceptionBy(() -> targetTypeManagement.update(entityFactory.targetType().update(NOT_EXIST_IDL)), verifyThrownExceptionBy(() -> targetTypeManagement.update(Update.builder().id(NOT_EXIST_IDL).build()),"TargetType");
"TargetType");
} }
/** /**
@@ -68,9 +67,7 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void createAndUpdateTargetTypeWithInvalidFields() { void createAndUpdateTargetTypeWithInvalidFields() {
final TargetType targetType = targetTypeManagement final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create() .create(Create.builder().name("targettype1").description("targettypedes1").key("targettype1.key").build());
.name("targettype1").description("targettypedes1")
.key("targettype1.key"));
createAndUpdateTargetTypeWithInvalidDescription(targetType); createAndUpdateTargetTypeWithInvalidDescription(targetType);
createAndUpdateTargetTypeWithInvalidColour(targetType); createAndUpdateTargetTypeWithInvalidColour(targetType);
@@ -79,23 +76,24 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
} }
void createAndUpdateTargetTypeWithInvalidDescription(final TargetType targetType) { void createAndUpdateTargetTypeWithInvalidDescription(final TargetType targetType) {
final TargetTypeCreate targetTypeCreateTooLong = entityFactory.targetType().create().name("a").description(randomString(TargetType.DESCRIPTION_MAX_SIZE + 1)); final Create targetTypeCreateTooLong = Create.builder()
.name("a").description(randomString(TargetType.DESCRIPTION_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long description should not be created") .as("targetType with too long description should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateTooLong)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateTooLong));
final TargetTypeCreate targetTypeCreateInvalidHtml = entityFactory.targetType().create().name("a").description(INVALID_TEXT_HTML); final Create targetTypeCreateInvalidHtml = Create.builder().name("a").description(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid description should not be created") .as("targetType with invalid description should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtml)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtml));
final TargetTypeUpdate targetTypeUpdateTooLong = entityFactory.targetType().update(targetType.getId()) final Update targetTypeUpdateTooLong = Update.builder().id(targetType.getId())
.description(randomString(TargetType.DESCRIPTION_MAX_SIZE + 1)); .description(randomString(TargetType.DESCRIPTION_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long description should not be updated") .as("targetType with too long description should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateTooLong)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateTooLong));
final TargetTypeUpdate targetTypeUpdateInvalidHtml = entityFactory.targetType().update(targetType.getId()).description(INVALID_TEXT_HTML); final Update targetTypeUpdateInvalidHtml = Update.builder().id(targetType.getId()).description(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid description should not be updated") .as("targetType with invalid description should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateInvalidHtml)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateInvalidHtml));
@@ -107,15 +105,14 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void assignCompatibleDistributionSetTypesToTargetType() { void assignCompatibleDistributionSetTypesToTargetType() {
final TargetType targetType = targetTypeManagement final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create() .create(Create.builder()
.name("targettype1").description("targettypedes1") .name("targettype1").description("targettypedes1").key("targettyp1.key").build());
.key("targettyp1.key"));
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst", "dst1"); DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst", "dst1");
targetTypeManagement.assignCompatibleDistributionSetTypes(targetType.getId(), Collections.singletonList(distributionSetType.getId())); targetTypeManagement.assignCompatibleDistributionSetTypes(targetType.getId(), Collections.singletonList(distributionSetType.getId()));
Optional<JpaTargetType> targetTypeWithDsTypes = targetTypeRepository.findById(targetType.getId()); Optional<JpaTargetType> targetTypeWithDsTypes = targetTypeRepository.findById(targetType.getId());
assertThat(targetTypeWithDsTypes).isPresent(); assertThat(targetTypeWithDsTypes).isPresent();
assertThat(targetTypeWithDsTypes.get().getCompatibleDistributionSetTypes()).extracting("key").contains("testDst"); assertThat(targetTypeWithDsTypes.get().getDistributionSetTypes()).extracting("key").contains("testDst");
} }
/** /**
@@ -124,18 +121,16 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void unassignCompatibleDistributionSetTypesToTargetType() { void unassignCompatibleDistributionSetTypesToTargetType() {
final TargetType targetType = targetTypeManagement final TargetType targetType = targetTypeManagement
.create(entityFactory.targetType().create() .create(Create.builder().name("targettype1").description("targettypedes1").key("targettyp1.key").build());
.name("targettype1").description("targettypedes1")
.key("targettyp1.key"));
DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst1", "dst11"); DistributionSetType distributionSetType = testdataFactory.findOrCreateDistributionSetType("testDst1", "dst11");
targetTypeManagement.assignCompatibleDistributionSetTypes(targetType.getId(), Collections.singletonList(distributionSetType.getId())); targetTypeManagement.assignCompatibleDistributionSetTypes(targetType.getId(), Collections.singletonList(distributionSetType.getId()));
Optional<JpaTargetType> targetTypeWithDsTypes = targetTypeRepository.findById(targetType.getId()); Optional<JpaTargetType> targetTypeWithDsTypes = targetTypeRepository.findById(targetType.getId());
assertThat(targetTypeWithDsTypes).isPresent(); assertThat(targetTypeWithDsTypes).isPresent();
assertThat(targetTypeWithDsTypes.get().getCompatibleDistributionSetTypes()).extracting("key").contains("testDst1"); assertThat(targetTypeWithDsTypes.get().getDistributionSetTypes()).extracting("key").contains("testDst1");
targetTypeManagement.unassignDistributionSetType(targetType.getId(), distributionSetType.getId()); targetTypeManagement.unassignDistributionSetType(targetType.getId(), distributionSetType.getId());
Optional<JpaTargetType> targetTypeWithDsTypes1 = targetTypeRepository.findById(targetType.getId()); Optional<JpaTargetType> targetTypeWithDsTypes1 = targetTypeRepository.findById(targetType.getId());
assertThat(targetTypeWithDsTypes1).isPresent(); assertThat(targetTypeWithDsTypes1).isPresent();
assertThat(targetTypeWithDsTypes1.get().getCompatibleDistributionSetTypes()).isEmpty(); assertThat(targetTypeWithDsTypes1.get().getDistributionSetTypes()).isEmpty();
} }
/** /**
@@ -154,12 +149,7 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
void createTargetType() { void createTargetType() {
final String name = "targettype1"; final String name = "targettype1";
final String key = "targettype1.key"; final String key = "targettype1.key";
targetTypeManagement targetTypeManagement.create(Create.builder().name(name).description("targettypedes1").key(key).colour("colour1").build());
.create(entityFactory.targetType().create()
.name(name)
.description("targettypedes1")
.key(key)
.colour("colour1"));
assertThat(findByName(name).map(JpaTargetType::getName).orElse(null)).as("type found (name)") assertThat(findByName(name).map(JpaTargetType::getName).orElse(null)).as("type found (name)")
.isEqualTo(name); .isEqualTo(name);
@@ -185,10 +175,8 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
void deleteTargetType() { void deleteTargetType() {
// create test data // create test data
final TargetType targetType = targetTypeManagement final TargetType targetType = targetTypeManagement.create(Create.builder().name("targettype11").description("targettypedes11").build());
.create(entityFactory.targetType().create().name("targettype11").description("targettypedes11")); assertThat(findByName("targettype11").get().getDescription()).as("type found").isEqualTo("targettypedes11");
assertThat(findByName("targettype11").get().getDescription()).as("type found")
.isEqualTo("targettypedes11");
targetTypeManagement.delete(targetType.getId()); targetTypeManagement.delete(targetType.getId());
assertThat(targetTypeRepository.findById(targetType.getId())).as("No target type should be found").isNotPresent(); assertThat(targetTypeRepository.findById(targetType.getId())).as("No target type should be found").isNotPresent();
@@ -199,11 +187,10 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void updateTargetType() { void updateTargetType() {
final TargetType targetType = targetTypeManagement final TargetType targetType =
.create(entityFactory.targetType().create().name("targettype111").description("targettypedes111")); targetTypeManagement.create(Create.builder().name("targettype111").description("targettypedes111").build());
assertThat(findByName("targettype111").get().getDescription()).as("type found") assertThat(findByName("targettype111").get().getDescription()).as("type found").isEqualTo("targettypedes111");
.isEqualTo("targettypedes111"); targetTypeManagement.update(Update.builder().id(targetType.getId()).name("updatedtargettype111").build());
targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("updatedtargettype111"));
assertThat(findByName("updatedtargettype111")).as("Updated target type should be found").isPresent(); assertThat(findByName("updatedtargettype111")).as("Updated target type should be found").isPresent();
} }
@@ -212,7 +199,7 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void failedDuplicateTargetTypeNameException() { void failedDuplicateTargetTypeNameException() {
final TargetTypeCreate targetTypeCreate = entityFactory.targetType().create().name("targettype123"); final Create targetTypeCreate = Create.builder().name("targettype123").build();
targetTypeManagement.create(targetTypeCreate); targetTypeManagement.create(targetTypeCreate);
assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.create(targetTypeCreate)); assertThrows(EntityAlreadyExistsException.class, () -> targetTypeManagement.create(targetTypeCreate));
} }
@@ -222,69 +209,71 @@ class TargetTypeManagementTest extends AbstractJpaIntegrationTest {
*/ */
@Test @Test
void failedDuplicateTargetTypeNameExceptionAfterUpdate() { void failedDuplicateTargetTypeNameExceptionAfterUpdate() {
targetTypeManagement.create(entityFactory.targetType().create().name("targettype1234")); targetTypeManagement.create(Create.builder().name("targettype1234").build());
TargetType targetType = targetTypeManagement.create(entityFactory.targetType().create().name("targettype12345")); TargetType targetType = targetTypeManagement.create(Create.builder().name("targettype12345").build());
assertThrows(EntityAlreadyExistsException.class, assertThrows(EntityAlreadyExistsException.class,
() -> targetTypeManagement.update(entityFactory.targetType().update(targetType.getId()).name("targettype1234"))); () -> targetTypeManagement.update(Update.builder().id(targetType.getId()).name("targettype1234").build()));
} }
private void createAndUpdateTargetTypeWithInvalidColour(final TargetType targetType) { private void createAndUpdateTargetTypeWithInvalidColour(final TargetType targetType) {
final TargetTypeCreate targetTypeCreateTooLong = entityFactory.targetType().create().name("a").colour(randomString(Type.COLOUR_MAX_SIZE + 1)); final Create targetTypeCreateTooLong = Create.builder().name("a").colour(randomString(Type.COLOUR_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long colour should not be created") .as("targetType with too long colour should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateTooLong)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateTooLong));
final TargetTypeCreate targetTypeCreateInvalidHtml = entityFactory.targetType().create().name("a").colour(INVALID_TEXT_HTML); final Create targetTypeCreateInvalidHtml = Create.builder().name("a").colour(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid colour should not be created") .as("targetType with invalid colour should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtml)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtml));
final TargetTypeUpdate targetTypeUpdateTooLong = entityFactory.targetType().update(targetType.getId()).colour(randomString(Type.COLOUR_MAX_SIZE + 1)); final Update targetTypeUpdateTooLong = Update.builder()
.id(targetType.getId()).colour(randomString(Type.COLOUR_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long colour should not be updated") .as("targetType with too long colour should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateTooLong)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateTooLong));
final TargetTypeUpdate targetTypeUpdateInvalidHtml = entityFactory.targetType().update(targetType.getId()).colour(INVALID_TEXT_HTML); final Update targetTypeUpdateInvalidHtml = Update.builder().id(targetType.getId()).colour(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid colour should not be updated") .as("targetType with invalid colour should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateInvalidHtml)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateInvalidHtml));
} }
private void createTargetTypeWithInvalidKey() { private void createTargetTypeWithInvalidKey() {
final TargetTypeCreate targetTypeCreateTooLong = entityFactory.targetType().create().name(randomString(Type.KEY_MAX_SIZE + 1)); final Create targetTypeCreateTooLong = Create.builder().name(randomString(Type.KEY_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long key should not be created") .as("targetType with too long key should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateTooLong)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateTooLong));
final TargetTypeCreate targetTypeCreateInvalidHtmle = entityFactory.targetType().create().name(INVALID_TEXT_HTML); final Create targetTypeCreateInvalidHtmle = Create.builder().name(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid key should not be created") .as("targetType with invalid key should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtmle)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtmle));
} }
private void createAndUpdateTargetTypeWithInvalidName(final TargetType targetType) { private void createAndUpdateTargetTypeWithInvalidName(final TargetType targetType) {
final TargetTypeCreate targetTypeCreateTooLong = entityFactory.targetType().create().name(randomString(NamedEntity.NAME_MAX_SIZE + 1)); final Create targetTypeCreateTooLong = Create.builder().name(randomString(NamedEntity.NAME_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long name should not be created") .as("targetType with too long name should not be created")
.isThrownBy(() -> targetTypeManagement .isThrownBy(() -> targetTypeManagement
.create(targetTypeCreateTooLong)); .create(targetTypeCreateTooLong));
final TargetTypeCreate targetTypeCreateInvalidHtml = entityFactory.targetType().create().name(INVALID_TEXT_HTML); final Create targetTypeCreateInvalidHtml = Create.builder().name(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid name should not be created") .as("targetType with invalid name should not be created")
.isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtml)); .isThrownBy(() -> targetTypeManagement.create(targetTypeCreateInvalidHtml));
final TargetTypeUpdate targetTypeUpdateTooLong = entityFactory.targetType().update(targetType.getId()).name(randomString(NamedEntity.NAME_MAX_SIZE + 1)); final Update targetTypeUpdateTooLong = Update.builder()
.id(targetType.getId()).name(randomString(NamedEntity.NAME_MAX_SIZE + 1)).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too long name should not be updated") .as("targetType with too long name should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateTooLong)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateTooLong));
final TargetTypeUpdate targetTypeUpdateInvalidHtml = entityFactory.targetType().update(targetType.getId()).name(INVALID_TEXT_HTML); final Update targetTypeUpdateInvalidHtml = Update.builder().id(targetType.getId()).name(INVALID_TEXT_HTML).build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with invalid name should not be updated") .as("targetType with invalid name should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateInvalidHtml)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateInvalidHtml));
final TargetTypeUpdate targetTypeUpdateEmpty = entityFactory.targetType().update(targetType.getId()).name(""); final Update targetTypeUpdateEmpty = Update.builder().id(targetType.getId()).name("").build();
assertThatExceptionOfType(ConstraintViolationException.class) assertThatExceptionOfType(ConstraintViolationException.class)
.as("targetType with too short name should not be updated") .as("targetType with too short name should not be updated")
.isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateEmpty)); .isThrownBy(() -> targetTypeManagement.update(targetTypeUpdateEmpty));

View File

@@ -20,6 +20,7 @@ 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.TargetTagManagement;
import org.eclipse.hawkbit.repository.TargetTypeFields; import org.eclipse.hawkbit.repository.TargetTypeFields;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
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;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
@@ -50,13 +51,13 @@ class RsqlTargetFieldTest extends AbstractJpaIntegrationTest {
@BeforeEach @BeforeEach
void setupBeforeTest() { void setupBeforeTest() {
targetType1 = targetTypeManagement targetType1 = targetTypeManagement
.create(entityFactory.targetType().create() .create(TargetTypeManagement.Create.builder()
.name("Type1").description("Desc. Type1") .name("Type1").description("Desc. Type1").key("Type1.key")
.key("Type1.key")); .build());
targetType2 = targetTypeManagement targetType2 = targetTypeManagement
.create(entityFactory.targetType().create() .create(TargetTypeManagement.Create.builder()
.name("Type2").description("Desc. Type2") .name("Type2").description("Desc. Type2").key("Type2.key")
.key("Type2.key")); .build());
final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs"); final DistributionSet ds = testdataFactory.createDistributionSet("AssignedDs");

View File

@@ -67,6 +67,7 @@ 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.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetType;
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;
@@ -141,7 +142,7 @@ public abstract class AbstractIntegrationTest {
@Autowired @Autowired
protected TargetManagement targetManagement; protected TargetManagement targetManagement;
@Autowired @Autowired
protected TargetTypeManagement targetTypeManagement; protected TargetTypeManagement<? extends TargetType> targetTypeManagement;
@Autowired @Autowired
protected TargetFilterQueryManagement targetFilterQueryManagement; protected TargetFilterQueryManagement targetFilterQueryManagement;
@Autowired @Autowired

View File

@@ -50,7 +50,6 @@ 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.TargetCreate; import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -75,7 +74,6 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModule.MetadataValueCreate; import org.eclipse.hawkbit.repository.model.SoftwareModule.MetadataValueCreate;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
@@ -157,8 +155,8 @@ public class TestdataFactory {
private final DistributionSetInvalidationManagement distributionSetInvalidationManagement; private final DistributionSetInvalidationManagement distributionSetInvalidationManagement;
private final TargetManagement targetManagement; private final TargetManagement targetManagement;
private final TargetFilterQueryManagement targetFilterQueryManagement; private final TargetFilterQueryManagement targetFilterQueryManagement;
private final TargetTypeManagement targetTypeManagement; private final TargetTypeManagement<? extends TargetType> targetTypeManagement;
private final TargetTagManagement targetTagManagement; private final TargetTagManagement<? extends TargetTag> targetTagManagement;
private final DeploymentManagement deploymentManagement; private final DeploymentManagement deploymentManagement;
private final RolloutManagement rolloutManagement; private final RolloutManagement rolloutManagement;
private final RolloutHandler rolloutHandler; private final RolloutHandler rolloutHandler;
@@ -175,7 +173,8 @@ public class TestdataFactory {
final DistributionSetTagManagement<? extends DistributionSetTag> distributionSetTagManagement, final DistributionSetTagManagement<? extends DistributionSetTag> distributionSetTagManagement,
final DistributionSetInvalidationManagement distributionSetInvalidationManagement, final DistributionSetInvalidationManagement distributionSetInvalidationManagement,
final TargetManagement targetManagement, final TargetFilterQueryManagement targetFilterQueryManagement, final TargetManagement targetManagement, final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetTypeManagement targetTypeManagement, final TargetTagManagement targetTagManagement, final TargetTypeManagement<? extends TargetType> targetTypeManagement,
final TargetTagManagement<? extends TargetTag> targetTagManagement,
final DeploymentManagement deploymentManagement, final DeploymentManagement deploymentManagement,
final RolloutManagement rolloutManagement, final RolloutHandler rolloutHandler, final RolloutManagement rolloutManagement, final RolloutHandler rolloutHandler,
final QuotaManagement quotaManagement, final QuotaManagement quotaManagement,
@@ -912,7 +911,7 @@ public class TestdataFactory {
* @param tagPrefix prefix for the {@link TargetTag#getName()} * @param tagPrefix prefix for the {@link TargetTag#getName()}
* @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<? extends TargetTag> createTargetTags(final int number, final String tagPrefix) {
final List<TargetTagManagement.Create> 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(TargetTagManagement.Create.builder().name(tagPrefix + i).description(tagPrefix + i).colour(String.valueOf(i)).build()); result.add(TargetTagManagement.Create.builder().name(tagPrefix + i).description(tagPrefix + i).colour(String.valueOf(i)).build());
@@ -1184,9 +1183,10 @@ public class TestdataFactory {
*/ */
public TargetType findOrCreateTargetType(final String targetTypeName) { public TargetType findOrCreateTargetType(final String targetTypeName) {
return targetTypeManagement.getByName(targetTypeName) return targetTypeManagement.getByName(targetTypeName)
.orElseGet(() -> targetTypeManagement.create(entityFactory.targetType().create() .orElseGet(() -> targetTypeManagement.create(TargetTypeManagement.Create.builder()
.name(targetTypeName).description(targetTypeName + SPACE_AND_DESCRIPTION) .name(targetTypeName).description(targetTypeName + SPACE_AND_DESCRIPTION)
.key(targetTypeName + " key").colour(DEFAULT_COLOUR))); .key(targetTypeName + " key").colour(DEFAULT_COLOUR)
.build()));
} }
/** /**
@@ -1196,10 +1196,11 @@ public class TestdataFactory {
* @param targetTypeName {@link TargetType#getName()} * @param targetTypeName {@link TargetType#getName()}
* @return persisted {@link TargetType} * @return persisted {@link TargetType}
*/ */
public TargetType createTargetType(final String targetTypeName, final List<DistributionSetType> compatibleDsTypes) { public TargetType createTargetType(final String targetTypeName, final Set<DistributionSetType> compatibleDsTypes) {
return targetTypeManagement.create(entityFactory.targetType().create().name(targetTypeName) return targetTypeManagement.create(TargetTypeManagement.Create.builder()
.description(targetTypeName + SPACE_AND_DESCRIPTION).colour(DEFAULT_COLOUR) .name(targetTypeName).description(targetTypeName + SPACE_AND_DESCRIPTION).colour(DEFAULT_COLOUR)
.compatible(compatibleDsTypes.stream().map(DistributionSetType::getId).toList())); .distributionSetTypes(compatibleDsTypes)
.build());
} }
/** /**
@@ -1208,12 +1209,13 @@ public class TestdataFactory {
* @param targetTypePrefix {@link TargetType#getName()} * @param targetTypePrefix {@link TargetType#getName()}
* @return persisted {@link TargetType} * @return persisted {@link TargetType}
*/ */
public List<TargetType> createTargetTypes(final String targetTypePrefix, final int count) { public List<? extends TargetType> createTargetTypes(final String targetTypePrefix, final int count) {
final List<TargetTypeCreate> result = new ArrayList<>(count); final List<TargetTypeManagement.Create> result = new ArrayList<>(count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
result.add(entityFactory.targetType().create() result.add(TargetTypeManagement.Create.builder()
.name(targetTypePrefix + i).description(targetTypePrefix + SPACE_AND_DESCRIPTION) .name(targetTypePrefix + i).description(targetTypePrefix + SPACE_AND_DESCRIPTION)
.key(targetTypePrefix + i + " key").colour(DEFAULT_COLOUR)); .key(targetTypePrefix + i + " key").colour(DEFAULT_COLOUR)
.build());
} }
return targetTypeManagement.create(result); return targetTypeManagement.create(result);
} }

View File

@@ -24,6 +24,7 @@ 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.TargetTagManagement;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
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;
@@ -314,7 +315,7 @@ public class JsonBuilder {
for (final TargetType type : types) { for (final TargetType type : types) {
final JSONArray dsTypes = new JSONArray(); final JSONArray dsTypes = new JSONArray();
type.getCompatibleDistributionSetTypes().forEach(dsType -> { type.getDistributionSetTypes().forEach(dsType -> {
try { try {
dsTypes.put(new JSONObject().put("id", dsType.getId())); dsTypes.put(new JSONObject().put("id", dsType.getId()));
} catch (final JSONException e1) { } catch (final JSONException e1) {
@@ -332,6 +333,30 @@ public class JsonBuilder {
return result.toString(); return result.toString();
} }
public static String targetTypesCreate(final List<TargetTypeManagement.Create> types) throws JSONException {
final JSONArray result = new JSONArray();
for (final TargetTypeManagement.Create type : types) {
final JSONArray dsTypes = new JSONArray();
type.getDistributionSetTypes().forEach(dsType -> {
try {
dsTypes.put(new JSONObject().put("id", dsType));
} catch (final JSONException e1) {
log.error("JSONException (skip)", e1);
}
});
result.put(new JSONObject().put("name", type.getName()).put("description", type.getDescription())
.put("id", Long.MAX_VALUE).put("colour", type.getColour()).put("createdAt", "0")
.put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh")
.put("distributionsets", dsTypes));
}
return result.toString();
}
public static String rollout(final String name, final String description, final int groupSize, public static String rollout(final String name, final String description, final int groupSize,
final long distributionSetId, final String targetFilterQuery, final RolloutGroupConditions conditions) { final long distributionSetId, final String targetFilterQuery, final RolloutGroupConditions conditions) {
return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, null, null, null, return rollout(name, description, groupSize, distributionSetId, targetFilterQuery, conditions, null, null, null,