Remove unused DistributionSetManagement#findByDistributionSetFilterOrderByLinkedTarget (#2141)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -279,28 +279,6 @@ public interface DistributionSetManagement
|
|||||||
Slice<DistributionSet> findByDistributionSetFilter(@NotNull Pageable pageable,
|
Slice<DistributionSet> findByDistributionSetFilter(@NotNull Pageable pageable,
|
||||||
@NotNull DistributionSetFilter distributionSetFilter);
|
@NotNull DistributionSetFilter distributionSetFilter);
|
||||||
|
|
||||||
/**
|
|
||||||
* Method retrieves all {@link DistributionSet}s from the repository in the
|
|
||||||
* following order:
|
|
||||||
* <p>
|
|
||||||
* 1) {@link DistributionSet}s which have the given {@link Target} as
|
|
||||||
* {@link TargetInfo#getInstalledDistributionSet()}
|
|
||||||
* <p>
|
|
||||||
* 2) {@link DistributionSet}s which have the given {@link Target} as
|
|
||||||
* {@link Target#getAssignedDistributionSet()}
|
|
||||||
* <p>
|
|
||||||
* 3) {@link DistributionSet}s which have no connection to the given
|
|
||||||
* {@link Target} ordered by ID of the DistributionSet.
|
|
||||||
*
|
|
||||||
* @param pageable the page request to page the result set *
|
|
||||||
* @param distributionSetFilter has details of filters to be applied.
|
|
||||||
* @param assignedOrInstalled the id of the Target to be ordered by
|
|
||||||
* @return {@link DistributionSet}s
|
|
||||||
*/
|
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
|
||||||
Slice<DistributionSet> findByDistributionSetFilterOrderByLinkedTarget(@NotNull Pageable pageable,
|
|
||||||
@NotNull DistributionSetFilter distributionSetFilter, @NotEmpty String assignedOrInstalled);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts all {@link DistributionSet}s in repository based on given filter.
|
* Counts all {@link DistributionSet}s in repository based on given filter.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
|||||||
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
|
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
|
||||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
|
||||||
import org.eclipse.hawkbit.repository.QuotaManagement;
|
import org.eclipse.hawkbit.repository.QuotaManagement;
|
||||||
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
import org.eclipse.hawkbit.repository.RepositoryProperties;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
@@ -83,7 +82,6 @@ import org.springframework.dao.ConcurrencyFailureException;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Slice;
|
import org.springframework.data.domain.Slice;
|
||||||
import org.springframework.data.domain.Sort;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.orm.jpa.vendor.Database;
|
import org.springframework.orm.jpa.vendor.Database;
|
||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
@@ -409,7 +407,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
throw new InsufficientPermissionException("Target not accessible (or not found)!");
|
throw new InsufficientPermissionException("Target not accessible (or not found)!");
|
||||||
}
|
}
|
||||||
return distributionSetRepository
|
return distributionSetRepository
|
||||||
.findOne(DistributionSetSpecification.byId(action.getDistributionSet().getId()))
|
.findOne(DistributionSetSpecification.byIdFetch(action.getDistributionSet().getId()))
|
||||||
.orElseThrow(() ->
|
.orElseThrow(() ->
|
||||||
new InsufficientPermissionException("DistributionSet not accessible (or not found)!"));
|
new InsufficientPermissionException("DistributionSet not accessible (or not found)!"));
|
||||||
})
|
})
|
||||||
@@ -518,25 +516,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, pageable, specList);
|
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, pageable, specList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Slice<DistributionSet> findByDistributionSetFilterOrderByLinkedTarget(final Pageable pageable,
|
|
||||||
final DistributionSetFilter distributionSetFilter, final String assignedOrInstalled) {
|
|
||||||
// remove default sort from pageable to not overwrite sorted spec
|
|
||||||
final OffsetBasedPageRequest unsortedPage = new OffsetBasedPageRequest(pageable.getOffset(),
|
|
||||||
pageable.getPageSize(), Sort.unsorted());
|
|
||||||
|
|
||||||
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
|
|
||||||
distributionSetFilter);
|
|
||||||
specList.add(DistributionSetSpecification.orderedByLinkedTarget(assignedOrInstalled, pageable.getSort()));
|
|
||||||
|
|
||||||
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, unsortedPage, specList);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long countByDistributionSetFilter(@NotNull final DistributionSetFilter distributionSetFilter) {
|
public long countByDistributionSetFilter(@NotNull final DistributionSetFilter distributionSetFilter) {
|
||||||
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
|
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(distributionSetFilter);
|
||||||
distributionSetFilter);
|
|
||||||
|
|
||||||
return JpaManagementHelper.countBySpec(distributionSetRepository, specList);
|
return JpaManagementHelper.countBySpec(distributionSetRepository, specList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,7 +773,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
distributionSetRepository.findById(dsIds.iterator().next())
|
distributionSetRepository.findById(dsIds.iterator().next())
|
||||||
.map(List::of)
|
.map(List::of)
|
||||||
.orElseGet(Collections::emptyList) :
|
.orElseGet(Collections::emptyList) :
|
||||||
distributionSetRepository.findAll(DistributionSetSpecification.byIds(dsIds));
|
distributionSetRepository.findAll(DistributionSetSpecification.byIdsFetch(dsIds));
|
||||||
if (allDs.size() < dsIds.size()) {
|
if (allDs.size() < dsIds.size()) {
|
||||||
throw new EntityNotFoundException(DistributionSet.class, notFound(dsIds, allDs));
|
throw new EntityNotFoundException(DistributionSet.class, notFound(dsIds, allDs));
|
||||||
}
|
}
|
||||||
@@ -898,7 +880,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
final BiFunction<List<JpaDistributionSet>, DistributionSetTag, T> updater) {
|
final BiFunction<List<JpaDistributionSet>, DistributionSetTag, T> updater) {
|
||||||
final List<JpaDistributionSet> allDs = dsIds.size() == 1 ?
|
final List<JpaDistributionSet> allDs = dsIds.size() == 1 ?
|
||||||
distributionSetRepository.findById(dsIds.iterator().next()).map(List::of).orElseGet(Collections::emptyList) :
|
distributionSetRepository.findById(dsIds.iterator().next()).map(List::of).orElseGet(Collections::emptyList) :
|
||||||
distributionSetRepository.findAll(DistributionSetSpecification.byIds(dsIds));
|
distributionSetRepository.findAll(DistributionSetSpecification.byIdsFetch(dsIds));
|
||||||
if (allDs.size() < dsIds.size()) {
|
if (allDs.size() < dsIds.size()) {
|
||||||
throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).toList());
|
throw new EntityNotFoundException(DistributionSet.class, dsIds, allDs.stream().map(DistributionSet::getId).toList());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,8 +66,7 @@ public interface DistributionSetRepository extends BaseEntityRepository<JpaDistr
|
|||||||
Long countAutoAssignmentsForDistributionSet(@Param("dsId") Long dsId);
|
Long countAutoAssignmentsForDistributionSet(@Param("dsId") Long dsId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds {@link DistributionSet}s where given {@link SoftwareModule} is
|
* Finds {@link DistributionSet}s where given {@link SoftwareModule} is assigned.
|
||||||
* assigned.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* No access control applied.
|
* No access control applied.
|
||||||
*
|
*
|
||||||
@@ -77,8 +76,7 @@ public interface DistributionSetRepository extends BaseEntityRepository<JpaDistr
|
|||||||
Long countByModulesId(Long moduleId);
|
Long countByModulesId(Long moduleId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds {@link DistributionSet}s based on given ID that are assigned yet to
|
* Finds {@link DistributionSet}s based on given ID that are assigned yet to an {@link Action}, i.e. in use.
|
||||||
* an {@link Action}, i.e. in use.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* No access control applied.
|
* No access control applied.
|
||||||
*
|
*
|
||||||
@@ -89,8 +87,7 @@ public interface DistributionSetRepository extends BaseEntityRepository<JpaDistr
|
|||||||
List<Long> findAssignedToTargetDistributionSetsById(@Param("ids") Collection<Long> ids);
|
List<Long> findAssignedToTargetDistributionSetsById(@Param("ids") Collection<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds {@link DistributionSet}s based on given ID that are assigned yet to
|
* Finds {@link DistributionSet}s based on given ID that are assigned yet to an {@link Rollout}, i.e. in use.
|
||||||
* an {@link Rollout}, i.e. in use.
|
|
||||||
* <p/>
|
* <p/>
|
||||||
* No access control applied.
|
* No access control applied.
|
||||||
*
|
*
|
||||||
@@ -111,10 +108,8 @@ public interface DistributionSetRepository extends BaseEntityRepository<JpaDistr
|
|||||||
long countByTypeId(Long typeId);
|
long countByTypeId(Long typeId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety
|
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety reasons (this is a "delete everything" query after all) we add
|
||||||
* reasons (this is a "delete everything" query after all) we add the tenant
|
* the tenant manually to query even if this will by done by {@link EntityManager} anyhow. The DB should take care of optimizing this away.
|
||||||
* manually to query even if this will by done by {@link EntityManager}
|
|
||||||
* anyhow. The DB should take care of optimizing this away.
|
|
||||||
*
|
*
|
||||||
* @param tenant to delete data from
|
* @param tenant to delete data from
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
import jakarta.persistence.criteria.Expression;
|
|
||||||
import jakarta.persistence.criteria.JoinType;
|
import jakarta.persistence.criteria.JoinType;
|
||||||
import jakarta.persistence.criteria.Order;
|
|
||||||
import jakarta.persistence.criteria.Path;
|
import jakarta.persistence.criteria.Path;
|
||||||
import jakarta.persistence.criteria.Predicate;
|
import jakarta.persistence.criteria.Predicate;
|
||||||
import jakarta.persistence.criteria.Root;
|
import jakarta.persistence.criteria.Root;
|
||||||
@@ -29,24 +27,18 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.springframework.data.domain.Sort;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.query.QueryUtils;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifications class for {@link DistributionSet}s. The class provides Spring
|
* Specifications class for {@link DistributionSet}s. The class provides Spring Data JPQL Specifications.
|
||||||
* Data JPQL Specifications.
|
|
||||||
*/
|
*/
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public final class DistributionSetSpecification {
|
public final class DistributionSetSpecification {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet}s with
|
* {@link Specification} for retrieving {@link DistributionSet}s with DELETED attribute <code>false</code> - i.e. is not deleted.
|
||||||
* DELETED attribute <code>false</code> - i.e. is not deleted.
|
|
||||||
*
|
*
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
@@ -55,51 +47,44 @@ public final class DistributionSetSpecification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet}s by its
|
* {@link Specification} for retrieving {@link DistributionSet}s by its DELETED attribute.
|
||||||
* DELETED attribute.
|
|
||||||
*
|
*
|
||||||
* @param isDeleted TRUE/FALSE are compared to the attribute DELETED. If NULL the
|
* @param isDeleted TRUE/FALSE are compared to the attribute DELETED. If NULL the attribute is ignored
|
||||||
* attribute is ignored
|
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> isDeleted(final Boolean isDeleted) {
|
public static Specification<JpaDistributionSet> isDeleted(final Boolean isDeleted) {
|
||||||
return (dsRoot, query, cb) -> cb.equal(dsRoot.<Boolean> get(JpaDistributionSet_.deleted), isDeleted);
|
return (dsRoot, query, cb) -> cb.equal(dsRoot.get(JpaDistributionSet_.deleted), isDeleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet}s by its
|
* {@link Specification} for retrieving {@link DistributionSet}s by its COMPLETED attribute.
|
||||||
* COMPLETED attribute.
|
|
||||||
*
|
*
|
||||||
* @param isCompleted TRUE/FALSE are compared to the attribute COMPLETED. If NULL the
|
* @param isCompleted TRUE/FALSE are compared to the attribute COMPLETED. If NULL the attribute is ignored
|
||||||
* attribute is ignored
|
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> isCompleted(final Boolean isCompleted) {
|
public static Specification<JpaDistributionSet> isCompleted(final Boolean isCompleted) {
|
||||||
return (dsRoot, query, cb) -> cb.equal(dsRoot.<Boolean> get(JpaDistributionSet_.complete), isCompleted);
|
return (dsRoot, query, cb) -> cb.equal(dsRoot.get(JpaDistributionSet_.complete), isCompleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet}s by its VALID
|
* {@link Specification} for retrieving {@link DistributionSet}s by its VALID attribute.
|
||||||
* attribute.
|
|
||||||
*
|
*
|
||||||
* @param isValid TRUE/FALSE are compared to the attribute VALID. If NULL the
|
* @param isValid TRUE/FALSE are compared to the attribute VALID. If NULL the attribute is ignored
|
||||||
* attribute is ignored
|
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> isValid(final Boolean isValid) {
|
public static Specification<JpaDistributionSet> isValid(final Boolean isValid) {
|
||||||
return (dsRoot, query, cb) -> cb.equal(dsRoot.<Boolean> get(JpaDistributionSet_.valid), isValid);
|
return (dsRoot, query, cb) -> cb.equal(dsRoot.get(JpaDistributionSet_.valid), isValid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet} with given
|
* {@link Specification} for retrieving {@link DistributionSet} with given {@link DistributionSet#getId()}.
|
||||||
* {@link DistributionSet#getId()}.
|
|
||||||
*
|
*
|
||||||
* @param distid to search
|
* @param distid to search
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> byId(final Long distid) {
|
public static Specification<JpaDistributionSet> byIdFetch(final Long distid) {
|
||||||
return (dsRoot, query, cb) -> {
|
return (dsRoot, query, cb) -> {
|
||||||
final Predicate predicate = cb.equal(dsRoot.<Long> get(JpaDistributionSet_.id), distid);
|
final Predicate predicate = cb.equal(dsRoot.get(JpaDistributionSet_.id), distid);
|
||||||
dsRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
|
dsRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
|
||||||
dsRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
|
dsRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
|
||||||
query.distinct(true);
|
query.distinct(true);
|
||||||
@@ -109,15 +94,14 @@ public final class DistributionSetSpecification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet} with given
|
* {@link Specification} for retrieving {@link DistributionSet} with given {@link DistributionSet#getId()}s.
|
||||||
* {@link DistributionSet#getId()}s.
|
|
||||||
*
|
*
|
||||||
* @param distids to search
|
* @param distids to search
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> byIds(final Collection<Long> distids) {
|
public static Specification<JpaDistributionSet> byIdsFetch(final Collection<Long> distids) {
|
||||||
return (dsRoot, query, cb) -> {
|
return (dsRoot, query, cb) -> {
|
||||||
final Predicate predicate = dsRoot.<Long> get(JpaDistributionSet_.id).in(distids);
|
final Predicate predicate = dsRoot.get(JpaDistributionSet_.id).in(distids);
|
||||||
dsRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
|
dsRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
|
||||||
dsRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
|
dsRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
|
||||||
dsRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
|
dsRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
|
||||||
@@ -127,8 +111,7 @@ public final class DistributionSetSpecification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet}s by "like name
|
* {@link Specification} for retrieving {@link DistributionSet}s by "like name and like version".
|
||||||
* and like version".
|
|
||||||
*
|
*
|
||||||
* @param name to be filtered on
|
* @param name to be filtered on
|
||||||
* @param version to be filtered on
|
* @param version to be filtered on
|
||||||
@@ -136,20 +119,18 @@ public final class DistributionSetSpecification {
|
|||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> likeNameAndVersion(final String name, final String version) {
|
public static Specification<JpaDistributionSet> likeNameAndVersion(final String name, final String version) {
|
||||||
return (dsRoot, query, cb) -> cb.and(
|
return (dsRoot, query, cb) -> cb.and(
|
||||||
cb.like(cb.lower(dsRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
|
cb.like(cb.lower(dsRoot.get(JpaDistributionSet_.name)), name.toLowerCase()),
|
||||||
cb.like(cb.lower(dsRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
|
cb.like(cb.lower(dsRoot.get(JpaDistributionSet_.version)), version.toLowerCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet}s by "has at
|
* {@link Specification} for retrieving {@link DistributionSet}s by "has at least one of the given tag names".
|
||||||
* least one of the given tag names".
|
|
||||||
*
|
*
|
||||||
* @param tagNames to be filtered on
|
* @param tagNames to be filtered on
|
||||||
* @param selectDSWithNoTag flag to select distribution sets with no tag
|
* @param selectDSWithNoTag flag to select distribution sets with no tag
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> hasTags(final Collection<String> tagNames,
|
public static Specification<JpaDistributionSet> hasTags(final Collection<String> tagNames, final Boolean selectDSWithNoTag) {
|
||||||
final Boolean selectDSWithNoTag) {
|
|
||||||
return (dsRoot, query, cb) -> {
|
return (dsRoot, query, cb) -> {
|
||||||
final Predicate predicate = getHasTagsPredicate(dsRoot, cb, selectDSWithNoTag, tagNames);
|
final Predicate predicate = getHasTagsPredicate(dsRoot, cb, selectDSWithNoTag, tagNames);
|
||||||
query.distinct(true);
|
query.distinct(true);
|
||||||
@@ -158,36 +139,30 @@ public final class DistributionSetSpecification {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns query criteria {@link Specification} comparing case insensitive "NAME
|
* returns query criteria {@link Specification} comparing case insensitive "NAME == AND VERSION ==".
|
||||||
* == AND VERSION ==".
|
|
||||||
*
|
*
|
||||||
* @param name to be filtered on
|
* @param name to be filtered on
|
||||||
* @param version to be filtered on
|
* @param version to be filtered on
|
||||||
* @return the {@link Specification}
|
* @return the {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> equalsNameAndVersionIgnoreCase(final String name,
|
public static Specification<JpaDistributionSet> equalsNameAndVersionIgnoreCase(final String name, final String version) {
|
||||||
final String version) {
|
|
||||||
return (dsRoot, query, cb) -> cb.and(
|
return (dsRoot, query, cb) -> cb.and(
|
||||||
cb.equal(cb.lower(dsRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
|
cb.equal(cb.lower(dsRoot.get(JpaDistributionSet_.name)), name.toLowerCase()),
|
||||||
cb.equal(cb.lower(dsRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
|
cb.equal(cb.lower(dsRoot.get(JpaDistributionSet_.version)), version.toLowerCase()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet} with given
|
* {@link Specification} for retrieving {@link DistributionSet} with given {@link DistributionSet#getType()}.
|
||||||
* {@link DistributionSet#getType()}.
|
|
||||||
*
|
*
|
||||||
* @param typeId id of distribution set type to search
|
* @param typeId id of distribution set type to search
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> byType(final Long typeId) {
|
public static Specification<JpaDistributionSet> byType(final Long typeId) {
|
||||||
return (dsRoot, query, cb) -> cb.equal(dsRoot.get(JpaDistributionSet_.type).get(JpaDistributionSetType_.id),
|
return (dsRoot, query, cb) -> cb.equal(dsRoot.get(JpaDistributionSet_.type).get(JpaDistributionSetType_.id), typeId);
|
||||||
typeId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link DistributionSet} for given id
|
* {@link Specification} for retrieving {@link DistributionSet} for given id collection of {@link DistributionSet#getType()}.
|
||||||
* collection of {@link DistributionSet#getType()}.
|
|
||||||
*
|
*
|
||||||
* @param typeIds id collection of distribution set type to search
|
* @param typeIds id collection of distribution set type to search
|
||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
@@ -203,54 +178,16 @@ public final class DistributionSetSpecification {
|
|||||||
* @return the {@link DistributionSet} {@link Specification}
|
* @return the {@link DistributionSet} {@link Specification}
|
||||||
*/
|
*/
|
||||||
public static Specification<JpaDistributionSet> hasTag(final Long tagId) {
|
public static Specification<JpaDistributionSet> hasTag(final Long tagId) {
|
||||||
|
|
||||||
return (dsRoot, query, cb) -> {
|
return (dsRoot, query, cb) -> {
|
||||||
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = dsRoot.join(JpaDistributionSet_.tags,
|
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = dsRoot.join(JpaDistributionSet_.tags, JoinType.LEFT);
|
||||||
JoinType.LEFT);
|
|
||||||
return cb.equal(tags.get(JpaDistributionSetTag_.id), tagId);
|
return cb.equal(tags.get(JpaDistributionSetTag_.id), tagId);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static Predicate getHasTagsPredicate(
|
||||||
* Can be added to specification chain to order result by provided target
|
final Root<JpaDistributionSet> dsRoot, final CriteriaBuilder cb,
|
||||||
*
|
|
||||||
* Order: 1. Distribution set installed on target, 2. Distribution set(s)
|
|
||||||
* assigned to target, 3. Based on requested sorting or id if <code>null</code>.
|
|
||||||
*
|
|
||||||
* NOTE: Other specs, pagables and sort objects may alter the queries orderBy
|
|
||||||
* entry too, possibly invalidating the applied order, keep in mind when using
|
|
||||||
* this
|
|
||||||
*
|
|
||||||
* @param linkedControllerId controller id to get installed/assigned DS for
|
|
||||||
* @param sort
|
|
||||||
* @return specification that applies order by target, may be overwritten
|
|
||||||
*/
|
|
||||||
public static Specification<JpaDistributionSet> orderedByLinkedTarget(final String linkedControllerId,
|
|
||||||
final Sort sort) {
|
|
||||||
return (dsRoot, query, cb) -> {
|
|
||||||
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
|
|
||||||
|
|
||||||
final Expression<Object> assignedInstalledCase = cb.selectCase()
|
|
||||||
.when(cb.equal(targetRoot.get(JpaTarget_.installedDistributionSet), dsRoot), 1)
|
|
||||||
.when(cb.equal(targetRoot.get(JpaTarget_.assignedDistributionSet), dsRoot), 2).otherwise(3);
|
|
||||||
|
|
||||||
final List<Order> orders = new ArrayList<>();
|
|
||||||
orders.add(cb.asc(assignedInstalledCase));
|
|
||||||
if (sort == null || sort.isEmpty()) {
|
|
||||||
orders.add(cb.asc(dsRoot.get(JpaDistributionSet_.id)));
|
|
||||||
} else {
|
|
||||||
orders.addAll(QueryUtils.toOrders(sort, dsRoot, cb));
|
|
||||||
}
|
|
||||||
query.orderBy(orders);
|
|
||||||
|
|
||||||
return cb.equal(targetRoot.get(JpaTarget_.controllerId), linkedControllerId);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Predicate getHasTagsPredicate(final Root<JpaDistributionSet> dsRoot, final CriteriaBuilder cb,
|
|
||||||
final Boolean selectDSWithNoTag, final Collection<String> tagNames) {
|
final Boolean selectDSWithNoTag, final Collection<String> tagNames) {
|
||||||
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = dsRoot.join(JpaDistributionSet_.tags,
|
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = dsRoot.join(JpaDistributionSet_.tags, JoinType.LEFT);
|
||||||
JoinType.LEFT);
|
|
||||||
final Path<String> exp = tags.get(JpaDistributionSetTag_.name);
|
final Path<String> exp = tags.get(JpaDistributionSetTag_.name);
|
||||||
|
|
||||||
final List<Predicate> hasTagsPredicates = new ArrayList<>();
|
final List<Predicate> hasTagsPredicates = new ArrayList<>();
|
||||||
@@ -261,8 +198,8 @@ public final class DistributionSetSpecification {
|
|||||||
hasTagsPredicates.add(exp.in(tagNames));
|
hasTagsPredicates.add(exp.in(tagNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasTagsPredicates.stream().reduce(cb::or).orElseThrow(
|
return hasTagsPredicates.stream().reduce(cb::or)
|
||||||
() -> new RuntimeException("Neither NO_TAG, nor TAG distribution set tag filter was provided!"));
|
.orElseThrow(() -> new RuntimeException("Neither NO_TAG, nor TAG distribution set tag filter was provided!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isNoTagActive(final Boolean selectDSWithNoTag) {
|
private static boolean isNoTagActive(final Boolean selectDSWithNoTag) {
|
||||||
|
|||||||
@@ -41,12 +41,9 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void permitAllOperations(final AccessController.Operation operation) {
|
protected void permitAllOperations(final AccessController.Operation operation) {
|
||||||
testAccessControlManger.defineAccessRule(
|
testAccessControlManger.defineAccessRule(JpaTarget.class, operation, Specification.where(null), type -> true);
|
||||||
JpaTarget.class, operation, Specification.where(null), type -> true);
|
testAccessControlManger.defineAccessRule(JpaTargetType.class, operation, Specification.where(null), type -> true);
|
||||||
testAccessControlManger.defineAccessRule(
|
testAccessControlManger.defineAccessRule(JpaDistributionSet.class, operation, Specification.where(null), type -> true);
|
||||||
JpaTargetType.class, operation, Specification.where(null), type -> true);
|
|
||||||
testAccessControlManger.defineAccessRule(
|
|
||||||
JpaDistributionSet.class, operation, Specification.where(null), type -> true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@@ -79,17 +76,17 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Specification<JpaTarget>> getAccessRules(final Operation operation) {
|
public Optional<Specification<JpaTarget>> getAccessRules(final Operation operation) {
|
||||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(
|
if (contextAware.getCurrentTenant() != null
|
||||||
contextAware.getCurrentUsername())) {
|
&& SecurityContextTenantAware.SYSTEM_USER.equals(contextAware.getCurrentUsername())) {
|
||||||
// as tenant, no restrictions
|
// as tenant, no restrictions
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.ofNullable(testAccessControlManger.getAccessRule(JpaTarget.class, operation));
|
return Optional.ofNullable(testAccessControlManger.getAccessRule(JpaTarget.class, operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void assertOperationAllowed(final Operation operation, final JpaTarget entity)
|
public void assertOperationAllowed(final Operation operation, final JpaTarget entity) throws InsufficientPermissionException {
|
||||||
throws InsufficientPermissionException {
|
|
||||||
testAccessControlManger.assertOperation(JpaTarget.class, operation, List.of(entity));
|
testAccessControlManger.assertOperation(JpaTarget.class, operation, List.of(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,17 +98,17 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AccessController<JpaTargetType> targetTypeAccessController(
|
public AccessController<JpaTargetType> targetTypeAccessController(final TestAccessControlManger testAccessControlManger) {
|
||||||
final TestAccessControlManger testAccessControlManger) {
|
|
||||||
return new AccessController<>() {
|
return new AccessController<>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Specification<JpaTargetType>> getAccessRules(final Operation operation) {
|
public Optional<Specification<JpaTargetType>> getAccessRules(final Operation operation) {
|
||||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(
|
if (contextAware.getCurrentTenant() != null
|
||||||
contextAware.getCurrentUsername())) {
|
&& SecurityContextTenantAware.SYSTEM_USER.equals(contextAware.getCurrentUsername())) {
|
||||||
// as tenant, no restrictions
|
// as tenant, no restrictions
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.ofNullable(testAccessControlManger.getAccessRule(JpaTargetType.class, operation));
|
return Optional.ofNullable(testAccessControlManger.getAccessRule(JpaTargetType.class, operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,17 +126,17 @@ public abstract class AbstractAccessControllerTest extends AbstractJpaIntegratio
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AccessController<JpaDistributionSet> distributionSetAccessController(
|
public AccessController<JpaDistributionSet> distributionSetAccessController(final TestAccessControlManger testAccessControlManger) {
|
||||||
final TestAccessControlManger testAccessControlManger) {
|
|
||||||
return new AccessController<>() {
|
return new AccessController<>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Specification<JpaDistributionSet>> getAccessRules(final Operation operation) {
|
public Optional<Specification<JpaDistributionSet>> getAccessRules(final Operation operation) {
|
||||||
if (contextAware.getCurrentTenant() != null && SecurityContextTenantAware.SYSTEM_USER.equals(
|
if (contextAware.getCurrentTenant() != null
|
||||||
contextAware.getCurrentUsername())) {
|
&& SecurityContextTenantAware.SYSTEM_USER.equals(contextAware.getCurrentUsername())) {
|
||||||
// as tenant, no restrictions
|
// as tenant, no restrictions
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Optional.ofNullable(testAccessControlManger.getAccessRule(JpaDistributionSet.class, operation));
|
return Optional.ofNullable(testAccessControlManger.getAccessRule(JpaDistributionSet.class, operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,12 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
@@ -26,8 +29,8 @@ import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -37,6 +40,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
|
||||||
@Feature("Component Tests - Access Control")
|
@Feature("Component Tests - Access Control")
|
||||||
@Story("Test Distribution Set Access Controller")
|
@Story("Test Distribution Set Access Controller")
|
||||||
@@ -136,47 +140,43 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
defineAccess(AccessController.Operation.UPDATE, permitted);
|
defineAccess(AccessController.Operation.UPDATE, permitted);
|
||||||
|
|
||||||
// verify distributionSetManagement#assignSoftwareModules
|
// verify distributionSetManagement#assignSoftwareModules
|
||||||
assertThat(distributionSetManagement.assignSoftwareModules(permitted.getId(),
|
assertThat(distributionSetManagement.assignSoftwareModules(permitted.getId(), Collections.singletonList(swModule.getId())))
|
||||||
Collections.singletonList(swModule.getId()))).satisfies(ds -> {
|
.satisfies(ds -> assertThat(ds.getModules().stream().map(Identifiable::getId).toList()).contains(swModule.getId()));
|
||||||
assertThat(ds.getModules().stream().map(Identifiable::getId).toList()).contains(swModule.getId());
|
assertThatThrownBy(() -> distributionSetManagement.assignSoftwareModules(readOnly.getId(), Collections.singletonList(swModule.getId())))
|
||||||
});
|
.as("Distribution set not allowed to me modified.")
|
||||||
assertThatThrownBy(() -> {
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
distributionSetManagement.assignSoftwareModules(readOnly.getId(),
|
assertThatThrownBy(() -> distributionSetManagement.assignSoftwareModules(hidden.getId(), Collections.singletonList(swModule.getId())))
|
||||||
Collections.singletonList(swModule.getId()));
|
.as("Distribution set should not be visible.")
|
||||||
}).as("Distribution set not allowed to me modified.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
assertThatThrownBy(() -> {
|
|
||||||
distributionSetManagement.assignSoftwareModules(hidden.getId(),
|
|
||||||
Collections.singletonList(swModule.getId()));
|
|
||||||
}).as("Distribution set should not be visible.").isInstanceOf(EntityNotFoundException.class);
|
|
||||||
|
|
||||||
final JpaDistributionSetMetadata metadata = new JpaDistributionSetMetadata("test", "test");
|
final JpaDistributionSetMetadata metadata = new JpaDistributionSetMetadata("test", "test");
|
||||||
|
|
||||||
// verify distributionSetManagement#createMetaData
|
// verify distributionSetManagement#createMetaData
|
||||||
distributionSetManagement.createMetaData(permitted.getId(), Collections.singletonList(metadata));
|
distributionSetManagement.createMetaData(permitted.getId(), Collections.singletonList(metadata));
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> distributionSetManagement.createMetaData(readOnly.getId(), Collections.singletonList(metadata)))
|
||||||
distributionSetManagement.createMetaData(readOnly.getId(), Collections.singletonList(metadata));
|
.as("Distribution set not allowed to me modified.")
|
||||||
}).as("Distribution set not allowed to me modified.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> distributionSetManagement.createMetaData(hidden.getId(), Collections.singletonList(metadata)))
|
||||||
distributionSetManagement.createMetaData(hidden.getId(), Collections.singletonList(metadata));
|
.as("Distribution set should not be visible.")
|
||||||
}).as("Distribution set should not be visible.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
|
|
||||||
// verify distributionSetManagement#updateMetaData
|
// verify distributionSetManagement#updateMetaData
|
||||||
distributionSetManagement.updateMetaData(permitted.getId(), metadata);
|
distributionSetManagement.updateMetaData(permitted.getId(), metadata);
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> distributionSetManagement.updateMetaData(readOnly.getId(), metadata))
|
||||||
distributionSetManagement.updateMetaData(readOnly.getId(), metadata);
|
.as("Distribution set not allowed to me modified.")
|
||||||
}).as("Distribution set not allowed to me modified.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> distributionSetManagement.updateMetaData(hidden.getId(), metadata))
|
||||||
distributionSetManagement.updateMetaData(hidden.getId(), metadata);
|
.as("Distribution set should not be visible.")
|
||||||
}).as("Distribution set should not be visible.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
|
|
||||||
// verify distributionSetManagement#deleteMetaData
|
// verify distributionSetManagement#deleteMetaData
|
||||||
distributionSetManagement.deleteMetaData(permitted.getId(), metadata.getKey());
|
distributionSetManagement.deleteMetaData(permitted.getId(), metadata.getKey());
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> distributionSetManagement.deleteMetaData(readOnly.getId(), metadata.getKey()))
|
||||||
distributionSetManagement.deleteMetaData(readOnly.getId(), metadata.getKey());
|
.as("Distribution set not allowed to me modified.")
|
||||||
}).as("Distribution set not allowed to me modified.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> distributionSetManagement.deleteMetaData(hidden.getId(), metadata.getKey()))
|
||||||
distributionSetManagement.deleteMetaData(hidden.getId(), metadata.getKey());
|
.as("Distribution set should not be visible.")
|
||||||
}).as("Distribution set should not be visible.").isInstanceOf(EntityNotFoundException.class);
|
.isInstanceOf(EntityNotFoundException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -303,7 +303,15 @@ class DistributionSetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
final List<Long> ids = targets.stream().map(DistributionSet::getId).toList();
|
final List<Long> ids = targets.stream().map(DistributionSet::getId).toList();
|
||||||
testAccessControlManger.defineAccessRule(
|
testAccessControlManger.defineAccessRule(
|
||||||
JpaDistributionSet.class, operation,
|
JpaDistributionSet.class, operation,
|
||||||
DistributionSetSpecification.byIds(ids),
|
dsByIds(ids),
|
||||||
distributionSet -> ids.contains(distributionSet.getId()));
|
distributionSet -> ids.contains(distributionSet.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Specification<JpaDistributionSet> dsByIds(final Collection<Long> distids) {
|
||||||
|
return (dsRoot, query, cb) -> {
|
||||||
|
final Predicate predicate = dsRoot.get(JpaDistributionSet_.id).in(distids);
|
||||||
|
query.distinct(true);
|
||||||
|
return predicate;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.criteria.Predicate;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
@@ -25,8 +27,8 @@ import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
import org.eclipse.hawkbit.repository.jpa.acm.AccessController;
|
||||||
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
|
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -39,6 +41,7 @@ import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
|
||||||
@Feature("Component Tests - Access Control")
|
@Feature("Component Tests - Access Control")
|
||||||
@Story("Test Target Access Controller")
|
@Story("Test Target Access Controller")
|
||||||
@@ -75,13 +78,14 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
|
|
||||||
// verify targetManagement#getByControllerID
|
// verify targetManagement#getByControllerID
|
||||||
assertThat(targetManagement.getByControllerID(permittedTarget.getControllerId())).isPresent();
|
assertThat(targetManagement.getByControllerID(permittedTarget.getControllerId())).isPresent();
|
||||||
assertThatThrownBy(() -> targetManagement.getByControllerID(hiddenTarget.getControllerId()))
|
final String hiddenTargetControllerId = hiddenTarget.getControllerId();
|
||||||
|
assertThatThrownBy(() -> targetManagement.getByControllerID(hiddenTargetControllerId))
|
||||||
.as("Missing read permissions for hidden target.")
|
.as("Missing read permissions for hidden target.")
|
||||||
.isInstanceOf(InsufficientPermissionException.class);
|
.isInstanceOf(InsufficientPermissionException.class);
|
||||||
|
|
||||||
// verify targetManagement#getByControllerID
|
// verify targetManagement#getByControllerID
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.getByControllerID(Arrays.asList(permittedTarget.getControllerId(), hiddenTarget.getControllerId()))
|
.getByControllerID(Arrays.asList(permittedTarget.getControllerId(), hiddenTargetControllerId))
|
||||||
.stream().map(Identifiable::getId).toList()).containsOnly(permittedTarget.getId());
|
.stream().map(Identifiable::getId).toList()).containsOnly(permittedTarget.getId());
|
||||||
|
|
||||||
// verify targetManagement#get
|
// verify targetManagement#get
|
||||||
@@ -94,9 +98,9 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
|
|
||||||
// verify targetManagement#getControllerAttributes
|
// verify targetManagement#getControllerAttributes
|
||||||
assertThat(targetManagement.getControllerAttributes(permittedTarget.getControllerId())).isEmpty();
|
assertThat(targetManagement.getControllerAttributes(permittedTarget.getControllerId())).isEmpty();
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> targetManagement.getControllerAttributes(hiddenTargetControllerId))
|
||||||
assertThat(targetManagement.getControllerAttributes(hiddenTarget.getControllerId())).isEmpty();
|
.as("Target should not be found.")
|
||||||
}).as("Target should not be found.").isInstanceOf(InsufficientPermissionException.class);
|
.isInstanceOf(InsufficientPermissionException.class);
|
||||||
|
|
||||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||||
.create(entityFactory.targetFilterQuery().create().name("test").query("id==*"));
|
.create(entityFactory.targetFilterQuery().create().name("test").query("id==*"));
|
||||||
@@ -149,16 +153,13 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
.map(Identifiable::getId).toList()).containsOnly(permittedTarget.getId(), readOnlyTarget.getId());
|
.map(Identifiable::getId).toList()).containsOnly(permittedTarget.getId(), readOnlyTarget.getId());
|
||||||
|
|
||||||
// verify targetManagement#assignTag on permitted target
|
// verify targetManagement#assignTag on permitted target
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement.assignTag(Collections.singletonList(permittedTarget.getControllerId()), myTag.getId()))
|
||||||
.assignTag(Collections.singletonList(permittedTarget.getControllerId()), myTag.getId())
|
.hasSize(1);
|
||||||
.size()).isEqualTo(1);
|
|
||||||
// verify targetManagement#unassignTag on permitted target
|
// verify targetManagement#unassignTag on permitted target
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement.unassignTag(Collections.singletonList(permittedTarget.getControllerId()), myTag.getId()))
|
||||||
.unassignTag(Collections.singletonList(permittedTarget.getControllerId()), myTag.getId())
|
.hasSize(1);
|
||||||
.size()).isEqualTo(1);
|
|
||||||
// verify targetManagement#assignTag on permitted target
|
// verify targetManagement#assignTag on permitted target
|
||||||
assertThat(
|
assertThat(targetManagement.assignTag(Collections.singletonList(permittedTarget.getControllerId()), myTag.getId()))
|
||||||
targetManagement.assignTag(Collections.singletonList(permittedTarget.getControllerId()), myTag.getId()))
|
|
||||||
.hasSize(1);
|
.hasSize(1);
|
||||||
// verify targetManagement#unAssignTag on permitted target
|
// verify targetManagement#unAssignTag on permitted target
|
||||||
assertThat(targetManagement.unassignTag(List.of(permittedTarget.getControllerId()), myTag.getId()).get(0).getControllerId())
|
assertThat(targetManagement.unassignTag(List.of(permittedTarget.getControllerId()), myTag.getId()).get(0).getControllerId())
|
||||||
@@ -174,29 +175,23 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
// .isInstanceOf(InsufficientPermissionException.class);
|
// .isInstanceOf(InsufficientPermissionException.class);
|
||||||
|
|
||||||
// assignment is denied for readOnlyTarget (read, but no update permissions)
|
// assignment is denied for readOnlyTarget (read, but no update permissions)
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> targetManagement.assignTag(Collections.singletonList(readOnlyTarget.getControllerId()), myTag.getId()))
|
||||||
targetManagement.assignTag(Collections.singletonList(readOnlyTarget.getControllerId()), myTag.getId());
|
.as("Missing update permissions for target to toggle tag assignment.")
|
||||||
}).as("Missing update permissions for target to toggle tag assignment.")
|
|
||||||
.isInstanceOfAny(InsufficientPermissionException.class);
|
.isInstanceOfAny(InsufficientPermissionException.class);
|
||||||
|
|
||||||
// assignment is denied for readOnlyTarget (read, but no update permissions)
|
// assignment is denied for readOnlyTarget (read, but no update permissions)
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> targetManagement.unassignTag(List.of(readOnlyTarget.getControllerId()), myTag.getId()))
|
||||||
targetManagement.unassignTag(List.of(readOnlyTarget.getControllerId()), myTag.getId());
|
.as("Missing update permissions for target to toggle tag assignment.")
|
||||||
}).as("Missing update permissions for target to toggle tag assignment.")
|
|
||||||
.isInstanceOf(InsufficientPermissionException.class);
|
.isInstanceOf(InsufficientPermissionException.class);
|
||||||
|
|
||||||
// assignment is denied for hiddenTarget since it's hidden
|
// assignment is denied for hiddenTarget since it's hidden
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> targetManagement.assignTag(Collections.singletonList(hiddenTarget.getControllerId()), myTag.getId()))
|
||||||
targetManagement
|
.as("Missing update permissions for target to toggle tag assignment.")
|
||||||
.assignTag(Collections.singletonList(hiddenTarget.getControllerId()), myTag.getId())
|
|
||||||
.size();
|
|
||||||
}).as("Missing update permissions for target to toggle tag assignment.")
|
|
||||||
.isInstanceOf(InsufficientPermissionException.class);
|
.isInstanceOf(InsufficientPermissionException.class);
|
||||||
|
|
||||||
// assignment is denied for hiddenTarget since it's hidden
|
// assignment is denied for hiddenTarget since it's hidden
|
||||||
assertThatThrownBy(() -> {
|
assertThatThrownBy(() -> targetManagement.assignTag(Collections.singletonList(hiddenTarget.getControllerId()), myTag.getId()))
|
||||||
targetManagement.assignTag(Collections.singletonList(hiddenTarget.getControllerId()), myTag.getId());
|
.as("Missing update permissions for target to toggle tag assignment.")
|
||||||
}).as("Missing update permissions for target to toggle tag assignment.")
|
|
||||||
.isInstanceOf(InsufficientPermissionException.class);
|
.isInstanceOf(InsufficientPermissionException.class);
|
||||||
|
|
||||||
// assignment is denied for hiddenTarget since it's hidden
|
// assignment is denied for hiddenTarget since it's hidden
|
||||||
@@ -358,14 +353,13 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
|
|
||||||
defineAccess(AccessController.Operation.UPDATE, updateTargets);
|
defineAccess(AccessController.Operation.UPDATE, updateTargets);
|
||||||
defineAccess(AccessController.Operation.READ, merge(updateTargets, readTargets));
|
defineAccess(AccessController.Operation.READ, merge(updateTargets, readTargets));
|
||||||
;
|
|
||||||
|
|
||||||
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
final TargetFilterQuery targetFilterQuery = targetFilterQueryManagement
|
||||||
.create(entityFactory.targetFilterQuery().create().name("testName").query("id==*"));
|
.create(entityFactory.targetFilterQuery().create().name("testName").query("id==*"));
|
||||||
|
|
||||||
testAccessControlManger.defineAccessRule(
|
testAccessControlManger.defineAccessRule(
|
||||||
JpaDistributionSet.class, AccessController.Operation.READ,
|
JpaDistributionSet.class, AccessController.Operation.READ,
|
||||||
DistributionSetSpecification.byId(distributionSet.getId()),
|
dsById(distributionSet.getId()),
|
||||||
ds -> ds.getId().equals(distributionSet.getId()));
|
ds -> ds.getId().equals(distributionSet.getId()));
|
||||||
|
|
||||||
targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
targetFilterQueryManagement.updateAutoAssignDS(entityFactory.targetFilterQuery()
|
||||||
@@ -395,4 +389,12 @@ class TargetAccessControllerTest extends AbstractAccessControllerTest {
|
|||||||
TargetSpecifications.hasIdIn(ids),
|
TargetSpecifications.hasIdIn(ids),
|
||||||
target -> ids.contains(target.getId()));
|
target -> ids.contains(target.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Specification<JpaDistributionSet> dsById(final Long distid) {
|
||||||
|
return (dsRoot, query, cb) -> {
|
||||||
|
final Predicate predicate = cb.equal(dsRoot.get(JpaDistributionSet_.id), distid);
|
||||||
|
query.distinct(true);
|
||||||
|
return predicate;
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,13 +31,13 @@ public class TestAccessControlManger {
|
|||||||
public <T> void defineAccessRule(
|
public <T> void defineAccessRule(
|
||||||
final Class<T> ruleClass, final AccessController.Operation operation,
|
final Class<T> ruleClass, final AccessController.Operation operation,
|
||||||
final Specification<T> specification, final Predicate<T> check) {
|
final Specification<T> specification, final Predicate<T> check) {
|
||||||
accessRules.put(new AccessRuleId<T>(ruleClass, operation), new AccessRule<T>(specification, check));
|
accessRules.put(new AccessRuleId<>(ruleClass, operation), new AccessRule<>(specification, check));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends AbstractJpaBaseEntity> Specification<T> getAccessRule(final Class<T> ruleClass,
|
public <T extends AbstractJpaBaseEntity> Specification<T> getAccessRule(final Class<T> ruleClass,
|
||||||
final AccessController.Operation operation) {
|
final AccessController.Operation operation) {
|
||||||
@SuppressWarnings("unchecked") final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(
|
@SuppressWarnings("unchecked")
|
||||||
new AccessRuleId<T>(ruleClass, operation), null);
|
final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(new AccessRuleId<>(ruleClass, operation), null);
|
||||||
if (accessRule == null) {
|
if (accessRule == null) {
|
||||||
return nop();
|
return nop();
|
||||||
} else {
|
} else {
|
||||||
@@ -46,8 +46,8 @@ public class TestAccessControlManger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> void assertOperation(final Class<T> ruleClass, final AccessController.Operation operation, final List<T> entities) {
|
public <T> void assertOperation(final Class<T> ruleClass, final AccessController.Operation operation, final List<T> entities) {
|
||||||
@SuppressWarnings("unchecked") final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(
|
@SuppressWarnings("unchecked")
|
||||||
new AccessRuleId<T>(ruleClass, operation), null);
|
final AccessRule<T> accessRule = (AccessRule<T>) accessRules.getOrDefault(new AccessRuleId<>(ruleClass, operation), null);
|
||||||
if (accessRule == null) {
|
if (accessRule == null) {
|
||||||
throw new InsufficientPermissionException("No access define - reject all");
|
throw new InsufficientPermissionException("No access define - reject all");
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@@ -75,8 +74,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
|
||||||
import org.springframework.data.domain.Sort.Direction;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link DistributionSetManagement} tests.
|
* {@link DistributionSetManagement} tests.
|
||||||
@@ -532,89 +529,6 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
assertThat(updated.getDistributionSet().getId()).isEqualTo(ds.getId());
|
assertThat(updated.getDistributionSet().getId()).isEqualTo(ds.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@Description("Tests that a DS queue is possible where the result is ordered by the target assignment, i.e. assigned first in the list.")
|
|
||||||
void findDistributionSetsAllOrderedByLinkTarget() {
|
|
||||||
final List<DistributionSet> buildDistributionSets = testdataFactory.createDistributionSets("dsOrder", 10);
|
|
||||||
|
|
||||||
final List<Target> buildTargetFixtures = testdataFactory.createTargets(5, "tOrder", "someDesc");
|
|
||||||
|
|
||||||
final Iterator<DistributionSet> dsIterator = buildDistributionSets.iterator();
|
|
||||||
final Iterator<Target> tIterator = buildTargetFixtures.iterator();
|
|
||||||
final DistributionSet dsFirst = dsIterator.next();
|
|
||||||
final DistributionSet dsSecond = dsIterator.next();
|
|
||||||
final DistributionSet dsThree = dsIterator.next();
|
|
||||||
final DistributionSet dsFour = dsIterator.next();
|
|
||||||
final Target tFirst = tIterator.next();
|
|
||||||
final Target tSecond = tIterator.next();
|
|
||||||
|
|
||||||
// set assigned
|
|
||||||
assignDistributionSet(dsSecond.getId(), tSecond.getControllerId());
|
|
||||||
implicitLock(dsSecond);
|
|
||||||
assignDistributionSet(dsThree.getId(), tFirst.getControllerId());
|
|
||||||
implicitLock(dsThree);
|
|
||||||
// set installed
|
|
||||||
testdataFactory.sendUpdateActionStatusToTargets(Collections.singleton(tSecond), Status.FINISHED,
|
|
||||||
singletonList("some message"));
|
|
||||||
|
|
||||||
assignDistributionSet(dsFour.getId(), tSecond.getControllerId());
|
|
||||||
implicitLock(dsFour);
|
|
||||||
|
|
||||||
final DistributionSetFilter distributionSetFilter =
|
|
||||||
DistributionSetFilter.builder()
|
|
||||||
.isDeleted(false)
|
|
||||||
.isComplete(true)
|
|
||||||
.selectDSWithNoTag(Boolean.FALSE).build();
|
|
||||||
|
|
||||||
// target first only has an assigned DS-three so check order correct
|
|
||||||
final List<DistributionSet> tFirstPin = distributionSetManagement
|
|
||||||
.findByDistributionSetFilterOrderByLinkedTarget(PAGE, distributionSetFilter, tFirst.getControllerId())
|
|
||||||
.getContent();
|
|
||||||
assertThat(tFirstPin).hasSize(10);
|
|
||||||
// assigned
|
|
||||||
assertThat(tFirstPin.get(0)).isEqualTo(dsThree);
|
|
||||||
// remaining id:ASC
|
|
||||||
assertThat(tFirstPin.get(1)).isEqualTo(dsFirst);
|
|
||||||
assertThat(tFirstPin.get(2)).isEqualTo(dsSecond);
|
|
||||||
assertThat(tFirstPin.get(3)).isEqualTo(dsFour);
|
|
||||||
|
|
||||||
// target second has installed DS-2 and assigned DS-4 so check order
|
|
||||||
// correct
|
|
||||||
final List<DistributionSet> tSecondPin = distributionSetManagement
|
|
||||||
.findByDistributionSetFilterOrderByLinkedTarget(PAGE, distributionSetFilter, tSecond.getControllerId())
|
|
||||||
.getContent();
|
|
||||||
assertThat(tSecondPin).hasSize(10);
|
|
||||||
// installed
|
|
||||||
assertThat(tSecondPin.get(0)).isEqualTo(dsSecond);
|
|
||||||
// assigned
|
|
||||||
assertThat(tSecondPin.get(1)).isEqualTo(dsFour);
|
|
||||||
// remaining id:ASC
|
|
||||||
assertThat(tSecondPin.get(2)).isEqualTo(dsFirst);
|
|
||||||
assertThat(tSecondPin.get(3)).isEqualTo(dsThree);
|
|
||||||
|
|
||||||
// target second has installed DS-2 and assigned DS-4 so check order
|
|
||||||
// correct
|
|
||||||
final List<DistributionSet> tSecondPinOrderedByName = distributionSetManagement
|
|
||||||
.findByDistributionSetFilterOrderByLinkedTarget(
|
|
||||||
PageRequest.of(0, 500, Sort.by(Direction.DESC, "version")), distributionSetFilter,
|
|
||||||
tSecond.getControllerId())
|
|
||||||
.getContent();
|
|
||||||
assertThat(tSecondPinOrderedByName).hasSize(10);
|
|
||||||
// installed
|
|
||||||
assertThat(tSecondPinOrderedByName.get(0)).isEqualTo(buildDistributionSets.get(1));
|
|
||||||
// assigned
|
|
||||||
assertThat(tSecondPinOrderedByName.get(1)).isEqualTo(buildDistributionSets.get(3));
|
|
||||||
// remaining version:DESC
|
|
||||||
assertThat(tSecondPinOrderedByName.get(2)).isEqualTo(buildDistributionSets.get(9));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(3)).isEqualTo(buildDistributionSets.get(8));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(4)).isEqualTo(buildDistributionSets.get(7));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(5)).isEqualTo(buildDistributionSets.get(6));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(6)).isEqualTo(buildDistributionSets.get(5));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(7)).isEqualTo(buildDistributionSets.get(4));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(8)).isEqualTo(buildDistributionSets.get(2));
|
|
||||||
assertThat(tSecondPinOrderedByName.get(9)).isEqualTo(buildDistributionSets.get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.")
|
@Description("searches for distribution sets based on the various filter options, e.g. name, version, desc., tags.")
|
||||||
void searchDistributionSetsOnFilters() {
|
void searchDistributionSetsOnFilters() {
|
||||||
|
|||||||
Reference in New Issue
Block a user