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
@@ -23,7 +23,6 @@ import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Slice;
|
||||
@@ -56,7 +55,7 @@ public interface RepositoryManagement<T, C, U> {
|
||||
List<T> create(@NotNull @Valid Collection<C> creates);
|
||||
|
||||
/**
|
||||
* Creates new {@link SoftwareModuleType}.
|
||||
* Creates new {@link BaseEntity}.
|
||||
*
|
||||
* @param create
|
||||
* to create
|
||||
|
||||
@@ -18,9 +18,12 @@ import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
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.exception.QuotaExceededException;
|
||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||
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.TargetFilterQuery;
|
||||
import org.springframework.data.domain.Page;
|
||||
@@ -213,13 +216,14 @@ public interface TargetFilterQueryManagement {
|
||||
TargetFilterQuery update(@NotNull @Valid TargetFilterQueryUpdate update);
|
||||
|
||||
/**
|
||||
* Updates the the auto-assign {@link DistributionSet} of the addressed
|
||||
* {@link TargetFilterQuery}.
|
||||
* Updates the the auto-assign {@link DistributionSet} and sets default
|
||||
* (FORCED) {@link ActionType} of the addressed {@link TargetFilterQuery}.
|
||||
*
|
||||
* @param queryId
|
||||
* of the target filter query to be updated
|
||||
* @param dsId
|
||||
* to be updated or <code>null</code> in order to remove it
|
||||
* together with the auto-assign {@link ActionType}
|
||||
*
|
||||
* @return the updated {@link TargetFilterQuery}
|
||||
*
|
||||
@@ -230,8 +234,47 @@ public interface TargetFilterQueryManagement {
|
||||
* @throws QuotaExceededException
|
||||
* if the query that is already associated with this filter
|
||||
* query addresses too many targets (auto-assignments only)
|
||||
*
|
||||
* @throws InvalidAutoAssignDistributionSetException
|
||||
* if the provided auto-assign {@link DistributionSet} is not
|
||||
* valid (incomplete or soft deleted)
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
TargetFilterQuery updateAutoAssignDS(long queryId, Long dsId);
|
||||
default TargetFilterQuery updateAutoAssignDS(final long queryId, final Long dsId) {
|
||||
return updateAutoAssignDSWithActionType(queryId, dsId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the the auto-assign {@link DistributionSet} and
|
||||
* {@link ActionType} of the addressed {@link TargetFilterQuery}.
|
||||
*
|
||||
* @param queryId
|
||||
* of the target filter query to be updated
|
||||
* @param dsId
|
||||
* to be updated or <code>null</code> in order to remove it
|
||||
* together with the auto-assign {@link ActionType}
|
||||
* @param actionType
|
||||
* to be updated or <code>null</code> for default (FORCED) if
|
||||
* distribution set Id is present
|
||||
*
|
||||
* @return the updated {@link TargetFilterQuery}
|
||||
*
|
||||
* @throws EntityNotFoundException
|
||||
* if either {@link TargetFilterQuery} and/or autoAssignDs are
|
||||
* provided but not found
|
||||
*
|
||||
* @throws QuotaExceededException
|
||||
* if the query that is already associated with this filter
|
||||
* query addresses too many targets (auto-assignments only)
|
||||
*
|
||||
* @throws InvalidAutoAssignActionTypeException
|
||||
* if the provided auto-assign {@link ActionType} is not valid
|
||||
* (neither FORCED, nor SOFT)
|
||||
*
|
||||
* @throws InvalidAutoAssignDistributionSetException
|
||||
* if the provided auto-assign {@link DistributionSet} is not
|
||||
* valid (incomplete or soft deleted)
|
||||
*/
|
||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
|
||||
TargetFilterQuery updateAutoAssignDSWithActionType(long queryId, Long dsId, ActionType actionType);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.Optional;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||
@@ -40,20 +41,27 @@ public interface TargetFilterQueryCreate {
|
||||
TargetFilterQueryCreate query(@Size(min = 1, max = TargetFilterQuery.QUERY_MAX_SIZE) @NotNull String query);
|
||||
|
||||
/**
|
||||
* @param set
|
||||
* @param distributionSet
|
||||
* for {@link TargetFilterQuery#getAutoAssignDistributionSet()}
|
||||
* @return updated builder instance
|
||||
*/
|
||||
default TargetFilterQueryCreate set(final DistributionSet set) {
|
||||
return set(Optional.ofNullable(set).map(DistributionSet::getId).orElse(null));
|
||||
default TargetFilterQueryCreate autoAssignDistributionSet(final DistributionSet distributionSet) {
|
||||
return autoAssignDistributionSet(Optional.ofNullable(distributionSet).map(DistributionSet::getId).orElse(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param setId
|
||||
* @param dsId
|
||||
* for {@link TargetFilterQuery#getAutoAssignDistributionSet()}
|
||||
* @return updated builder instance
|
||||
*/
|
||||
TargetFilterQueryCreate set(long setId);
|
||||
TargetFilterQueryCreate autoAssignDistributionSet(Long dsId);
|
||||
|
||||
/**
|
||||
* @param actionType
|
||||
* for {@link TargetFilterQuery#getAutoAssignActionType()}
|
||||
* @return updated builder instance
|
||||
*/
|
||||
TargetFilterQueryCreate autoAssignActionType(ActionType actionType);
|
||||
|
||||
/**
|
||||
* @return peek on current state of {@link TargetFilterQuery} in the builder
|
||||
|
||||
@@ -88,7 +88,7 @@ public class EntityNotFoundException extends AbstractServerRtException {
|
||||
* for the {@link MetaData} entry
|
||||
*/
|
||||
public EntityNotFoundException(final Class<? extends MetaData> type, final Long entityId, final String key) {
|
||||
this(type.getSimpleName() + " for given entity {" + entityId + "} and with key {" + key + "} does not exist.");
|
||||
this(type, String.valueOf(entityId), key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,13 +96,13 @@ public class EntityNotFoundException extends AbstractServerRtException {
|
||||
*
|
||||
* @param type
|
||||
* of the entity that was not found
|
||||
* @param enityId
|
||||
* @param entityId
|
||||
* of the {@link BaseEntity} the {@link MetaData} was for
|
||||
* @param key
|
||||
* for the {@link MetaData} entry
|
||||
*/
|
||||
public EntityNotFoundException(final Class<? extends MetaData> type, final String enityId, final String key) {
|
||||
this(type.getSimpleName() + " for given entity {" + enityId + "} and with key {" + key + "} does not exist.");
|
||||
public EntityNotFoundException(final Class<? extends MetaData> type, final String entityId, final String key) {
|
||||
this(type.getSimpleName() + " for given entity {" + entityId + "} and with key {" + key + "} does not exist.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2018 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.exception;
|
||||
|
||||
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
|
||||
/**
|
||||
* Thrown if an action type for auto-assignment is neither 'forced', nor 'soft'.
|
||||
*/
|
||||
public class InvalidAutoAssignActionTypeException extends AbstractServerRtException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final SpServerError THIS_ERROR = SpServerError.SP_AUTO_ASSIGN_ACTION_TYPE_INVALID;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public InvalidAutoAssignActionTypeException() {
|
||||
super(THIS_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.exception;
|
||||
|
||||
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||
import org.eclipse.hawkbit.exception.SpServerError;
|
||||
|
||||
/**
|
||||
* Thrown if a distribution set for auto-assignment is incomplete (i.e.
|
||||
* mandatory modules are missing) or soft deleted.
|
||||
*/
|
||||
public class InvalidAutoAssignDistributionSetException extends AbstractServerRtException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final SpServerError THIS_ERROR = SpServerError.SP_AUTO_ASSIGN_DISTRIBUTION_SET_INVALID;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public InvalidAutoAssignDistributionSetException() {
|
||||
super(THIS_ERROR);
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@ public final class DistributionSetFilter {
|
||||
private Boolean isComplete;
|
||||
private DistributionSetType type;
|
||||
private String searchText;
|
||||
private String filterString;
|
||||
private Boolean selectDSWithNoTag;
|
||||
private Collection<String> tagNames;
|
||||
private String assignedTargetId;
|
||||
@@ -61,6 +62,11 @@ public final class DistributionSetFilter {
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionSetFilterBuilder setFilterString(final String filterString) {
|
||||
this.filterString = filterString;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DistributionSetFilterBuilder setSelectDSWithNoTag(final Boolean selectDSWithNoTag) {
|
||||
this.selectDSWithNoTag = selectDSWithNoTag;
|
||||
return this;
|
||||
@@ -82,6 +88,7 @@ public final class DistributionSetFilter {
|
||||
private final Boolean isComplete;
|
||||
private final DistributionSetType type;
|
||||
private final String searchText;
|
||||
private final String filterString;
|
||||
private final Boolean selectDSWithNoTag;
|
||||
private final Collection<String> tagNames;
|
||||
private final String assignedTargetId;
|
||||
@@ -99,6 +106,7 @@ public final class DistributionSetFilter {
|
||||
this.isComplete = builder.isComplete;
|
||||
this.type = builder.type;
|
||||
this.searchText = builder.searchText;
|
||||
this.filterString = builder.filterString;
|
||||
this.selectDSWithNoTag = builder.selectDSWithNoTag;
|
||||
this.tagNames = builder.tagNames;
|
||||
this.assignedTargetId = builder.assignedTargetId;
|
||||
@@ -125,6 +133,10 @@ public final class DistributionSetFilter {
|
||||
return searchText;
|
||||
}
|
||||
|
||||
public String getFilterString() {
|
||||
return filterString;
|
||||
}
|
||||
|
||||
public Boolean getSelectDSWithNoTag() {
|
||||
return selectDSWithNoTag;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.repository.model;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
|
||||
/**
|
||||
* Managed filter entity.
|
||||
*
|
||||
@@ -38,6 +44,12 @@ public interface TargetFilterQuery extends TenantAwareBaseEntity {
|
||||
*/
|
||||
int QUERY_MAX_SIZE = 1024;
|
||||
|
||||
/**
|
||||
* Allowed values for auto-assign action type
|
||||
*/
|
||||
Set<ActionType> ALLOWED_AUTO_ASSIGN_ACTION_TYPES = Collections
|
||||
.unmodifiableSet(EnumSet.of(ActionType.FORCED, ActionType.SOFT));
|
||||
|
||||
/**
|
||||
* @return name of the {@link TargetFilterQuery}.
|
||||
*/
|
||||
@@ -53,4 +65,9 @@ public interface TargetFilterQuery extends TenantAwareBaseEntity {
|
||||
*/
|
||||
DistributionSet getAutoAssignDistributionSet();
|
||||
|
||||
/**
|
||||
* @return the auto assign {@link ActionType} if given.
|
||||
*/
|
||||
ActionType getAutoAssignActionType();
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository.builder;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.hawkbit.repository.ValidString;
|
||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -26,15 +27,26 @@ public abstract class AbstractTargetFilterQueryUpdateCreate<T> extends AbstractB
|
||||
@ValidString
|
||||
protected String query;
|
||||
|
||||
protected Long set;
|
||||
protected Long distributionSetId;
|
||||
|
||||
public T set(final long set) {
|
||||
this.set = set;
|
||||
protected ActionType actionType;
|
||||
|
||||
public T autoAssignDistributionSet(final Long distributionSetId) {
|
||||
this.distributionSetId = distributionSetId;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public Optional<Long> getSet() {
|
||||
return Optional.ofNullable(set);
|
||||
public Optional<Long> getAutoAssignDistributionSetId() {
|
||||
return Optional.ofNullable(distributionSetId);
|
||||
}
|
||||
|
||||
public T autoAssignActionType(final ActionType actionType) {
|
||||
this.actionType = actionType;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public Optional<ActionType> getAutoAssignActionType() {
|
||||
return Optional.ofNullable(actionType);
|
||||
}
|
||||
|
||||
public T name(final String name) {
|
||||
|
||||
@@ -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