Fine grained repository permissions (#2562)

1. Introduce @PrreAuthorize check based on hasPermission - allowing custom processing (compared with non-modifiable hasAuthority/Role processing)
2. Dedicated permissions could be implemented on management api level. Check is made by plugged in PermissionEvaluator
3. Thus common XXX_REPOSITORY permissions could differ for extending services
4. Change create/update entity builder pattern - not via EntityFactory but via clean static lombok based builders (with fine fluent api).
5. Implement abstract repository management jpa class that handles the boilerplate code from extending classes in single place consistently -> AbsreactJpaRepositoryManagement
6. Register management api-s as **Sevice**-s instead of **Bean**-s in order to make easier maintainable and get away from heavy argument forwading
7. Simplify custom hawkbit repository registration + adding proxy to handle exception mapping at lower level - thus not depending on Aspects for converting exceptions
8. Implemented general purpose 'copy' utility (ObjectCopyUtil) that using getter/setter patterns is able to copy (e.g. Create/Update) objects to other objects (e.g. JPA entity objects)
This commit is contained in:
Avgustin Marinov
2025-07-28 14:57:33 +03:00
committed by GitHub
parent 8cdbe54cbe
commit 2b66449ff1
214 changed files with 3456 additions and 4416 deletions

View File

@@ -157,25 +157,6 @@ public class TestConfiguration implements AsyncConfigurer {
return SystemManagementHolder.getInstance();
}
@Bean
TestdataFactory testdataFactory(
final ControllerManagement controllerManagement, final ArtifactManagement artifactManagement,
final SoftwareModuleManagement softwareModuleManagement, final SoftwareModuleTypeManagement softwareModuleTypeManagement,
final DistributionSetManagement distributionSetManagement,
final DistributionSetInvalidationManagement distributionSetInvalidationManagement,
final DistributionSetTypeManagement distributionSetTypeManagement,
final TargetManagement targetManagement, final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetTypeManagement targetTypeManagement, final TargetTagManagement targetTagManagement,
final DeploymentManagement deploymentManagement, final DistributionSetTagManagement distributionSetTagManagement,
final RolloutManagement rolloutManagement, final RolloutHandler rolloutHandler,
final QuotaManagement quotaManagement,
final EntityFactory entityFactory, final TenantAware tenantAware) {
return new TestdataFactory(controllerManagement, artifactManagement, softwareModuleManagement, softwareModuleTypeManagement,
distributionSetManagement, distributionSetInvalidationManagement, distributionSetTypeManagement, targetManagement,
targetFilterQueryManagement, targetTypeManagement, targetTagManagement, deploymentManagement,
distributionSetTagManagement, rolloutManagement, rolloutHandler, quotaManagement, entityFactory, tenantAware);
}
@Bean
PropertyBasedArtifactUrlHandler testPropertyBasedArtifactUrlHandler(final ArtifactUrlHandlerProperties urlHandlerProperties) {
return new PropertyBasedArtifactUrlHandler(urlHandlerProperties, "");

View File

@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
@@ -59,8 +60,10 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.DeploymentRequest;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.test.TestConfiguration;
@@ -77,6 +80,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.bus.ServiceMatcher;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@@ -104,6 +108,7 @@ import org.springframework.test.context.TestPropertySource;
listeners = { EventVerifier.class, CleanupTestExecutionListener.class },
mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
@TestPropertySource(properties = "spring.main.allow-bean-definition-overriding=true")
@Import(TestdataFactory.class)
@SuppressWarnings("java:S6813") // constructor injects are not possible for test classes
public abstract class AbstractIntegrationTest {
@@ -122,13 +127,15 @@ public abstract class AbstractIntegrationTest {
@Autowired
protected EntityFactory entityFactory;
@Autowired
protected SoftwareModuleManagement softwareModuleManagement;
protected SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement;
@Autowired
protected SoftwareModuleTypeManagement softwareModuleTypeManagement;
protected SoftwareModuleTypeManagement<? extends SoftwareModuleType> softwareModuleTypeManagement;
@Autowired
protected DistributionSetManagement distributionSetManagement;
protected DistributionSetManagement<? extends DistributionSet> distributionSetManagement;
@Autowired
protected DistributionSetTypeManagement distributionSetTypeManagement;
protected DistributionSetTagManagement<? extends DistributionSetTag> distributionSetTagManagement;
@Autowired
protected DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement;
@Autowired
protected ControllerManagement controllerManagement;
@Autowired
@@ -140,8 +147,6 @@ public abstract class AbstractIntegrationTest {
@Autowired
protected TargetTagManagement targetTagManagement;
@Autowired
protected DistributionSetTagManagement distributionSetTagManagement;
@Autowired
protected DeploymentManagement deploymentManagement;
@Autowired
protected ConfirmationManagement confirmationManagement;
@@ -205,17 +210,17 @@ public abstract class AbstractIntegrationTest {
osType = SecurityContextSwitch
.callAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_OS));
osType = SecurityContextSwitch.callAsPrivileged(() -> softwareModuleTypeManagement
.update(entityFactory.softwareModuleType().update(osType.getId()).description(description)));
.update(SoftwareModuleTypeManagement.Update.builder().id(osType.getId()).description(description).build()));
appType = SecurityContextSwitch.callAsPrivileged(
() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_APP, Integer.MAX_VALUE));
appType = SecurityContextSwitch.callAsPrivileged(() -> softwareModuleTypeManagement
.update(entityFactory.softwareModuleType().update(appType.getId()).description(description)));
.update(SoftwareModuleTypeManagement.Update.builder().id(appType.getId()).description(description).build()));
runtimeType = SecurityContextSwitch
.callAsPrivileged(() -> testdataFactory.findOrCreateSoftwareModuleType(TestdataFactory.SM_TYPE_RT));
runtimeType = SecurityContextSwitch.callAsPrivileged(() -> softwareModuleTypeManagement
.update(entityFactory.softwareModuleType().update(runtimeType.getId()).description(description)));
.update(SoftwareModuleTypeManagement.Update.builder().id(runtimeType.getId()).description(description).build()));
standardDsType = SecurityContextSwitch.callAsPrivileged(() -> testdataFactory.findOrCreateDefaultTestDsType());
@@ -273,6 +278,14 @@ public abstract class AbstractIntegrationTest {
return Awaitility.await().atLeast(AT_LEAST).pollInterval(POLL_INTERVAL).atMost(TIMEOUT);
}
protected DistributionSetType defaultDsType() {
return systemManagement.getTenantMetadata().getDefaultDsType();
}
protected SoftwareModuleType getASmType() {
return defaultDsType().getMandatoryModuleTypes().stream().findAny().orElseThrow();
}
protected static Action getFirstAssignedAction(
final DistributionSetAssignmentResult distributionSetAssignmentResult) {
return distributionSetAssignmentResult.getAssignedEntity().stream().findFirst()
@@ -422,7 +435,15 @@ public abstract class AbstractIntegrationTest {
}
protected Long getOsModule(final DistributionSet ds) {
return ds.findFirstModuleByType(osType).orElseThrow(NoSuchElementException::new).getId();
return findFirstModuleByType(ds, osType).orElseThrow(NoSuchElementException::new).getId();
}
protected Optional<SoftwareModule> findFirstModuleByType(final DistributionSet ds, final SoftwareModuleType type) {
return ds.getModules().stream().filter(module -> module.getType().equals(type)).findAny();
}
protected Optional<? extends SoftwareModule> findFirstModuleByType(final DistributionSetManagement.Create dsCreate, final SoftwareModuleType type) {
return dsCreate.getModules().stream().filter(module -> module.getType().equals(type)).findAny();
}
protected Action prepareFinishedUpdate() {

View File

@@ -19,11 +19,12 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.UUID;
import java.util.stream.IntStream;
@@ -75,19 +76,24 @@ import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
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.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.context.annotation.Profile;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
/**
* Data generator utility for tests.
*/
@Service
@Profile("test")
@SuppressWarnings("java:S107")
public class TestdataFactory {
@@ -144,17 +150,17 @@ public class TestdataFactory {
private final ControllerManagement controllerManagement;
private final ArtifactManagement artifactManagement;
private final SoftwareModuleManagement softwareModuleManagement;
private final SoftwareModuleTypeManagement softwareModuleTypeManagement;
private final DistributionSetManagement distributionSetManagement;
private final SoftwareModuleManagement<?> softwareModuleManagement;
private final SoftwareModuleTypeManagement<?> softwareModuleTypeManagement;
private final DistributionSetManagement<?> distributionSetManagement;
private final DistributionSetTagManagement<?> distributionSetTagManagement;
private final DistributionSetTypeManagement<?> distributionSetTypeManagement;
private final DistributionSetInvalidationManagement distributionSetInvalidationManagement;
private final DistributionSetTypeManagement distributionSetTypeManagement;
private final TargetManagement targetManagement;
private final TargetFilterQueryManagement targetFilterQueryManagement;
private final TargetTypeManagement targetTypeManagement;
private final TargetTagManagement targetTagManagement;
private final DeploymentManagement deploymentManagement;
private final DistributionSetTagManagement distributionSetTagManagement;
private final RolloutManagement rolloutManagement;
private final RolloutHandler rolloutHandler;
private final QuotaManagement quotaManagement;
@@ -163,13 +169,15 @@ public class TestdataFactory {
public TestdataFactory(
final ControllerManagement controllerManagement, final ArtifactManagement artifactManagement,
final SoftwareModuleManagement softwareModuleManagement, final SoftwareModuleTypeManagement softwareModuleTypeManagement,
final DistributionSetManagement distributionSetManagement,
final SoftwareModuleManagement<? extends SoftwareModule> softwareModuleManagement,
final SoftwareModuleTypeManagement<? extends SoftwareModuleType> softwareModuleTypeManagement,
final DistributionSetManagement<? extends DistributionSet> distributionSetManagement,
final DistributionSetTypeManagement<? extends DistributionSetType> distributionSetTypeManagement,
final DistributionSetTagManagement<? extends DistributionSetTag> distributionSetTagManagement,
final DistributionSetInvalidationManagement distributionSetInvalidationManagement,
final DistributionSetTypeManagement distributionSetTypeManagement,
final TargetManagement targetManagement, final TargetFilterQueryManagement targetFilterQueryManagement,
final TargetTypeManagement targetTypeManagement, final TargetTagManagement targetTagManagement,
final DeploymentManagement deploymentManagement, final DistributionSetTagManagement distributionSetTagManagement,
final DeploymentManagement deploymentManagement,
final RolloutManagement rolloutManagement, final RolloutHandler rolloutHandler,
final QuotaManagement quotaManagement,
final EntityFactory entityFactory, final TenantAware tenantAware) {
@@ -177,14 +185,14 @@ public class TestdataFactory {
this.softwareModuleManagement = softwareModuleManagement;
this.softwareModuleTypeManagement = softwareModuleTypeManagement;
this.distributionSetManagement = distributionSetManagement;
this.distributionSetInvalidationManagement = distributionSetInvalidationManagement;
this.distributionSetTagManagement = distributionSetTagManagement;
this.distributionSetTypeManagement = distributionSetTypeManagement;
this.distributionSetInvalidationManagement = distributionSetInvalidationManagement;
this.targetManagement = targetManagement;
this.targetFilterQueryManagement = targetFilterQueryManagement;
this.targetTypeManagement = targetTypeManagement;
this.targetTagManagement = targetTagManagement;
this.deploymentManagement = deploymentManagement;
this.distributionSetTagManagement = distributionSetTagManagement;
this.entityFactory = entityFactory;
this.artifactManagement = artifactManagement;
this.rolloutManagement = rolloutManagement;
@@ -298,32 +306,43 @@ public class TestdataFactory {
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix, final String version, final boolean isRequiredMigrationStep) {
final SoftwareModule appMod = softwareModuleManagement.create(entityFactory.softwareModule().create()
.type(findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE)).name(prefix + SM_TYPE_APP)
.version(version + "." + new SecureRandom().nextInt(100)).description(randomDescriptionLong())
.vendor(prefix + " vendor Limited, California"));
final SoftwareModule appMod = softwareModuleManagement.create(
SoftwareModuleManagement.Create.builder()
.type(findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE))
.name(prefix + SM_TYPE_APP)
.version(version + "." + new SecureRandom().nextInt(100))
.description(randomDescriptionLong())
.vendor(prefix + " vendor Limited, California")
.build());
final SoftwareModule runtimeMod = softwareModuleManagement
.create(entityFactory.softwareModule().create().type(findOrCreateSoftwareModuleType(SM_TYPE_RT))
.name(prefix + "app runtime").version(version + "." + new SecureRandom().nextInt(100))
.description(randomDescriptionLong()).vendor(prefix + " vendor GmbH, Stuttgart, Germany"));
.create(SoftwareModuleManagement.Create.builder()
.type(findOrCreateSoftwareModuleType(SM_TYPE_RT))
.name(prefix + "app runtime")
.version(version + "." + new SecureRandom().nextInt(100))
.description(randomDescriptionLong()).vendor(prefix + " vendor GmbH, Stuttgart, Germany")
.build());
final SoftwareModule osMod = softwareModuleManagement
.create(entityFactory.softwareModule().create().type(findOrCreateSoftwareModuleType(SM_TYPE_OS))
.name(prefix + " Firmware").version(version + "." + new SecureRandom().nextInt(100))
.description(randomDescriptionLong()).vendor(prefix + " vendor Limited Inc, California"));
.create(SoftwareModuleManagement.Create.builder()
.type(findOrCreateSoftwareModuleType(SM_TYPE_OS))
.name(prefix + " Firmware")
.version(version + "." + new SecureRandom().nextInt(100))
.description(randomDescriptionLong()).vendor(prefix + " vendor Limited Inc, California")
.build());
return distributionSetManagement.create(
entityFactory.distributionSet().create()
DistributionSetManagement.Create.builder()
.type(findOrCreateDefaultTestDsType())
.name(ObjectUtils.isEmpty(prefix) ? "DS" : prefix)
.version(version)
.description(randomDescriptionShort())
.modules(Arrays.asList(osMod.getId(), runtimeMod.getId(), appMod.getId()))
.requiredMigrationStep(isRequiredMigrationStep));
.modules(Set.of(osMod, runtimeMod, appMod))
.requiredMigrationStep(isRequiredMigrationStep)
.build());
}
/**
* Adds {@link SoftwareModuleMetadata} to every module of given {@link DistributionSet}.
*
* <p/>
* {@link #VISIBLE_SM_MD_VALUE}, {@link #VISIBLE_SM_MD_KEY} with
* {@link SoftwareModuleMetadata#isTargetVisible()} and
* {@link #INVISIBLE_SM_MD_KEY}, {@link #INVISIBLE_SM_MD_VALUE} without
@@ -349,10 +368,13 @@ public class TestdataFactory {
public DistributionSet createDistributionSet(
final String prefix, final String version, final boolean isRequiredMigrationStep, final Collection<SoftwareModule> modules) {
return distributionSetManagement.create(
entityFactory.distributionSet().create().name(prefix != null && !prefix.isEmpty() ? prefix : "DS")
.version(version).description(randomDescriptionShort()).type(findOrCreateDefaultTestDsType())
.modules(modules.stream().map(SoftwareModule::getId).toList())
.requiredMigrationStep(isRequiredMigrationStep));
DistributionSetManagement.Create.builder()
.type(findOrCreateDefaultTestDsType())
.name(prefix != null && !prefix.isEmpty() ? prefix : "DS")
.version(version).description(randomDescriptionShort())
.modules(new HashSet<>(modules))
.requiredMigrationStep(isRequiredMigrationStep)
.build());
}
/**
@@ -360,14 +382,14 @@ public class TestdataFactory {
* {@link #SM_TYPE_APP}.
*
* @param prefix for {@link SoftwareModule}s and {@link DistributionSet}s name, vendor and description.
* @param version {@link DistributionSet#getVersion()} and {@link SoftwareModule#getVersion()} extended by a random number.updat
* @param version {@link DistributionSet#getVersion()} and {@link SoftwareModule#getVersion()} extended by a random number.
* @param tags DistributionSet tags
* @return {@link DistributionSet} entity.
*/
public DistributionSet createDistributionSet(final String prefix, final String version, final Collection<DistributionSetTag> tags) {
final DistributionSet set = createDistributionSet(prefix, version, false);
tags.forEach(tag -> distributionSetManagement.assignTag(List.of(set.getId()), tag.getId()));
return distributionSetManagement.get(set.getId()).get();
return distributionSetManagement.get(set.getId()).orElseThrow();
}
/**
@@ -391,12 +413,13 @@ public class TestdataFactory {
public List<DistributionSet> createDistributionSetsWithoutModules(final int number) {
final List<DistributionSet> sets = new ArrayList<>(number);
for (int i = 0; i < number; i++) {
sets.add(distributionSetManagement
.create(entityFactory.distributionSet().create()
sets.add(distributionSetManagement.create(
DistributionSetManagement.Create.builder()
.type(findOrCreateDefaultTestDsType())
.name("DS" + i)
.version(DEFAULT_VERSION + "." + i)
.description(randomDescriptionShort())
.type(findOrCreateDefaultTestDsType())));
.build()));
}
return sets;
}
@@ -427,11 +450,13 @@ public class TestdataFactory {
* @return {@link DistributionSet} entity
*/
public DistributionSet createDistributionSetWithNoSoftwareModules(final String name, final String version) {
return distributionSetManagement.create(entityFactory.distributionSet().create()
.name(name)
.version(version)
.description(DEFAULT_DESCRIPTION)
.type(findOrCreateDefaultTestDsType()));
return distributionSetManagement.create(
DistributionSetManagement.Create.builder()
.type(findOrCreateDefaultTestDsType())
.name(name)
.version(version)
.description(DEFAULT_DESCRIPTION)
.build());
}
/**
@@ -538,13 +563,15 @@ public class TestdataFactory {
* @return persisted {@link SoftwareModule}.
*/
public SoftwareModule createSoftwareModule(final String typeKey, final String prefix, final boolean encrypted) {
return softwareModuleManagement.create(entityFactory.softwareModule().create()
.type(findOrCreateSoftwareModuleType(typeKey))
.name(prefix + typeKey)
.version(prefix + DEFAULT_VERSION)
.description(randomDescriptionShort())
.vendor(DEFAULT_VENDOR)
.encrypted(encrypted));
return softwareModuleManagement.create(
SoftwareModuleManagement.Create.builder()
.type(findOrCreateSoftwareModuleType(typeKey))
.name(prefix + typeKey)
.version(prefix + DEFAULT_VERSION)
.description(randomDescriptionShort())
.vendor(DEFAULT_VENDOR)
.encrypted(encrypted)
.build());
}
/**
@@ -597,7 +624,7 @@ public class TestdataFactory {
* Creates {@link DistributionSet}s in repository including three {@link SoftwareModule}s of types {@link #SM_TYPE_OS}, {@link #SM_TYPE_RT} ,
* {@link #SM_TYPE_APP} with {@link #DEFAULT_VERSION} followed by an iterative number and {@link DistributionSet#isRequiredMigrationStep()}
* <code>false</code>.
*
* <p/>
* In addition, it updates the created {@link DistributionSet}s and {@link SoftwareModule}s to ensure that
* {@link BaseEntity#getLastModifiedAt()} and {@link BaseEntity#getLastModifiedBy()} is filled.
*
@@ -606,13 +633,13 @@ public class TestdataFactory {
public DistributionSet createUpdatedDistributionSet() {
DistributionSet set = createDistributionSet("");
set = distributionSetManagement.update(
entityFactory.distributionSet().update(set.getId()).description("Updated " + DEFAULT_DESCRIPTION));
DistributionSetManagement.Update.builder().id(set.getId()).description("Updated " + DEFAULT_DESCRIPTION).build());
set.getModules().forEach(module -> softwareModuleManagement.update(
entityFactory.softwareModule().update(module.getId()).description("Updated " + DEFAULT_DESCRIPTION)));
SoftwareModuleManagement.Update.builder().id(module.getId()).description("Updated " + DEFAULT_DESCRIPTION).build()));
// load also lazy stuff
return distributionSetManagement.getWithDetails(set.getId()).get();
return distributionSetManagement.getWithDetails(set.getId()).orElseThrow();
}
/**
@@ -639,8 +666,10 @@ public class TestdataFactory {
*/
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName) {
return distributionSetTypeManagement.findByKey(dsTypeKey)
.orElseGet(() -> distributionSetTypeManagement.create(entityFactory.distributionSetType().create()
.key(dsTypeKey).name(dsTypeName).description(randomDescriptionShort()).colour("black")));
.map(DistributionSetType.class::cast)
.orElseGet(() -> distributionSetTypeManagement.create(
DistributionSetTypeManagement.Create.builder()
.key(dsTypeKey).name(dsTypeName).description(randomDescriptionShort()).colour("black").build()));
}
/**
@@ -656,14 +685,16 @@ public class TestdataFactory {
public DistributionSetType findOrCreateDistributionSetType(final String dsTypeKey, final String dsTypeName,
final Collection<SoftwareModuleType> mandatory, final Collection<SoftwareModuleType> optional) {
return distributionSetTypeManagement.findByKey(dsTypeKey)
.map(DistributionSetType.class::cast)
.orElseGet(() -> distributionSetTypeManagement.create(
entityFactory.distributionSetType().create()
DistributionSetTypeManagement.Create.builder()
.key(dsTypeKey)
.name(dsTypeName)
.description(randomDescriptionShort())
.colour("black")
.optional(optional.stream().map(SoftwareModuleType::getId).toList())
.mandatory(mandatory.stream().map(SoftwareModuleType::getId).toList())));
.mandatoryModuleTypes(new HashSet<>(mandatory))
.optionalModuleTypes(new HashSet<>(optional))
.build()));
}
/**
@@ -686,11 +717,14 @@ public class TestdataFactory {
*/
public SoftwareModuleType findOrCreateSoftwareModuleType(final String key, final int maxAssignments) {
return softwareModuleTypeManagement.findByKey(key)
.orElseGet(() -> softwareModuleTypeManagement.create(entityFactory.softwareModuleType().create()
.key(key)
.name(key)
.description(randomDescriptionShort()).colour("#ffffff")
.maxAssignments(maxAssignments)));
.map(SoftwareModuleType.class::cast)
.orElseGet(() -> softwareModuleTypeManagement.create(
SoftwareModuleTypeManagement.Create.builder()
.key(key)
.name(key)
.description(randomDescriptionShort()).colour("#ffffff")
.maxAssignments(maxAssignments)
.build()));
}
/**
@@ -704,12 +738,14 @@ public class TestdataFactory {
*/
public DistributionSet createDistributionSet(
final String name, final String version, final DistributionSetType type, final Collection<SoftwareModule> modules) {
return distributionSetManagement.create(entityFactory.distributionSet().create()
.type(type)
.name(name)
.version(version)
.description(randomDescriptionShort())
.modules(modules.stream().map(SoftwareModule::getId).toList()));
return distributionSetManagement.create(
DistributionSetManagement.Create.builder()
.type(type)
.name(name)
.version(version)
.description(randomDescriptionShort())
.modules(new HashSet<>(modules))
.build());
}
/**
@@ -722,15 +758,15 @@ public class TestdataFactory {
* @param requiredMigrationStep {@link DistributionSet#isRequiredMigrationStep()}
* @return the created {@link DistributionSet}
*/
public DistributionSet generateDistributionSet(
public DistributionSetManagement.Create generateDistributionSet(
final String name, final String version, final DistributionSetType type, final Collection<SoftwareModule> modules,
final boolean requiredMigrationStep) {
return entityFactory.distributionSet().create()
return DistributionSetManagement.Create.builder()
.type(type)
.name(name)
.version(version)
.description(randomDescriptionShort())
.modules(modules.stream().map(SoftwareModule::getId).toList())
.modules(new HashSet<>(modules))
.requiredMigrationStep(requiredMigrationStep)
.build();
}
@@ -744,7 +780,7 @@ public class TestdataFactory {
* @param modules {@link DistributionSet#getModules()}
* @return the created {@link DistributionSet}
*/
public DistributionSet generateDistributionSet(
public DistributionSetManagement.Create generateDistributionSet(
final String name, final String version, final DistributionSetType type, final Collection<SoftwareModule> modules) {
return generateDistributionSet(name, version, type, modules, false);
}
@@ -755,7 +791,7 @@ public class TestdataFactory {
* @param name {@link DistributionSet#getName()}
* @return the generated {@link DistributionSet}
*/
public DistributionSet generateDistributionSet(final String name) {
public DistributionSetManagement.Create generateDistributionSet(final String name) {
return generateDistributionSet(name, DEFAULT_VERSION, findOrCreateDefaultTestDsType(), Collections.emptyList(), false);
}
@@ -828,7 +864,7 @@ public class TestdataFactory {
*
* @param numberOfTargets number of targets to create
* @param prefix prefix used for the controller ID and description
* @return set of {@link Target}
* @return list of {@link Target}
*/
public List<Target> createTargets(final int numberOfTargets, final String prefix) {
return createTargets(numberOfTargets, prefix, prefix);
@@ -840,7 +876,7 @@ public class TestdataFactory {
* @param numberOfTargets number of targets to create
* @param controllerIdPrefix prefix used for the controller ID
* @param descriptionPrefix prefix used for the description
* @return set of {@link Target}
* @return list of {@link Target}
*/
public List<Target> createTargets(final int numberOfTargets, final String controllerIdPrefix, final String descriptionPrefix) {
final List<TargetCreate> targets = IntStream.range(0, numberOfTargets)
@@ -858,7 +894,7 @@ public class TestdataFactory {
* @param controllerIdPrefix prefix used for the controller ID
* @param descriptionPrefix prefix used for the description
* @param lastTargetQuery last time the target polled
* @return set of {@link Target}
* @return list of {@link Target}
*/
public List<Target> createTargets(
final int numberOfTargets, final String controllerIdPrefix, final String descriptionPrefix, final Long lastTargetQuery) {
@@ -878,7 +914,7 @@ public class TestdataFactory {
* @return the created set of {@link TargetTag}s
*/
public List<TargetTag> createTargetTags(final int number, final String tagPrefix) {
final List<TagCreate> result = new ArrayList<>(number);
final List<TagCreate<Tag>> result = new ArrayList<>(number);
for (int i = 0; i < number; i++) {
result.add(entityFactory.tag().create().name(tagPrefix + i).description(tagPrefix + i).colour(String.valueOf(i)));
}
@@ -892,11 +928,12 @@ public class TestdataFactory {
* @return the persisted {@link DistributionSetTag}s
*/
public List<DistributionSetTag> createDistributionSetTags(final int number) {
final List<TagCreate> result = new ArrayList<>(number);
final List<DistributionSetTagManagement.Create> result = new ArrayList<>(number);
for (int i = 0; i < number; i++) {
result.add(entityFactory.tag().create().name("tag" + i).description("tagdesc" + i).colour(String.valueOf(i)));
result.add(
DistributionSetTagManagement.Create.builder().name("tag" + i).description("tagdesc" + i).colour(String.valueOf(i)).build());
}
return distributionSetTagManagement.create(result);
return distributionSetTagManagement.create(result).stream().map(DistributionSetTag.class::cast).toList();
}
/**
@@ -908,7 +945,7 @@ public class TestdataFactory {
* @return updated {@link Action}.
*/
public List<Action> sendUpdateActionStatusToTargets(final Collection<Target> targets, final Status status, final String message) {
return sendUpdateActionStatusToTargets(targets, status, Arrays.asList(message));
return sendUpdateActionStatusToTargets(targets, status, List.of(message));
}
/**
@@ -1026,7 +1063,7 @@ public class TestdataFactory {
// Run here, because Scheduler is disabled during tests
rolloutHandleAll();
return rolloutManagement.get(rollout.getId()).get();
return rolloutManagement.get(rollout.getId()).orElseThrow();
}
/**
@@ -1202,9 +1239,12 @@ public class TestdataFactory {
* @return created incomplete {@link DistributionSet}
*/
public DistributionSet createIncompleteDistributionSet() {
return distributionSetManagement.create(entityFactory.distributionSet().create()
.name(UUID.randomUUID().toString()).version(DEFAULT_VERSION).description(randomDescriptionShort())
.type(findOrCreateDefaultTestDsType()).requiredMigrationStep(false));
return distributionSetManagement.create(
DistributionSetManagement.Create.builder()
.name(UUID.randomUUID().toString()).version(DEFAULT_VERSION).description(randomDescriptionShort())
.type(findOrCreateDefaultTestDsType())
.requiredMigrationStep(false)
.build());
}
private static String randomDescriptionShort() {
@@ -1248,7 +1288,7 @@ public class TestdataFactory {
}
private List<Target> createTargets(final Collection<TargetCreate> targetCreates) {
// init new instance of array list since the TargetManagement#create will provide a unmodifiable list
// init new instance of array list since the TargetManagement#create will provide an unmodifiable list
return new ArrayList<>(targetManagement.create(targetCreates));
}