Feature soft autoassignment (#789)
* Repository layer and database migration * Changed target filter management to update auto assignment action type together with distribution set, extended mgmt API, adapted auto assign checker/scheduler, changed auto assign distribution set select table to combobox, added filter functionality (needs refactoring) * Refactored auto assignment dialog window, added soft/forced option group, restructured action type option group layout * Added forced icon to target filter table autoassignment cell for the forced auto assign actions * First working draft of distribution set select combobox for auto assignment window * Optimised filtering queries, added alphabetical sorting on distribution set name and version * Refactoring of distribution bean query for lazy loading * Distribution set combobox refactoring and comments * Added verification of auto assign distribution set validity (completed, not deleted), exdended target filter query fields with auto assign action type field, added rsql filter tests, added repository layer tests * Added mgmt API tests * Changed target filter rest docu tests to include auto-assignment type * Updated hawkbit docs with auto-assignment description * Added debouncing to key and value input fields of metadata popup layout to get rid of unnecessary value change events, removed redundant set value call in common dialog window, minimizing the repaint components calls * Fixed sonar findings * Reverted changes of common dialog window validaton, setting the value of the field explicitly as before, until we rethink the whole concept of validaton mechanism * Fixed review findings * Removed rsql filtering by filter auto-assign action type, due to missing conversion of disallowed timeforced action type * Small fix regarding usage of page request * Updated sql script version for flyway * Extended tests for soft deleted distribution sets for auto-assignment and filter string within distribution set specification builder Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch-si.com>
This commit is contained in:
committed by
Stefan Behl
parent
185f88e19b
commit
664c467920
@@ -267,7 +267,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
if (!assigned.isEmpty()) {
|
||||
final Long[] dsIds = assigned.toArray(new Long[assigned.size()]);
|
||||
distributionSetRepository.deleteDistributionSet(dsIds);
|
||||
targetFilterQueryRepository.unsetAutoAssignDistributionSet(dsIds);
|
||||
targetFilterQueryRepository.unsetAutoAssignDistributionSetAndActionType(dsIds);
|
||||
}
|
||||
|
||||
// mark the rest as hard delete
|
||||
@@ -276,6 +276,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
|
||||
// hard delete the rest if exists
|
||||
if (!toHardDelete.isEmpty()) {
|
||||
targetFilterQueryRepository
|
||||
.unsetAutoAssignDistributionSetAndActionType(toHardDelete.toArray(new Long[toHardDelete.size()]));
|
||||
// don't give the delete statement an empty list, JPA/Oracle cannot
|
||||
// handle the empty list
|
||||
distributionSetRepository.deleteByIdIn(toHardDelete);
|
||||
@@ -602,7 +604,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
|
||||
private static List<Specification<JpaDistributionSet>> buildDistributionSetSpecifications(
|
||||
final DistributionSetFilter distributionSetFilter) {
|
||||
final List<Specification<JpaDistributionSet>> specList = Lists.newArrayListWithExpectedSize(7);
|
||||
final List<Specification<JpaDistributionSet>> specList = Lists.newArrayListWithExpectedSize(8);
|
||||
|
||||
Specification<JpaDistributionSet> spec;
|
||||
|
||||
@@ -626,6 +628,14 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
specList.add(spec);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(distributionSetFilter.getFilterString())) {
|
||||
final String[] dsFilterNameAndVersionEntries = getDsFilterNameAndVersionEntries(
|
||||
distributionSetFilter.getFilterString().trim());
|
||||
spec = DistributionSetSpecification.likeNameAndVersion(dsFilterNameAndVersionEntries[0],
|
||||
dsFilterNameAndVersionEntries[1]);
|
||||
specList.add(spec);
|
||||
}
|
||||
|
||||
if (isDSWithNoTagSelected(distributionSetFilter) || isTagsSelected(distributionSetFilter)) {
|
||||
spec = DistributionSetSpecification.hasTags(distributionSetFilter.getTagNames(),
|
||||
distributionSetFilter.getSelectDSWithNoTag());
|
||||
@@ -642,6 +652,19 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
||||
return specList;
|
||||
}
|
||||
|
||||
// the format of filter string is 'name:version'. 'name' and 'version'
|
||||
// fields follow the starts_with semantic, that changes to equal for 'name'
|
||||
// field when the semicolon is present
|
||||
private static String[] getDsFilterNameAndVersionEntries(final String filterString) {
|
||||
final int semicolonIndex = filterString.indexOf(':');
|
||||
|
||||
final String dsFilterName = semicolonIndex != -1 ? filterString.substring(0, semicolonIndex)
|
||||
: (filterString + "%");
|
||||
final String dsFilterVersion = semicolonIndex != -1 ? (filterString.substring(semicolonIndex + 1) + "%") : "%";
|
||||
|
||||
return new String[] { !StringUtils.isEmpty(dsFilterName) ? dsFilterName : "%", dsFilterVersion };
|
||||
}
|
||||
|
||||
private void assertDistributionSetIsNotAssignedToTargets(final Long distributionSet) {
|
||||
if (actionRepository.countByDistributionSetId(distributionSet) > 0) {
|
||||
throw new EntityReadOnlyException(String.format(
|
||||
|
||||
@@ -22,6 +22,8 @@ import org.eclipse.hawkbit.repository.builder.GenericTargetFilterQueryUpdate;
|
||||
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
|
||||
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryUpdate;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.jpa.builder.JpaTargetFilterQueryCreate;
|
||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
@@ -30,6 +32,7 @@ import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
@@ -88,7 +91,9 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
|
||||
// enforce the 'max targets per auto assign' quota right here even if
|
||||
// the result of the filter query can vary over time
|
||||
create.getSet().flatMap(set -> create.getQuery()).ifPresent(this::assertMaxTargetsQuota);
|
||||
if (create.getAutoAssignDistributionSetId().isPresent()) {
|
||||
create.getQuery().ifPresent(this::assertMaxTargetsQuota);
|
||||
}
|
||||
|
||||
return targetFilterQueryRepository.save(create.build());
|
||||
}
|
||||
@@ -217,24 +222,53 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public TargetFilterQuery updateAutoAssignDS(final long queryId, final Long dsId) {
|
||||
public TargetFilterQuery updateAutoAssignDSWithActionType(final long queryId, final Long dsId,
|
||||
final ActionType actionType) {
|
||||
final JpaTargetFilterQuery targetFilterQuery = findTargetFilterQueryOrThrowExceptionIfNotFound(queryId);
|
||||
|
||||
targetFilterQuery.setAutoAssignDistributionSet(
|
||||
Optional.ofNullable(dsId).map(this::findDistributionSetAndThrowExceptionIfNotFound).orElse(null));
|
||||
|
||||
// we cannot be sure that the quota was enforced at creation time
|
||||
// because the Target Filter Query REST API does not allow to specify an
|
||||
// auto-assign distribution set when creating a target filter query
|
||||
if (dsId != null) {
|
||||
if (dsId == null) {
|
||||
targetFilterQuery.setAutoAssignDistributionSet(null);
|
||||
targetFilterQuery.setAutoAssignActionType(null);
|
||||
} else {
|
||||
// we cannot be sure that the quota was enforced at creation time
|
||||
// because the Target Filter Query REST API does not allow to
|
||||
// specify an
|
||||
// auto-assign distribution set when creating a target filter query
|
||||
assertMaxTargetsQuota(targetFilterQuery.getQuery());
|
||||
|
||||
final JpaDistributionSet distributionSetToAutoAssign = findDistributionSetAndThrowExceptionIfNotFound(dsId);
|
||||
// must be completed and not soft deleted
|
||||
verifyDistributionSetAndThrowExceptionIfNotValid(distributionSetToAutoAssign);
|
||||
|
||||
targetFilterQuery.setAutoAssignDistributionSet(distributionSetToAutoAssign);
|
||||
// the action type is set to FORCED per default (when not explicitly
|
||||
// specified)
|
||||
targetFilterQuery.setAutoAssignActionType(sanitizeAutoAssignActionType(actionType));
|
||||
}
|
||||
|
||||
return targetFilterQueryRepository.save(targetFilterQuery);
|
||||
}
|
||||
|
||||
private static void verifyDistributionSetAndThrowExceptionIfNotValid(final DistributionSet distributionSet) {
|
||||
if (!distributionSet.isComplete() || distributionSet.isDeleted()) {
|
||||
throw new InvalidAutoAssignDistributionSetException();
|
||||
}
|
||||
}
|
||||
|
||||
private static ActionType sanitizeAutoAssignActionType(final ActionType actionType) {
|
||||
if (actionType == null) {
|
||||
return ActionType.FORCED;
|
||||
}
|
||||
|
||||
if (!TargetFilterQuery.ALLOWED_AUTO_ASSIGN_ACTION_TYPES.contains(actionType)) {
|
||||
throw new InvalidAutoAssignActionTypeException();
|
||||
}
|
||||
|
||||
return actionType;
|
||||
}
|
||||
|
||||
private JpaDistributionSet findDistributionSetAndThrowExceptionIfNotFound(final Long setId) {
|
||||
return (JpaDistributionSet) distributionSetManagement.getWithDetails(setId)
|
||||
return (JpaDistributionSet) distributionSetManagement.get(setId)
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, setId));
|
||||
}
|
||||
|
||||
|
||||
@@ -45,15 +45,16 @@ public interface TargetFilterQueryRepository
|
||||
Page<JpaTargetFilterQuery> findAll();
|
||||
|
||||
/**
|
||||
* Sets the auto assign distribution sets to null which match the ds ids.
|
||||
* Sets the auto assign distribution sets and action types to null which
|
||||
* match the ds ids.
|
||||
*
|
||||
* @param dsIds
|
||||
* distribution set ids to be set to null
|
||||
*/
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query("update JpaTargetFilterQuery d set d.autoAssignDistributionSet = NULL where d.autoAssignDistributionSet in :ids")
|
||||
void unsetAutoAssignDistributionSet(@Param("ids") Long... dsIds);
|
||||
@Query("update JpaTargetFilterQuery d set d.autoAssignDistributionSet = NULL, d.autoAssignActionType = NULL where d.autoAssignDistributionSet in :ids")
|
||||
void unsetAutoAssignDistributionSetAndActionType(@Param("ids") Long... dsIds);
|
||||
|
||||
/**
|
||||
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety
|
||||
|
||||
@@ -17,7 +17,8 @@ import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||
import org.eclipse.hawkbit.repository.DeploymentManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.RepositoryModelConstants;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
@@ -28,12 +29,9 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
/**
|
||||
* Checks if targets need a new distribution set (DS) based on the target filter
|
||||
@@ -52,7 +50,7 @@ public class AutoAssignChecker {
|
||||
|
||||
private final DeploymentManagement deploymentManagement;
|
||||
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
private final PlatformTransactionManager transactionManager;
|
||||
|
||||
/**
|
||||
* Maximum for target filter queries with auto assign DS Maximum for targets
|
||||
@@ -84,13 +82,7 @@ public class AutoAssignChecker {
|
||||
this.targetFilterQueryManagement = targetFilterQueryManagement;
|
||||
this.targetManagement = targetManagement;
|
||||
this.deploymentManagement = deploymentManagement;
|
||||
|
||||
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
|
||||
def.setName("autoAssignDSToTargets");
|
||||
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
def.setReadOnly(false);
|
||||
def.setIsolationLevel(Isolation.READ_COMMITTED.value());
|
||||
transactionTemplate = new TransactionTemplate(transactionManager, def);
|
||||
this.transactionManager = transactionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,8 +96,7 @@ public class AutoAssignChecker {
|
||||
|
||||
final PageRequest pageRequest = PageRequest.of(0, PAGE_SIZE);
|
||||
|
||||
final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement
|
||||
.findWithAutoAssignDS(pageRequest);
|
||||
final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement.findWithAutoAssignDS(pageRequest);
|
||||
|
||||
for (final TargetFilterQuery filterQuery : filterQueries) {
|
||||
checkByTargetFilterQueryAndAssignDS(filterQuery);
|
||||
@@ -149,15 +140,17 @@ public class AutoAssignChecker {
|
||||
*/
|
||||
private int runTransactionalAssignment(final TargetFilterQuery targetFilterQuery, final Long dsId) {
|
||||
final String actionMessage = String.format(ACTION_MESSAGE, targetFilterQuery.getName());
|
||||
return transactionTemplate.execute(status -> {
|
||||
final List<TargetWithActionType> targets = getTargetsWithActionType(targetFilterQuery.getQuery(), dsId,
|
||||
PAGE_SIZE);
|
||||
final int count = targets.size();
|
||||
if (count > 0) {
|
||||
deploymentManagement.assignDistributionSet(dsId, targets, actionMessage);
|
||||
}
|
||||
return count;
|
||||
});
|
||||
|
||||
return DeploymentHelper.runInNewTransaction(transactionManager, "autoAssignDSToTargets",
|
||||
Isolation.READ_COMMITTED.value(), status -> {
|
||||
final List<TargetWithActionType> targets = getTargetsWithActionType(targetFilterQuery.getQuery(),
|
||||
dsId, targetFilterQuery.getAutoAssignActionType(), PAGE_SIZE);
|
||||
final int count = targets.size();
|
||||
if (count > 0) {
|
||||
deploymentManagement.assignDistributionSet(dsId, targets, actionMessage);
|
||||
}
|
||||
return count;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,17 +162,22 @@ public class AutoAssignChecker {
|
||||
* @param dsId
|
||||
* dsId the targets are not allowed to have in their action
|
||||
* history
|
||||
* @param type
|
||||
* action type for targets auto assignment
|
||||
* @param count
|
||||
* maximum amount of targets to retrieve
|
||||
* @return list of targets with action type
|
||||
*/
|
||||
private List<TargetWithActionType> getTargetsWithActionType(final String targetFilterQuery, final Long dsId,
|
||||
final int count) {
|
||||
final Page<Target> targets = targetManagement
|
||||
.findByTargetFilterQueryAndNonDS(PageRequest.of(0, count), dsId, targetFilterQuery);
|
||||
final ActionType type, final int count) {
|
||||
final Page<Target> targets = targetManagement.findByTargetFilterQueryAndNonDS(PageRequest.of(0, count), dsId,
|
||||
targetFilterQuery);
|
||||
// the action type is set to FORCED per default (when not explicitly
|
||||
// specified)
|
||||
final ActionType autoAssignActionType = type == null ? ActionType.FORCED : type;
|
||||
|
||||
return targets.getContent().stream().map(t -> new TargetWithActionType(t.getControllerId(),
|
||||
Action.ActionType.FORCED, RepositoryModelConstants.NO_FORCE_TIME)).collect(Collectors.toList());
|
||||
autoAssignActionType, RepositoryModelConstants.NO_FORCE_TIME)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,8 +12,11 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.AbstractTargetFilterQueryUpdateCreate;
|
||||
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryCreate;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
|
||||
/**
|
||||
* Create/build implementation.
|
||||
@@ -32,7 +35,8 @@ public class JpaTargetFilterQueryCreate extends AbstractTargetFilterQueryUpdateC
|
||||
public JpaTargetFilterQuery build() {
|
||||
|
||||
return new JpaTargetFilterQuery(name, query,
|
||||
getSet().map(this::findDistributionSetAndThrowExceptionIfNotFound).orElse(null));
|
||||
getAutoAssignDistributionSetId().map(this::findDistributionSetAndThrowExceptionIfNotFound).orElse(null),
|
||||
getAutoAssignActionType().filter(JpaTargetFilterQueryCreate::isAutoAssignActionTypeValid).orElse(null));
|
||||
}
|
||||
|
||||
private DistributionSet findDistributionSetAndThrowExceptionIfNotFound(final Long setId) {
|
||||
@@ -40,4 +44,12 @@ public class JpaTargetFilterQueryCreate extends AbstractTargetFilterQueryUpdateC
|
||||
.orElseThrow(() -> new EntityNotFoundException(DistributionSet.class, setId));
|
||||
}
|
||||
|
||||
private static boolean isAutoAssignActionTypeValid(final ActionType actionType) {
|
||||
if (!TargetFilterQuery.ALLOWED_AUTO_ASSIGN_ACTION_TYPES.contains(actionType)) {
|
||||
throw new InvalidAutoAssignActionTypeException();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,10 +23,15 @@ import javax.validation.constraints.Size;
|
||||
import org.eclipse.hawkbit.repository.event.remote.TargetFilterQueryDeletedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryUpdatedEvent;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
|
||||
import org.eclipse.persistence.annotations.ConversionValue;
|
||||
import org.eclipse.persistence.annotations.Convert;
|
||||
import org.eclipse.persistence.annotations.ObjectTypeConverter;
|
||||
import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
|
||||
/**
|
||||
@@ -41,7 +46,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent;
|
||||
@SuppressWarnings("squid:S2160")
|
||||
public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity
|
||||
implements TargetFilterQuery, EventAwareEntity {
|
||||
private static final long serialVersionUID = 7493966984413479089L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column(name = "name", length = NamedEntity.NAME_MAX_SIZE, nullable = false)
|
||||
@Size(max = NamedEntity.NAME_MAX_SIZE)
|
||||
@@ -57,6 +62,13 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity
|
||||
@JoinColumn(name = "auto_assign_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_filter_auto_assign_ds"))
|
||||
private JpaDistributionSet autoAssignDistributionSet;
|
||||
|
||||
@Column(name = "auto_assign_action_type", nullable = true)
|
||||
@ObjectTypeConverter(name = "autoAssignActionType", objectType = Action.ActionType.class, dataType = Integer.class, conversionValues = {
|
||||
@ConversionValue(objectValue = "FORCED", dataValue = "0"),
|
||||
@ConversionValue(objectValue = "SOFT", dataValue = "1") })
|
||||
@Convert("autoAssignActionType")
|
||||
private ActionType autoAssignActionType;
|
||||
|
||||
public JpaTargetFilterQuery() {
|
||||
// Default constructor for JPA.
|
||||
}
|
||||
@@ -70,12 +82,15 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity
|
||||
* of the {@link TargetFilterQuery}.
|
||||
* @param autoAssignDistributionSet
|
||||
* of the {@link TargetFilterQuery}.
|
||||
* @param autoAssignActionType
|
||||
* of the {@link TargetFilterQuery}.
|
||||
*/
|
||||
public JpaTargetFilterQuery(final String name, final String query,
|
||||
final DistributionSet autoAssignDistributionSet) {
|
||||
public JpaTargetFilterQuery(final String name, final String query, final DistributionSet autoAssignDistributionSet,
|
||||
final ActionType autoAssignActionType) {
|
||||
this.name = name;
|
||||
this.query = query;
|
||||
this.autoAssignDistributionSet = (JpaDistributionSet) autoAssignDistributionSet;
|
||||
this.autoAssignActionType = autoAssignActionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -105,6 +120,15 @@ public class JpaTargetFilterQuery extends AbstractJpaTenantAwareBaseEntity
|
||||
this.autoAssignDistributionSet = distributionSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionType getAutoAssignActionType() {
|
||||
return autoAssignActionType;
|
||||
}
|
||||
|
||||
public void setAutoAssignActionType(final ActionType actionType) {
|
||||
this.autoAssignActionType = actionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireCreateEvent(final DescriptorEvent descriptorEvent) {
|
||||
EventPublisherHolder.getInstance().getEventPublisher().publishEvent(
|
||||
|
||||
@@ -120,6 +120,22 @@ public final class DistributionSetSpecification {
|
||||
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.description)), subString.toLowerCase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Specification} for retrieving {@link DistributionSet}s by "like
|
||||
* name and like version".
|
||||
*
|
||||
* @param name
|
||||
* to be filtered on
|
||||
* @param version
|
||||
* to be filtered on
|
||||
* @return the {@link DistributionSet} {@link Specification}
|
||||
*/
|
||||
public static Specification<JpaDistributionSet> likeNameAndVersion(final String name, final String version) {
|
||||
return (targetRoot, query, cb) -> cb.and(
|
||||
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
|
||||
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Specification} for retrieving {@link DistributionSet}s by "has at
|
||||
* least one of the given tag names".
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
@@ -83,10 +84,30 @@ public final class DeploymentHelper {
|
||||
*/
|
||||
public static <T> T runInNewTransaction(@NotNull final PlatformTransactionManager txManager,
|
||||
final String transactionName, @NotNull final TransactionCallback<T> action) {
|
||||
return runInNewTransaction(txManager, transactionName, Isolation.DEFAULT.value(), action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the modifying action in new transaction
|
||||
*
|
||||
* @param txManager
|
||||
* transaction manager interface
|
||||
* @param transactionName
|
||||
* the name of the new transaction
|
||||
* @param isolationLevel
|
||||
* isolation level of the new transaction
|
||||
* @param action
|
||||
* the callback to execute in new tranaction
|
||||
*
|
||||
* @return the result of the action
|
||||
*/
|
||||
public static <T> T runInNewTransaction(@NotNull final PlatformTransactionManager txManager,
|
||||
final String transactionName, final int isolationLevel, @NotNull final TransactionCallback<T> action) {
|
||||
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
|
||||
def.setName(transactionName);
|
||||
def.setReadOnly(false);
|
||||
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||
def.setIsolationLevel(isolationLevel);
|
||||
return new TransactionTemplate(txManager, def).execute(action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_action_type INTEGER;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_action_type integer;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE sp_target_filter_query ADD COLUMN auto_assign_action_type integer;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE sp_target_filter_query ADD auto_assign_action_type INTEGER;
|
||||
@@ -14,10 +14,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
@@ -627,9 +629,10 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
.create(entityFactory.tag().create().name("DistributionSetTag-C"));
|
||||
distributionSetTagManagement.create(entityFactory.tag().create().name("DistributionSetTag-D"));
|
||||
|
||||
List<DistributionSet> ds5Group1 = testdataFactory.createDistributionSets("", 5);
|
||||
List<DistributionSet> dsGroup2 = testdataFactory.createDistributionSets("test2", 5);
|
||||
DistributionSet dsDeleted = testdataFactory.createDistributionSet("deleted");
|
||||
List<DistributionSet> dsGroup1 = testdataFactory.createDistributionSets("", 5);
|
||||
final String dsGroup2Prefix = "test";
|
||||
List<DistributionSet> dsGroup2 = testdataFactory.createDistributionSets(dsGroup2Prefix, 5);
|
||||
DistributionSet dsDeleted = testdataFactory.createDistributionSet("testDeleted");
|
||||
final DistributionSet dsInComplete = distributionSetManagement.create(entityFactory.distributionSet().create()
|
||||
.name("notcomplete").version("1").type(standardDsType.getKey()));
|
||||
|
||||
@@ -649,185 +652,268 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
||||
distributionSetManagement.delete(dsDeleted.getId());
|
||||
dsDeleted = distributionSetManagement.get(dsDeleted.getId()).get();
|
||||
|
||||
ds5Group1 = toggleTagAssignment(ds5Group1, dsTagA).getAssignedEntity();
|
||||
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagA).getAssignedEntity();
|
||||
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
|
||||
ds5Group1 = toggleTagAssignment(ds5Group1, dsTagB).getAssignedEntity();
|
||||
dsGroup1 = toggleTagAssignment(dsGroup1, dsTagB).getAssignedEntity();
|
||||
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
|
||||
dsGroup2 = toggleTagAssignment(dsGroup2, dsTagA).getAssignedEntity();
|
||||
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName()).get();
|
||||
|
||||
final List<DistributionSet> allDistributionSets = Stream
|
||||
.of(dsGroup1, dsGroup2, Arrays.asList(dsDeleted, dsInComplete, dsNewType)).flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
final List<DistributionSet> dsGroup1WithGroup2 = Stream.of(dsGroup1, dsGroup2).flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
final int sizeOfAllDistributionSets = allDistributionSets.size();
|
||||
|
||||
// check setup
|
||||
assertThat(distributionSetRepository.findAll()).hasSize(13);
|
||||
assertThat(distributionSetRepository.findAll()).hasSize(sizeOfAllDistributionSets);
|
||||
|
||||
// Find all
|
||||
List<DistributionSet> expected = Lists.newArrayListWithExpectedSize(13);
|
||||
expected.addAll(ds5Group1);
|
||||
expected.addAll(dsGroup2);
|
||||
expected.add(dsDeleted);
|
||||
expected.add(dsInComplete);
|
||||
expected.add(dsNewType);
|
||||
validateFindAll(allDistributionSets);
|
||||
validateDeleted(dsDeleted, sizeOfAllDistributionSets - 1);
|
||||
validateCompleted(dsInComplete, sizeOfAllDistributionSets - 1);
|
||||
validateType(newType, dsNewType, sizeOfAllDistributionSets - 1);
|
||||
validateSearchText(dsGroup2, "%" + dsGroup2Prefix);
|
||||
validateFilterString(allDistributionSets, dsGroup2Prefix);
|
||||
validateTags(dsTagA, dsTagB, dsTagC, dsGroup1WithGroup2, dsGroup1);
|
||||
validateDeletedAndCompleted(dsGroup1WithGroup2, dsNewType, dsDeleted);
|
||||
validateDeletedAndCompletedAndType(dsGroup1WithGroup2, dsDeleted, newType, dsNewType);
|
||||
validateDeletedAndCompletedAndTypeAndSearchText(dsGroup2, newType, "%" + dsGroup2Prefix);
|
||||
validateDeletedAndCompletedAndTypeAndFilterString(dsGroup1WithGroup2, dsDeleted, dsInComplete, dsNewType,
|
||||
newType, ":1");
|
||||
validateDeletedAndCompletedAndTypeAndSearchTextAndTag(dsGroup2, dsTagA, "%" + dsGroup2Prefix);
|
||||
}
|
||||
|
||||
assertThat(distributionSetManagement
|
||||
.findByDistributionSetFilter(PAGE, getDistributionSetFilterBuilder().build()).getContent()).hasSize(13)
|
||||
.containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
@Step
|
||||
private void validateFindAll(final List<DistributionSet> expectedDistributionsets) {
|
||||
|
||||
DistributionSetFilterBuilder distributionSetFilterBuilder;
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder(), expectedDistributionsets);
|
||||
}
|
||||
|
||||
// search for not deleted
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1);
|
||||
@Step
|
||||
private void validateDeleted(final DistributionSet deletedDistributionSet, final int notDeletedSize) {
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(false);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(12);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE),
|
||||
Arrays.asList(deletedDistributionSet));
|
||||
|
||||
// search for completed
|
||||
expected = new ArrayList<>();
|
||||
expected.addAll(ds5Group1);
|
||||
expected.addAll(dsGroup2);
|
||||
expected.add(dsDeleted);
|
||||
expected.add(dsNewType);
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE), notDeletedSize, deletedDistributionSet);
|
||||
}
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(12).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
@Step
|
||||
private void validateCompleted(final DistributionSet dsIncomplete, final int completedSize) {
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE);
|
||||
expected = new ArrayList<>();
|
||||
expected.add(dsInComplete);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE), completedSize, dsIncomplete);
|
||||
|
||||
// search for type
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(newType);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE), Arrays.asList(dsIncomplete));
|
||||
}
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(standardDsType);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(12);
|
||||
@Step
|
||||
private void validateType(final DistributionSetType newType, final DistributionSet dsNewType,
|
||||
final int standardDsTypeSize) {
|
||||
|
||||
// search for text
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setSearchText("%test2");
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(5);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType),
|
||||
Arrays.asList(dsNewType));
|
||||
|
||||
// search for tags
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName()));
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(10);
|
||||
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
getDistributionSetFilterBuilder().setType(standardDsType), standardDsTypeSize, dsNewType);
|
||||
}
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagB.getName()));
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(5);
|
||||
@Step
|
||||
private void validateSearchText(final List<DistributionSet> withText, final String text) {
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
|
||||
.setTagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName()));
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(10);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(text),
|
||||
withText);
|
||||
}
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder()
|
||||
.setTagNames(Arrays.asList(dsTagC.getName(), dsTagB.getName()));
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(5);
|
||||
@Step
|
||||
private void validateFilterString(final List<DistributionSet> allDistributionSets, final String dsNamePrefix) {
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagC.getName()));
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
final List<DistributionSet> withTestNamePrefix = allDistributionSets.stream()
|
||||
.filter(ds -> ds.getName().startsWith(dsNamePrefix)).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix), withTestNamePrefix);
|
||||
|
||||
// combine deleted and complete
|
||||
expected = new ArrayList<>();
|
||||
expected.addAll(ds5Group1);
|
||||
expected.addAll(dsGroup2);
|
||||
expected.add(dsNewType);
|
||||
final List<DistributionSet> withTestNameExact = withTestNamePrefix.stream()
|
||||
.filter(ds -> ds.getName().equals(dsNamePrefix)).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix + ":"), withTestNameExact);
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setIsDeleted(Boolean.FALSE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(11).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
final List<DistributionSet> withTestNameExactAndVersionPrefix = withTestNameExact.stream()
|
||||
.filter(ds -> ds.getVersion().startsWith("1")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix + ":1"),
|
||||
withTestNameExactAndVersionPrefix);
|
||||
|
||||
expected = Arrays.asList(dsInComplete);
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
final List<DistributionSet> dsWithExactNameAndVersion = withTestNameExactAndVersionPrefix.stream()
|
||||
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
|
||||
assertThat(dsWithExactNameAndVersion).hasSize(1);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix + ":1.0.0"), dsWithExactNameAndVersion);
|
||||
|
||||
expected = Arrays.asList(dsDeleted);
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setIsDeleted(Boolean.TRUE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
final List<DistributionSet> withVersionPrefix = allDistributionSets.stream()
|
||||
.filter(ds -> ds.getVersion().startsWith("1.0.")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(":1.0."),
|
||||
withVersionPrefix);
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
|
||||
.setIsComplete(Boolean.FALSE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
final List<DistributionSet> withVersionExact = withVersionPrefix.stream()
|
||||
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(":1.0.0"),
|
||||
withVersionExact);
|
||||
|
||||
// combine deleted and complete and type
|
||||
expected = new ArrayList<>();
|
||||
expected.addAll(ds5Group1);
|
||||
expected.addAll(dsGroup2);
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE)
|
||||
.setIsComplete(Boolean.TRUE).setType(standardDsType);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(10).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(":"),
|
||||
allDistributionSets);
|
||||
|
||||
expected = Arrays.asList(dsDeleted);
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setType(standardDsType).setIsDeleted(Boolean.TRUE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(" : "),
|
||||
allDistributionSets);
|
||||
}
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
|
||||
.setIsComplete(Boolean.FALSE).setType(standardDsType);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
@Step
|
||||
private void validateTags(final DistributionSetTag dsTagA, final DistributionSetTag dsTagB,
|
||||
final DistributionSetTag dsTagC, final List<DistributionSet> dsWithTagA,
|
||||
final List<DistributionSet> dsWithTagB) {
|
||||
|
||||
expected = Arrays.asList(dsNewType);
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(1).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName())), dsWithTagA);
|
||||
|
||||
// combine deleted and complete and type and text
|
||||
expected = dsGroup2;
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setType(standardDsType).setSearchText("%test2");
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(5).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagB.getName())), dsWithTagB);
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setSearchText("%test2");
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagA.getName(), dsTagB.getName())),
|
||||
dsWithTagA);
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(standardDsType).setSearchText("%test2")
|
||||
.setIsComplete(false).setIsDeleted(false);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagC.getName(), dsTagB.getName())),
|
||||
dsWithTagB);
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(newType).setSearchText("%test2")
|
||||
.setIsComplete(Boolean.TRUE).setIsDeleted(false);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
getDistributionSetFilterBuilder().setTagNames(Arrays.asList(dsTagC.getName())));
|
||||
}
|
||||
|
||||
// combine deleted and complete and type and text and tag
|
||||
expected = dsGroup2;
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true).setType(standardDsType)
|
||||
.setSearchText("%test2").setTagNames(Arrays.asList(dsTagA.getName()));
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(5).containsOnly(expected.toArray(new DistributionSet[0]));
|
||||
@Step
|
||||
private void validateDeletedAndCompleted(final List<DistributionSet> completedStandardType,
|
||||
final DistributionSet dsNewType, final DistributionSet dsDeleted) {
|
||||
|
||||
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setType(standardDsType).setSearchText("%test2")
|
||||
.setTagNames(Arrays.asList(dsTagA.getName())).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE);
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
|
||||
.getContent()).hasSize(0);
|
||||
final List<DistributionSet> completedNotDeleted = new ArrayList<>(completedStandardType);
|
||||
completedNotDeleted.add(dsNewType);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
|
||||
completedNotDeleted);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.TRUE),
|
||||
Arrays.asList(dsDeleted));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.TRUE));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndType(final List<DistributionSet> deletedAndCompletedAndStandardType,
|
||||
final DistributionSet dsDeleted, final DistributionSetType newType, final DistributionSet dsNewType) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE)
|
||||
.setIsComplete(Boolean.TRUE).setType(standardDsType), deletedAndCompletedAndStandardType);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setType(standardDsType).setIsDeleted(Boolean.TRUE), Arrays.asList(dsDeleted));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
|
||||
.setIsComplete(Boolean.FALSE).setType(standardDsType));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType),
|
||||
Arrays.asList(dsNewType));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchText(
|
||||
final List<DistributionSet> completedAndStandardTypeAndSearchText, final DistributionSetType newType,
|
||||
final String text) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setType(standardDsType).setSearchText(text), completedAndStandardTypeAndSearchText);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setSearchText(text));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
|
||||
.setSearchText(text).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE));
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(newType)
|
||||
.setSearchText(text).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndFilterString(
|
||||
final List<DistributionSet> completedAndNotDeletedStandardTypeAndFilterString,
|
||||
final DistributionSet dsDeleted, final DistributionSet dsInComplete, final DistributionSet dsNewType,
|
||||
final DistributionSetType newType, final String filterString) {
|
||||
|
||||
final List<DistributionSet> completedAndStandardTypeAndFilterString = new ArrayList<>(
|
||||
completedAndNotDeletedStandardTypeAndFilterString);
|
||||
completedAndStandardTypeAndFilterString.add(dsDeleted);
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setType(standardDsType).setFilterString(filterString), completedAndStandardTypeAndFilterString);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE)
|
||||
.setType(standardDsType).setFilterString(filterString),
|
||||
completedAndNotDeletedStandardTypeAndFilterString);
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
|
||||
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setFilterString(filterString),
|
||||
Arrays.asList(dsDeleted));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(standardDsType)
|
||||
.setFilterString(filterString).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE),
|
||||
Arrays.asList(dsInComplete));
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType)
|
||||
.setFilterString(filterString).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
|
||||
Arrays.asList(dsNewType));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void validateDeletedAndCompletedAndTypeAndSearchTextAndTag(
|
||||
final List<DistributionSet> completedAndStandartTypeAndSearchTextAndTagA, final DistributionSetTag dsTagA,
|
||||
final String text) {
|
||||
|
||||
assertThatFilterContainsOnlyGivenDistributionSets(
|
||||
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(standardDsType)
|
||||
.setSearchText(text).setTagNames(Arrays.asList(dsTagA.getName())),
|
||||
completedAndStandartTypeAndSearchTextAndTagA);
|
||||
|
||||
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
|
||||
.setSearchText(text).setTagNames(Arrays.asList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
|
||||
.setIsDeleted(Boolean.FALSE));
|
||||
}
|
||||
|
||||
private DistributionSetFilterBuilder getDistributionSetFilterBuilder() {
|
||||
return new DistributionSetFilterBuilder();
|
||||
}
|
||||
|
||||
private void assertThatFilterContainsOnlyGivenDistributionSets(final DistributionSetFilterBuilder filterBuilder,
|
||||
final List<DistributionSet> distributionSets) {
|
||||
final int expectedDsSize = distributionSets.size();
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(expectedDsSize).containsOnly(distributionSets.toArray(new DistributionSet[expectedDsSize]));
|
||||
}
|
||||
|
||||
private void assertThatFilterDoesNotContainAnyDistributionSet(final DistributionSetFilterBuilder filterBuilder) {
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(0);
|
||||
}
|
||||
|
||||
private void assertThatFilterHasSizeAndDoesNotContainDistributionSet(
|
||||
final DistributionSetFilterBuilder filterBuilder, final int size, final DistributionSet ds) {
|
||||
assertThat(distributionSetManagement.findByDistributionSetFilter(PAGE, filterBuilder.build()).getContent())
|
||||
.hasSize(size).doesNotContain(ds);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Simple DS load without the related data that should be loaded lazy.")
|
||||
public void findDistributionSetsWithoutLazy() {
|
||||
|
||||
@@ -17,7 +17,7 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||
@@ -26,8 +26,11 @@ import org.eclipse.hawkbit.repository.event.remote.entity.SoftwareModuleCreatedE
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.event.remote.entity.TargetFilterQueryCreatedEvent;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignActionTypeException;
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.exception.QuotaExceededException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.Target;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
@@ -39,6 +42,7 @@ import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Step;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
/**
|
||||
@@ -108,8 +112,9 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||
|
||||
// creation is supposed to work as there is no distribution set
|
||||
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("testfilter").set(set.getId()).query("name==target*")));
|
||||
assertThatExceptionOfType(QuotaExceededException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create()
|
||||
.name("testfilter").autoAssignDistributionSet(set.getId()).query("name==target*")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -180,20 +185,76 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test assigning a distribution set")
|
||||
@Description("Test assigning a distribution set for auto assignment with different action types")
|
||||
public void assignDistributionSet() {
|
||||
final String filterName = "target_filter_02";
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterName).query("name==PendingTargets001"));
|
||||
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery.getId(), distributionSet.getId());
|
||||
verifyAutoAssignmentWithDefaultActionType(filterName, targetFilterQuery, distributionSet);
|
||||
|
||||
verifyAutoAssignmentWithSoftActionType(filterName, targetFilterQuery, distributionSet);
|
||||
|
||||
verifyAutoAssignmentWithInvalidActionType(targetFilterQuery, distributionSet);
|
||||
|
||||
verifyAutoAssignmentWithIncompleteDs(targetFilterQuery);
|
||||
|
||||
verifyAutoAssignmentWithSoftDeletedDs(targetFilterQuery);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithDefaultActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery.getId(), distributionSet.getId());
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.FORCED);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithSoftActionType(final String filterName,
|
||||
final TargetFilterQuery targetFilterQuery, final DistributionSet distributionSet) {
|
||||
targetFilterQueryManagement.updateAutoAssignDSWithActionType(targetFilterQuery.getId(), distributionSet.getId(),
|
||||
ActionType.SOFT);
|
||||
verifyAutoAssignDsAndActionType(filterName, distributionSet, ActionType.SOFT);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithInvalidActionType(final TargetFilterQuery targetFilterQuery,
|
||||
final DistributionSet distributionSet) {
|
||||
// assigning a distribution set with TIMEFORCED action is supposed to
|
||||
// fail as only FORCED and SOFT action types are allowed
|
||||
assertThatExceptionOfType(InvalidAutoAssignActionTypeException.class).isThrownBy(
|
||||
() -> targetFilterQueryManagement.updateAutoAssignDSWithActionType(targetFilterQuery.getId(),
|
||||
distributionSet.getId(), ActionType.TIMEFORCED));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithIncompleteDs(final TargetFilterQuery targetFilterQuery) {
|
||||
final DistributionSet incompleteDistributionSet = distributionSetManagement
|
||||
.create(entityFactory.distributionSet().create().name("incomplete").version("1")
|
||||
.type(testdataFactory.findOrCreateDefaultTestDsType()));
|
||||
|
||||
assertThatExceptionOfType(InvalidAutoAssignDistributionSetException.class)
|
||||
.isThrownBy(() -> targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery.getId(),
|
||||
incompleteDistributionSet.getId()));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyAutoAssignmentWithSoftDeletedDs(final TargetFilterQuery targetFilterQuery) {
|
||||
final DistributionSet softDeletedDs = testdataFactory.createDistributionSet("softDeleted");
|
||||
assignDistributionSet(softDeletedDs, testdataFactory.createTarget("forSoftDeletedDs"));
|
||||
distributionSetManagement.delete(softDeletedDs.getId());
|
||||
|
||||
assertThatExceptionOfType(InvalidAutoAssignDistributionSetException.class).isThrownBy(
|
||||
() -> targetFilterQueryManagement.updateAutoAssignDS(targetFilterQuery.getId(), softDeletedDs.getId()));
|
||||
}
|
||||
|
||||
private void verifyAutoAssignDsAndActionType(final String filterName, final DistributionSet distributionSet,
|
||||
final ActionType actionType) {
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement.getByName(filterName).get();
|
||||
|
||||
assertEquals("Returns correct distribution set", distributionSet, tfq.getAutoAssignDistributionSet());
|
||||
|
||||
assertEquals("Return correct action type", actionType, tfq.getAutoAssignActionType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -225,8 +286,8 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
final DistributionSet set = testdataFactory.createDistributionSet();
|
||||
|
||||
// creation is supposed to work as the query does not exceed the quota
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("testfilter").set(set.getId()).query("name==foo"));
|
||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement.create(entityFactory.targetFilterQuery()
|
||||
.create().name("testfilter").autoAssignDistributionSet(set.getId()).query("name==foo"));
|
||||
|
||||
// update with a query string that addresses too many targets
|
||||
assertThatExceptionOfType(QuotaExceededException.class).isThrownBy(() -> targetFilterQueryManagement
|
||||
@@ -247,6 +308,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
// Check if target filter query is there
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.getByName(filterName).get();
|
||||
assertEquals("Returns correct distribution set", distributionSet, tfq.getAutoAssignDistributionSet());
|
||||
assertEquals("Return correct action type", ActionType.FORCED, tfq.getAutoAssignActionType());
|
||||
|
||||
distributionSetManagement.delete(distributionSet.getId());
|
||||
|
||||
@@ -254,7 +316,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
tfq = targetFilterQueryManagement.getByName(filterName).get();
|
||||
assertNotNull("Returns target filter query", tfq);
|
||||
assertNull("Returns distribution set as null", tfq.getAutoAssignDistributionSet());
|
||||
|
||||
assertNull("Returns action type as null", tfq.getAutoAssignActionType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -275,6 +337,7 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
// Check if target filter query is there with the distribution set
|
||||
TargetFilterQuery tfq = targetFilterQueryManagement.getByName(filterName).get();
|
||||
assertEquals("Returns correct distribution set", distributionSet, tfq.getAutoAssignDistributionSet());
|
||||
assertEquals("Return correct action type", ActionType.FORCED, tfq.getAutoAssignActionType());
|
||||
|
||||
distributionSetManagement.delete(distributionSet.getId());
|
||||
|
||||
@@ -286,66 +349,66 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
|
||||
tfq = targetFilterQueryManagement.getByName(filterName).get();
|
||||
assertNotNull("Returns target filter query", tfq);
|
||||
assertNull("Returns distribution set as null", tfq.getAutoAssignDistributionSet());
|
||||
|
||||
assertNull("Returns action type as null", tfq.getAutoAssignActionType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test finding and auto assign distribution set")
|
||||
public void findFiltersWithDistributionSet() {
|
||||
|
||||
final String filterName = "d";
|
||||
|
||||
assertEquals(0L, targetFilterQueryManagement.count());
|
||||
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("a").query("name==*"));
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("b").query("name==*"));
|
||||
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
final DistributionSet distributionSet2 = testdataFactory.createDistributionSet("2");
|
||||
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement.updateAutoAssignDS(
|
||||
final TargetFilterQuery tfq = targetFilterQueryManagement.updateAutoAssignDSWithActionType(
|
||||
targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name("c").query("name==x")).getId(),
|
||||
distributionSet.getId());
|
||||
|
||||
distributionSet.getId(), ActionType.SOFT);
|
||||
final TargetFilterQuery tfq2 = targetFilterQueryManagement.updateAutoAssignDS(
|
||||
targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterName).query("name==z*")).getId(),
|
||||
distributionSet2.getId());
|
||||
|
||||
assertEquals(4L, targetFilterQueryManagement.count());
|
||||
|
||||
// check if find works
|
||||
Page<TargetFilterQuery> tfqList = targetFilterQueryManagement.findByAutoAssignDSAndRsql(PageRequest.of(0, 500),
|
||||
distributionSet.getId(), null);
|
||||
assertThat(1L).as("Target filter query").isEqualTo(tfqList.getTotalElements());
|
||||
|
||||
assertEquals("Returns correct target filter query", tfq.getId(), tfqList.iterator().next().getId());
|
||||
verifyFindByDistributionSetAndRsql(distributionSet, null, tfq);
|
||||
|
||||
targetFilterQueryManagement.updateAutoAssignDS(tfq2.getId(), distributionSet.getId());
|
||||
|
||||
// check if find works for two
|
||||
tfqList = targetFilterQueryManagement.findByAutoAssignDSAndRsql(PageRequest.of(0, 500), distributionSet.getId(),
|
||||
null);
|
||||
assertThat(2L).as("Target filter query count").isEqualTo(tfqList.getTotalElements());
|
||||
Iterator<TargetFilterQuery> iterator = tfqList.iterator();
|
||||
assertEquals("Returns correct target filter query 1", tfq.getId(), iterator.next().getId());
|
||||
assertEquals("Returns correct target filter query 2", tfq2.getId(), iterator.next().getId());
|
||||
verifyFindByDistributionSetAndRsql(distributionSet, null, tfq, tfq2);
|
||||
|
||||
// check if find works with name filter
|
||||
tfqList = targetFilterQueryManagement.findByAutoAssignDSAndRsql(PageRequest.of(0, 500), distributionSet.getId(),
|
||||
"name==" + filterName);
|
||||
assertThat(1L).as("Target filter query count").isEqualTo(tfqList.getTotalElements());
|
||||
|
||||
assertEquals("Returns correct target filter query", tfq2.getId(), tfqList.iterator().next().getId());
|
||||
|
||||
// check if find works for all with auto assign DS
|
||||
tfqList = targetFilterQueryManagement.findWithAutoAssignDS(PageRequest.of(0, 500));
|
||||
assertThat(2L).as("Target filter query count").isEqualTo(tfqList.getTotalElements());
|
||||
iterator = tfqList.iterator();
|
||||
assertEquals("Returns correct target filter query 1", tfq.getId(), iterator.next().getId());
|
||||
assertEquals("Returns correct target filter query 2", tfq2.getId(), iterator.next().getId());
|
||||
verifyFindByDistributionSetAndRsql(distributionSet, "name==" + filterName, tfq2);
|
||||
|
||||
verifyFindForAllWithAutoAssignDs(tfq, tfq2);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyFindByDistributionSetAndRsql(final DistributionSet distributionSet, final String rsql,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
final Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findByAutoAssignDSAndRsql(PageRequest.of(0, 500), distributionSet.getId(), rsql);
|
||||
|
||||
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
|
||||
}
|
||||
|
||||
private void verifyExpectedFilterQueriesInList(final Page<TargetFilterQuery> tfqList,
|
||||
final TargetFilterQuery... expectedFilterQueries) {
|
||||
assertThat(expectedFilterQueries.length).as("Target filter query count")
|
||||
.isEqualTo((int) tfqList.getTotalElements());
|
||||
|
||||
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
|
||||
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyFindForAllWithAutoAssignDs(final TargetFilterQuery... expectedFilterQueries) {
|
||||
final Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
|
||||
.findWithAutoAssignDS(PageRequest.of(0, 500));
|
||||
|
||||
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1036,10 +1036,10 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
||||
final Target target2 = createTargetWithMetadata("target2", 8);
|
||||
|
||||
final Page<TargetMetadata> metadataOfTarget1 = targetManagement
|
||||
.findMetaDataByControllerId(new PageRequest(0, 100), target1.getControllerId());
|
||||
.findMetaDataByControllerId(PageRequest.of(0, 100), target1.getControllerId());
|
||||
|
||||
final Page<TargetMetadata> metadataOfTarget2 = targetManagement
|
||||
.findMetaDataByControllerId(new PageRequest(0, 100), target2.getControllerId());
|
||||
.findMetaDataByControllerId(PageRequest.of(0, 100), target2.getControllerId());
|
||||
|
||||
assertThat(metadataOfTarget1.getNumberOfElements()).isEqualTo(10);
|
||||
assertThat(metadataOfTarget1.getTotalElements()).isEqualTo(10);
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
package org.eclipse.hawkbit.repository.jpa.autoassign;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.hawkbit.repository.exception.InvalidAutoAssignDistributionSetException;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.Action;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
@@ -80,7 +82,7 @@ public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
|
||||
final Action rolloutCreatedAction = actionsByKnownTarget.stream()
|
||||
.filter(action -> !action.getId().equals(manuallyAssignedActionId)).findAny().get();
|
||||
assertThat(rolloutCreatedAction.getStatus()).isEqualTo(Status.RUNNING);
|
||||
|
||||
assertThat(rolloutCreatedAction.getActionType()).isEqualTo(ActionType.FORCED);
|
||||
} finally {
|
||||
tenantConfigurationManagement
|
||||
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, false);
|
||||
@@ -149,9 +151,13 @@ public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
// target filter query that matches first bunch of targets, that should
|
||||
// fail
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement.create(
|
||||
entityFactory.targetFilterQuery().create().name("filterA").query("id==" + targetDsFIdPref + "*"))
|
||||
.getId(), setF.getId());
|
||||
assertThatExceptionOfType(
|
||||
InvalidAutoAssignDistributionSetException.class)
|
||||
.isThrownBy(
|
||||
() -> targetFilterQueryManagement.updateAutoAssignDS(
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create()
|
||||
.name("filterA").query("id==" + targetDsFIdPref + "*")).getId(),
|
||||
setF.getId()));
|
||||
|
||||
// target filter query that matches failed bunch of targets
|
||||
targetFilterQueryManagement.updateAutoAssignDS(targetFilterQueryManagement.create(
|
||||
@@ -204,4 +210,47 @@ public class AutoAssignCheckerTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test auto assignment of a distribution set with FORCED and SOFT action types")
|
||||
public void checkAutoAssignWithDifferentActionTypes() {
|
||||
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
|
||||
final String targetDsAIdPref = "targA";
|
||||
final String targetDsBIdPref = "targB";
|
||||
|
||||
final List<Target> targetsA = testdataFactory.createTargets(5, targetDsAIdPref,
|
||||
targetDsAIdPref.concat(" description"));
|
||||
final List<Target> targetsB = testdataFactory.createTargets(10, targetDsBIdPref,
|
||||
targetDsBIdPref.concat(" description"));
|
||||
final int targetsCount = targetsA.size() + targetsB.size();
|
||||
|
||||
targetFilterQueryManagement
|
||||
.updateAutoAssignDSWithActionType(
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("filterA")
|
||||
.query("id==" + targetDsAIdPref + "*")).getId(),
|
||||
distributionSet.getId(), ActionType.FORCED);
|
||||
targetFilterQueryManagement
|
||||
.updateAutoAssignDSWithActionType(
|
||||
targetFilterQueryManagement.create(entityFactory.targetFilterQuery().create().name("filterB")
|
||||
.query("id==" + targetDsBIdPref + "*")).getId(),
|
||||
distributionSet.getId(), ActionType.SOFT);
|
||||
|
||||
autoAssignChecker.check();
|
||||
|
||||
verifyThatTargetsHaveDistributionSetAssignment(distributionSet, targetsA, targetsCount);
|
||||
verifyThatTargetsHaveDistributionSetAssignment(distributionSet, targetsB, targetsCount);
|
||||
|
||||
verifyThatTargetsHaveAssignmentActionType(ActionType.FORCED, targetsA);
|
||||
verifyThatTargetsHaveAssignmentActionType(ActionType.SOFT, targetsB);
|
||||
}
|
||||
|
||||
@Step
|
||||
private void verifyThatTargetsHaveAssignmentActionType(final ActionType actionType, final List<Target> targets) {
|
||||
final List<Action> actions = targets.stream().map(Target::getControllerId).flatMap(
|
||||
controllerId -> deploymentManagement.findActionsByTarget(controllerId, PAGE).getContent().stream())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
assertThat(actions).hasSize(targets.size());
|
||||
assertThat(actions).allMatch(action -> action.getActionType().equals(actionType));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Copyright (c) 2019 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.eclipse.hawkbit.repository.TargetFilterQueryFields;
|
||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
import io.qameta.allure.Description;
|
||||
import io.qameta.allure.Feature;
|
||||
import io.qameta.allure.Story;
|
||||
|
||||
@Feature("Component Tests - Repository")
|
||||
@Story("RSQL filter target filter query")
|
||||
public class RSQLTargetFilterQueryFieldsTest extends AbstractJpaIntegrationTest {
|
||||
|
||||
private TargetFilterQuery filter1;
|
||||
private TargetFilterQuery filter2;
|
||||
|
||||
@Before
|
||||
public void setupBeforeTest() throws InterruptedException {
|
||||
final String filterName1 = "filter_a";
|
||||
final String filterName2 = "filter_b";
|
||||
final String filterName3 = "filter_c";
|
||||
|
||||
final DistributionSet ds1 = testdataFactory.createDistributionSet("AutoAssignedDs_1");
|
||||
final DistributionSet ds2 = testdataFactory.createDistributionSet("AutoAssignedDs_2");
|
||||
|
||||
filter1 = targetFilterQueryManagement.updateAutoAssignDSWithActionType(
|
||||
targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterName1).query("name==*")).getId(),
|
||||
ds1.getId(), ActionType.SOFT);
|
||||
filter2 = targetFilterQueryManagement.updateAutoAssignDS(
|
||||
targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterName2).query("name==*")).getId(),
|
||||
ds2.getId());
|
||||
targetFilterQueryManagement
|
||||
.create(entityFactory.targetFilterQuery().create().name(filterName3).query("name==*"));
|
||||
|
||||
assertEquals(3L, targetFilterQueryManagement.count());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter target filter query by id")
|
||||
public void testFilterByParameterId() {
|
||||
assertRSQLQuery(TargetFilterQueryFields.ID.name() + "==*", 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter target filter query by name")
|
||||
public void testFilterByParameterName() {
|
||||
assertRSQLQuery(TargetFilterQueryFields.NAME.name() + "==" + filter1.getName(), 1);
|
||||
assertRSQLQuery(TargetFilterQueryFields.NAME.name() + "==" + filter2.getName(), 1);
|
||||
assertRSQLQuery(TargetFilterQueryFields.NAME.name() + "==filter_*", 3);
|
||||
assertRSQLQuery(TargetFilterQueryFields.NAME.name() + "==noExist*", 0);
|
||||
assertRSQLQuery(TargetFilterQueryFields.NAME.name() + "=in=(" + filter1.getName() + ",notexist)", 1);
|
||||
assertRSQLQuery(TargetFilterQueryFields.NAME.name() + "=out=(" + filter1.getName() + ",notexist)", 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter target filter query by auto assigned ds name")
|
||||
public void testFilterByAutoAssignedDsName() {
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".name=="
|
||||
+ filter1.getAutoAssignDistributionSet().getName(), 1);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".name=="
|
||||
+ filter2.getAutoAssignDistributionSet().getName(), 1);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".name==AutoAssignedDs_*", 2);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".name==noExist*", 0);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".name=in=("
|
||||
+ filter1.getAutoAssignDistributionSet().getName() + ",notexist)", 1);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".name=out=("
|
||||
+ filter1.getAutoAssignDistributionSet().getName() + ",notexist)", 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Description("Test filter target filter query by auto assigned ds version")
|
||||
public void testFilterByAutoAssignedDsVersion() {
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".version=="
|
||||
+ TestdataFactory.DEFAULT_VERSION, 2);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".version==*1*", 2);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".version==noExist*", 0);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".version=in=("
|
||||
+ TestdataFactory.DEFAULT_VERSION + ",notexist)", 2);
|
||||
assertRSQLQuery(TargetFilterQueryFields.AUTOASSIGNDISTRIBUTIONSET.name() + ".version=out=("
|
||||
+ TestdataFactory.DEFAULT_VERSION + ",notexist)", 0);
|
||||
}
|
||||
|
||||
private void assertRSQLQuery(final String rsqlParam, final long expectedFilterQueriesSize) {
|
||||
final Page<TargetFilterQuery> findTargetFilterQueryPage = targetFilterQueryManagement.findByRsql(PAGE,
|
||||
rsqlParam);
|
||||
assertThat(findTargetFilterQueryPage).isNotNull();
|
||||
assertThat(findTargetFilterQueryPage.getTotalElements()).isEqualTo(expectedFilterQueriesSize);
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class RSQLTargetMetadataFieldsTest extends AbstractJpaIntegrationTest {
|
||||
private void assertRSQLQuery(final String rsqlParam, final long expectedEntities) {
|
||||
|
||||
final Page<TargetMetadata> findEnitity = targetManagement
|
||||
.findMetaDataByControllerIdAndRsql(new PageRequest(0, 100), controllerId, rsqlParam);
|
||||
.findMetaDataByControllerIdAndRsql(PageRequest.of(0, 100), controllerId, rsqlParam);
|
||||
final long countAllEntities = findEnitity.getTotalElements();
|
||||
assertThat(findEnitity).isNotNull();
|
||||
assertThat(countAllEntities).isEqualTo(expectedEntities);
|
||||
|
||||
Reference in New Issue
Block a user