Align target queries to only use specifications (#1148)

* Add additional specifications to cover use cases of queries

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch.io>

* Replace reading target queries by spec, use empty spec in default repo calls

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch.io>

* Use correct NonNull annotation

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch.io>

* Added default exists based on spec count to TargetRepository

Signed-off-by: Alexander Dobler <alexander.dobler3@bosch.io>
This commit is contained in:
Alexander Dobler
2021-08-04 17:47:23 +02:00
committed by GitHub
parent 8c0bd2ffd2
commit 101401a6a8
9 changed files with 259 additions and 212 deletions

View File

@@ -66,6 +66,7 @@ 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.ActionSpecifications;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.Action;
@@ -310,7 +311,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
}
private void throwExceptionIfTargetDoesNotExist(final String controllerId) {
if (!targetRepository.existsByControllerId(controllerId)) {
if (!targetRepository.exists(TargetSpecifications.hasControllerId(controllerId))) {
throw new EntityNotFoundException(Target.class, controllerId);
}
}
@@ -367,9 +368,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
@Override
public void deleteExistingTarget(@NotEmpty final String controllerId) {
final Target target = targetRepository.findByControllerId(controllerId)
final Target target = targetRepository.findOne(TargetSpecifications.hasControllerId(controllerId))
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
targetRepository.deleteById(target.getId());
targetRepository.deleteById(target.getId());
}
@Override
@@ -738,7 +739,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
throw new InvalidTargetAttributeException();
}
final JpaTarget target = (JpaTarget) targetRepository.findByControllerId(controllerId)
final JpaTarget target = (JpaTarget) targetRepository.findOne(TargetSpecifications.hasControllerId(controllerId))
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
// get the modifiable attribute map
@@ -884,7 +885,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont
@Override
public Optional<Target> getByControllerId(final String controllerId) {
return targetRepository.findByControllerId(controllerId);
return targetRepository.findOne(TargetSpecifications.hasControllerId(controllerId)).map(Target.class::cast);
}
@Override

View File

@@ -55,6 +55,7 @@ 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.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.jpa.utils.TenantConfigHelper;
@@ -289,8 +290,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
.distinct().collect(Collectors.toList());
final List<String> existingTargetIds = Lists.partition(providedTargetIds, Constants.MAX_ENTRIES_IN_STATEMENT)
.stream().map(targetRepository::filterNonExistingControllerIds).flatMap(List::stream)
.collect(Collectors.toList());
.stream().map(ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids)))
.flatMap(List::stream).map(JpaTarget::getControllerId).collect(Collectors.toList());
final List<JpaTarget> targetEntities = assignmentStrategy.findTargetsForAssignment(existingTargetIds,
distributionSetEntity.getId());
@@ -701,7 +702,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
}
private void throwExceptionIfTargetDoesNotExist(final String controllerId) {
if (!targetRepository.existsByControllerId(controllerId)) {
if (!targetRepository.exists(TargetSpecifications.hasControllerId(controllerId))) {
throw new EntityNotFoundException(Target.class, controllerId);
}
}

View File

@@ -37,6 +37,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup_;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
@@ -232,9 +233,11 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
// in case of status ready the action has not been created yet and
// the relation information between target and rollout-group is
// stored in the #TargetRolloutGroup.
return targetRepository.findByRolloutTargetGroupRolloutGroupId(rolloutGroupId, page);
return JpaTargetManagement.convertPage(
targetRepository.findAll(TargetSpecifications.isInRolloutGroup(rolloutGroupId), page), page);
}
return targetRepository.findByActionsRolloutGroupId(rolloutGroupId, page);
return JpaTargetManagement.convertPage(
targetRepository.findAll(TargetSpecifications.isInActionRolloutGroup(rolloutGroupId), page), page);
}
private static boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) {

View File

@@ -144,11 +144,11 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Optional<Target> getByControllerID(final String controllerId) {
return targetRepository.findByControllerId(controllerId);
return targetRepository.findOne(TargetSpecifications.hasControllerId(controllerId)).map(Target.class::cast);
}
private JpaTarget getByControllerIdAndThrowIfNotFound(final String controllerId) {
return targetRepository.findByControllerId(controllerId).map(JpaTarget.class::cast)
return targetRepository.findOne(TargetSpecifications.hasControllerId(controllerId))
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
}
@@ -342,7 +342,7 @@ public class JpaTargetManagement implements TargetManagement {
@Retryable(include = {
ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY))
public void delete(final Collection<Long> targetIDs) {
final List<JpaTarget> targets = targetRepository.findAllById(targetIDs);
final List<JpaTarget> targets = targetRepository.findAll(TargetSpecifications.hasIdIn(targetIDs));
if (targets.size() < targetIDs.size()) {
throw new EntityNotFoundException(Target.class, targetIDs,
@@ -373,7 +373,9 @@ public class JpaTargetManagement implements TargetManagement {
public Page<Target> findByAssignedDistributionSet(final Pageable pageReq, final long distributionSetID) {
throwEntityNotFoundIfDsDoesNotExist(distributionSetID);
return targetRepository.findByAssignedDistributionSetId(pageReq, distributionSetID);
return convertPage(
targetRepository.findAll(TargetSpecifications.hasAssignedDistributionSet(distributionSetID), pageReq),
pageReq);
}
@Override
@@ -399,7 +401,7 @@ public class JpaTargetManagement implements TargetManagement {
}
}
private static Page<Target> convertPage(final Page<JpaTarget> findAll, final Pageable pageable) {
public static Page<Target> convertPage(final Page<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
@@ -410,7 +412,9 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findByInstalledDistributionSet(final Pageable pageReq, final long distributionSetID) {
throwEntityNotFoundIfDsDoesNotExist(distributionSetID);
return targetRepository.findByInstalledDistributionSetId(pageReq, distributionSetID);
return convertPage(
targetRepository.findAll(TargetSpecifications.hasInstalledDistributionSet(distributionSetID), pageReq),
pageReq);
}
@Override
@@ -432,7 +436,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findByUpdateStatus(final Pageable pageable, final TargetUpdateStatus status) {
return targetRepository.findByUpdateStatus(pageable, status);
return convertPage(targetRepository.findAll(TargetSpecifications.hasTargetUpdateStatus(status), pageable),
pageable);
}
@Override
@@ -515,8 +520,8 @@ public class JpaTargetManagement implements TargetManagement {
allTargets.stream().map(Target::getControllerId).collect(Collectors.toList()));
}
final List<JpaTarget> alreadyAssignedTargets = targetRepository.findByTagNameAndControllerIdIn(tagName,
controllerIds);
final List<JpaTarget> alreadyAssignedTargets = targetRepository.findAll(
TargetSpecifications.hasTagName(tagName).and(TargetSpecifications.hasControllerIdIn(controllerIds)));
// all are already assigned -> unassign
if (alreadyAssignedTargets.size() == allTargets.size()) {
@@ -633,21 +638,21 @@ public class JpaTargetManagement implements TargetManagement {
public long countByAssignedDistributionSet(final long distId) {
throwEntityNotFoundIfDsDoesNotExist(distId);
return targetRepository.countByAssignedDistributionSetId(distId);
return targetRepository.count(TargetSpecifications.hasAssignedDistributionSet(distId));
}
@Override
public long countByInstalledDistributionSet(final long distId) {
throwEntityNotFoundIfDsDoesNotExist(distId);
return targetRepository.countByInstalledDistributionSetId(distId);
return targetRepository.count(TargetSpecifications.hasInstalledDistributionSet(distId));
}
@Override
public boolean existsByInstalledOrAssignedDistributionSet(final long distId) {
throwEntityNotFoundIfDsDoesNotExist(distId);
return targetRepository.existsByInstalledOrAssignedDistributionSet(distId);
return targetRepository.exists(TargetSpecifications.hasInstalledOrAssignedDistributionSet(distId));
}
@Override
@@ -733,7 +738,7 @@ public class JpaTargetManagement implements TargetManagement {
public Page<Target> findByTag(final Pageable pageable, final long tagId) {
throwEntityNotFoundExceptionIfTagDoesNotExist(tagId);
return convertPage(targetRepository.findByTag(pageable, tagId), pageable);
return convertPage(targetRepository.findAll(TargetSpecifications.hasTag(tagId), pageable), pageable);
}
private void throwEntityNotFoundExceptionIfTagDoesNotExist(final Long tagId) {
@@ -782,7 +787,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public List<Target> get(final Collection<Long> ids) {
return Collections.unmodifiableList(targetRepository.findAllById(ids));
return Collections.unmodifiableList(targetRepository.findAll(TargetSpecifications.hasIdIn(ids)));
}
@Override
@@ -824,12 +829,13 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public boolean existsByControllerId(final String controllerId) {
return targetRepository.existsByControllerId(controllerId);
return targetRepository.exists(TargetSpecifications.hasControllerId(controllerId));
}
@Override
public Page<Target> findByControllerAttributesRequested(final Pageable pageReq) {
return targetRepository.findByRequestControllerAttributesIsTrue(pageReq);
return convertPage(targetRepository.findAll(TargetSpecifications.hasRequestControllerAttributesTrue(), pageReq),
pageReq);
}
}

View File

@@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.TagSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
@@ -154,7 +155,7 @@ public class JpaTargetTagManagement implements TargetTagManagement {
@Override
public Page<TargetTag> findByTarget(final Pageable pageable, final String controllerId) {
if (!targetRepository.existsByControllerId(controllerId)) {
if (!targetRepository.exists(TargetSpecifications.hasControllerId(controllerId))) {
throw new EntityNotFoundException(Target.class, controllerId);
}

View File

@@ -62,7 +62,7 @@ public class OfflineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
public List<JpaTarget> findTargetsForAssignment(final List<String> controllerIDs, final long setId) {
final Function<List<String>, List<JpaTarget>> mapper;
if (isMultiAssignmentsEnabled()) {
mapper = targetRepository::findAllByControllerId;
mapper = ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids));
} else {
mapper = ids -> targetRepository.findAll(SpecificationsBuilder.combineWithAnd(
Arrays.asList(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId),

View File

@@ -32,7 +32,6 @@ import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
@@ -98,7 +97,7 @@ public class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy {
List<JpaTarget> findTargetsForAssignment(final List<String> controllerIDs, final long setId) {
final Function<List<String>, List<JpaTarget>> mapper;
if (isMultiAssignmentsEnabled()) {
mapper = targetRepository::findAllByControllerId;
mapper = ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids));
} else {
mapper = ids -> targetRepository
.findAll(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId));

View File

@@ -10,24 +10,27 @@ package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.persistence.EntityManager;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.lang.NonNull;
import org.springframework.transaction.annotation.Transactional;
/**
@@ -80,28 +83,6 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
@Param("set") JpaDistributionSet set, @Param("lastModifiedAt") Long modifiedAt,
@Param("lastModifiedBy") String modifiedBy, @Param("targets") Collection<Long> targets);
/**
* Loads {@link Target} by given ID.
*
* @param controllerID
* to search for
* @return found {@link Target} or <code>null</code> if not found.
*/
Optional<Target> findByControllerId(String controllerID);
@Query("SELECT t.controllerAttributes FROM JpaTarget t WHERE t.controllerId=:controllerId")
Map<String, String> getControllerAttributes(@Param("controllerId") String controllerId);
/**
* Checks if target with given id exists.
*
* @param controllerId
* to check
* @return <code>true</code> if target with given id exists
*/
@Query("SELECT CASE WHEN COUNT(t)>0 THEN 'true' ELSE 'false' END FROM JpaTarget t WHERE t.controllerId=:controllerId")
boolean existsByControllerId(@Param("controllerId") String controllerId);
/**
* Deletes the {@link Target}s with the given target IDs.
*
@@ -114,165 +95,116 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
@Query("DELETE FROM JpaTarget t WHERE t.id IN ?1")
void deleteByIdIn(Collection<Long> targetIDs);
/**
* Finds {@link Target}s by assigned {@link Tag}.
*
* @param page
* pages query and sorting information
*
* @param tagId
* to be found
* @return page of found targets
*/
@Query(value = "SELECT DISTINCT t FROM JpaTarget t JOIN t.tags tt WHERE tt.id = :tag")
Page<JpaTarget> findByTag(Pageable page, @Param("tag") Long tagId);
/**
* Finds all {@link Target}s based on given {@link Target#getControllerId()}
* list and assigned {@link Tag#getName()}.
*
* @param tag
* to search for
* @param controllerIds
* to search for
* @return {@link List} of found {@link Target}s.
*/
@Query(value = "SELECT DISTINCT t from JpaTarget t JOIN t.tags tt WHERE tt.name = :tagname AND t.controllerId IN :targets")
List<JpaTarget> findByTagNameAndControllerIdIn(@Param("tagname") String tag,
@Param("targets") Collection<String> controllerIds);
/**
* Used by UI to filter based on selected status.
*
* @param pageable
* for page configuration
* @param status
* to filter for
*
* @return found targets
*/
Page<Target> findByUpdateStatus(Pageable pageable, TargetUpdateStatus status);
/**
* retrieves the {@link Target}s which has the {@link DistributionSet}
* installed with the given ID.
*
* @param pageable
* parameter
* @param setID
* the ID of the {@link DistributionSet}
* @return the found {@link Target}s
*/
Page<Target> findByInstalledDistributionSetId(Pageable pageable, Long setID);
/**
* Finds all targets that have defined {@link DistributionSet} assigned.
*
* @param pageable
* for page configuration
* @param setID
* is the ID of the {@link DistributionSet} to filter for.
*
* @return page of found targets
*/
Page<Target> findByAssignedDistributionSetId(Pageable pageable, Long setID);
/**
* retrieves {@link Target}s where
* {@link JpaTarget#isRequestControllerAttributes()}.
*
* @param pageReq
* page parameter
*
* @return the found {@link Target}s
*
*/
Page<Target> findByRequestControllerAttributesIsTrue(Pageable pageable);
/**
* Counts number of targets with given distribution set Id.
*
* @param distId
* to search for
*
* @return number of found {@link Target}s.
*/
Long countByAssignedDistributionSetId(Long distId);
/**
* Counts number of targets with given distribution set Id.
*
* @param distId
* to search for
* @return number of found {@link Target}s.
*/
Long countByInstalledDistributionSetId(Long distId);
/**
* Checks if there is already a {@link Target} that has the given distribution set Id assigned or installed.
*
* @param distId
* to check
* @return <code>true</code> if a {@link Target} exists.
*/
@Query("SELECT CASE WHEN COUNT(t)>0 THEN 'true' ELSE 'false' END FROM JpaTarget t WHERE t.installedDistributionSet.id=:distId OR t.assignedDistributionSet.id=:distId")
boolean existsByInstalledOrAssignedDistributionSet(@Param("distId") Long distId);
/**
* Finds all {@link Target}s in the repository.
*
* @return {@link List} of {@link Target}s
* Calls version with (empty) spec to allow injecting further specs
*
* @see org.springframework.data.repository.CrudRepository#findAll()
* @return {@link List} of {@link Target}s
*/
@Override
List<JpaTarget> findAll();
@NonNull
default List<JpaTarget> findAll() {
return this.findAll(Specification.where(null));
}
/**
* Finds all {@link Target}s in the repository sorted.
*
* Calls version with (empty) spec to allow injecting further specs
*
* @param sort instructions to sort result by
* @return {@link List} of {@link Target}s
*/
@Override
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("SELECT t FROM JpaTarget t WHERE t.id IN ?1")
List<JpaTarget> findAllById(Iterable<Long> ids);
@NonNull
default Iterable<JpaTarget> findAll(@NonNull Sort sort) {
return this.findAll(Specification.where(null), sort);
}
/**
* Finds all targets for the given list of controller IDs.
*
* @param controllerIds
* The controller IDs to look for.
*
* @return The list of matching targets.
* Finds a page of {@link Target}s in the repository.
*
* Calls version with (empty) spec to allow injecting further specs
*
* @param pageable paging context
* @return {@link List} of {@link Target}s
*/
@Query("SELECT t FROM JpaTarget t WHERE t.controllerId IN ?1")
List<JpaTarget> findAllByControllerId(Iterable<String> controllerIds);
@Override
@NonNull
default Page<JpaTarget> findAll(@NonNull Pageable pageable) {
return this.findAll(Specification.where(null), pageable);
}
/**
*
* Finds all targets of a rollout group.
*
* @param rolloutGroupId
* the ID of the rollout group
* @param page
* the page request parameter
* @return a page of all targets related to a rollout group
* Finds {@link Target}s in the repository matching a list of ids.
*
* Calls version based on spec to allow injecting further specs
*
* @param ids ids to filter for
* @return {@link List} of {@link Target}s
*/
Page<Target> findByRolloutTargetGroupRolloutGroupId(Long rolloutGroupId, Pageable page);
@Override
@NonNull
default List<JpaTarget> findAllById(Iterable<Long> ids) {
final List<Long> collectedIds = StreamSupport.stream(ids.spliterator(), true).collect(Collectors.toList());
return this.findAll(Specification.where(TargetSpecifications.hasIdIn(collectedIds)));
}
/**
* Finds all targets related to a target rollout group stored for a specific
* rollout.
*
* @param rolloutGroupId
* the rollout group the targets should belong to
* @param page
* the page request parameter
* @return a page of all targets related to a rollout group
* Finds {@link Target} in the repository matching an id.
*
* Calls version based on spec to allow injecting further specs
*
* @param id id to filter for
* @return {@link Optional} of {@link Target}
*/
Page<Target> findByActionsRolloutGroupId(Long rolloutGroupId, Pageable page);
@Override
@NonNull
default Optional<JpaTarget> findById(@NonNull Long id) {
return this.findOne(Specification.where(TargetSpecifications.hasId(id)));
}
/**
* Checks whether {@link Target} in the repository matching an id exists or not.
*
* Calls version based on spec to allow injecting further specs
*
* @param id id to check for
* @return true if target with id exists
*/
@Override
default boolean existsById(@NonNull Long id) {
return this.exists(TargetSpecifications.hasId(id));
}
/**
* Checks whether {@link Target} in the repository matching a spec exists or not.
*
* @param spec to check for existence
* @return true if target with id exists
*/
default boolean exists(@NonNull Specification<JpaTarget> spec) {
return this.count(spec) > 0;
}
/**
* Count number of {@link Target}s in the repository.
*
* Calls version with an empty spec to allow injecting further specs
*
* @return number of targets in the repository
*/
@Override
default long count() {
return this.count(Specification.where(null));
}
/**
* Deletes all {@link TenantAwareBaseEntity} of a given tenant. For safety
* reasons (this is a "delete everything" query after all) we add 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
@@ -281,14 +213,4 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
@Transactional
@Query("DELETE FROM JpaTarget t WHERE t.tenant = :tenant")
void deleteByTenant(@Param("tenant") String tenant);
/**
* Filters a given list of controllerIds and returns only the existing IDs.
*
* @param controllerIds
* The IDs to be filtered
* @return only the existing controllerIds
*/
@Query("SELECT t.controllerId FROM JpaTarget t WHERE t.controllerId IN ?1")
List<String> filterNonExistingControllerIds(Iterable<String> controllerIds);
}

View File

@@ -68,6 +68,64 @@ public final class TargetSpecifications {
};
}
/**
* {@link Specification} for retrieving {@link Target}s by controllerId
*
* @param controllerID
* to search for
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasControllerId(final String controllerID) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.get(JpaTarget_.controllerId), controllerID);
}
/**
* {@link Specification} for retrieving {@link Target}s by controllerId
*
* @param controllerIDs
* to search for
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasControllerIdIn(final Collection<String> controllerIDs) {
return (targetRoot, query, cb) -> targetRoot.get(JpaTarget_.controllerId).in(controllerIDs);
}
/**
* {@link Specification} for retrieving {@link Target}s by controllerId
*
* @param id
* to search for
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasId(final Long id) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.get(JpaTarget_.id), id);
}
/**
* {@link Specification} for retrieving {@link Target}s by controllerId
*
* @param ids
* to search for
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasIdIn(final Collection<Long> ids) {
return (targetRoot, query, cb) -> targetRoot.get(JpaTarget_.id).in(ids);
}
/**
* {@link Specification} for retrieving {@link Target}s that have the request
* controller attributes flag set
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasRequestControllerAttributesTrue() {
return (targetRoot, query, cb) -> cb.equal(targetRoot.get(JpaTarget_.requestControllerAttributes), true);
}
/**
* {@link Specification} for retrieving {@link JpaTarget}s including
* {@link JpaTarget#getAssignedDistributionSet()}.
@@ -87,7 +145,7 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by "equal to given
* {@link Specification} for retrieving {@link Target}s by "equal to any given
* {@link TargetUpdateStatus}".
*
* @param updateStatus
@@ -100,8 +158,21 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by "not equal to
* given {@link TargetUpdateStatus}".
* {@link Specification} for retrieving {@link Target}s by "equal to given
* {@link TargetUpdateStatus}".
*
* @param updateStatus
* to be filtered on
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasTargetUpdateStatus(final TargetUpdateStatus updateStatus) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.get(JpaTarget_.updateStatus), updateStatus);
}
/**
* {@link Specification} for retrieving {@link Target}s by "not equal to given
* {@link TargetUpdateStatus}".
*
* @param updateStatus
* to be filtered on
@@ -189,11 +260,7 @@ public final class TargetSpecifications {
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasInstalledOrAssignedDistributionSet(@NotNull final Long distributionId) {
return (targetRoot, query, cb) -> cb.or(
cb.equal(targetRoot.get(JpaTarget_.installedDistributionSet).get(JpaDistributionSet_.id),
distributionId),
cb.equal(targetRoot.<JpaDistributionSet> get(JpaTarget_.assignedDistributionSet)
.get(JpaDistributionSet_.id), distributionId));
return hasInstalledDistributionSet(distributionId).or(hasAssignedDistributionSet(distributionId));
}
/**
@@ -214,6 +281,22 @@ public final class TargetSpecifications {
cb.isNull(targetRoot.<JpaDistributionSet> get(JpaTarget_.assignedDistributionSet))));
}
/**
* {@link Specification} for retrieving {@link Target}s based on a
* {@link TargetTag} name.
*
* @param tagName
* to search for
*
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasTagName(final String tagName) {
return (targetRoot, query, cb) -> {
final SetJoin<JpaTarget, JpaTargetTag> join = targetRoot.join(JpaTarget_.tags);
return cb.equal(join.get(JpaTargetTag_.name), tagName);
};
}
/**
* {@link Specification} for retrieving {@link Target}s by "has no tag
* names"or "has at least on of the given tag names".
@@ -289,6 +372,37 @@ public final class TargetSpecifications {
};
}
/**
* {@link Specification} for retrieving {@link Target}s that are in a given
* {@link RolloutGroup}
*
* @param group
* the {@link RolloutGroup}
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> isInRolloutGroup(final Long group) {
return (targetRoot, query, cb) -> {
final ListJoin<JpaTarget, RolloutTargetGroup> targetGroupJoin = targetRoot
.join(JpaTarget_.rolloutTargetGroup);
return cb.equal(targetGroupJoin.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id), group);
};
}
/**
* {@link Specification} for retrieving {@link Target}s that are in an action
* for a given {@link RolloutGroup}
*
* @param group
* the {@link RolloutGroup}
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> isInActionRolloutGroup(final Long group) {
return (targetRoot, query, cb) -> {
final ListJoin<JpaTarget, JpaAction> targetActionJoin = targetRoot.join(JpaTarget_.actions);
return cb.equal(targetActionJoin.get(JpaAction_.rolloutGroup).get(JpaRolloutGroup_.id), group);
};
}
/**
* {@link Specification} for retrieving {@link Target}s that are not in the
* given {@link RolloutGroup}s
@@ -347,7 +461,7 @@ public final class TargetSpecifications {
* {@link Specification} for retrieving {@link Target}s by tag.
*
* @param tagId
* the ID of the distribution set which must be assigned
* the ID of the tag that should be to be assigned to target
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> hasTag(final Long tagId) {