Optimize UI queries (#1234)

* first iteration of query optimization for target and distribution set
* fixed type distribution set filter
* adapted all ui dataproviders to use repository count
* adapted test to not check target attributes within search query
* unified search behaviuor for ds and sm
* removed unneccessary count queries for some mgmt calls
* removed unneccessary type id proprty from ProxyDistributionSetInfo to minimize lazy fetches
* refactored mgmt classes
* removed duplication of name version filter
* fixed copy rollout compatibility check
* cleaned-up management left overs
* added index to rollouts table on tenant/status queries

Signed-off-by: Bogdan Bondar <Bogdan.Bondar@bosch.io>
This commit is contained in:
Bondar Bogdan
2022-03-23 09:08:56 +01:00
committed by GitHub
parent 681df6c1f1
commit c9eafbbc26
74 changed files with 1444 additions and 1617 deletions

View File

@@ -160,6 +160,19 @@ public interface ArtifactManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<Artifact> findBySoftwareModule(@NotNull Pageable pageReq, long swId);
/**
* Count local artifacts for a base software module.
*
* @param swId
* software module id
* @return count by software module
*
* @throws EntityNotFoundException
* if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
long countBySoftwareModule(long swId);
/**
* Loads {@link DbArtifact} from store for given {@link Artifact}.
*

View File

@@ -331,7 +331,7 @@ public interface DeploymentManagement {
/**
* Retrieves all the {@link ActionStatus} entries of the given
* {@link Action} and {@link Target}.
* {@link Action}.
*
* @param pageReq
* pagination parameter
@@ -345,6 +345,19 @@ public interface DeploymentManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<ActionStatus> findActionStatusByAction(@NotNull Pageable pageReq, long actionId);
/**
* Counts all the {@link ActionStatus} entries of the given {@link Action}.
*
* @param actionId
* to be filtered on
* @return count of {@link ActionStatus} entries
*
* @throws EntityNotFoundException
* if action with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countActionStatusByAction(long actionId);
/**
* Retrieves all messages for an {@link ActionStatus}.
*
@@ -358,6 +371,19 @@ public interface DeploymentManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<String> findMessagesByActionStatusId(@NotNull Pageable pageable, long actionStatusId);
/**
* Counts all messages for an {@link ActionStatus}.
*
*
* @param pageable
* the page request parameter for paging and sorting the result
* @param actionStatusId
* the id of {@link ActionStatus} to count the messages from
* @return count of messages by a specific {@link ActionStatus} id
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countMessagesByActionStatusId(long actionStatusId);
/**
* Get the {@link Action} entity for given actionId with all lazy attributes
* (i.e. distributionSet, target, target.assignedDs).

View File

@@ -29,7 +29,6 @@ import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldExc
import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
@@ -39,6 +38,7 @@ import org.eclipse.hawkbit.repository.model.Tag;
import org.eclipse.hawkbit.repository.model.Target;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -244,6 +244,22 @@ public interface DistributionSetManagement
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSetMetadata> findMetaDataByDistributionSetId(@NotNull Pageable pageable, long setId);
/**
* Counts all meta data by the given distribution set id.
*
* @param pageable
* the page request to page the result
* @param setId
* the distribution set id to retrieve the meta data count from
*
* @return count of ds metadata
*
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
long countMetaDataByDistributionSetId(long setId);
/**
* Finds all meta data by the given distribution set id.
*
@@ -272,7 +288,7 @@ public interface DistributionSetManagement
@NotNull String rsqlParam);
/**
* Finds all {@link DistributionSet}s.
* Finds all {@link DistributionSet}s based on completeness.
*
* @param pageable
* the pagination parameter
@@ -284,7 +300,33 @@ public interface DistributionSetManagement
* @return all found {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSet> findByCompleted(@NotNull Pageable pageable, Boolean complete);
Slice<DistributionSet> findByCompleted(@NotNull Pageable pageable, Boolean complete);
/**
* Counts all {@link DistributionSet}s based on completeness.
*
* @param complete
* to <code>true</code> for counting only completed distribution
* sets or <code>false</code> for only incomplete ones nor
* <code>null</code> to count both.
*
* @return count of all found {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
long countByCompleted(Boolean complete);
/**
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
*
* @param pageable
* page parameter
* @param distributionSetFilter
* has details of filters to be applied.
* @return the page of found {@link DistributionSet}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Slice<DistributionSet> findByDistributionSetFilter(@NotNull Pageable pageable,
@NotNull DistributionSetFilter distributionSetFilter);
/**
* Method retrieves all {@link DistributionSet}s from the repository in the
@@ -301,29 +343,27 @@ public interface DistributionSetManagement
*
* @param pageable
* the page request to page the result set *
* @param distributionSetFilterBuilder
* has details of filters to be applied
* @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)
Page<DistributionSet> findByFilterAndAssignedInstalledDsOrderedByLinkTarget(@NotNull Pageable pageable,
@NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled);
Slice<DistributionSet> findByDistributionSetFilterOrderByLinkedTarget(@NotNull Pageable pageable,
@NotNull DistributionSetFilter distributionSetFilter, @NotEmpty String assignedOrInstalled);
/**
* Retrieves {@link DistributionSet}s by filtering on the given parameters.
* Counts all {@link DistributionSet}s in repository based on given filter.
*
* @param pageable
* page parameter
* @param distributionSetFilter
* has details of filters to be applied.
* @return the page of found {@link DistributionSet}
*
* @return count of {@link DistributionSet}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<DistributionSet> findByDistributionSetFilter(@NotNull Pageable pageable,
@NotNull DistributionSetFilter distributionSetFilter);
long countByDistributionSetFilter(@NotNull DistributionSetFilter distributionSetFilter);
/**
* Retrieves {@link DistributionSet}s by filtering on the given parameters.

View File

@@ -181,8 +181,8 @@ public interface RolloutManagement {
RolloutGroupConditions conditions);
/**
* Calculates how many targets are addressed by each rollout group and returns
* the validation information.
* Calculates how many targets are addressed by each rollout group and
* returns the validation information.
*
* @param groups
* a list of rollout groups
@@ -226,7 +226,7 @@ public interface RolloutManagement {
* statuses
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ)
Page<Rollout> findAllWithDetailedStatus(@NotNull Pageable pageable, boolean deleted);
Slice<Rollout> findAllWithDetailedStatus(@NotNull Pageable pageable, boolean deleted);
/**
* Retrieves all rollouts found by the given specification.

View File

@@ -220,6 +220,20 @@ public interface SoftwareModuleManagement
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(@NotNull Pageable pageable, long moduleId);
/**
* Counts all meta data by the given software module id.
*
* @param moduleId
* the software module id to retrieve the meta data count from
*
* @return count of all meta data entries for a given software module id
*
* @throws EntityNotFoundException
* if software module with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
long countMetaDataBySoftwareModuleId(long moduleId);
/**
* Finds all meta data by the given software module id where
* {@link SoftwareModuleMetadata#isTargetVisible()}.

View File

@@ -30,6 +30,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PreAuthorize;
/**
@@ -96,7 +97,7 @@ public interface TargetFilterQueryManagement {
* @return the found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findAll(@NotNull Pageable pageable);
Slice<TargetFilterQuery> findAll(@NotNull Pageable pageable);
/**
* Counts all {@link TargetFilterQuery}s.
@@ -128,7 +129,17 @@ public interface TargetFilterQueryManagement {
* @return the page with the found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findByName(@NotNull Pageable pageable, @NotNull String name);
Slice<TargetFilterQuery> findByName(@NotNull Pageable pageable, @NotNull String name);
/**
* Counts all {@link TargetFilterQuery}s which match the given name filter.
*
* @param name
* name filter
* @return count of found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countByName(@NotNull String name);
/**
* Retrieves all {@link TargetFilterQuery} which match the given RSQL
@@ -153,7 +164,23 @@ public interface TargetFilterQueryManagement {
* @return the page with the found {@link TargetFilterQuery}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findByQuery(@NotNull Pageable pageable, @NotNull String query);
Slice<TargetFilterQuery> findByQuery(@NotNull Pageable pageable, @NotNull String query);
/**
* Retrieves all {@link TargetFilterQuery}s which match the given
* auto-assign distribution set ID.
*
* @param pageable
* pagination parameter
* @param setId
* the auto assign distribution set
* @return the page with the found {@link TargetFilterQuery}s
*
* @throws EntityNotFoundException
* if DS with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Slice<TargetFilterQuery> findByAutoAssignDistributionSetId(@NotNull Pageable pageable, long setId);
/**
* Retrieves all {@link TargetFilterQuery}s which match the given
@@ -181,7 +208,7 @@ public interface TargetFilterQueryManagement {
* @param pageable
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findWithAutoAssignDS(@NotNull Pageable pageable);
Slice<TargetFilterQuery> findWithAutoAssignDS(@NotNull Pageable pageable);
/**
* Finds the {@link TargetFilterQuery} by id.

View File

@@ -8,6 +8,16 @@
*/
package org.eclipse.hawkbit.repository;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.builder.TargetCreate;
import org.eclipse.hawkbit.repository.builder.TargetUpdate;
@@ -34,15 +44,6 @@ import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* Management service for {@link Target}s.
*
@@ -109,7 +110,9 @@ public interface TargetManagement {
* @throws EntityNotFoundException
* if distribution set with given ID does not exist
*
* @deprecated this method {@link TargetManagement#countByFilters(FilterParams)} should be used instead.
* @deprecated this method
* {@link TargetManagement#countByFilters(FilterParams)} should
* be used instead.
*/
@Deprecated
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -146,7 +149,8 @@ public interface TargetManagement {
long countByInstalledDistributionSet(long distId);
/**
* Checks if there is already a {@link Target} that has the given distribution set Id assigned or installed.
* Checks if there is already a {@link Target} that has the given
* distribution set Id assigned or installed.
*
* @param distId
* to search for
@@ -170,8 +174,8 @@ public interface TargetManagement {
long countByRsql(@NotEmpty String rsqlParam);
/**
* Count all targets for given {@link TargetFilterQuery} and that are compatible
* with the passed {@link DistributionSetType}.
* Count all targets for given {@link TargetFilterQuery} and that are
* compatible with the passed {@link DistributionSetType}.
*
* @param rsqlParam
* filter definition in RSQL syntax
@@ -190,7 +194,7 @@ public interface TargetManagement {
* {@link TargetFilterQuery#getId()}
* @return the found number of {@link Target}s
*
* @throws EntityNotFoundException
* @throws EntityNotFoundException
* if {@link TargetFilterQuery} with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -265,9 +269,9 @@ public interface TargetManagement {
void deleteByControllerID(@NotEmpty String controllerID);
/**
* Finds all targets for all the given parameter {@link TargetFilterQuery} and
* that don't have the specified distribution set in their action history and
* are compatible with the passed {@link DistributionSetType}.
* Finds all targets for all the given parameter {@link TargetFilterQuery}
* and that don't have the specified distribution set in their action
* history and are compatible with the passed {@link DistributionSetType}.
*
* @param pageRequest
* the pageRequest to enhance the query for paging and sorting
@@ -281,13 +285,13 @@ public interface TargetManagement {
* if distribution set with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<Target> findByTargetFilterQueryAndNonDSAndCompatible(@NotNull Pageable pageRequest, long distributionSetId,
Slice<Target> findByTargetFilterQueryAndNonDSAndCompatible(@NotNull Pageable pageRequest, long distributionSetId,
@NotNull String rsqlParam);
/**
* Counts all targets for all the given parameter {@link TargetFilterQuery} and
* that don't have the specified distribution set in their action history and
* are compatible with the passed {@link DistributionSetType}.
* Counts all targets for all the given parameter {@link TargetFilterQuery}
* and that don't have the specified distribution set in their action
* history and are compatible with the passed {@link DistributionSetType}.
*
* @param distributionSetId
* id of the {@link DistributionSet}
@@ -302,9 +306,9 @@ public interface TargetManagement {
long countByRsqlAndNonDSAndCompatible(long distributionSetId, @NotNull String rsqlParam);
/**
* Finds all targets for all the given parameter {@link TargetFilterQuery} and
* that are not assigned to one of the {@link RolloutGroup}s and are compatible
* with the passed {@link DistributionSetType}.
* Finds all targets for all the given parameter {@link TargetFilterQuery}
* and that are not assigned to one of the {@link RolloutGroup}s and are
* compatible with the passed {@link DistributionSetType}.
*
* @param pageRequest
* the pageRequest to enhance the query for paging and sorting
@@ -313,27 +317,27 @@ public interface TargetManagement {
* @param rsqlParam
* filter definition in RSQL syntax
* @param distributionSetType
* type of the {@link DistributionSet} the targets must be compatible
* with
* type of the {@link DistributionSet} the targets must be
* compatible with
* @return a page of the found {@link Target}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<Target> findByTargetFilterQueryAndNotInRolloutGroupsAndCompatible(@NotNull Pageable pageRequest,
Slice<Target> findByTargetFilterQueryAndNotInRolloutGroupsAndCompatible(@NotNull Pageable pageRequest,
@NotEmpty Collection<Long> groups, @NotNull String rsqlParam,
@NotNull DistributionSetType distributionSetType);
/**
* Counts all targets for all the given parameter {@link TargetFilterQuery} and
* that are not assigned to one of the {@link RolloutGroup}s and are compatible
* with the passed {@link DistributionSetType}.
* Counts all targets for all the given parameter {@link TargetFilterQuery}
* and that are not assigned to one of the {@link RolloutGroup}s and are
* compatible with the passed {@link DistributionSetType}.
*
* @param groups
* the list of {@link RolloutGroup}s
* @param rsqlParam
* filter definition in RSQL syntax
* @param distributionSetType
* type of the {@link DistributionSet} the targets must be compatible
* with
* type of the {@link DistributionSet} the targets must be
* compatible with
* @return count of the found {@link Target}s
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -354,7 +358,7 @@ public interface TargetManagement {
* if rollout group with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<Target> findByInRolloutGroupWithoutAction(@NotNull Pageable pageRequest, long group);
Slice<Target> findByInRolloutGroupWithoutAction(@NotNull Pageable pageRequest, long group);
/**
* retrieves {@link Target}s by the assigned {@link DistributionSet}.
@@ -518,7 +522,7 @@ public interface TargetManagement {
* if the RSQL syntax is wrong
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<Target> findByRsql(@NotNull Pageable pageable, @NotNull String rsqlParam);
Slice<Target> findByRsql(@NotNull Pageable pageable, @NotNull String rsqlParam);
/**
* Retrieves all target based on {@link TargetFilterQuery}.
@@ -612,8 +616,8 @@ public interface TargetManagement {
/**
* Toggles {@link TargetTag} assignment to given {@link Target}s by means
* that if some (or all) of the targets in the list have the {@link Tag} not
* yet assigned, they will be. Only if all of theme have the tag already assigned
* they will be removed instead.
* yet assigned, they will be. Only if all of theme have the tag already
* assigned they will be removed instead.
*
* @param controllerIds
* to toggle for
@@ -627,12 +631,11 @@ public interface TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
TargetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection<String> controllerIds, @NotEmpty String tagName);
/**
* Initiates {@link TargetType} assignment to given {@link Target}s. If some
* targets in the list have the {@link TargetType} not yet assigned, they will
* get assigned. If all targets are already of that type, there will be no
* un-assignment.
* targets in the list have the {@link TargetType} not yet assigned, they
* will get assigned. If all targets are already of that type, there will be
* no un-assignment.
*
* @param controllerIds
* to set the type to
@@ -648,8 +651,8 @@ public interface TargetManagement {
TargetTypeAssignmentResult assignType(@NotEmpty Collection<String> controllerIds, @NotNull Long typeId);
/**
* Initiates {@link TargetType} un-assignment to given {@link Target}s. The type
* of the targets will be set to {@code null}
* Initiates {@link TargetType} un-assignment to given {@link Target}s. The
* type of the targets will be set to {@code null}
*
* @param controllerIds
* to remove the type from
@@ -851,6 +854,20 @@ public interface TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
Page<TargetMetadata> findMetaDataByControllerId(@NotNull Pageable pageable, @NotEmpty String controllerId);
/**
* Counts all meta data by the given target id.
*
* @param controllerId
* the controller id to retrieve the meta data from
*
* @return count of all meta data entries for a given target id
*
* @throws EntityNotFoundException
* if target with given ID does not exist
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
long countMetaDataByControllerId(@NotEmpty String controllerId);
/**
* Finds all meta data by the given target id and query.
*

View File

@@ -8,21 +8,23 @@
*/
package org.eclipse.hawkbit.repository;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.repository.builder.TargetTypeCreate;
import org.eclipse.hawkbit.repository.builder.TargetTypeUpdate;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
/**
* Management service for {@link TargetType}s.
*
@@ -43,9 +45,17 @@ public interface TargetTypeManagement {
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long count();
/**
* @param name
* as {@link TargetType#getName()}
* @return total count by name
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
long countByName(String name);
/**
* @param create
* TargetTypeCreate
* TargetTypeCreate
* @return targetType
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
@@ -53,31 +63,32 @@ public interface TargetTypeManagement {
/**
* @param creates
* List of TargetTypeCreate
* List of TargetTypeCreate
* @return List of targetType
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_CREATE_TARGET)
List<TargetType> create(@NotEmpty @Valid Collection<TargetTypeCreate> creates);
/**
* @param id targetTypeId
* @param id
* targetTypeId
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_DELETE_TARGET)
void delete(@NotNull Long id);
/**
* @param pageable
* Page
* Page
* @return TargetType page
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetType> findAll(@NotNull Pageable pageable);
Slice<TargetType> findAll(@NotNull Pageable pageable);
/**
* @param pageable
* Page
* Page
* @param rsqlParam
* query param
* query param
* @return Target type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -93,11 +104,11 @@ public interface TargetTypeManagement {
* @return the page of found {@link TargetType}
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetType> findByName(@NotNull Pageable pageable, String name);
Slice<TargetType> findByName(@NotNull Pageable pageable, String name);
/**
* @param id
* Target type ID
* Target type ID
* @return Target Type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -105,7 +116,7 @@ public interface TargetTypeManagement {
/**
* @param targetId
* Target ID
* Target ID
* @return Target Type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -113,7 +124,7 @@ public interface TargetTypeManagement {
/**
* @param targetIds
* List of Target ID
* List of Target ID
* @return Target Type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -121,7 +132,7 @@ public interface TargetTypeManagement {
/**
* @param controllerId
* Target controller ID
* Target controller ID
* @return Target Type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
@@ -129,25 +140,23 @@ public interface TargetTypeManagement {
/**
* @param controllerIds
* List of Target controller ID
* List of Target controller ID
* @return Target Type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
List<TargetType> findByTargetControllerIds(Collection<String> controllerIds);
/**
* @param ids
* List of Target type ID
* List of Target type ID
* @return Target type list
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_TARGET)
List<TargetType> get(@NotEmpty Collection<Long> ids);
/**
* @param update
* TargetTypeUpdate
* TargetTypeUpdate
* @return Target Type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET)
@@ -155,20 +164,20 @@ public interface TargetTypeManagement {
/**
* @param targetTypeId
* Target type ID
* Target type ID
* @param distributionSetTypeIds
* Distribution set ID
* Distribution set ID
* @return Target type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)
TargetType assignCompatibleDistributionSetTypes(long targetTypeId,
@NotEmpty Collection<Long> distributionSetTypeIds);
@NotEmpty Collection<Long> distributionSetTypeIds);
/**
* @param targetTypeId
* Target type ID
* Target type ID
* @param distributionSetTypeIds
* Distribution set ID
* Distribution set ID
* @return Target type
*/
@PreAuthorize(SpPermission.SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET)

View File

@@ -21,9 +21,8 @@ public final class DistributionSetFilter {
private Boolean isDeleted;
private Boolean isComplete;
private Boolean isValid;
private DistributionSetType type;
private Long typeId;
private String searchText;
private String filterString;
private Boolean selectDSWithNoTag;
private Collection<String> tagNames;
private String assignedTargetId;
@@ -68,11 +67,6 @@ public final class DistributionSetFilter {
return this;
}
public DistributionSetFilterBuilder setFilterString(final String filterString) {
this.filterString = filterString;
return this;
}
public DistributionSetFilterBuilder setSelectDSWithNoTag(final Boolean selectDSWithNoTag) {
this.selectDSWithNoTag = selectDSWithNoTag;
return this;
@@ -83,8 +77,8 @@ public final class DistributionSetFilter {
return this;
}
public DistributionSetFilterBuilder setType(final DistributionSetType type) {
this.type = type;
public DistributionSetFilterBuilder setTypeId(final Long typeId) {
this.typeId = typeId;
return this;
}
@@ -93,9 +87,8 @@ public final class DistributionSetFilter {
private final Boolean isDeleted;
private final Boolean isComplete;
private final Boolean isValid;
private final DistributionSetType type;
private final Long typeId;
private final String searchText;
private final String filterString;
private final Boolean selectDSWithNoTag;
private final Collection<String> tagNames;
private final String assignedTargetId;
@@ -112,9 +105,8 @@ public final class DistributionSetFilter {
this.isDeleted = builder.isDeleted;
this.isComplete = builder.isComplete;
this.isValid = builder.isValid;
this.type = builder.type;
this.typeId = builder.typeId;
this.searchText = builder.searchText;
this.filterString = builder.filterString;
this.selectDSWithNoTag = builder.selectDSWithNoTag;
this.tagNames = builder.tagNames;
this.assignedTargetId = builder.assignedTargetId;
@@ -145,10 +137,6 @@ public final class DistributionSetFilter {
return searchText;
}
public String getFilterString() {
return filterString;
}
public Boolean getSelectDSWithNoTag() {
return selectDSWithNoTag;
}
@@ -157,8 +145,8 @@ public final class DistributionSetFilter {
return tagNames;
}
public DistributionSetType getType() {
return type;
public Long getTypeId() {
return typeId;
}
}

View File

@@ -220,6 +220,13 @@ public class JpaArtifactManagement implements ArtifactManagement {
return localArtifactRepository.findBySoftwareModuleId(pageReq, swId);
}
@Override
public long countBySoftwareModule(final long swId) {
throwExceptionIfSoftwareModuleDoesNotExist(swId);
return localArtifactRepository.countBySoftwareModuleId(swId);
}
private void throwExceptionIfSoftwareModuleDoesNotExist(final Long swId) {
if (!softwareModuleRepository.existsById(swId)) {
throw new EntityNotFoundException(SoftwareModule.class, swId);

View File

@@ -12,6 +12,7 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumMap;
@@ -273,7 +274,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
.orElseThrow(() -> new EntityNotFoundException(Target.class, controllerId));
if (target.getTargetType() != null) {
// we assume that list of assigned DS is less than MAX_ENTRIES_IN_STATEMENT
// we assume that list of assigned DS is less than
// MAX_ENTRIES_IN_STATEMENT
final Set<DistributionSetType> incompatibleDistSetTypes = distributionSetManagement.get(distSetIds).stream()
.map(DistributionSet::getType).collect(Collectors.toSet());
incompatibleDistSetTypes.removeAll(target.getTargetType().getCompatibleDistributionSetTypes());
@@ -309,8 +311,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
}
/**
* method assigns the {@link DistributionSet} to all {@link Target}s by their
* IDs with a specific {@link ActionType} and {@code forcetime}.
* method assigns the {@link DistributionSet} to all {@link Target}s by
* their IDs with a specific {@link ActionType} and {@code forcetime}.
*
*
* In case the update was executed offline (i.e. not managed by hawkBit) the
@@ -318,8 +320,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
* A. it ignores targets completely that are in
* {@link TargetUpdateStatus#PENDING}.<br/>
* B. it created completed actions.<br/>
* C. sets both installed and assigned DS on the target and switches the status
* to {@link TargetUpdateStatus#IN_SYNC} <br/>
* C. sets both installed and assigned DS on the target and switches the
* status to {@link TargetUpdateStatus#IN_SYNC} <br/>
* D. does not send a {@link TargetAssignDistributionSetEvent}.<br/>
*
* @param initiatedBy
@@ -404,9 +406,9 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
}
/**
* split tIDs length into max entries in-statement because many database have
* constraint of max entries in in-statements e.g. Oracle with maximum 1000
* elements, so we need to split the entries here and execute multiple
* split tIDs length into max entries in-statement because many database
* have constraint of max entries in in-statements e.g. Oracle with maximum
* 1000 elements, so we need to split the entries here and execute multiple
* statements
*/
private static List<List<Long>> getTargetEntitiesAsChunks(final List<JpaTarget> targetEntities) {
@@ -579,10 +581,10 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
return 0L;
}
final List<Action> targetAssignments = rolloutGroupActions.getContent().stream()
.map(action -> (JpaAction) action).map(this::closeActionIfSetWasAlreadyAssigned)
.filter(Objects::nonNull).map(this::startScheduledActionIfNoCancelationHasToBeHandledFirst)
.filter(Objects::nonNull).collect(Collectors.toList());
final List<Action> targetAssignments = rolloutGroupActions.getContent().stream().map(JpaAction.class::cast)
.map(this::closeActionIfSetWasAlreadyAssigned).filter(Objects::nonNull)
.map(this::startScheduledActionIfNoCancelationHasToBeHandledFirst).filter(Objects::nonNull)
.collect(Collectors.toList());
if (!targetAssignments.isEmpty()) {
onlineDsAssignmentStrategy.sendDeploymentEvents(distributionSetId, targetAssignments);
@@ -696,20 +698,15 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
final Pageable pageable) {
throwExceptionIfTargetDoesNotExist(controllerId);
final Specification<JpaAction> byTargetSpec = createSpecificationFor(controllerId, rsqlParam);
final Page<JpaAction> actions = actionRepository.findAll(byTargetSpec, pageable);
return convertAcPage(actions, pageable);
final List<Specification<JpaAction>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, ActionFields.class, virtualPropertyReplacer, database),
byControllerIdSpec(controllerId));
return JpaManagementHelper.findAllWithCountBySpec(actionRepository, pageable, specList);
}
private Specification<JpaAction> createSpecificationFor(final String controllerId, final String rsqlParam) {
final Specification<JpaAction> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, ActionFields.class,
virtualPropertyReplacer, database);
return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb),
cb.equal(root.get(JpaAction_.target).get(JpaTarget_.controllerId), controllerId));
}
private static Page<Action> convertAcPage(final Page<JpaAction> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements());
private Specification<JpaAction> byControllerIdSpec(final String controllerId) {
return (root, query, cb) -> cb.equal(root.get(JpaAction_.target).get(JpaTarget_.controllerId), controllerId);
}
@Override
@@ -744,7 +741,11 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
@Override
public long countActionsByTarget(final String rsqlParam, final String controllerId) {
throwExceptionIfTargetDoesNotExist(controllerId);
return actionRepository.count(createSpecificationFor(controllerId, rsqlParam));
final List<Specification<JpaAction>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, ActionFields.class, virtualPropertyReplacer, database),
byControllerIdSpec(controllerId));
return JpaManagementHelper.countBySpec(actionRepository, specList);
}
private void throwExceptionIfTargetDoesNotExist(final String controllerId) {
@@ -776,24 +777,28 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
@Override
public Page<ActionStatus> findActionStatusByAction(final Pageable pageReq, final long actionId) {
verifyActionExists(actionId);
return actionStatusRepository.findByActionId(pageReq, actionId);
}
private void verifyActionExists(final long actionId) {
if (!actionRepository.existsById(actionId)) {
throw new EntityNotFoundException(Action.class, actionId);
}
}
return actionStatusRepository.findByActionId(pageReq, actionId);
@Override
public long countActionStatusByAction(final long actionId) {
verifyActionExists(actionId);
return actionStatusRepository.countByActionId(actionId);
}
@Override
public Page<String> findMessagesByActionStatusId(final Pageable pageable, final long actionStatusId) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> countMsgQuery = cb.createQuery(Long.class);
final Root<JpaActionStatus> countMsgQueryFrom = countMsgQuery.distinct(true).from(JpaActionStatus.class);
final ListJoin<JpaActionStatus, String> cJoin = countMsgQueryFrom.joinList("messages", JoinType.LEFT);
countMsgQuery.select(cb.count(cJoin))
.where(cb.equal(countMsgQueryFrom.get(JpaActionStatus_.id), actionStatusId));
final Long totalCount = entityManager.createQuery(countMsgQuery).getSingleResult();
final CriteriaQuery<String> msgQuery = cb.createQuery(String.class);
final Root<JpaActionStatus> as = msgQuery.from(JpaActionStatus.class);
final ListJoin<JpaActionStatus, String> join = as.joinList("messages", JoinType.LEFT);
@@ -803,16 +808,25 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
final List<String> result = new ArrayList<>(entityManager.createQuery(selMsgQuery)
.setFirstResult((int) pageable.getOffset()).setMaxResults(pageable.getPageSize()).getResultList());
return new PageImpl<>(result, pageable, totalCount);
return new PageImpl<>(result, pageable, result.size());
}
@Override
public long countMessagesByActionStatusId(final long actionStatusId) {
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> countMsgQuery = cb.createQuery(Long.class);
final Root<JpaActionStatus> countMsgQueryFrom = countMsgQuery.distinct(true).from(JpaActionStatus.class);
final ListJoin<JpaActionStatus, String> cJoin = countMsgQueryFrom.joinList("messages", JoinType.LEFT);
countMsgQuery.select(cb.count(cJoin))
.where(cb.equal(countMsgQueryFrom.get(JpaActionStatus_.id), actionStatusId));
return entityManager.createQuery(countMsgQuery).getSingleResult();
}
@Override
public Page<ActionStatus> findActionStatusAll(final Pageable pageable) {
return convertAcSPage(actionStatusRepository.findAll(pageable), pageable);
}
private static Page<ActionStatus> convertAcSPage(final Page<JpaActionStatus> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements());
return JpaManagementHelper.findAllWithCountBySpec(actionStatusRepository, pageable, null);
}
@Override
@@ -844,7 +858,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
@Override
public Slice<Action> findActionsAll(final Pageable pageable) {
return convertAcPage(actionRepository.findAll(pageable), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(actionRepository, pageable, null);
}
@Override
@@ -866,10 +880,10 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl
return 0;
}
/*
* We use a native query here because Spring JPA does not support to specify a
* LIMIT clause on a DELETE statement. However, for this specific use case
* (action cleanup), we must specify a row limit to reduce the overall load on
* the database.
* We use a native query here because Spring JPA does not support to
* specify a LIMIT clause on a DELETE statement. However, for this
* specific use case (action cleanup), we must specify a row limit to
* reduce the overall load on the database.
*/
final int statusCount = status.size();

View File

@@ -8,7 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -17,12 +16,14 @@ import java.util.Optional;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.DistributionSetFields;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
@@ -50,7 +51,6 @@ import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
@@ -62,9 +62,9 @@ import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
@@ -148,7 +148,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override
public Optional<DistributionSet> getWithDetails(final long distid) {
return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid))
.map(d -> (DistributionSet) d);
.map(DistributionSet.class::cast);
}
@Override
@@ -337,101 +337,59 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
@Override
public Page<DistributionSet> findByDistributionSetFilter(final Pageable pageable,
public Slice<DistributionSet> findByDistributionSetFilter(final Pageable pageable,
final DistributionSetFilter distributionSetFilter) {
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
distributionSetFilter);
return convertDsPage(findByCriteriaAPI(pageable, specList), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, pageable, specList);
}
private static Page<DistributionSet> convertDsPage(final Page<JpaDistributionSet> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Slice<DistributionSet> convertDsPage(final Slice<JpaDistributionSet> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
}
/**
*
* @param distributionSetFilter
* had details of filters to be applied
* @return a single DistributionSet which is either installed or assigned to
* a specific target or {@code null}.
*/
private Optional<JpaDistributionSet> findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
final DistributionSetFilter distributionSetFilter) {
@Override
public long countByDistributionSetFilter(@NotNull final DistributionSetFilter distributionSetFilter) {
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
distributionSetFilter);
if (CollectionUtils.isEmpty(specList)) {
return Optional.empty();
}
return distributionSetRepository.findOne(SpecificationsBuilder.combineWithAnd(specList));
return JpaManagementHelper.countBySpec(distributionSetRepository, specList);
}
@Override
public Page<DistributionSet> findByCompleted(final Pageable pageReq, final Boolean complete) {
public Slice<DistributionSet> findByCompleted(final Pageable pageReq, final Boolean complete) {
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, pageReq,
buildSpecsByComplete(complete));
}
List<Specification<JpaDistributionSet>> specList;
if (complete != null) {
specList = Arrays.asList(DistributionSetSpecification.isDeleted(false),
DistributionSetSpecification.isCompleted(complete));
} else {
specList = Collections.singletonList(DistributionSetSpecification.isDeleted(false));
}
return convertDsPage(findByCriteriaAPI(pageReq, specList), pageReq);
private List<Specification<JpaDistributionSet>> buildSpecsByComplete(final Boolean complete) {
return complete != null
? Arrays.asList(DistributionSetSpecification.isDeleted(false),
DistributionSetSpecification.isCompleted(complete))
: Collections.singletonList(DistributionSetSpecification.isDeleted(false));
}
@Override
public Page<DistributionSet> findByFilterAndAssignedInstalledDsOrderedByLinkTarget(final Pageable pageable,
final DistributionSetFilterBuilder distributionSetFilterBuilder, final String assignedOrInstalled) {
public long countByCompleted(final Boolean complete) {
return JpaManagementHelper.countBySpec(distributionSetRepository, buildSpecsByComplete(complete));
}
final DistributionSetFilter filterWithInstalledTargets = distributionSetFilterBuilder
.setInstalledTargetId(assignedOrInstalled).setAssignedTargetId(null).build();
final Optional<JpaDistributionSet> installedDS = findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
filterWithInstalledTargets);
@Override
public Slice<DistributionSet> findByDistributionSetFilterOrderByLinkedTarget(final Pageable pageable,
final DistributionSetFilter distributionSetFilter, final String assignedOrInstalled) {
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
distributionSetFilter);
specList.add(DistributionSetSpecification.orderedByLinkedTarget(assignedOrInstalled));
final DistributionSetFilter filterWithAssignedTargets = distributionSetFilterBuilder.setInstalledTargetId(null)
.setAssignedTargetId(assignedOrInstalled).build();
final Optional<JpaDistributionSet> assignedDS = findDistributionSetsByFiltersAndInstalledOrAssignedTarget(
filterWithAssignedTargets);
// remove default sort from pageable to not overwrite sorted spec
final OffsetBasedPageRequest unsortedPage = new OffsetBasedPageRequest(pageable.getOffset(),
pageable.getPageSize(), Sort.unsorted());
final DistributionSetFilter dsFilterWithNoTargetLinked = distributionSetFilterBuilder.setInstalledTargetId(null)
.setAssignedTargetId(null).build();
// first fine the distribution sets filtered by the given filter
// parameters
final Page<DistributionSet> findDistributionSetsByFilters = findByDistributionSetFilter(pageable,
dsFilterWithNoTargetLinked);
final List<DistributionSet> resultSet = new ArrayList<>(findDistributionSetsByFilters.getContent());
int orderIndex = 0;
if (installedDS.isPresent()) {
final boolean remove = resultSet.remove(installedDS.get());
if (!remove) {
resultSet.remove(resultSet.size() - 1);
}
resultSet.add(orderIndex, installedDS.get());
orderIndex++;
}
if (assignedDS.isPresent() && !assignedDS.equals(installedDS)) {
final boolean remove = resultSet.remove(assignedDS.get());
if (!remove) {
resultSet.remove(resultSet.size() - 1);
}
resultSet.add(orderIndex, assignedDS.get());
}
return new PageImpl<>(resultSet, pageable, findDistributionSetsByFilters.getTotalElements());
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, unsortedPage, specList);
}
@Override
public Optional<DistributionSet> getByNameAndVersion(final String distributionName, final String version) {
final Specification<JpaDistributionSet> spec = DistributionSetSpecification
.equalsNameAndVersionIgnoreCase(distributionName, version);
return distributionSetRepository.findOne(spec).map(d -> (DistributionSet) d);
return distributionSetRepository.findOne(spec).map(DistributionSet.class::cast);
}
@@ -453,7 +411,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
assertMetaDataQuota(dsId, md.size());
final JpaDistributionSet set = touch(dsId);
final JpaDistributionSet set = JpaManagementHelper.touch(entityManager, distributionSetRepository,
(JpaDistributionSet) getValid(dsId));
return Collections.unmodifiableList(md.stream()
.map(meta -> distributionSetMetadataRepository
@@ -485,7 +444,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
toUpdate.setValue(md.getValue());
// touch it to update the lock revision because we are modifying the
// DS indirectly
touch(dsId);
JpaManagementHelper.touch(entityManager, distributionSetRepository, (JpaDistributionSet) getValid(dsId));
return distributionSetMetadataRepository.save(toUpdate);
}
@@ -498,72 +457,42 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
distributionSetId, key).orElseThrow(
() -> new EntityNotFoundException(DistributionSetMetadata.class, distributionSetId, key));
touch(metadata.getDistributionSet());
JpaManagementHelper.touch(entityManager, distributionSetRepository,
(JpaDistributionSet) metadata.getDistributionSet());
distributionSetMetadataRepository.deleteById(metadata.getId());
}
/**
* Method to get the latest distribution set based on DS ID after the
* metadata changes for that distribution set.
*
* @param ds
* is the DS to touch
*/
private JpaDistributionSet touch(final DistributionSet ds) {
// merge base distribution set so optLockRevision gets updated and audit
// log written because modifying metadata is modifying the base
// distribution set itself for auditing purposes.
final JpaDistributionSet result = entityManager.merge((JpaDistributionSet) ds);
result.setLastModifiedAt(0L);
return distributionSetRepository.save(result);
}
/**
* Method to get the latest distribution set based on DS ID after the
* metadata changes for that distribution set.
*
* @param distId
* of the DS to touch
*/
private JpaDistributionSet touch(final Long distId) {
return touch(getValid(distId));
}
@Override
public Page<DistributionSetMetadata> findMetaDataByDistributionSetId(final Pageable pageable,
final long distributionSetId) {
throwExceptionIfDistributionSetDoesNotExist(distributionSetId);
return convertMdPage(distributionSetMetadataRepository
.findAll((Specification<JpaDistributionSetMetadata>) (root, query, cb) -> cb.equal(
root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id),
distributionSetId), pageable),
pageable);
return JpaManagementHelper.findAllWithCountBySpec(distributionSetMetadataRepository, pageable,
Collections.singletonList(byDsIdSpec(distributionSetId)));
}
private Specification<JpaDistributionSetMetadata> byDsIdSpec(final long dsId) {
return (root, query, cb) -> cb
.equal(root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), dsId);
}
@Override
public long countMetaDataByDistributionSetId(final long setId) {
throwExceptionIfDistributionSetDoesNotExist(setId);
return distributionSetMetadataRepository.countByDistributionSetId(setId);
}
@Override
public Page<DistributionSetMetadata> findMetaDataByDistributionSetIdAndRsql(final Pageable pageable,
final long distributionSetId, final String rsqlParam) {
throwExceptionIfDistributionSetDoesNotExist(distributionSetId);
final Specification<JpaDistributionSetMetadata> spec = RSQLUtility.buildRsqlSpecification(rsqlParam,
DistributionSetMetadataFields.class, virtualPropertyReplacer, database);
final List<Specification<JpaDistributionSetMetadata>> specList = Arrays
.asList(RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetMetadataFields.class,
virtualPropertyReplacer, database), byDsIdSpec(distributionSetId));
return convertMdPage(
distributionSetMetadataRepository
.findAll((Specification<JpaDistributionSetMetadata>) (root, query, cb) -> cb.and(
cb.equal(root.get(JpaDistributionSetMetadata_.distributionSet)
.get(JpaDistributionSet_.id), distributionSetId),
spec.toPredicate(root, query, cb)), pageable),
pageable);
}
private static Page<DistributionSetMetadata> convertMdPage(final Page<JpaDistributionSetMetadata> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
return JpaManagementHelper.findAllWithCountBySpec(distributionSetMetadataRepository, pageable, specList);
}
@Override
@@ -571,7 +500,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
throwExceptionIfDistributionSetDoesNotExist(setId);
return distributionSetMetadataRepository.findById(new DsMetadataCompositeKey(setId, key))
.map(dmd -> (DistributionSetMetadata) dmd);
.map(DistributionSetMetadata.class::cast);
}
@Override
@@ -611,19 +540,14 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
specList.add(spec);
}
if (distributionSetFilter.getType() != null) {
spec = DistributionSetSpecification.byType(distributionSetFilter.getType());
if (distributionSetFilter.getTypeId() != null) {
spec = DistributionSetSpecification.byType(distributionSetFilter.getTypeId());
specList.add(spec);
}
if (!StringUtils.isEmpty(distributionSetFilter.getSearchText())) {
spec = DistributionSetSpecification.likeNameOrDescriptionOrVersion(distributionSetFilter.getSearchText());
specList.add(spec);
}
if (!StringUtils.isEmpty(distributionSetFilter.getFilterString())) {
final String[] dsFilterNameAndVersionEntries = getDsFilterNameAndVersionEntries(
distributionSetFilter.getFilterString().trim());
final String[] dsFilterNameAndVersionEntries = JpaManagementHelper
.getFilterNameAndVersionEntries(distributionSetFilter.getSearchText().trim());
spec = DistributionSetSpecification.likeNameAndVersion(dsFilterNameAndVersionEntries[0],
dsFilterNameAndVersionEntries[1]);
specList.add(spec);
@@ -645,19 +569,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return specList;
}
// the format of filter string is 'name:version'. 'name' and 'version'
// fields follow the starts_with semantic, that changes to equal for 'name'
// field when the semicolon is present
private static String[] getDsFilterNameAndVersionEntries(final String filterString) {
final int semicolonIndex = filterString.indexOf(':');
final String dsFilterName = semicolonIndex != -1 ? filterString.substring(0, semicolonIndex)
: (filterString + "%");
final String dsFilterVersion = semicolonIndex != -1 ? (filterString.substring(semicolonIndex + 1) + "%") : "%";
return new String[] { !StringUtils.isEmpty(dsFilterName) ? dsFilterName : "%", dsFilterVersion };
}
private void assertDistributionSetIsNotAssignedToTargets(final Long distributionSet) {
if (actionRepository.countByDistributionSetId(distributionSet) > 0) {
throw new EntityReadOnlyException(String.format(
@@ -672,26 +583,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
return isNoTagActive || isAtLeastOneTagActive;
}
/**
* executes findAll with the given {@link DistributionSet}
* {@link Specification}s.
*
* @param pageable
* paging parameter
* @param specList
* list of @link {@link Specification}
* @return the page with the found {@link DistributionSet}
*/
private Page<JpaDistributionSet> findByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaDistributionSet>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return distributionSetRepository.findAll(pageable);
}
return distributionSetRepository.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable);
}
private void checkAndThrowIfDistributionSetMetadataAlreadyExists(final DsMetadataCompositeKey metadataId) {
if (distributionSetMetadataRepository.existsById(metadataId)) {
throw new EntityAlreadyExistsException(
@@ -769,7 +660,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public Page<DistributionSet> findByTag(final Pageable pageable, final long tagId) {
throwEntityNotFoundExceptionIfDsTagDoesNotExist(tagId);
return convertDsPage(distributionSetRepository.findByTag(pageable, tagId), pageable);
return JpaManagementHelper.convertPage(distributionSetRepository.findByTag(pageable, tagId), pageable);
}
@@ -783,28 +674,27 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public Page<DistributionSet> findByRsqlAndTag(final Pageable pageable, final String rsqlParam, final long tagId) {
throwEntityNotFoundExceptionIfDsTagDoesNotExist(tagId);
final Specification<JpaDistributionSet> spec = RSQLUtility.buildRsqlSpecification(rsqlParam,
DistributionSetFields.class, virtualPropertyReplacer, database);
final List<Specification<JpaDistributionSet>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetFields.class, virtualPropertyReplacer,
database),
DistributionSetSpecification.hasTag(tagId), DistributionSetSpecification.isDeleted(false));
return convertDsPage(findByCriteriaAPI(pageable, Arrays.asList(spec, DistributionSetSpecification.hasTag(tagId),
DistributionSetSpecification.isDeleted(false))), pageable);
return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, pageable, specList);
}
@Override
public Slice<DistributionSet> findAll(final Pageable pageable) {
return convertDsPage(
distributionSetRepository.findAllWithoutCount(DistributionSetSpecification.isDeleted(false), pageable),
pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetRepository, pageable,
Collections.singletonList(DistributionSetSpecification.isDeleted(false)));
}
@Override
public Page<DistributionSet> findByRsql(final Pageable pageable, final String rsqlParam) {
final Specification<JpaDistributionSet> spec = RSQLUtility.buildRsqlSpecification(rsqlParam,
DistributionSetFields.class, virtualPropertyReplacer, database);
final List<Specification<JpaDistributionSet>> specList = Arrays.asList(RSQLUtility
.buildRsqlSpecification(rsqlParam, DistributionSetFields.class, virtualPropertyReplacer, database),
DistributionSetSpecification.isDeleted(false));
return convertDsPage(
findByCriteriaAPI(pageable, Arrays.asList(spec, DistributionSetSpecification.isDeleted(false))),
pageable);
return JpaManagementHelper.findAllWithCountBySpec(distributionSetRepository, pageable, specList);
}
@Override

View File

@@ -31,7 +31,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
@@ -125,7 +124,7 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage
@Override
public Slice<DistributionSetTag> findAll(final Pageable pageable) {
return convertDsPage(distributionSetTagRepository.findAllWithoutCount(pageable), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetTagRepository, pageable, null);
}
@Override
@@ -133,7 +132,8 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage
final Specification<JpaDistributionSetTag> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, TagFields.class,
virtualPropertyReplacer, database);
return convertDsPage(distributionSetTagRepository.findAll(spec, pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTagRepository, pageable,
Collections.singletonList(spec));
}
@Override
@@ -142,18 +142,8 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage
throw new EntityNotFoundException(DistributionSet.class, setId);
}
return convertDsPage(distributionSetTagRepository.findAll(TagSpecification.ofDistributionSet(setId), pageable),
pageable);
}
private static Page<DistributionSetTag> convertDsPage(final Page<JpaDistributionSetTag> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Slice<DistributionSetTag> convertDsPage(final Slice<JpaDistributionSetTag> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
return JpaManagementHelper.findAllWithCountBySpec(distributionSetTagRepository, pageable,
Collections.singletonList(TagSpecification.ofDistributionSet(setId)));
}
@Override
@@ -178,7 +168,7 @@ public class JpaDistributionSetTagManagement implements DistributionSetTagManage
@Override
public Optional<DistributionSetTag> get(final long id) {
return distributionSetTagRepository.findById(id).map(dst -> (DistributionSetTag) dst);
return distributionSetTagRepository.findById(id).map(DistributionSetTag.class::cast);
}
@Override

View File

@@ -35,17 +35,14 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
@@ -227,17 +224,18 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
@Override
public Page<DistributionSetType> findByRsql(final Pageable pageable, final String rsqlParam) {
return convertPage(
findByCriteriaAPI(pageable,
Arrays.asList(RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetTypeFields.class,
virtualPropertyReplacer, database), DistributionSetTypeSpecification.isDeleted(false))),
pageable);
return JpaManagementHelper
.findAllWithCountBySpec(distributionSetTypeRepository, pageable,
Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, DistributionSetTypeFields.class,
virtualPropertyReplacer, database),
DistributionSetTypeSpecification.isDeleted(false)));
}
@Override
public Slice<DistributionSetType> findAll(final Pageable pageable) {
return convertPage(distributionSetTypeRepository
.findAllWithoutCount(DistributionSetTypeSpecification.isDeleted(false), pageable), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(distributionSetTypeRepository, pageable,
Collections.singletonList(DistributionSetTypeSpecification.isDeleted(false)));
}
@Override
@@ -280,14 +278,13 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
if (distributionSetRepository.countByTypeId(typeId) > 0) {
toDelete.setDeleted(true);
distributionSetTypeRepository.save(toDelete);
}
else {
} else {
distributionSetTypeRepository.deleteById(typeId);
}
}
private void unassignDsTypeFromTargetTypes(long typeId) {
List<JpaTargetType> targetTypesByDsType = targetTypeRepository.findByDsType(typeId);
private void unassignDsTypeFromTargetTypes(final long typeId) {
final List<JpaTargetType> targetTypesByDsType = targetTypeRepository.findByDsType(typeId);
targetTypesByDsType.forEach(targetType -> {
targetType.removeDistributionSetType(typeId);
targetTypeRepository.save(targetType);
@@ -318,26 +315,6 @@ public class JpaDistributionSetTypeManagement implements DistributionSetTypeMana
}
}
private static Page<DistributionSetType> convertPage(final Page<JpaDistributionSetType> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Slice<DistributionSetType> convertPage(final Slice<JpaDistributionSetType> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
}
private Page<JpaDistributionSetType> findByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaDistributionSetType>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return distributionSetTypeRepository.findAll(pageable);
}
return distributionSetTypeRepository.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable);
}
@Override
@Transactional
@Retryable(include = {

View File

@@ -0,0 +1,98 @@
/**
* Copyright (c) 2022 Bosch.IO GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collections;
import java.util.List;
import javax.persistence.EntityManager;
import org.eclipse.hawkbit.repository.jpa.model.AbstractJpaBaseEntity;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* A collection of static helper methods for the management classes
*/
public final class JpaManagementHelper {
private JpaManagementHelper() {
}
public static <T, J extends T> Page<T> findAllWithCountBySpec(final JpaSpecificationExecutor<J> repository,
final Pageable pageable, final List<Specification<J>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return convertPage(repository.findAll(Specification.where(null), pageable), pageable);
}
return convertPage(repository.findAll(combineWithAnd(specList), pageable), pageable);
}
public static <T, J extends T> Page<T> convertPage(final Page<J> jpaAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(jpaAll.getContent()), pageable, jpaAll.getTotalElements());
}
private static <J> Specification<J> combineWithAnd(final List<Specification<J>> specList) {
return specList.size() == 1 ? specList.get(0) : SpecificationsBuilder.combineWithAnd(specList);
}
public static <T, J extends T> Slice<T> findAllWithoutCountBySpec(final NoCountSliceRepository<J> repository,
final Pageable pageable, final List<Specification<J>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return convertPage(repository.findAllWithoutCount(pageable), pageable);
}
return convertPage(repository.findAllWithoutCount(combineWithAnd(specList), pageable), pageable);
}
public static <T, J extends T> Slice<T> convertPage(final Slice<J> jpaAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(jpaAll.getContent()), pageable, 0);
}
public static <J> long countBySpec(final JpaSpecificationExecutor<J> repository,
final List<Specification<J>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return repository.count(Specification.where(null));
}
return repository.count(combineWithAnd(specList));
}
public static <J extends AbstractJpaBaseEntity> J touch(final EntityManager entityManager,
final CrudRepository<J, ?> repository, final J entity) {
// merge base entity so optLockRevision gets updated and audit
// log written because modifying e.g. metadata is modifying the base
// entity itself for auditing purposes.
final J result = entityManager.merge(entity);
result.setLastModifiedAt(0L);
return repository.save(result);
}
// the format of filter string is 'name:version'. 'name' and 'version'
// fields follow the starts_with semantic, that changes to equal for 'name'
// field when the semicolon is present
public static String[] getFilterNameAndVersionEntries(final String filterString) {
final int semicolonIndex = filterString.indexOf(':');
final String filterName = semicolonIndex != -1 ? filterString.substring(0, semicolonIndex)
: (filterString + "%");
final String filterVersion = semicolonIndex != -1 ? (filterString.substring(semicolonIndex + 1) + "%") : "%";
return new String[] { !StringUtils.isEmpty(filterName) ? filterName : "%", filterVersion };
}
}

View File

@@ -55,7 +55,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
@@ -575,7 +574,7 @@ public class JpaRolloutExecutor implements RolloutExecutor {
final PageRequest pageRequest = PageRequest.of(0, Math.toIntExact(limit));
final List<Long> readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout.getRolloutGroups(),
RolloutGroupStatus.READY, group);
final Page<Target> targets = targetManagement.findByTargetFilterQueryAndNotInRolloutGroupsAndCompatible(
final Slice<Target> targets = targetManagement.findByTargetFilterQueryAndNotInRolloutGroupsAndCompatible(
pageRequest, readyGroups, targetFilter, rollout.getDistributionSet().getType());
createAssignmentOfTargetsToGroup(targets, group);
@@ -585,8 +584,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
}
/**
* Schedules a group of the rollout. Scheduled Actions are created to achieve
* this. The creation of those Actions is allowed to fail.
* Schedules a group of the rollout. Scheduled Actions are created to
* achieve this. The creation of those Actions is allowed to fail.
*/
private boolean scheduleRolloutGroup(final JpaRollout rollout, final JpaRolloutGroup group) {
final long targetsInGroup = rolloutTargetGroupRepository.countByRolloutGroup(group);
@@ -634,8 +633,8 @@ public class JpaRolloutExecutor implements RolloutExecutor {
final ActionType actionType = rollout.getActionType();
final long forceTime = rollout.getForcedTime();
final Page<Target> targets = targetManagement.findByInRolloutGroupWithoutAction(pageRequest, groupId);
if (targets.getTotalElements() > 0) {
final Slice<Target> targets = targetManagement.findByInRolloutGroupWithoutAction(pageRequest, groupId);
if (targets.getNumberOfElements() > 0) {
createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group);
}
@@ -643,14 +642,14 @@ public class JpaRolloutExecutor implements RolloutExecutor {
});
}
private void createAssignmentOfTargetsToGroup(final Page<Target> targets, final RolloutGroup group) {
private void createAssignmentOfTargetsToGroup(final Slice<Target> targets, final RolloutGroup group) {
targets.forEach(target -> rolloutTargetGroupRepository.save(new RolloutTargetGroup(group, target)));
}
/**
* Creates an action entry into the action repository. In case of existing
* scheduled actions the scheduled actions gets canceled. A scheduled action is
* created in-active.
* scheduled actions the scheduled actions gets canceled. A scheduled action
* is created in-active.
*/
private void createScheduledAction(final Collection<Target> targets, final DistributionSet distributionSet,
final ActionType actionType, final Long forcedTime, final Rollout rollout,

View File

@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -104,15 +105,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
public Page<RolloutGroup> findByRollout(final Pageable pageable, final long rolloutId) {
throwEntityNotFoundExceptionIfRolloutDoesNotExist(rolloutId);
return convertPage(rolloutGroupRepository.findByRolloutId(rolloutId, pageable), pageable);
}
private static Page<RolloutGroup> convertPage(final Page<JpaRolloutGroup> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Page<Target> convertTPage(final Page<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
return JpaManagementHelper.convertPage(rolloutGroupRepository.findByRolloutId(rolloutId, pageable), pageable);
}
@Override
@@ -120,12 +113,12 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
final String rsqlParam) {
throwEntityNotFoundExceptionIfRolloutDoesNotExist(rolloutId);
final Specification<JpaRolloutGroup> specification = RSQLUtility.buildRsqlSpecification(rsqlParam, RolloutGroupFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaRolloutGroup>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, RolloutGroupFields.class, virtualPropertyReplacer,
database),
(root, query, cb) -> cb.equal(root.get(JpaRolloutGroup_.rollout).get(JpaRollout_.id), rolloutId));
return convertPage(rolloutGroupRepository.findAll((root, query, criteriaBuilder) -> criteriaBuilder.and(
criteriaBuilder.equal(root.get(JpaRolloutGroup_.rollout).get(JpaRollout_.id), rolloutId),
specification.toPredicate(root, query, criteriaBuilder)), pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(rolloutGroupRepository, pageable, specList);
}
private void throwEntityNotFoundExceptionIfRolloutDoesNotExist(final Long rolloutId) {
@@ -157,7 +150,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus);
}
return convertPage(rolloutGroups, pageable);
return JpaManagementHelper.convertPage(rolloutGroups, pageable);
}
@Override
@@ -209,19 +202,18 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
@Override
public Page<Target> findTargetsOfRolloutGroupByRsql(final Pageable pageable, final long rolloutGroupId,
final String rsqlParam) {
throwExceptionIfRolloutGroupDoesNotExist(rolloutGroupId);
final Specification<JpaTarget> rsqlSpecification = RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class, virtualPropertyReplacer, database),
(root, query, cb) -> {
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root
.join(JpaTarget_.rolloutTargetGroup);
return cb.equal(rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id),
rolloutGroupId);
});
return convertTPage(targetRepository.findAll((root, query, criteriaBuilder) -> {
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup);
return criteriaBuilder.and(rsqlSpecification.toPredicate(root, query, criteriaBuilder),
criteriaBuilder.equal(
rolloutTargetJoin.get(RolloutTargetGroup_.rolloutGroup).get(JpaRolloutGroup_.id),
rolloutGroupId));
}, pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageable, specList);
}
@Override
@@ -233,11 +225,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 JpaTargetManagement.convertPage(
targetRepository.findAll(TargetSpecifications.isInRolloutGroup(rolloutGroupId), page), page);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, page,
Collections.singletonList(TargetSpecifications.isInRolloutGroup(rolloutGroupId)));
}
return JpaTargetManagement.convertPage(
targetRepository.findAll(TargetSpecifications.isInActionRolloutGroup(rolloutGroupId), page), page);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, page,
Collections.singletonList(TargetSpecifications.isInActionRolloutGroup(rolloutGroupId)));
}
private static boolean isRolloutStatusReady(final RolloutGroup rolloutGroup) {

View File

@@ -1,106 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collections;
import org.eclipse.hawkbit.repository.builder.RolloutGroupCreate;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupCreate;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout_;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
/**
* A collection of static helper methods for the {@link JpaRolloutManagement}
*/
final class JpaRolloutHelper {
private JpaRolloutHelper() {
}
/**
* In case the given group is missing conditions or actions, they will be
* set from the supplied default conditions.
*
* @param create
* group to check
* @param conditions
* default conditions and actions
*/
static JpaRolloutGroup prepareRolloutGroupWithDefaultConditions(final RolloutGroupCreate create,
final RolloutGroupConditions conditions) {
final JpaRolloutGroup group = ((JpaRolloutGroupCreate) create).build();
if (group.getSuccessCondition() == null) {
group.setSuccessCondition(conditions.getSuccessCondition());
}
if (group.getSuccessConditionExp() == null) {
group.setSuccessConditionExp(conditions.getSuccessConditionExp());
}
if (group.getSuccessAction() == null) {
group.setSuccessAction(conditions.getSuccessAction());
}
if (group.getSuccessActionExp() == null) {
group.setSuccessActionExp(conditions.getSuccessActionExp());
}
if (group.getErrorCondition() == null) {
group.setErrorCondition(conditions.getErrorCondition());
}
if (group.getErrorConditionExp() == null) {
group.setErrorConditionExp(conditions.getErrorConditionExp());
}
if (group.getErrorAction() == null) {
group.setErrorAction(conditions.getErrorAction());
}
if (group.getErrorActionExp() == null) {
group.setErrorActionExp(conditions.getErrorActionExp());
}
return group;
}
/**
* Builds a {@link Specification} to search a rollout by name or
* description.
*
* @param searchText
* search string
* @param isDeleted
* <code>true</code> if deleted rollouts should be included in
* the search. Otherwise <code>false</code>
* @return criteria specification with a query for name or description of a
* rollout
*/
static Specification<JpaRollout> likeNameOrDescription(final String searchText, final boolean isDeleted) {
return (rolloutRoot, query, criteriaBuilder) -> {
final String searchTextToLower = searchText.toLowerCase();
return criteriaBuilder.and(criteriaBuilder.or(
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.name)), searchTextToLower),
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.description)),
searchTextToLower)),
criteriaBuilder.equal(rolloutRoot.get(JpaRollout_.deleted), isDeleted));
};
}
static Page<Rollout> convertPage(final Page<JpaRollout> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
static Slice<Rollout> convertPage(final Slice<JpaRollout> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
}
}

View File

@@ -12,6 +12,7 @@ import static org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupCreate.a
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -41,13 +42,13 @@ import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEve
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException;
import org.eclipse.hawkbit.repository.exception.RolloutIllegalStateException;
import org.eclipse.hawkbit.repository.jpa.builder.JpaRolloutGroupCreate;
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor;
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
import org.eclipse.hawkbit.repository.jpa.model.JpaRolloutGroup;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.RolloutSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.utils.DeploymentHelper;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.jpa.utils.WeightValidationHelper;
@@ -160,8 +161,8 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
public Page<Rollout> findAll(final Pageable pageable, final boolean deleted) {
final Specification<JpaRollout> spec = RolloutSpecification.isDeletedWithDistributionSet(deleted);
return JpaRolloutHelper.convertPage(rolloutRepository.findAll(spec, pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(rolloutRepository, pageable,
Collections.singletonList(RolloutSpecification.isDeletedWithDistributionSet(deleted)));
}
@Override
@@ -171,24 +172,12 @@ public class JpaRolloutManagement implements RolloutManagement {
RSQLUtility.buildRsqlSpecification(rsqlParam, RolloutFields.class, virtualPropertyReplacer, database));
specList.add(RolloutSpecification.isDeletedWithDistributionSet(deleted));
return JpaRolloutHelper.convertPage(findByCriteriaAPI(pageable, specList), pageable);
}
/**
* Executes findAll with the given {@link Rollout} {@link Specification}s.
*/
private Page<JpaRollout> findByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaRollout>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return rolloutRepository.findAll(pageable);
}
return rolloutRepository.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable);
return JpaManagementHelper.findAllWithCountBySpec(rolloutRepository, pageable, specList);
}
@Override
public Optional<Rollout> get(final long rolloutId) {
return rolloutRepository.findById(rolloutId).map(r -> (Rollout) r);
return rolloutRepository.findById(rolloutId).map(Rollout.class::cast);
}
@Override
@@ -264,8 +253,7 @@ public class JpaRolloutManagement implements RolloutManagement {
// prepare the groups
final List<RolloutGroup> groups = groupList.stream()
.map(group -> JpaRolloutHelper.prepareRolloutGroupWithDefaultConditions(group, conditions))
.collect(Collectors.toList());
.map(group -> prepareRolloutGroupWithDefaultConditions(group, conditions)).collect(Collectors.toList());
groups.forEach(RolloutHelper::verifyRolloutGroupHasConditions);
RolloutHelper.verifyRemainingTargets(calculateRemainingTargets(groups, savedRollout.getTargetFilterQuery(),
@@ -307,6 +295,48 @@ public class JpaRolloutManagement implements RolloutManagement {
return rolloutRepository.save(savedRollout);
}
/**
* In case the given group is missing conditions or actions, they will be
* set from the supplied default conditions.
*
* @param create
* group to check
* @param conditions
* default conditions and actions
*/
private static JpaRolloutGroup prepareRolloutGroupWithDefaultConditions(final RolloutGroupCreate create,
final RolloutGroupConditions conditions) {
final JpaRolloutGroup group = ((JpaRolloutGroupCreate) create).build();
if (group.getSuccessCondition() == null) {
group.setSuccessCondition(conditions.getSuccessCondition());
}
if (group.getSuccessConditionExp() == null) {
group.setSuccessConditionExp(conditions.getSuccessConditionExp());
}
if (group.getSuccessAction() == null) {
group.setSuccessAction(conditions.getSuccessAction());
}
if (group.getSuccessActionExp() == null) {
group.setSuccessActionExp(conditions.getSuccessActionExp());
}
if (group.getErrorCondition() == null) {
group.setErrorCondition(conditions.getErrorCondition());
}
if (group.getErrorConditionExp() == null) {
group.setErrorConditionExp(conditions.getErrorConditionExp());
}
if (group.getErrorAction() == null) {
group.setErrorAction(conditions.getErrorAction());
}
if (group.getErrorActionExp() == null) {
group.setErrorActionExp(conditions.getErrorActionExp());
}
return group;
}
private void publishRolloutGroupCreatedEventAfterCommit(final RolloutGroup group, final Rollout rollout) {
afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher().publishEvent(
new RolloutGroupCreatedEvent(group, rollout.getId(), eventPublisherHolder.getApplicationId())));
@@ -456,7 +486,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
public long countByFilters(final String searchText) {
return rolloutRepository.count(JpaRolloutHelper.likeNameOrDescription(searchText, false));
return rolloutRepository.count(RolloutSpecification.likeName(searchText, false));
}
@Override
@@ -467,10 +497,10 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override
public Slice<Rollout> findByFiltersWithDetailedStatus(final Pageable pageable, final String searchText,
final boolean deleted) {
final Slice<JpaRollout> findAll = findByCriteriaAPI(pageable,
Arrays.asList(JpaRolloutHelper.likeNameOrDescription(searchText, deleted)));
final Slice<Rollout> findAll = JpaManagementHelper.findAllWithoutCountBySpec(rolloutRepository, pageable,
Collections.singletonList(RolloutSpecification.likeName(searchText, deleted)));
setRolloutStatusDetails(findAll);
return JpaRolloutHelper.convertPage(findAll, pageable);
return findAll;
}
@Override
@@ -521,12 +551,11 @@ public class JpaRolloutManagement implements RolloutManagement {
}
@Override
public Page<Rollout> findAllWithDetailedStatus(final Pageable pageable, final boolean deleted) {
final Page<JpaRollout> rollouts;
final Specification<JpaRollout> spec = RolloutSpecification.isDeletedWithDistributionSet(deleted);
rollouts = rolloutRepository.findAll(spec, pageable);
public Slice<Rollout> findAllWithDetailedStatus(final Pageable pageable, final boolean deleted) {
final Slice<Rollout> rollouts = JpaManagementHelper.findAllWithoutCountBySpec(rolloutRepository, pageable,
Collections.singletonList(RolloutSpecification.isDeletedWithDistributionSet(deleted)));
setRolloutStatusDetails(rollouts);
return JpaRolloutHelper.convertPage(rollouts, pageable);
return rollouts;
}
@Override
@@ -579,7 +608,7 @@ public class JpaRolloutManagement implements RolloutManagement {
return fromCache;
}
private void setRolloutStatusDetails(final Slice<JpaRollout> rollouts) {
private void setRolloutStatusDetails(final Slice<Rollout> rollouts) {
final List<Long> rolloutIds = rollouts.getContent().stream().map(Rollout::getId).collect(Collectors.toList());
final Map<Long, List<TotalTargetCountActionStatus>> allStatesForRollout = getStatusCountItemForRollout(
rolloutIds);
@@ -588,7 +617,7 @@ public class JpaRolloutManagement implements RolloutManagement {
rollouts.forEach(rollout -> {
final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(
allStatesForRollout.get(rollout.getId()), rollout.getTotalTargets(), rollout.getActionType());
rollout.setTotalTargetCountStatus(totalTargetCountStatus);
((JpaRollout) rollout).setTotalTargetCountStatus(totalTargetCountStatus);
});
}
}

View File

@@ -58,7 +58,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_;
import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
@@ -70,7 +69,6 @@ import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.AuditorAware;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
@@ -183,7 +181,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
specList.add(SoftwareModuleSpecification.equalType(typeId));
specList.add(SoftwareModuleSpecification.isDeletedFalse());
return convertSmPage(findByCriteriaAPI(pageable, specList), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(softwareModuleRepository, pageable, specList);
}
private void throwExceptionIfSoftwareModuleTypeDoesNotExist(final Long typeId) {
@@ -192,23 +190,9 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
}
}
private static Slice<SoftwareModule> convertSmPage(final Slice<JpaSoftwareModule> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
}
private static Page<SoftwareModule> convertSmPage(final Page<JpaSoftwareModule> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Page<SoftwareModuleMetadata> convertSmMdPage(final Page<JpaSoftwareModuleMetadata> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
@Override
public Optional<SoftwareModule> get(final long id) {
return softwareModuleRepository.findById(id).map(sm -> (SoftwareModule) sm);
return softwareModuleRepository.findById(id).map(SoftwareModule.class::cast);
}
@Override
@@ -224,15 +208,6 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
return distributionSetRepository.countByModulesId(moduleId) <= 0;
}
private Slice<JpaSoftwareModule> findByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaSoftwareModule>> specList) {
return softwareModuleRepository.findAllWithoutCount(SpecificationsBuilder.combineWithAnd(specList), pageable);
}
private Long countSwModuleByCriteriaAPI(final List<Specification<JpaSoftwareModule>> specList) {
return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) {
for (final Artifact localArtifact : swModule.getArtifacts()) {
artifactManagement.clearArtifactBinary(localArtifact.getSha1Hash(), swModule.getId());
@@ -276,29 +251,18 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@Override
public Slice<SoftwareModule> findAll(final Pageable pageable) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(2);
specList.add(SoftwareModuleSpecification.isDeletedFalse());
specList.add(SoftwareModuleSpecification.fetchType());
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(JpaSoftwareModule_.type);
}
return cb.conjunction();
};
specList.add(spec);
return convertSmPage(findByCriteriaAPI(pageable, specList), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(softwareModuleRepository, pageable, specList);
}
@Override
public long count() {
final Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
return countSwModuleByCriteriaAPI(Arrays.asList(spec));
return JpaManagementHelper.countBySpec(softwareModuleRepository, Collections.singletonList(spec));
}
@Override
@@ -306,7 +270,8 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
final Specification<JpaSoftwareModule> spec = RSQLUtility.buildRsqlSpecification(rsqlParam,
SoftwareModuleFields.class, virtualPropertyReplacer, database);
return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleRepository, pageable,
Collections.singletonList(spec));
}
@Override
@@ -318,34 +283,28 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@Override
public Slice<SoftwareModule> findByTextAndType(final Pageable pageable, final String searchText,
final Long typeId) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(4);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
specList.add(SoftwareModuleSpecification.isDeletedFalse());
if (!StringUtils.isEmpty(searchText)) {
spec = SoftwareModuleSpecification.likeNameOrVersion(searchText);
specList.add(spec);
specList.add(buildSmSearchQuerySpec(searchText));
}
if (null != typeId) {
throwExceptionIfSoftwareModuleTypeDoesNotExist(typeId);
spec = SoftwareModuleSpecification.equalType(typeId);
specList.add(spec);
specList.add(SoftwareModuleSpecification.equalType(typeId));
}
spec = (root, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
root.fetch(JpaSoftwareModule_.type);
}
return cb.conjunction();
};
specList.add(SoftwareModuleSpecification.fetchType());
specList.add(spec);
return JpaManagementHelper.findAllWithoutCountBySpec(softwareModuleRepository, pageable, specList);
}
return convertSmPage(findByCriteriaAPI(pageable, specList), pageable);
private Specification<JpaSoftwareModule> buildSmSearchQuerySpec(final String searchText) {
final String[] smFilterNameAndVersionEntries = JpaManagementHelper
.getFilterNameAndVersionEntries(searchText.trim());
return SoftwareModuleSpecification.likeNameAndVersion(smFilterNameAndVersionEntries[0],
smFilterNameAndVersionEntries[1]);
}
@Override
@@ -392,8 +351,9 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
private List<Specification<JpaSoftwareModule>> buildSpecificationList(final String searchText, final Long typeId) {
final List<Specification<JpaSoftwareModule>> specList = Lists.newArrayListWithExpectedSize(3);
if (!StringUtils.isEmpty(searchText)) {
specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText));
specList.add(buildSmSearchQuerySpec(searchText));
}
if (typeId != null) {
throwExceptionIfSoftwareModuleTypeDoesNotExist(typeId);
@@ -413,15 +373,13 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@Override
public long countByTextAndType(final String searchText, final Long typeId) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(3);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
if (!StringUtils.isEmpty(searchText)) {
spec = SoftwareModuleSpecification.likeNameOrVersion(searchText);
specList.add(spec);
specList.add(buildSmSearchQuerySpec(searchText));
}
if (null != typeId) {
@@ -431,7 +389,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
specList.add(spec);
}
return countSwModuleByCriteriaAPI(specList);
return JpaManagementHelper.countBySpec(softwareModuleRepository, specList);
}
@Override
@@ -506,7 +464,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
private static Stream<JpaSoftwareModuleMetadataCreate> createJpaMetadataCreateStream(
final Collection<SoftwareModuleMetadataCreate> create) {
return create.stream().map(c -> (JpaSoftwareModuleMetadataCreate) c);
return create.stream().map(JpaSoftwareModuleMetadataCreate.class::cast);
}
private SoftwareModuleMetadata saveMetadata(final JpaSoftwareModuleMetadataCreate create) {
@@ -522,7 +480,8 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
}
private void assertSoftwareModuleExists(final Long moduleId) {
touch(moduleId);
JpaManagementHelper.touch(entityManager, softwareModuleRepository, (JpaSoftwareModule) get(moduleId)
.orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, moduleId)));
}
/**
@@ -555,38 +514,11 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
update.getValue().ifPresent(metadata::setValue);
update.isTargetVisible().ifPresent(metadata::setTargetVisible);
touch(metadata.getSoftwareModule());
JpaManagementHelper.touch(entityManager, softwareModuleRepository,
(JpaSoftwareModule) metadata.getSoftwareModule());
return softwareModuleMetadataRepository.save(metadata);
}
/**
* Method to get the latest module based on ID after the metadata changes
* for that module.
*
* @param latestModule
* module to touch
*/
private JpaSoftwareModule touch(final SoftwareModule latestModule) {
// merge base distribution set so optLockRevision gets updated and audit
// log written because modifying metadata is modifying the base
// distribution set itself for auditing purposes.
final JpaSoftwareModule result = entityManager.merge((JpaSoftwareModule) latestModule);
result.setLastModifiedAt(0L);
return result;
}
/**
* Method to get the latest module based on ID after the metadata changes
* for that module.
*
* @param moduleId
* of the module to touch
*/
private JpaSoftwareModule touch(final Long moduleId) {
return touch(get(moduleId).orElseThrow(() -> new EntityNotFoundException(SoftwareModule.class, moduleId)));
}
@Override
@Transactional
@Retryable(include = {
@@ -595,7 +527,8 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) getMetaDataBySoftwareModuleId(moduleId,
key).orElseThrow(() -> new EntityNotFoundException(SoftwareModuleMetadata.class, moduleId, key));
touch(metadata.getSoftwareModule());
JpaManagementHelper.touch(entityManager, softwareModuleRepository,
(JpaSoftwareModule) metadata.getSoftwareModule());
softwareModuleMetadataRepository.deleteById(metadata.getId());
}
@@ -608,35 +541,32 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
@Override
public Page<SoftwareModuleMetadata> findMetaDataByRsql(final Pageable pageable, final long softwareModuleId,
final String rsqlParam) {
throwExceptionIfSoftwareModuleDoesNotExist(softwareModuleId);
final Specification<JpaSoftwareModuleMetadata> spec = RSQLUtility.buildRsqlSpecification(rsqlParam,
SoftwareModuleMetadataFields.class, virtualPropertyReplacer, database);
return convertSmMdPage(
softwareModuleMetadataRepository
.findAll(
(root, query, cb) -> cb.and(
cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule)
.get(JpaSoftwareModule_.id), softwareModuleId),
spec.toPredicate(root, query, cb)),
pageable),
pageable);
final List<Specification<JpaSoftwareModuleMetadata>> specList = Arrays
.asList(RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleMetadataFields.class,
virtualPropertyReplacer, database), bySmIdSpec(softwareModuleId));
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleMetadataRepository, pageable, specList);
}
private static Page<SoftwareModuleMetadata> convertMdPage(final Page<JpaSoftwareModuleMetadata> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
private static Specification<JpaSoftwareModuleMetadata> bySmIdSpec(final long smId) {
return (root, query, cb) -> cb
.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id), smId);
}
@Override
public Page<SoftwareModuleMetadata> findMetaDataBySoftwareModuleId(final Pageable pageable, final long swId) {
throwExceptionIfSoftwareModuleDoesNotExist(swId);
return convertMdPage(softwareModuleMetadataRepository.findAll(
(Specification<JpaSoftwareModuleMetadata>) (root, query, cb) -> cb
.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id), swId),
pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleMetadataRepository, pageable,
Collections.singletonList(bySmIdSpec(swId)));
}
@Override
public long countMetaDataBySoftwareModuleId(final long moduleId) {
throwExceptionIfSoftwareModuleDoesNotExist(moduleId);
return softwareModuleMetadataRepository.countBySoftwareModuleId(moduleId);
}
@Override
@@ -644,7 +574,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
throwExceptionIfSoftwareModuleDoesNotExist(moduleId);
return softwareModuleMetadataRepository.findById(new SwMetadataCompositeKey(moduleId, key))
.map(smmd -> (SoftwareModuleMetadata) smmd);
.map(SoftwareModuleMetadata.class::cast);
}
private static void throwMetadataKeyAlreadyExists(final String metadataKey) {
@@ -669,7 +599,7 @@ public class JpaSoftwareModuleManagement implements SoftwareModuleManagement {
final long moduleId) {
throwExceptionIfSoftwareModuleDoesNotExist(moduleId);
return convertMdPage(softwareModuleMetadataRepository.findBySoftwareModuleIdAndTargetVisible(
return JpaManagementHelper.convertPage(softwareModuleMetadataRepository.findBySoftwareModuleIdAndTargetVisible(
PageRequest.of(0, RepositoryConstants.MAX_META_DATA_COUNT), moduleId, true), pageable);
}

View File

@@ -29,10 +29,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
@@ -60,8 +58,7 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage
public JpaSoftwareModuleTypeManagement(final DistributionSetTypeRepository distributionSetTypeRepository,
final SoftwareModuleTypeRepository softwareModuleTypeRepository,
final VirtualPropertyReplacer virtualPropertyReplacer,
final SoftwareModuleRepository softwareModuleRepository,
final Database database) {
final SoftwareModuleRepository softwareModuleRepository, final Database database) {
this.distributionSetTypeRepository = distributionSetTypeRepository;
this.softwareModuleTypeRepository = softwareModuleTypeRepository;
this.virtualPropertyReplacer = virtualPropertyReplacer;
@@ -87,18 +84,16 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage
@Override
public Page<SoftwareModuleType> findByRsql(final Pageable pageable, final String rsqlParam) {
final Specification<JpaSoftwareModuleType> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleTypeFields.class,
virtualPropertyReplacer, database);
return convertPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(softwareModuleTypeRepository, pageable,
Collections.singletonList(RSQLUtility.buildRsqlSpecification(rsqlParam, SoftwareModuleTypeFields.class,
virtualPropertyReplacer, database)));
}
@Override
public Slice<SoftwareModuleType> findAll(final Pageable pageable) {
return convertPage(softwareModuleTypeRepository.findAllWithoutCount(
(targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaSoftwareModuleType_.deleted), false),
pageable), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(softwareModuleTypeRepository, pageable,
Collections.singletonList(
(smTypeRoot, query, cb) -> cb.equal(smTypeRoot.get(JpaSoftwareModuleType_.deleted), false)));
}
@Override
@@ -151,16 +146,6 @@ public class JpaSoftwareModuleTypeManagement implements SoftwareModuleTypeManage
return creates.stream().map(this::create).collect(Collectors.toList());
}
private static Page<SoftwareModuleType> convertPage(final Page<JpaSoftwareModuleType> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Slice<SoftwareModuleType> convertPage(final Slice<JpaSoftwareModuleType> findAll,
final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
}
@Override
@Transactional
@Retryable(include = {

View File

@@ -8,11 +8,12 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.TargetFields;
@@ -32,7 +33,6 @@ import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.jpa.utils.WeightValidationHelper;
@@ -47,14 +47,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
@@ -137,8 +136,8 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
}
@Override
public Page<TargetFilterQuery> findAll(final Pageable pageable) {
return convertPage(targetFilterQueryRepository.findAll(pageable), pageable);
public Slice<TargetFilterQuery> findAll(final Pageable pageable) {
return JpaManagementHelper.findAllWithoutCountBySpec(targetFilterQueryRepository, pageable, null);
}
@Override
@@ -151,70 +150,73 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
return targetFilterQueryRepository.countByAutoAssignDistributionSetId(autoAssignDistributionSetId);
}
private static Page<TargetFilterQuery> convertPage(final Page<JpaTargetFilterQuery> findAll,
final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements());
@Override
public Slice<TargetFilterQuery> findByName(final Pageable pageable, final String name) {
if (StringUtils.isEmpty(name)) {
return findAll(pageable);
}
return JpaManagementHelper.findAllWithoutCountBySpec(targetFilterQueryRepository, pageable,
Collections.singletonList(TargetFilterQuerySpecification.likeName(name)));
}
@Override
public Page<TargetFilterQuery> findByName(final Pageable pageable, final String name) {
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
if (!StringUtils.isEmpty(name)) {
specList = Collections.singletonList(TargetFilterQuerySpecification.likeName(name));
public long countByName(final String name) {
if (StringUtils.isEmpty(name)) {
return count();
}
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
return JpaManagementHelper.countBySpec(targetFilterQueryRepository,
Collections.singletonList(TargetFilterQuerySpecification.likeName(name)));
}
@Override
public Page<TargetFilterQuery> findByRsql(final Pageable pageable, final String rsqlFilter) {
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
if (!StringUtils.isEmpty(rsqlFilter)) {
specList = Collections.singletonList(RSQLUtility.buildRsqlSpecification(rsqlFilter,
TargetFilterQueryFields.class, virtualPropertyReplacer, database));
}
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
final List<Specification<JpaTargetFilterQuery>> specList = !StringUtils.isEmpty(rsqlFilter)
? Collections.singletonList(RSQLUtility.buildRsqlSpecification(rsqlFilter,
TargetFilterQueryFields.class, virtualPropertyReplacer, database))
: Collections.emptyList();
return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, pageable, specList);
}
@Override
public Page<TargetFilterQuery> findByQuery(final Pageable pageable, final String query) {
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
if (!StringUtils.isEmpty(query)) {
specList = Collections.singletonList(TargetFilterQuerySpecification.equalsQuery(query));
}
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
public Slice<TargetFilterQuery> findByQuery(final Pageable pageable, final String query) {
final List<Specification<JpaTargetFilterQuery>> specList = !StringUtils.isEmpty(query)
? Collections.singletonList(TargetFilterQuerySpecification.equalsQuery(query))
: Collections.emptyList();
return JpaManagementHelper.findAllWithoutCountBySpec(targetFilterQueryRepository, pageable, specList);
}
@Override
public Slice<TargetFilterQuery> findByAutoAssignDistributionSetId(@NotNull final Pageable pageable,
final long setId) {
final DistributionSet distributionSet = distributionSetManagement.getOrElseThrowException(setId);
return JpaManagementHelper.findAllWithoutCountBySpec(targetFilterQueryRepository, pageable,
Collections.singletonList(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet)));
}
@Override
public Page<TargetFilterQuery> findByAutoAssignDSAndRsql(final Pageable pageable, final long setId,
final String rsqlFilter) {
final List<Specification<JpaTargetFilterQuery>> specList = Lists.newArrayListWithExpectedSize(2);
final DistributionSet distributionSet = distributionSetManagement.getOrElseThrowException(setId);
final List<Specification<JpaTargetFilterQuery>> specList = Lists.newArrayListWithExpectedSize(2);
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
if (!StringUtils.isEmpty(rsqlFilter)) {
specList.add(RSQLUtility.buildRsqlSpecification(rsqlFilter, TargetFilterQueryFields.class,
virtualPropertyReplacer, database));
}
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetFilterQueryRepository, pageable, specList);
}
@Override
public Page<TargetFilterQuery> findWithAutoAssignDS(final Pageable pageable) {
final List<Specification<JpaTargetFilterQuery>> specList = Collections
.singletonList(TargetFilterQuerySpecification.withAutoAssignDS());
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
}
private Page<JpaTargetFilterQuery> findTargetFilterQueryByCriteriaAPI(final Pageable pageable,
final List<Specification<JpaTargetFilterQuery>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return targetFilterQueryRepository.findAll(pageable);
}
final Specification<JpaTargetFilterQuery> specs = SpecificationsBuilder.combineWithAnd(specList);
return targetFilterQueryRepository.findAll(specs, pageable);
public Slice<TargetFilterQuery> findWithAutoAssignDS(final Pageable pageable) {
return JpaManagementHelper.findAllWithoutCountBySpec(targetFilterQueryRepository, pageable,
Collections.singletonList(TargetFilterQuerySpecification.withAutoAssignDS()));
}
@Override

View File

@@ -8,9 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import static org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications.orderedByLinkedDistributionSet;
import com.google.common.collect.Lists;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
@@ -21,11 +18,14 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.MapJoin;
import javax.persistence.criteria.Root;
import javax.validation.constraints.NotEmpty;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
@@ -53,7 +53,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.jpa.model.TargetMetadataCompositeKey;
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
import org.eclipse.hawkbit.repository.jpa.utils.QuotaHelper;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -73,7 +72,6 @@ import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
@@ -82,10 +80,11 @@ import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import com.google.common.collect.Lists;
/**
* JPA implementation of {@link TargetManagement}.
*
@@ -185,7 +184,7 @@ public class JpaTargetManagement implements TargetManagement {
assertMetaDataQuota(target.getId(), md.size());
final JpaTarget updatedTarget = touch(target);
final JpaTarget updatedTarget = JpaManagementHelper.touch(entityManager, targetRepository, target);
final List<TargetMetadata> createdMetadata = Collections.unmodifiableList(md.stream()
.map(meta -> targetMetadataRepository
@@ -212,21 +211,6 @@ public class JpaTargetManagement implements TargetManagement {
TargetMetadata.class, Target.class, targetMetadataRepository::countByTargetId);
}
private JpaTarget touch(final JpaTarget target) {
// merge base target so optLockRevision gets updated and audit
// log written because modifying metadata is modifying the base
// target itself for auditing purposes.
final JpaTarget result = entityManager.merge(target);
result.setLastModifiedAt(0L);
return targetRepository.save(result);
}
private JpaTarget touch(final String controllerId) {
return touch(getByControllerIdAndThrowIfNotFound(controllerId));
}
@Override
@Transactional
@Retryable(include = {
@@ -240,7 +224,8 @@ public class JpaTargetManagement implements TargetManagement {
updatedMetadata.setValue(md.getValue());
// touch it to update the lock revision because we are modifying the
// target indirectly
final JpaTarget target = touch(controllerId);
final JpaTarget target = JpaManagementHelper.touch(entityManager, targetRepository,
getByControllerIdAndThrowIfNotFound(controllerId));
final JpaTargetMetadata matadata = targetMetadataRepository.save(updatedMetadata);
// target update event is set to ignore "lastModifiedAt" field so it is
// not send automatically within the touch() method
@@ -257,7 +242,8 @@ public class JpaTargetManagement implements TargetManagement {
final JpaTargetMetadata metadata = (JpaTargetMetadata) getMetaDataByControllerId(controllerId, key)
.orElseThrow(() -> new EntityNotFoundException(TargetMetadata.class, controllerId, key));
final JpaTarget target = touch(controllerId);
final JpaTarget target = JpaManagementHelper.touch(entityManager, targetRepository,
getByControllerIdAndThrowIfNotFound(controllerId));
targetMetadataRepository.deleteById(metadata.getId());
// target update event is set to ignore "lastModifiedAt" field so it is
// not send automatically within the touch() method
@@ -269,32 +255,32 @@ public class JpaTargetManagement implements TargetManagement {
public Page<TargetMetadata> findMetaDataByControllerId(final Pageable pageable, final String controllerId) {
final Long targetId = getByControllerIdAndThrowIfNotFound(controllerId).getId();
return convertMdPage(
targetMetadataRepository
.findAll(
(Specification<JpaTargetMetadata>) (root, query, cb) -> cb
.equal(root.get(JpaTargetMetadata_.target).get(JpaTarget_.id), targetId),
pageable),
pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetMetadataRepository, pageable,
Collections.singletonList(metadataByTargetIdSpec(targetId)));
}
private static Page<TargetMetadata> convertMdPage(final Page<JpaTargetMetadata> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
private Specification<JpaTargetMetadata> metadataByTargetIdSpec(final Long targetId) {
return (root, query, cb) -> cb.equal(root.get(JpaTargetMetadata_.target).get(JpaTarget_.id), targetId);
}
@Override
public long countMetaDataByControllerId(@NotEmpty final String controllerId) {
final Long targetId = getByControllerIdAndThrowIfNotFound(controllerId).getId();
return JpaManagementHelper.countBySpec(targetMetadataRepository,
Collections.singletonList(metadataByTargetIdSpec(targetId)));
}
@Override
public Page<TargetMetadata> findMetaDataByControllerIdAndRsql(final Pageable pageable, final String controllerId,
final String rsqlParam) {
final Long targetId = getByControllerIdAndThrowIfNotFound(controllerId).getId();
final Specification<JpaTargetMetadata> spec = RSQLUtility.buildRsqlSpecification(rsqlParam,
TargetMetadataFields.class, virtualPropertyReplacer, database);
final List<Specification<JpaTargetMetadata>> specList = Arrays.asList(RSQLUtility
.buildRsqlSpecification(rsqlParam, TargetMetadataFields.class, virtualPropertyReplacer, database),
metadataByTargetIdSpec(targetId));
return convertMdPage(targetMetadataRepository.findAll((Specification<JpaTargetMetadata>) (root, query, cb) -> cb
.and(cb.equal(root.get(JpaTargetMetadata_.target).get(JpaTarget_.id), targetId),
spec.toPredicate(root, query, cb)),
pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetMetadataRepository, pageable, specList);
}
@Override
@@ -306,7 +292,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Slice<Target> findAll(final Pageable pageable) {
return convertPage(targetRepository.findAllWithoutCount(pageable), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageable, null);
}
@Override
@@ -314,18 +300,16 @@ public class JpaTargetManagement implements TargetManagement {
final TargetFilterQuery targetFilterQuery = targetFilterQueryRepository.findById(targetFilterQueryId)
.orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId));
return findTargetsBySpec(RSQLUtility.buildRsqlSpecification(targetFilterQuery.getQuery(), TargetFields.class,
virtualPropertyReplacer, database), pageable);
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageable,
Collections.singletonList(RSQLUtility.buildRsqlSpecification(targetFilterQuery.getQuery(),
TargetFields.class, virtualPropertyReplacer, database)));
}
@Override
public Page<Target> findByRsql(final Pageable pageable, final String targetFilterQuery) {
return findTargetsBySpec(RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database), pageable);
}
private Page<Target> findTargetsBySpec(final Specification<JpaTarget> spec, final Pageable pageable) {
return convertPage(targetRepository.findAll(spec, pageable), pageable);
public Slice<Target> findByRsql(final Pageable pageable, final String targetFilterQuery) {
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageable,
Collections.singletonList(RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database)));
}
@Override
@@ -385,8 +369,8 @@ public class JpaTargetManagement implements TargetManagement {
public Page<Target> findByAssignedDistributionSet(final Pageable pageReq, final long distributionSetID) {
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetID);
return convertPage(targetRepository
.findAll(TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId()), pageReq), pageReq);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageReq,
Collections.singletonList(TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId())));
}
@Override
@@ -394,31 +378,19 @@ public class JpaTargetManagement implements TargetManagement {
final String rsqlParam) {
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetID);
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class, virtualPropertyReplacer, database),
TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId()));
return convertPage(
targetRepository
.findAll((Specification<JpaTarget>) (root, query,
cb) -> cb.and(TargetSpecifications.hasAssignedDistributionSet(validDistSet.getId())
.toPredicate(root, query, cb), spec.toPredicate(root, query, cb)),
pageReq),
pageReq);
}
public static Page<Target> convertPage(final Page<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
private static Slice<Target> convertPage(final Slice<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageReq, specList);
}
@Override
public Page<Target> findByInstalledDistributionSet(final Pageable pageReq, final long distributionSetID) {
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetID);
return convertPage(targetRepository
.findAll(TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId()), pageReq), pageReq);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageReq,
Collections.singletonList(TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId())));
}
@Override
@@ -426,34 +398,29 @@ public class JpaTargetManagement implements TargetManagement {
final String rsqlParam) {
final DistributionSet validDistSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class, virtualPropertyReplacer, database),
TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId()));
return convertPage(
targetRepository
.findAll((Specification<JpaTarget>) (root, query,
cb) -> cb.and(TargetSpecifications.hasInstalledDistributionSet(validDistSet.getId())
.toPredicate(root, query, cb), spec.toPredicate(root, query, cb)),
pageable),
pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageable, specList);
}
@Override
public Page<Target> findByUpdateStatus(final Pageable pageable, final TargetUpdateStatus status) {
return convertPage(targetRepository.findAll(TargetSpecifications.hasTargetUpdateStatus(status), pageable),
pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageable,
Collections.singletonList(TargetSpecifications.hasTargetUpdateStatus(status)));
}
@Override
public Slice<Target> findByFilters(final Pageable pageable, final FilterParams filterParams) {
final List<Specification<JpaTarget>> specList = buildSpecificationList(filterParams);
return findByCriteriaAPI(pageable, specList);
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageable, specList);
}
@Override
public long countByFilters(Collection<TargetUpdateStatus> status, Boolean overdueState, String searchText,
Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag,
String... tagNames) {
public long countByFilters(final Collection<TargetUpdateStatus> status, final Boolean overdueState,
final String searchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final String... tagNames) {
return countByFilters(new FilterParams(status, overdueState, searchText, installedOrAssignedDistributionSetId,
selectTargetWithNoTag, tagNames));
}
@@ -461,7 +428,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public long countByFilters(final FilterParams filterParams) {
final List<Specification<JpaTarget>> specList = buildSpecificationList(filterParams);
return countByCriteriaAPI(specList);
return JpaManagementHelper.countBySpec(targetRepository, specList);
}
private List<Specification<JpaTarget>> buildSpecificationList(final FilterParams filterParams) {
@@ -479,8 +446,7 @@ public class JpaTargetManagement implements TargetManagement {
specList.add(TargetSpecifications.hasInstalledOrAssignedDistributionSet(validDistSet.getId()));
}
if (!StringUtils.isEmpty(filterParams.getFilterBySearchText())) {
specList.add(TargetSpecifications
.likeIdOrNameOrDescriptionOrAttributeValue(filterParams.getFilterBySearchText()));
specList.add(TargetSpecifications.likeControllerIdOrName(filterParams.getFilterBySearchText()));
}
if (hasTagsFilterActive(filterParams)) {
specList.add(TargetSpecifications.hasTags(filterParams.getFilterByTagNames(),
@@ -512,23 +478,6 @@ public class JpaTargetManagement implements TargetManagement {
return Boolean.TRUE.equals(filterParams.getSelectTargetWithNoTargetType());
}
private Slice<Target> findByCriteriaAPI(final Pageable pageable, final List<Specification<JpaTarget>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return convertPage(targetRepository.findAllWithoutCount(pageable), pageable);
}
return convertPage(
targetRepository.findAllWithoutCount(SpecificationsBuilder.combineWithAnd(specList), pageable),
pageable);
}
private Long countByCriteriaAPI(final List<Specification<JpaTarget>> specList) {
if (CollectionUtils.isEmpty(specList)) {
return targetRepository.count();
}
return targetRepository.count(SpecificationsBuilder.combineWithAnd(specList));
}
@Override
@Transactional
@Retryable(include = {
@@ -585,8 +534,8 @@ public class JpaTargetManagement implements TargetManagement {
targetsWithoutSameType.forEach(target -> target.setTargetType(type));
final TargetTypeAssignmentResult result = new TargetTypeAssignmentResult(targetsWithSameType.size(),
Collections
.unmodifiableList(targetsWithoutSameType.stream().map(targetRepository::save).collect(Collectors.toList())),
Collections.unmodifiableList(
targetsWithoutSameType.stream().map(targetRepository::save).collect(Collectors.toList())),
Collections.emptyList(), type);
// no reason to persist the type
@@ -613,8 +562,8 @@ public class JpaTargetManagement implements TargetManagement {
.unmodifiableList(allTargets.stream().map(targetRepository::save).collect(Collectors.toList())), null);
}
private List<JpaTarget> findTargetsByInSpecification(Collection<String> controllerIds,
Specification<JpaTarget> specification) {
private List<JpaTarget> findTargetsByInSpecification(final Collection<String> controllerIds,
final Specification<JpaTarget> specification) {
return Lists.partition(new ArrayList<>(controllerIds), Constants.MAX_ENTRIES_IN_STATEMENT).stream()
.map(ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids).and(specification)))
.flatMap(List::stream).collect(Collectors.toList());
@@ -690,30 +639,14 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Slice<Target> findByFilterOrderByLinkedDistributionSet(final Pageable pageable,
final long orderByDistributionId, final FilterParams filterParams) {
Specification<JpaTarget> orderedFilterSpec = combineFiltersAndDsOrder(orderByDistributionId, filterParams);
// remove default sort from pageable to not overwrite sorted spec
final OffsetBasedPageRequest unsortedPage = new OffsetBasedPageRequest(pageable.getOffset(),
pageable.getPageSize(), Sort.unsorted());
return convertPage(targetRepository.findAllWithoutCount(orderedFilterSpec, unsortedPage), unsortedPage);
}
/**
* Applies orderedByLinkedDistributionSet spec for order and adds additional
* specs based on filters
*
* @param orderByDistributionId
* distribution set used for order
* @param filterParams
* filters to generate additional specs for
* @return specification combining order and filter specs
*/
private Specification<JpaTarget> combineFiltersAndDsOrder(final long orderByDistributionId,
final FilterParams filterParams) {
Specification<JpaTarget> orderedFilterSpec = orderedByLinkedDistributionSet(orderByDistributionId);
for (Specification<JpaTarget> spec : buildSpecificationList(filterParams)) {
orderedFilterSpec = orderedFilterSpec.and(spec);
}
return orderedFilterSpec;
final List<Specification<JpaTarget>> specList = buildSpecificationList(filterParams);
specList.add(TargetSpecifications.orderedByLinkedDistributionSet(orderByDistributionId));
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, unsortedPage, specList);
}
@Override
@@ -739,55 +672,52 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Page<Target> findByTargetFilterQueryAndNonDSAndCompatible(final Pageable pageRequest,
public Slice<Target> findByTargetFilterQueryAndNonDSAndCompatible(final Pageable pageRequest,
final long distributionSetId, final String targetFilterQuery) {
final DistributionSet jpaDistributionSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
final Long distSetTypeId = jpaDistributionSet.getType().getId();
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database);
final Specification<JpaTarget> dsNotInActions = TargetSpecifications
.hasNotDistributionSetInActions(distributionSetId);
final Specification<JpaTarget> isCompatibleWithDsType = TargetSpecifications
.isCompatibleWithDistributionSetType(distSetTypeId);
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer,
database),
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId));
return findTargetsBySpec(spec.and(dsNotInActions).and(isCompatibleWithDsType), pageRequest);
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageRequest, specList);
}
@Override
public Page<Target> findByTargetFilterQueryAndNotInRolloutGroupsAndCompatible(final Pageable pageRequest,
public Slice<Target> findByTargetFilterQueryAndNotInRolloutGroupsAndCompatible(final Pageable pageRequest,
final Collection<Long> groups, final String targetFilterQuery, final DistributionSetType dsType) {
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer,
database),
TargetSpecifications.isNotInRolloutGroups(groups),
TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()));
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database);
final Specification<JpaTarget> notInRolloutGroups = TargetSpecifications.isNotInRolloutGroups(groups);
final Specification<JpaTarget> isCompatibleWithDsType = TargetSpecifications
.isCompatibleWithDistributionSetType(dsType.getId());
return findTargetsBySpec((spec.and(notInRolloutGroups).and(isCompatibleWithDsType)), pageRequest);
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageRequest, specList);
}
@Override
public Page<Target> findByInRolloutGroupWithoutAction(final Pageable pageRequest, final long group) {
public Slice<Target> findByInRolloutGroupWithoutAction(final Pageable pageRequest, final long group) {
if (!rolloutGroupRepository.existsById(group)) {
throw new EntityNotFoundException(RolloutGroup.class, group);
}
return findTargetsBySpec(
(root, cq, cb) -> TargetSpecifications.hasNoActionInRolloutGroup(group).toPredicate(root, cq, cb),
pageRequest);
return JpaManagementHelper.findAllWithoutCountBySpec(targetRepository, pageRequest,
Collections.singletonList(TargetSpecifications.hasNoActionInRolloutGroup(group)));
}
@Override
public long countByRsqlAndNotInRolloutGroupsAndCompatible(final Collection<Long> groups,
final String targetFilterQuery, final DistributionSetType dsType) {
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaTarget>> specList = Arrays.asList(spec,
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer,
database),
TargetSpecifications.isNotInRolloutGroups(groups),
TargetSpecifications.isCompatibleWithDistributionSetType(dsType.getId()));
return countByCriteriaAPI(specList);
return JpaManagementHelper.countBySpec(targetRepository, specList);
}
@Override
@@ -795,13 +725,13 @@ public class JpaTargetManagement implements TargetManagement {
final DistributionSet jpaDistributionSet = distributionSetManagement.getOrElseThrowException(distributionSetId);
final Long distSetTypeId = jpaDistributionSet.getType().getId();
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaTarget>> specList = Arrays.asList(spec,
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer,
database),
TargetSpecifications.hasNotDistributionSetInActions(distributionSetId),
TargetSpecifications.isCompatibleWithDistributionSetType(distSetTypeId));
return countByCriteriaAPI(specList);
return JpaManagementHelper.countBySpec(targetRepository, specList);
}
@Override
@@ -825,7 +755,8 @@ public class JpaTargetManagement implements TargetManagement {
public Page<Target> findByTag(final Pageable pageable, final long tagId) {
throwEntityNotFoundExceptionIfTagDoesNotExist(tagId);
return convertPage(targetRepository.findAll(TargetSpecifications.hasTag(tagId), pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageable,
Collections.singletonList(TargetSpecifications.hasTag(tagId)));
}
private void throwEntityNotFoundExceptionIfTagDoesNotExist(final Long tagId) {
@@ -836,15 +767,13 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findByRsqlAndTag(final Pageable pageable, final String rsqlParam, final long tagId) {
throwEntityNotFoundExceptionIfTagDoesNotExist(tagId);
final Specification<JpaTarget> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class,
virtualPropertyReplacer, database);
final List<Specification<JpaTarget>> specList = Arrays.asList(
RSQLUtility.buildRsqlSpecification(rsqlParam, TargetFields.class, virtualPropertyReplacer, database),
TargetSpecifications.hasTag(tagId));
return convertPage(targetRepository.findAll((Specification<JpaTarget>) (root, query, cb) -> cb.and(
TargetSpecifications.hasTag(tagId).toPredicate(root, query, cb), spec.toPredicate(root, query, cb)),
pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageable, specList);
}
@Override
@@ -852,23 +781,22 @@ public class JpaTargetManagement implements TargetManagement {
final TargetFilterQuery targetFilterQuery = targetFilterQueryRepository.findById(targetFilterQueryId)
.orElseThrow(() -> new EntityNotFoundException(TargetFilterQuery.class, targetFilterQueryId));
final Specification<JpaTarget> specs = RSQLUtility.buildRsqlSpecification(targetFilterQuery.getQuery(),
TargetFields.class, virtualPropertyReplacer, database);
return targetRepository.count(specs);
return countByRsql(targetFilterQuery.getQuery());
}
@Override
public long countByRsql(final String targetFilterQuery) {
final Specification<JpaTarget> specs = RSQLUtility.buildRsqlSpecification(targetFilterQuery, TargetFields.class,
virtualPropertyReplacer, database);
return targetRepository.count(specs);
return JpaManagementHelper.countBySpec(targetRepository, Collections.singletonList(RSQLUtility
.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database)));
}
@Override
public long countByRsqlAndCompatible(final String targetFilterQuery, final Long dsTypeId) {
final Specification<JpaTarget> rsqlSpec = RSQLUtility.buildRsqlSpecification(targetFilterQuery,
TargetFields.class, virtualPropertyReplacer, database);
return targetRepository.count(rsqlSpec.and(TargetSpecifications.isCompatibleWithDistributionSetType(dsTypeId)));
final List<Specification<JpaTarget>> specList = Arrays.asList(RSQLUtility
.buildRsqlSpecification(targetFilterQuery, TargetFields.class, virtualPropertyReplacer, database),
TargetSpecifications.isCompatibleWithDistributionSetType(dsTypeId));
return JpaManagementHelper.countBySpec(targetRepository, specList);
}
@Override
@@ -925,8 +853,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override
public Page<Target> findByControllerAttributesRequested(final Pageable pageReq) {
return convertPage(targetRepository.findAll(TargetSpecifications.hasRequestControllerAttributesTrue(), pageReq),
pageReq);
return JpaManagementHelper.findAllWithCountBySpec(targetRepository, pageReq,
Collections.singletonList(TargetSpecifications.hasRequestControllerAttributesTrue()));
}
}

View File

@@ -31,9 +31,7 @@ import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
@@ -106,14 +104,8 @@ public class JpaTargetTagManagement implements TargetTagManagement {
@Override
public Page<TargetTag> findByRsql(final Pageable pageable, final String rsqlParam) {
final Specification<JpaTargetTag> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, TagFields.class, virtualPropertyReplacer,
database);
return convertTPage(targetTagRepository.findAll(spec, pageable), pageable);
}
private static Page<TargetTag> convertTPage(final Page<JpaTargetTag> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, pageable, Collections.singletonList(
RSQLUtility.buildRsqlSpecification(rsqlParam, TagFields.class, virtualPropertyReplacer, database)));
}
@Override
@@ -140,7 +132,7 @@ public class JpaTargetTagManagement implements TargetTagManagement {
@Override
public Optional<TargetTag> get(final long id) {
return targetTagRepository.findById(id).map(tt -> (TargetTag) tt);
return targetTagRepository.findById(id).map(TargetTag.class::cast);
}
@Override
@@ -150,7 +142,7 @@ public class JpaTargetTagManagement implements TargetTagManagement {
@Override
public Page<TargetTag> findAll(final Pageable pageable) {
return convertTPage(targetTagRepository.findAll(pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, pageable, null);
}
@Override
@@ -159,6 +151,7 @@ public class JpaTargetTagManagement implements TargetTagManagement {
throw new EntityNotFoundException(Target.class, controllerId);
}
return convertTPage(targetTagRepository.findAll(TagSpecification.ofTarget(controllerId), pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetTagRepository, pageable,
Collections.singletonList(TagSpecification.ofTarget(controllerId)));
}
}

View File

@@ -8,6 +8,12 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.QuotaManagement;
import org.eclipse.hawkbit.repository.TargetTypeFields;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
@@ -29,21 +35,14 @@ import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.domain.Slice;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* JPA implementation of {@link TargetTypeManagement}.
*
@@ -95,6 +94,11 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
return targetTypeRepository.count();
}
@Override
public long countByName(final String name) {
return targetTypeRepository.countByName(name);
}
@Override
@Transactional
@Retryable(include = {
@@ -127,21 +131,21 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
}
@Override
public Page<TargetType> findAll(final Pageable pageable) {
return convertPage(targetTypeRepository.findAll(pageable), pageable);
public Slice<TargetType> findAll(final Pageable pageable) {
return JpaManagementHelper.findAllWithoutCountBySpec(targetTypeRepository, pageable, null);
}
@Override
public Page<TargetType> findByRsql(final Pageable pageable, final String rsqlParam) {
final Specification<JpaTargetType> spec = RSQLUtility.buildRsqlSpecification(rsqlParam, TargetTypeFields.class,
virtualPropertyReplacer, database);
return convertPage(targetTypeRepository.findAll(spec, pageable), pageable);
return JpaManagementHelper.findAllWithCountBySpec(targetTypeRepository, pageable,
Collections.singletonList(RSQLUtility.buildRsqlSpecification(rsqlParam, TargetTypeFields.class,
virtualPropertyReplacer, database)));
}
@Override
public Page<TargetType> findByName(Pageable pageable, String name) {
return convertPage(targetTypeRepository.findAll(TargetTypeSpecification.likeName(name), pageable), pageable);
public Slice<TargetType> findByName(final Pageable pageable, final String name) {
return JpaManagementHelper.findAllWithoutCountBySpec(targetTypeRepository, pageable,
Collections.singletonList(TargetTypeSpecification.likeName(name)));
}
@Override
@@ -258,9 +262,4 @@ public class JpaTargetTypeManagement implements TargetTypeManagement {
QuotaHelper.assertAssignmentQuota(id, requested, quotaManagement.getMaxDistributionSetTypesPerTargetType(),
DistributionSetType.class, TargetType.class, targetTypeRepository::countDsSetTypesById);
}
private static Page<TargetType> convertPage(final Page<JpaTargetType> findAll, final Pageable pageable) {
return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
}
}

View File

@@ -8,6 +8,12 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetType;
import org.eclipse.hawkbit.repository.jpa.specifications.TargetTypeSpecification;
import org.eclipse.hawkbit.repository.model.TargetType;
@@ -23,12 +29,6 @@ import org.springframework.data.repository.query.Param;
import org.springframework.lang.NonNull;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
/**
* {@link PagingAndSortingRepository} for {@link JpaTargetType}.
*
@@ -42,23 +42,24 @@ public interface TargetTypeRepository
*
* Calls version based on spec to allow injecting further specs
*
* @param id id to filter for
* @param id
* id to filter for
* @return {@link Optional} of {@link TargetType}
*/
@Override
@NonNull
default Optional<JpaTargetType> findById(@NonNull Long id) {
default Optional<JpaTargetType> findById(@NonNull final Long id) {
return this.findOne(Specification.where(TargetTypeSpecification.hasId(id)));
}
/**
* @param ids
* List of ID
* List of ID
* @return Target type list
*/
@Override
@NonNull
default List<JpaTargetType> findAllById(Iterable<Long> ids) {
default List<JpaTargetType> findAllById(final Iterable<Long> ids) {
final List<Long> collectedIds = StreamSupport.stream(ids.spliterator(), true).collect(Collectors.toList());
return this.findAll(Specification.where(TargetTypeSpecification.hasIdIn(collectedIds)));
}
@@ -92,12 +93,13 @@ public interface TargetTypeRepository
*
* Calls version with (empty) spec to allow injecting further specs
*
* @param sort instructions to sort result by
* @param sort
* instructions to sort result by
* @return {@link List} of {@link TargetType}s
*/
@Override
@NonNull
default Iterable<JpaTargetType> findAll(@NonNull Sort sort) {
default Iterable<JpaTargetType> findAll(@NonNull final Sort sort) {
return this.findAll(Specification.where(null), sort);
}
@@ -106,35 +108,40 @@ public interface TargetTypeRepository
*
* Calls version with (empty) spec to allow injecting further specs
*
* @param pageable paging context
* @param pageable
* paging context
* @return {@link List} of {@link TargetType}s
*/
@Override
@NonNull
default Page<JpaTargetType> findAll(@NonNull Pageable pageable) {
default Page<JpaTargetType> findAll(@NonNull final Pageable pageable) {
return this.findAll(Specification.where(null), pageable);
}
/**
* Checks whether {@link TargetType} in the repository matching an id exists or not.
* Checks whether {@link TargetType} 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
* @param id
* id to check for
* @return true if TargetType with id exists
*/
@Override
default boolean existsById(@NonNull Long id) {
default boolean existsById(@NonNull final Long id) {
return this.exists(TargetTypeSpecification.hasId(id));
}
/**
* Checks whether {@link TargetType} in the repository matching a spec exists or not.
* Checks whether {@link TargetType} in the repository matching a spec
* exists or not.
*
* @param spec to check for existence
* @param spec
* to check for existence
* @return true if target with id exists
*/
default boolean exists(@NonNull Specification<JpaTargetType> spec) {
default boolean exists(@NonNull final Specification<JpaTargetType> spec) {
return this.count(spec) > 0;
}
@@ -152,7 +159,7 @@ public interface TargetTypeRepository
/**
* @param tenant
* Tenant
* Tenant
*/
@Modifying
@Transactional
@@ -169,7 +176,7 @@ public interface TargetTypeRepository
* @return all {@link TargetType}s in the repository with given
* {@link TargetType#getName()}
*/
default List<JpaTargetType> findByDsType(@Param("id") Long dsTypeId) {
default List<JpaTargetType> findByDsType(@Param("id") final Long dsTypeId) {
return this.findAll(Specification.where(TargetTypeSpecification.hasDsSetType(dsTypeId)));
}
@@ -180,7 +187,18 @@ public interface TargetTypeRepository
* @return all {@link TargetType}s in the repository with given
* {@link TargetType#getName()}
*/
default Optional<JpaTargetType> findByName(String name){
default Optional<JpaTargetType> findByName(final String name) {
return this.findOne(Specification.where(TargetTypeSpecification.hasName(name)));
};
}
/**
* Count number of {@link TargetType}s in the repository by name.
*
* @param name
* target type name
* @return number of targetTypes in the repository by name
*/
default long countByName(final String name) {
return this.count(TargetTypeSpecification.hasName(name));
}
}

View File

@@ -23,9 +23,9 @@ import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.util.StringUtils;
@@ -38,11 +38,11 @@ public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAutoAssignExecutor.class);
/**
* The message which is added to the action status when a distribution set is
* assigned to an target. First %s is the name of the target filter.
* The message which is added to the action status when a distribution set
* is assigned to an target. First %s is the name of the target filter.
*/
private static final String ACTION_MESSAGE = "Auto assignment by target filter: %s";
/**
* Maximum for target filter queries with auto assign DS activated.
*/
@@ -94,7 +94,7 @@ public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
}
protected void forEachFilterWithAutoAssignDS(final Consumer<TargetFilterQuery> consumer) {
Page<TargetFilterQuery> filterQueries;
Slice<TargetFilterQuery> filterQueries;
Pageable query = PageRequest.of(0, PAGE_SIZE);
do {
@@ -117,8 +117,8 @@ public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
}
/**
* Runs target assignments within a dedicated transaction for a given list of
* controllerIDs
* Runs target assignments within a dedicated transaction for a given list
* of controllerIDs
*
* @param targetFilterQuery
* the target filter query
@@ -146,8 +146,8 @@ public abstract class AbstractAutoAssignExecutor implements AutoAssignExecutor {
}
/**
* Creates a list of {@link DeploymentRequest} for given list of controllerIds
* and {@link TargetFilterQuery}
* Creates a list of {@link DeploymentRequest} for given list of
* controllerIds and {@link TargetFilterQuery}
*
* @param controllerIds
* list of controllerIds

View File

@@ -13,6 +13,7 @@ import java.util.Collection;
import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Path;
@@ -23,12 +24,11 @@ import javax.persistence.criteria.SetJoin;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
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.JpaTarget;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;
@@ -52,7 +52,7 @@ public final class DistributionSetSpecification {
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> isDeleted(final Boolean isDeleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSet_.deleted), isDeleted);
return (dsRoot, query, cb) -> cb.equal(dsRoot.<Boolean> get(JpaDistributionSet_.deleted), isDeleted);
}
@@ -66,7 +66,7 @@ public final class DistributionSetSpecification {
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> isCompleted(final Boolean isCompleted) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSet_.complete), isCompleted);
return (dsRoot, query, cb) -> cb.equal(dsRoot.<Boolean> get(JpaDistributionSet_.complete), isCompleted);
}
@@ -80,7 +80,7 @@ public final class DistributionSetSpecification {
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> isValid(final Boolean isValid) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<Boolean> get(JpaDistributionSet_.valid), isValid);
return (dsRoot, query, cb) -> cb.equal(dsRoot.<Boolean> get(JpaDistributionSet_.valid), isValid);
}
@@ -93,10 +93,10 @@ public final class DistributionSetSpecification {
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> byId(final Long distid) {
return (targetRoot, query, cb) -> {
final Predicate predicate = cb.equal(targetRoot.<Long> get(JpaDistributionSet_.id), distid);
targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
return (dsRoot, query, cb) -> {
final Predicate predicate = cb.equal(dsRoot.<Long> get(JpaDistributionSet_.id), distid);
dsRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
dsRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
query.distinct(true);
return predicate;
@@ -112,31 +112,16 @@ public final class DistributionSetSpecification {
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> byIds(final Collection<Long> distids) {
return (targetRoot, query, cb) -> {
final Predicate predicate = targetRoot.<Long> get(JpaDistributionSet_.id).in(distids);
targetRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
targetRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
return (dsRoot, query, cb) -> {
final Predicate predicate = dsRoot.<Long> get(JpaDistributionSet_.id).in(distids);
dsRoot.fetch(JpaDistributionSet_.modules, JoinType.LEFT);
dsRoot.fetch(JpaDistributionSet_.tags, JoinType.LEFT);
dsRoot.fetch(JpaDistributionSet_.type, JoinType.LEFT);
query.distinct(true);
return predicate;
};
}
/**
* {@link Specification} for retrieving {@link DistributionSet}s by "like
* name or like description or like version".
*
* @param subString
* to be filtered on
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> likeNameOrDescriptionOrVersion(final String subString) {
return (targetRoot, query, cb) -> cb.or(
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.name)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.version)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.description)), subString.toLowerCase()));
}
/**
* {@link Specification} for retrieving {@link DistributionSet}s by "like
* name and like version".
@@ -148,9 +133,9 @@ public final class DistributionSetSpecification {
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> likeNameAndVersion(final String name, final String version) {
return (targetRoot, query, cb) -> cb.and(
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
return (dsRoot, query, cb) -> cb.and(
cb.like(cb.lower(dsRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
cb.like(cb.lower(dsRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
}
/**
@@ -165,16 +150,16 @@ public final class DistributionSetSpecification {
*/
public static Specification<JpaDistributionSet> hasTags(final Collection<String> tagNames,
final Boolean selectDSWithNoTag) {
return (targetRoot, query, cb) -> {
final Predicate predicate = getHasTagsPredicate(targetRoot, cb, selectDSWithNoTag, tagNames);
return (dsRoot, query, cb) -> {
final Predicate predicate = getHasTagsPredicate(dsRoot, cb, selectDSWithNoTag, tagNames);
query.distinct(true);
return predicate;
};
}
private static Predicate getHasTagsPredicate(final Root<JpaDistributionSet> targetRoot, final CriteriaBuilder cb,
private static Predicate getHasTagsPredicate(final Root<JpaDistributionSet> dsRoot, final CriteriaBuilder cb,
final Boolean selectDSWithNoTag, final Collection<String> tagNames) {
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = targetRoot.join(JpaDistributionSet_.tags,
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = dsRoot.join(JpaDistributionSet_.tags,
JoinType.LEFT);
final Path<String> exp = tags.get(JpaDistributionSetTag_.name);
@@ -210,9 +195,9 @@ public final class DistributionSetSpecification {
*/
public static Specification<JpaDistributionSet> equalsNameAndVersionIgnoreCase(final String name,
final String version) {
return (targetRoot, query, cb) -> cb.and(
cb.equal(cb.lower(targetRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
cb.equal(cb.lower(targetRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
return (dsRoot, query, cb) -> cb.and(
cb.equal(cb.lower(dsRoot.<String> get(JpaDistributionSet_.name)), name.toLowerCase()),
cb.equal(cb.lower(dsRoot.<String> get(JpaDistributionSet_.version)), version.toLowerCase()));
}
@@ -220,13 +205,13 @@ public final class DistributionSetSpecification {
* {@link Specification} for retrieving {@link DistributionSet} with given
* {@link DistributionSet#getType()}.
*
* @param type
* to search
* @param typeId
* id of distribution set type to search
* @return the {@link DistributionSet} {@link Specification}
*/
public static Specification<JpaDistributionSet> byType(final DistributionSetType type) {
return (targetRoot, query, cb) -> cb.equal(targetRoot.<JpaDistributionSetType> get(JpaDistributionSet_.type),
type);
public static Specification<JpaDistributionSet> byType(final Long typeId) {
return (dsRoot, query, cb) -> cb.equal(dsRoot.get(JpaDistributionSet_.type).get(JpaDistributionSetType_.id),
typeId);
}
@@ -269,11 +254,38 @@ public final class DistributionSetSpecification {
*/
public static Specification<JpaDistributionSet> hasTag(final Long tagId) {
return (targetRoot, query, cb) -> {
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = targetRoot.join(JpaDistributionSet_.tags,
return (dsRoot, query, cb) -> {
final SetJoin<JpaDistributionSet, JpaDistributionSetTag> tags = dsRoot.join(JpaDistributionSet_.tags,
JoinType.LEFT);
return cb.equal(tags.get(JpaDistributionSetTag_.id), tagId);
};
}
/**
* Can be added to specification chain to order result by provided target
*
* Order: 1. Distribution set installed on target, 2. Distribution set(s)
* assigned to target, 3. Based on distribution set id
*
* 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
* @return specification that applies order by target, may be overwritten
*/
public static Specification<JpaDistributionSet> orderedByLinkedTarget(final String linkedControllerId) {
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);
query.orderBy(cb.asc(assignedInstalledCase), cb.asc(dsRoot.get(JpaDistributionSet_.id)));
return cb.equal(targetRoot.get(JpaTarget_.controllerId), linkedControllerId);
};
}
}

View File

@@ -45,4 +45,24 @@ public final class RolloutSpecification {
}
/**
* Builds a {@link Specification} to search a rollout by name.
*
* @param searchText
* search string
* @param isDeleted
* <code>true</code> if deleted rollouts should be included in
* the search. Otherwise <code>false</code>
* @return criteria specification with a query for name of a rollout
*
*/
public static Specification<JpaRollout> likeName(final String searchText, final boolean isDeleted) {
return (rolloutRoot, query, criteriaBuilder) -> {
final String searchTextToLower = searchText.toLowerCase();
return criteriaBuilder.and(
criteriaBuilder.like(criteriaBuilder.lower(rolloutRoot.get(JpaRollout_.name)), searchTextToLower),
criteriaBuilder.equal(rolloutRoot.get(JpaRollout_.deleted), isDeleted));
};
}
}

View File

@@ -37,16 +37,18 @@ public final class SoftwareModuleSpecification {
/**
* {@link Specification} for retrieving {@link SoftwareModule}s by "like
* name or like version".
*
* @param subString
* name and like version".
*
* @param name
* to be filtered on
* @param version
* to be filtered on
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<JpaSoftwareModule> likeNameOrVersion(final String subString) {
return (targetRoot, query, cb) -> cb.or(
cb.like(cb.lower(targetRoot.<String> get(JpaSoftwareModule_.name)), subString.toLowerCase()),
cb.like(cb.lower(targetRoot.<String> get(JpaSoftwareModule_.version)), subString.toLowerCase()));
public static Specification<JpaSoftwareModule> likeNameAndVersion(final String name, final String version) {
return (smRoot, query, cb) -> cb.and(
cb.like(cb.lower(smRoot.<String> get(JpaSoftwareModule_.name)), name.toLowerCase()),
cb.like(cb.lower(smRoot.<String> get(JpaSoftwareModule_.version)), version.toLowerCase()));
}
/**
@@ -58,8 +60,22 @@ public final class SoftwareModuleSpecification {
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<JpaSoftwareModule> equalType(final Long type) {
return (targetRoot, query, cb) -> cb.equal(
targetRoot.<JpaSoftwareModuleType> get(JpaSoftwareModule_.type).get(JpaSoftwareModuleType_.id), type);
return (smRoot, query, cb) -> cb.equal(
smRoot.<JpaSoftwareModuleType> get(JpaSoftwareModule_.type).get(JpaSoftwareModuleType_.id), type);
}
/**
* {@link Specification} for fetching {@link SoftwareModule}s type.
*
* @return the {@link SoftwareModule} {@link Specification}
*/
public static Specification<JpaSoftwareModule> fetchType() {
return (smRoot, query, cb) -> {
if (!query.getResultType().isAssignableFrom(Long.class)) {
smRoot.fetch(JpaSoftwareModule_.type);
}
return cb.conjunction();
};
}
}

View File

@@ -126,8 +126,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s that have the request
* controller attributes flag set
* {@link Specification} for retrieving {@link Target}s that have the
* request controller attributes flag set
*
* @return the {@link Target} {@link Specification}
*/
@@ -154,8 +154,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by "equal to any given
* {@link TargetUpdateStatus}".
* {@link Specification} for retrieving {@link Target}s by "equal to any
* given {@link TargetUpdateStatus}".
*
* @param updateStatus
* to be filtered on
@@ -180,8 +180,8 @@ 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 "not equal to
* given {@link TargetUpdateStatus}".
*
* @param updateStatus
* to be filtered on
@@ -194,14 +194,15 @@ public final class TargetSpecifications {
/**
* {@link Specification} for retrieving {@link Target}s that are overdue. A
* target is overdue if it did not respond during the configured intervals:<br>
* target is overdue if it did not respond during the configured
* intervals:<br>
* <em>poll_itvl + overdue_itvl</em>
*
* @param overdueTimestamp
* the calculated timestamp to compare with the last respond of a
* target (lastTargetQuery).<br>
* The <code>overdueTimestamp</code> has to be calculated with the
* following expression:<br>
* The <code>overdueTimestamp</code> has to be calculated with
* the following expression:<br>
* <em>overdueTimestamp = nowTimestamp - poll_itvl -
* overdue_itvl</em>
*
@@ -212,23 +213,6 @@ public final class TargetSpecifications {
overdueTimestamp);
}
/**
* {@link Specification} for retrieving {@link Target}s by "like controllerId or
* like name or like description".
*
* @param searchText
* to be filtered on
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> likeIdOrNameOrDescription(final String searchText) {
return (targetRoot, query, cb) -> {
final String searchTextToLower = searchText.toLowerCase();
return cb.or(cb.like(cb.lower(targetRoot.get(JpaTarget_.controllerId)), searchTextToLower),
cb.like(cb.lower(targetRoot.get(JpaTarget_.name)), searchTextToLower),
cb.like(cb.lower(targetRoot.get(JpaTarget_.description)), searchTextToLower));
};
}
/**
* {@link Specification} for retrieving {@link Target}s by "like attribute
* value".
@@ -248,19 +232,24 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by "like controllerId or
* like name or like description or like attribute value".
* {@link Specification} for retrieving {@link Target}s by "like
* controllerId or like name".
*
* @param searchText
* to be filtered on
* @return the {@link Target} {@link Specification}
*/
public static Specification<JpaTarget> likeIdOrNameOrDescriptionOrAttributeValue(final String searchText) {
return Specification.where(likeIdOrNameOrDescription(searchText)).or(likeAttributeValue(searchText));
public static Specification<JpaTarget> likeControllerIdOrName(final String searchText) {
return (targetRoot, query, cb) -> {
final String searchTextToLower = searchText.toLowerCase();
return cb.or(cb.like(cb.lower(targetRoot.get(JpaTarget_.controllerId)), searchTextToLower),
cb.like(cb.lower(targetRoot.get(JpaTarget_.name)), searchTextToLower));
};
}
/**
* {@link Specification} for retrieving {@link Target}s by "like controllerId".
* {@link Specification} for retrieving {@link Target}s by "like
* controllerId".
*
* @param distributionId
* to be filtered on
@@ -271,8 +260,8 @@ public final class TargetSpecifications {
}
/**
* Finds all targets by given {@link Target#getControllerId()}s and which are
* not yet assigned to given {@link DistributionSet}.
* Finds all targets by given {@link Target#getControllerId()}s and which
* are not yet assigned to given {@link DistributionSet}.
*
* @param tIDs
* to search for.
@@ -305,8 +294,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by "has no tag names"or
* "has at least on of the given tag names".
* {@link Specification} for retrieving {@link Target}s by "has no tag
* names"or "has at least on of the given tag names".
*
* @param tagNames
* to be filtered on
@@ -348,8 +337,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by assigned distribution
* set.
* {@link Specification} for retrieving {@link Target}s by assigned
* distribution set.
*
* @param distributionSetId
* the ID of the distribution set which must be assigned
@@ -380,10 +369,10 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s that are compatible with
* given {@link DistributionSetType}. Compatibility is evaluated by checking the
* {@link TargetType} of a target. Targets that don't have a {@link TargetType}
* are compatible with all {@link DistributionSetType}
* {@link Specification} for retrieving {@link Target}s that are compatible
* with given {@link DistributionSetType}. Compatibility is evaluated by
* checking the {@link TargetType} of a target. Targets that don't have a
* {@link TargetType} are compatible with all {@link DistributionSetType}
*
* @param distributionSetTypeId
* the ID of the distribution set type which must be compatible
@@ -399,15 +388,16 @@ public final class TargetSpecifications {
};
}
private static Predicate getTargetTypeIsNullPredicate(Root<JpaTarget> targetRoot) {
private static Predicate getTargetTypeIsNullPredicate(final Root<JpaTarget> targetRoot) {
return targetRoot.get(JpaTarget_.targetType).isNull();
}
/**
* {@link Specification} for retrieving {@link Target}s that are NOT compatible
* with given {@link DistributionSetType}. Compatibility is evaluated by
* checking the {@link TargetType} of a target. Targets that don't have a
* {@link TargetType} are compatible with all {@link DistributionSetType}
* {@link Specification} for retrieving {@link Target}s that are NOT
* compatible with given {@link DistributionSetType}. Compatibility is
* evaluated by checking the {@link TargetType} of a target. Targets that
* don't have a {@link TargetType} are compatible with all
* {@link DistributionSetType}
*
* @param distributionSetTypeId
* the ID of the distribution set type which must be incompatible
@@ -456,8 +446,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s that are in an action
* for a given {@link RolloutGroup}
* {@link Specification} for retrieving {@link Target}s that are in an
* action for a given {@link RolloutGroup}
*
* @param group
* the {@link RolloutGroup}
@@ -490,8 +480,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s that have no Action of
* the {@link RolloutGroup}.
* {@link Specification} for retrieving {@link Target}s that have no Action
* of the {@link RolloutGroup}.
*
* @param group
* the {@link RolloutGroup}
@@ -512,8 +502,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by assigned distribution
* set.
* {@link Specification} for retrieving {@link Target}s by assigned
* distribution set.
*
* @param distributionSetId
* the ID of the distribution set which must be assigned
@@ -553,7 +543,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s by target type id is equal to null
* {@link Specification} for retrieving {@link Target}s by target type id is
* equal to null
*
* @return the {@link Target} {@link Specification}
*/
@@ -562,8 +553,8 @@ public final class TargetSpecifications {
}
/**
* {@link Specification} for retrieving {@link Target}s that don't have target
* type assigned
* {@link Specification} for retrieving {@link Target}s that don't have
* target type assigned
*
* @param typeId
* the id of the target type
@@ -576,15 +567,15 @@ public final class TargetSpecifications {
}
/**
* Can be added to specification chain to order result by provided distribution
* set
* Can be added to specification chain to order result by provided
* distribution set
*
* Order: 1. Targets with DS installed, 2. Targets with DS assigned, 3. Based on
* target id
* Order: 1. Targets with DS installed, 2. Targets with DS assigned, 3.
* Based on target id
*
* 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
* 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 distributionSetIdForOrder
* distribution set to consider

View File

@@ -0,0 +1 @@
CREATE INDEX sp_idx_rollout_status_tenant ON sp_rollout (tenant, status);

View File

@@ -0,0 +1 @@
CREATE INDEX sp_idx_rollout_status_tenant ON sp_rollout (tenant, status);

View File

@@ -0,0 +1 @@
CREATE INDEX sp_idx_rollout_status_tenant ON sp_rollout (tenant, status);

View File

@@ -0,0 +1,3 @@
CREATE INDEX sp_idx_rollout_status_tenant
ON sp_rollout
USING BTREE (tenant, status);

View File

@@ -0,0 +1 @@
CREATE INDEX sp_idx_rollout_status_tenant ON sp_rollout (tenant, status);

View File

@@ -45,6 +45,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation;
import org.eclipse.hawkbit.repository.model.DistributionSetInvalidation.CancelationType;
@@ -215,9 +216,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assertThatExceptionOfType(ConstraintViolationException.class)
.as("entity with invalid description should not be created")
.isThrownBy(() -> distributionSetManagement.create(
entityFactory.distributionSet().create().name("a").version("a")
.description(INVALID_TEXT_HTML)));
.isThrownBy(() -> distributionSetManagement.create(entityFactory.distributionSet().create().name("a")
.version("a").description(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("entity with too long description should not be updated")
@@ -225,8 +225,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.description(RandomStringUtils.randomAlphanumeric(513))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("entity with invalid characters should not be updated")
.isThrownBy(() -> distributionSetManagement
.as("entity with invalid characters should not be updated").isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).description(INVALID_TEXT_HTML)));
}
@@ -253,8 +252,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("entity with invalid characters should not be updated")
.isThrownBy(() -> distributionSetManagement
.as("entity with invalid characters should not be updated").isThrownBy(() -> distributionSetManagement
.update(entityFactory.distributionSet().update(set.getId()).name(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
@@ -383,7 +381,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// add some meta data entries
final DistributionSet ds3 = testdataFactory.createDistributionSet("ds3");
final int firstHalf = Math.round(((float) maxMetaData) / 2.f);
final int firstHalf = Math.round((maxMetaData) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
createDistributionSetMetadata(ds3.getId(), new JpaDistributionSetMetadata("k" + i, ds3, "v" + i));
}
@@ -415,7 +413,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assignedDS.stream().map(c -> (JpaDistributionSet) c)
.forEach(ds -> assertThat(ds.getTags().size()).as("ds has wrong tag size").isEqualTo(1));
DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.getByName(TAG1_NAME));
final DistributionSetTag findDistributionSetTag = getOrThrow(distributionSetTagManagement.getByName(TAG1_NAME));
assertThat(assignedDS.size()).as("assigned ds has wrong size")
.isEqualTo(distributionSetManagement.findByTag(PAGE, tag.getId()).getNumberOfElements());
@@ -549,7 +547,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// assign some software modules
final DistributionSet ds3 = testdataFactory.createDistributionSetWithNoSoftwareModules("ds3", "1.0");
final int firstHalf = Math.round(((float) maxModules) / 2.f);
final int firstHalf = Math.round((maxModules) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
distributionSetManagement.assignSoftwareModules(ds3.getId(), singletonList(modules.get(i)));
}
@@ -566,9 +564,8 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
singletonList(softwareModule.getId())));
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
.assignSoftwareModules(distributionSet.getId(), singletonList(softwareModule.getId())));
}
@Test
@@ -576,10 +573,9 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
void verifyUnassignSoftwareModulesToInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createDistributionSet();
final SoftwareModule softwareModule = testdataFactory.createSoftwareModuleOs();
distributionSetManagement.assignSoftwareModules(distributionSet.getId(),
singletonList(softwareModule.getId()));
distributionSetInvalidationManagement.invalidateDistributionSet(new DistributionSetInvalidation(
singletonList(distributionSet.getId()), CancelationType.NONE, false));
distributionSetManagement.assignSoftwareModules(distributionSet.getId(), singletonList(softwareModule.getId()));
distributionSetInvalidationManagement.invalidateDistributionSet(
new DistributionSetInvalidation(singletonList(distributionSet.getId()), CancelationType.NONE, false));
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> distributionSetManagement
@@ -647,13 +643,12 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
assignDistributionSet(dsFour.getId(), tSecond.getControllerId());
final DistributionSetFilterBuilder distributionSetFilterBuilder = new DistributionSetFilterBuilder()
.setIsDeleted(false).setIsComplete(true).setSelectDSWithNoTag(Boolean.FALSE);
final DistributionSetFilter distributionSetFilter = new DistributionSetFilterBuilder().setIsDeleted(false)
.setIsComplete(true).setSelectDSWithNoTag(Boolean.FALSE).build();
// target first only has an assigned DS-three so check order correct
final List<DistributionSet> tFirstPin = distributionSetManagement
.findByFilterAndAssignedInstalledDsOrderedByLinkTarget(PAGE, distributionSetFilterBuilder,
tFirst.getControllerId())
.findByDistributionSetFilterOrderByLinkedTarget(PAGE, distributionSetFilter, tFirst.getControllerId())
.getContent();
assertThat(tFirstPin.get(0)).isEqualTo(dsThree);
assertThat(tFirstPin).hasSize(10);
@@ -661,8 +656,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// target second has installed DS-2 and assigned DS-4 so check order
// correct
final List<DistributionSet> tSecondPin = distributionSetManagement
.findByFilterAndAssignedInstalledDsOrderedByLinkTarget(PAGE, distributionSetFilterBuilder,
tSecond.getControllerId())
.findByDistributionSetFilterOrderByLinkedTarget(PAGE, distributionSetFilter, tSecond.getControllerId())
.getContent();
assertThat(tSecondPin.get(0)).isEqualTo(dsSecond);
assertThat(tSecondPin.get(1)).isEqualTo(dsFour);
@@ -724,15 +718,14 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
validateDeleted(dsDeleted, sizeOfAllDistributionSets - 1);
validateCompleted(dsInComplete, sizeOfAllDistributionSets - 1);
validateType(newType, dsNewType, sizeOfAllDistributionSets - 1);
validateSearchText(dsGroup2, "%" + dsGroup2Prefix);
validateFilterString(allDistributionSets, dsGroup2Prefix);
validateSearchText(allDistributionSets, dsGroup2Prefix);
validateTags(dsTagA, dsTagB, dsTagC, dsGroup1WithGroup2, dsGroup1);
validateDeletedAndCompleted(dsGroup1WithGroup2, dsNewType, dsDeleted);
validateDeletedAndCompletedAndType(dsGroup1WithGroup2, dsDeleted, newType, dsNewType);
validateDeletedAndCompletedAndTypeAndSearchText(dsGroup2, newType, "%" + dsGroup2Prefix);
validateDeletedAndCompletedAndTypeAndFilterString(dsGroup1WithGroup2, dsDeleted, dsInComplete, dsNewType,
newType, ":1");
validateDeletedAndCompletedAndTypeAndSearchTextAndTag(dsGroup2, dsTagA, "%" + dsGroup2Prefix);
validateDeletedAndCompletedAndTypeAndSearchText(dsGroup2, newType, dsGroup2Prefix);
validateDeletedAndCompletedAndTypeAndSearchText(dsGroup1WithGroup2, dsDeleted, dsInComplete, dsNewType, newType,
":1");
validateDeletedAndCompletedAndTypeAndSearchTextAndTag(dsGroup2, dsTagA, dsGroup2Prefix);
}
@Step
@@ -764,59 +757,51 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Step
private void validateType(final DistributionSetType newType, final DistributionSet dsNewType,
final int standardDsTypeSize) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType),
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setTypeId(newType.getId()),
singletonList(dsNewType));
assertThatFilterHasSizeAndDoesNotContainDistributionSet(
getDistributionSetFilterBuilder().setType(standardDsType), standardDsTypeSize, dsNewType);
getDistributionSetFilterBuilder().setTypeId(standardDsType.getId()), standardDsTypeSize, dsNewType);
}
@Step
private void validateSearchText(final List<DistributionSet> withText, final String text) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(text),
withText);
}
@Step
private void validateFilterString(final List<DistributionSet> allDistributionSets, final String dsNamePrefix) {
private void validateSearchText(final List<DistributionSet> allDistributionSets, final String dsNamePrefix) {
final List<DistributionSet> withTestNamePrefix = allDistributionSets.stream()
.filter(ds -> ds.getName().startsWith(dsNamePrefix)).collect(Collectors.toList());
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix), withTestNamePrefix);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(dsNamePrefix),
withTestNamePrefix);
final List<DistributionSet> withTestNameExact = withTestNamePrefix.stream()
.filter(ds -> ds.getName().equals(dsNamePrefix)).collect(Collectors.toList());
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix + ":"), withTestNameExact);
getDistributionSetFilterBuilder().setSearchText(dsNamePrefix + ":"), withTestNameExact);
final List<DistributionSet> withTestNameExactAndVersionPrefix = withTestNameExact.stream()
.filter(ds -> ds.getVersion().startsWith("1")).collect(Collectors.toList());
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix + ":1"),
getDistributionSetFilterBuilder().setSearchText(dsNamePrefix + ":1"),
withTestNameExactAndVersionPrefix);
final List<DistributionSet> dsWithExactNameAndVersion = withTestNameExactAndVersionPrefix.stream()
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
assertThat(dsWithExactNameAndVersion).hasSize(1);
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setFilterString(dsNamePrefix + ":1.0.0"), dsWithExactNameAndVersion);
getDistributionSetFilterBuilder().setSearchText(dsNamePrefix + ":1.0.0"), dsWithExactNameAndVersion);
final List<DistributionSet> withVersionPrefix = allDistributionSets.stream()
.filter(ds -> ds.getVersion().startsWith("1.0.")).collect(Collectors.toList());
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(":1.0."),
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(":1.0."),
withVersionPrefix);
final List<DistributionSet> withVersionExact = withVersionPrefix.stream()
.filter(ds -> ds.getVersion().equals("1.0.0")).collect(Collectors.toList());
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(":1.0.0"),
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(":1.0.0"),
withVersionExact);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(":"),
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(":"),
allDistributionSets);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setFilterString(" : "),
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setSearchText(" : "),
allDistributionSets);
}
@@ -864,18 +849,14 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
@Step
private void validateDeletedAndCompletedAndType(final List<DistributionSet> deletedAndCompletedAndStandardType,
final DistributionSet dsDeleted, final DistributionSetType newType, final DistributionSet dsNewType) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE)
.setIsComplete(Boolean.TRUE).setType(standardDsType), deletedAndCompletedAndStandardType);
.setIsComplete(Boolean.TRUE).setTypeId(standardDsType.getId()), deletedAndCompletedAndStandardType);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setType(standardDsType).setIsDeleted(Boolean.TRUE), singletonList(dsDeleted));
.setTypeId(standardDsType.getId()).setIsDeleted(Boolean.TRUE), singletonList(dsDeleted));
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsDeleted(Boolean.TRUE)
.setIsComplete(Boolean.FALSE).setType(standardDsType));
.setIsComplete(Boolean.FALSE).setTypeId(standardDsType.getId()));
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(newType),
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setTypeId(newType.getId()),
singletonList(dsNewType));
}
@@ -884,21 +865,23 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final List<DistributionSet> completedAndStandardTypeAndSearchText, final DistributionSetType newType,
final String text) {
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setType(standardDsType).setSearchText(text), completedAndStandardTypeAndSearchText);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsDeleted(Boolean.FALSE)
.setIsComplete(Boolean.TRUE).setTypeId(standardDsType.getId()).setSearchText(text),
completedAndStandardTypeAndSearchText);
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setSearchText(text));
.setIsDeleted(Boolean.TRUE).setTypeId(standardDsType.getId()).setSearchText(text + ":"));
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
.setSearchText(text).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE));
assertThatFilterDoesNotContainAnyDistributionSet(
getDistributionSetFilterBuilder().setTypeId(standardDsType.getId()).setSearchText(text)
.setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE));
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(newType)
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setTypeId(newType.getId())
.setSearchText(text).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE));
}
@Step
private void validateDeletedAndCompletedAndTypeAndFilterString(
private void validateDeletedAndCompletedAndTypeAndSearchText(
final List<DistributionSet> completedAndNotDeletedStandardTypeAndFilterString,
final DistributionSet dsDeleted, final DistributionSet dsInComplete, final DistributionSet dsNewType,
final DistributionSetType newType, final String filterString) {
@@ -907,23 +890,25 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
completedAndNotDeletedStandardTypeAndFilterString);
completedAndStandardTypeAndFilterString.add(dsDeleted);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setType(standardDsType).setFilterString(filterString), completedAndStandardTypeAndFilterString);
.setTypeId(standardDsType.getId()).setSearchText(filterString),
completedAndStandardTypeAndFilterString);
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE)
.setType(standardDsType).setFilterString(filterString),
.setTypeId(standardDsType.getId()).setSearchText(filterString),
completedAndNotDeletedStandardTypeAndFilterString);
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setIsDeleted(Boolean.TRUE).setType(standardDsType).setFilterString(filterString),
.setIsDeleted(Boolean.TRUE).setTypeId(standardDsType.getId()).setSearchText(filterString),
singletonList(dsDeleted));
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(standardDsType)
.setFilterString(filterString).setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE),
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setTypeId(standardDsType.getId()).setSearchText(filterString)
.setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE),
singletonList(dsInComplete));
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setType(newType)
.setFilterString(filterString).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
assertThatFilterContainsOnlyGivenDistributionSets(getDistributionSetFilterBuilder().setTypeId(newType.getId())
.setSearchText(filterString).setIsComplete(Boolean.TRUE).setIsDeleted(Boolean.FALSE),
singletonList(dsNewType));
}
@@ -933,13 +918,13 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final String text) {
assertThatFilterContainsOnlyGivenDistributionSets(
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setType(standardDsType)
getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE).setTypeId(standardDsType.getId())
.setSearchText(text).setTagNames(singletonList(dsTagA.getName())),
completedAndStandartTypeAndSearchTextAndTagA);
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder().setType(standardDsType)
.setSearchText(text).setTagNames(singletonList(dsTagA.getName())).setIsComplete(Boolean.FALSE)
.setIsDeleted(Boolean.FALSE));
assertThatFilterDoesNotContainAnyDistributionSet(getDistributionSetFilterBuilder()
.setTypeId(standardDsType.getId()).setSearchText(text).setTagNames(singletonList(dsTagA.getName()))
.setIsComplete(Boolean.FALSE).setIsDeleted(Boolean.FALSE));
}
private DistributionSetFilterBuilder getDistributionSetFilterBuilder() {
@@ -983,7 +968,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
distributionSetManagement.delete(ds1.getId());
// not assigned so not marked as deleted but fully deleted
assertThat(distributionSetRepository.findAll()).hasSize(1);
assertThat(distributionSetManagement.findByCompleted(PAGE, true).getTotalElements()).isEqualTo(1);
assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(1);
}
@Test
@@ -1027,11 +1012,15 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
final Page<DistributionSetMetadata> metadataOfDs2 = distributionSetManagement
.findMetaDataByDistributionSetId(PageRequest.of(0, 100), ds2.getId());
assertThat(metadataOfDs1.getNumberOfElements()).isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet());
assertThat(metadataOfDs1.getTotalElements()).isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet());
assertThat(metadataOfDs1.getNumberOfElements())
.isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet());
assertThat(metadataOfDs1.getTotalElements())
.isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet());
assertThat(metadataOfDs2.getNumberOfElements()).isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet() - 1);
assertThat(metadataOfDs2.getTotalElements()).isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet() - 1);
assertThat(metadataOfDs2.getNumberOfElements())
.isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet() - 1);
assertThat(metadataOfDs2.getTotalElements())
.isEqualTo(quotaManagement.getMaxMetaDataEntriesPerDistributionSet() - 1);
}
@Test
@@ -1056,7 +1045,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// not assigned so not marked as deleted
assertThat(distributionSetRepository.findAll()).hasSize(4);
assertThat(distributionSetManagement.findByCompleted(PAGE, true).getTotalElements()).isEqualTo(2);
assertThat(distributionSetManagement.findByCompleted(PAGE, true)).hasSize(2);
}
@Test
@@ -1131,7 +1120,7 @@ class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
}
// can be removed with java-11
private <T> T getOrThrow(Optional<T> opt) {
private <T> T getOrThrow(final Optional<T> opt) {
return opt.orElseThrow(NoSuchElementException::new);
}
}

View File

@@ -10,13 +10,13 @@ package org.eclipse.hawkbit.repository.jpa;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.hawkbit.repository.DistributionSetTagManagement;
import org.eclipse.hawkbit.repository.builder.TagCreate;
@@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Step;
import io.qameta.allure.Story;
/**
@@ -103,71 +104,43 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
toggleTagAssignment(dsABCs, distributionSetTagManagement.getByName(tagB.getName()).get());
toggleTagAssignment(dsABCs, distributionSetTagManagement.getByName(tagC.getName()).get());
DistributionSetFilterBuilder distributionSetFilterBuilder;
// search for not deleted
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Arrays.asList(tagA.getName()));
assertEquals(dsAs.spliterator().getExactSizeIfKnown() + dsABs.spliterator().getExactSizeIfKnown()
+ dsACs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
.getTotalElements(),
"filter works not correct");
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Arrays.asList(tagB.getName()));
assertEquals(
dsBs.spliterator().getExactSizeIfKnown() + dsABs.spliterator().getExactSizeIfKnown()
+ dsBCs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
.getTotalElements(),
"filter works not correct");
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Arrays.asList(tagC.getName()));
assertEquals(dsCs.spliterator().getExactSizeIfKnown() + dsACs.spliterator().getExactSizeIfKnown()
+ dsBCs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
.getTotalElements(),
"filter works not correct");
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(true)
.setTagNames(Arrays.asList(tagX.getName()));
assertEquals(0, distributionSetManagement
.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build()).getTotalElements(),
"filter works not correct");
assertEquals(5, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown(), "wrong tag size");
final DistributionSetFilterBuilder distributionSetFilterBuilder = getDistributionSetFilterBuilder()
.setIsComplete(true);
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagA.getName())),
Stream.of(dsAs, dsABs, dsACs, dsABCs));
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagB.getName())),
Stream.of(dsBs, dsABs, dsBCs, dsABCs));
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagC.getName())),
Stream.of(dsCs, dsACs, dsBCs, dsABCs));
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagX.getName())),
Stream.empty());
assertThat(distributionSetTagRepository.findAll()).hasSize(5);
distributionSetTagManagement.delete(tagY.getName());
assertEquals(4, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown(), "wrong tag size");
assertThat(distributionSetTagRepository.findAll()).hasSize(4);
distributionSetTagManagement.delete(tagX.getName());
assertEquals(3, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown(), "wrong tag size");
assertThat(distributionSetTagRepository.findAll()).hasSize(3);
distributionSetTagManagement.delete(tagB.getName());
assertEquals(2, distributionSetTagRepository.findAll().spliterator().getExactSizeIfKnown(), "wrong tag size");
assertThat(distributionSetTagRepository.findAll()).hasSize(2);
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setTagNames(Arrays.asList(tagA.getName()));
assertEquals(dsAs.spliterator().getExactSizeIfKnown() + dsABs.spliterator().getExactSizeIfKnown()
+ dsACs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
.getTotalElements(),
"filter works not correct");
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagA.getName())),
Stream.of(dsAs, dsABs, dsACs, dsABCs));
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagB.getName())),
Stream.empty());
verifyExpectedFilteredDistributionSets(distributionSetFilterBuilder.setTagNames(Arrays.asList(tagC.getName())),
Stream.of(dsCs, dsACs, dsBCs, dsABCs));
}
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setTagNames(Arrays.asList(tagB.getName()));
assertEquals(0, distributionSetManagement
.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build()).getTotalElements(),
"filter works not correct");
distributionSetFilterBuilder = getDistributionSetFilterBuilder().setIsComplete(Boolean.TRUE)
.setTagNames(Arrays.asList(tagC.getName()));
assertEquals(dsCs.spliterator().getExactSizeIfKnown() + dsACs.spliterator().getExactSizeIfKnown()
+ dsBCs.spliterator().getExactSizeIfKnown() + dsABCs.spliterator().getExactSizeIfKnown(),
distributionSetManagement.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build())
.getTotalElements(),
"filter works not correct");
@Step
private void verifyExpectedFilteredDistributionSets(final DistributionSetFilterBuilder distributionSetFilterBuilder,
final Stream<Collection<DistributionSet>> expectedFilteredDistributionSets) {
final Collection<Long> retrievedFilteredDsIds = distributionSetManagement
.findByDistributionSetFilter(PAGE, distributionSetFilterBuilder.build()).stream()
.map(DistributionSet::getId).collect(Collectors.toList());
final Collection<Long> expectedFilteredDsIds = expectedFilteredDistributionSets.flatMap(Collection::stream)
.map(DistributionSet::getId).collect(Collectors.toList());
assertThat(retrievedFilteredDsIds).hasSameElementsAs(expectedFilteredDsIds);
}
@Test
@@ -182,11 +155,11 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
// toggle A only -> A is now assigned
DistributionSetTagAssignmentResult result = toggleTagAssignment(groupA, tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAlreadyAssigned()).isZero();
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement
.get(groupA.stream().map(DistributionSet::getId).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassigned()).isZero();
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
@@ -196,14 +169,14 @@ public class DistributionSetTagManagementTest extends AbstractJpaIntegrationTest
assertThat(result.getAssigned()).isEqualTo(20);
assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement
.get(groupB.stream().map(DistributionSet::getId).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
assertThat(result.getUnassigned()).isZero();
assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
// toggle A+B -> both unassigned
result = toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(0);
assertThat(result.getAlreadyAssigned()).isZero();
assertThat(result.getAssigned()).isZero();
assertThat(result.getAssignedEntity()).isEmpty();
assertThat(result.getUnassigned()).isEqualTo(40);
assertThat(result.getUnassignedEntity()).containsAll(distributionSetManagement

View File

@@ -22,6 +22,7 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
@@ -139,8 +140,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that a running action is auto canceled by a rollout which assigns another distribution-set.")
void rolloutAssignsNewDistributionSetAndAutoCloseActiveActions() {
tenantConfigurationManagement.addOrUpdateConfiguration(
TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
tenantConfigurationManagement
.addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true);
try {
// manually assign distribution set to target
@@ -197,9 +198,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Expect(type = RolloutGroupUpdatedEvent.class, count = 5),
@Expect(type = DistributionSetCreatedEvent.class, count = 1),
@Expect(type = SoftwareModuleCreatedEvent.class, count = 3),
@Expect(type = RolloutCreatedEvent.class, count = 1),
@Expect(type = RolloutUpdatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 125)})
@Expect(type = RolloutCreatedEvent.class, count = 1), @Expect(type = RolloutUpdatedEvent.class, count = 1),
@Expect(type = TargetCreatedEvent.class, count = 125) })
void entityQueriesReferringToNotExistingEntitiesThrowsException() {
testdataFactory.createRollout("xxx");
@@ -255,7 +255,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
scheduledGroups.forEach(group -> assertThat(group.getStatus())
.as("group which should be in scheduled state is in " + group.getStatus() + " state")
.isEqualTo(RolloutGroupStatus.SCHEDULED));
// verify that the first group actions has been started and are in state running
// verify that the first group actions has been started and are in state
// running
final List<Action> runningActions = findActionsByRolloutAndStatus(createdRollout, Status.RUNNING);
assertThat(runningActions).hasSize(amountTargetsForRollout / amountGroups)
.as("Created actions are initiated by rollout creator")
@@ -522,8 +523,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts();
// finish running actions, 2 actions should be finished
assertThat(changeStatusForAllRunningActions(createdRollout, Status.FINISHED)).isEqualTo(2);
assertThat(getRollout(createdRollout.getId()).getStatus())
.isEqualTo(RolloutStatus.RUNNING);
assertThat(getRollout(createdRollout.getId()).getStatus()).isEqualTo(RolloutStatus.RUNNING);
}
// check rollout to see that all actions and all groups are finished and
@@ -1006,7 +1006,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
changeStatusForAllRunningActions(rolloutD, Status.FINISHED);
rolloutManagement.handleRollouts();
final Page<Rollout> rolloutPage = rolloutManagement
final Slice<Rollout> rolloutPage = rolloutManagement
.findAllWithDetailedStatus(new OffsetBasedPageRequest(0, 100, Sort.by(Direction.ASC, "name")), false);
final List<Rollout> rolloutList = rolloutPage.getContent();
@@ -1387,12 +1387,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// group1 exceeds the quota
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout()
.create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.set(distributionSet), Arrays.asList(group1, group2), conditions));
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet),
Arrays.asList(group1, group2), conditions));
// create group definitions
final RolloutGroupCreate group3 = entityFactory.rolloutGroup().create().conditions(conditions).name("group3")
@@ -1402,37 +1399,23 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
// group4 exceeds the quota
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(() -> rolloutManagement.create(
entityFactory.rollout()
.create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.set(distributionSet), Arrays.asList(group3, group4), conditions));
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet),
Arrays.asList(group3, group4), conditions));
// create group definitions
final RolloutGroupCreate group5 = entityFactory.rolloutGroup()
.create()
.conditions(conditions)
.name("group5")
final RolloutGroupCreate group5 = entityFactory.rolloutGroup().create().conditions(conditions).name("group5")
.targetPercentage(33.3F);
final RolloutGroupCreate group6 = entityFactory.rolloutGroup()
.create()
.conditions(conditions)
.name("group6")
final RolloutGroupCreate group6 = entityFactory.rolloutGroup().create().conditions(conditions).name("group6")
.targetPercentage(66.6F);
final RolloutGroupCreate group7 = entityFactory.rolloutGroup()
.create()
.conditions(conditions)
.name("group7")
final RolloutGroupCreate group7 = entityFactory.rolloutGroup().create().conditions(conditions).name("group7")
.targetPercentage(100.0F);
// should work fine
assertThat(rolloutManagement.create(entityFactory.rollout()
.create()
.name(rolloutName)
.description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*")
.set(distributionSet), Arrays.asList(group5, group6, group7), conditions)).isNotNull();
assertThat(rolloutManagement.create(
entityFactory.rollout().create().name(rolloutName).description(rolloutName)
.targetFilterQuery("controllerId==" + rolloutName + "-*").set(distributionSet),
Arrays.asList(group5, group6, group7), conditions)).isNotNull();
}
@@ -1603,8 +1586,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
final RolloutCreate rollout = generateTargetsAndRollout(rolloutName, targets);
assertThatExceptionOfType(AssignmentQuotaExceededException.class).isThrownBy(
() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
assertThatExceptionOfType(AssignmentQuotaExceededException.class)
.isThrownBy(() -> rolloutManagement.create(rollout, maxGroups + 1, conditions))
.withMessageContaining("not be greater than " + maxGroups);
}
@@ -1625,8 +1608,7 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
.description("some description").targetFilterQuery("id==" + rolloutName + "-*")
.set(distributionSet);
.description("some description").targetFilterQuery("id==" + rolloutName + "-*").set(distributionSet);
Rollout myRollout = rolloutManagement.create(rolloutToCreate, amountGroups, conditions);
myRollout = getRollout(myRollout.getId());
@@ -1783,8 +1765,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
@Description("Creating a rollout without weight value when multi assignment in enabled.")
void weightNotRequiredInMultiAssignmentMode() {
enableMultiAssignments();
final Rollout rollout = createSimpleTestRolloutWithTargetsAndDistributionSet(
10, 10, 2, "50", "80", ActionType.FORCED, null);
final Rollout rollout = createSimpleTestRolloutWithTargetsAndDistributionSet(10, 10, 2, "50", "80",
ActionType.FORCED, null);
assertThat(rollout).isNotNull();
}
@@ -1854,8 +1836,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
void createRolloutWithInvalidDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class).as(
"Invalid distributionSet should throw an exception")
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception")
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithInvalidDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80"));
}
@@ -1865,8 +1847,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
void createRolloutWithIncompleteDistributionSet() {
final DistributionSet distributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class).as(
"Incomplete distributionSet should throw an exception")
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception")
.isThrownBy(() -> testdataFactory.createRolloutByVariables("createRolloutWithIncompleteDistributionSet",
"desc", 2, "name==*", distributionSet, "50", "80"));
}
@@ -1880,10 +1862,9 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
"desc", 2, "name==*", distributionSet, "50", "80");
final DistributionSet invalidDistributionSet = testdataFactory.createAndInvalidateDistributionSet();
assertThatExceptionOfType(InvalidDistributionSetException.class).as(
"Invalid distributionSet should throw an exception")
.isThrownBy(() -> rolloutManagement.update(
entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
assertThatExceptionOfType(InvalidDistributionSetException.class)
.as("Invalid distributionSet should throw an exception").isThrownBy(() -> rolloutManagement
.update(entityFactory.rollout().update(rollout.getId()).set(invalidDistributionSet.getId())));
}
@Test
@@ -1895,9 +1876,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
"desc", 2, "name==*", distributionSet, "50", "80");
final DistributionSet incompleteDistributionSet = testdataFactory.createIncompleteDistributionSet();
assertThatExceptionOfType(IncompleteDistributionSetException.class).as(
"Incomplete distributionSet should throw an exception")
.isThrownBy(() -> rolloutManagement.update(
assertThatExceptionOfType(IncompleteDistributionSetException.class)
.as("Incomplete distributionSet should throw an exception").isThrownBy(() -> rolloutManagement.update(
entityFactory.rollout().update(rollout.getId()).set(incompleteDistributionSet.getId())));
}
@@ -1920,11 +1900,8 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
targets.addAll(targetsWithoutType);
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder().withDefaults().build();
final RolloutCreate rolloutToCreate = entityFactory.rollout()
.create()
.name(rolloutName)
.targetFilterQuery("name==*")
.set(testDs);
final RolloutCreate rolloutToCreate = entityFactory.rollout().create().name(rolloutName)
.targetFilterQuery("name==*").set(testDs);
final Rollout createdRollout = rolloutManagement.create(rolloutToCreate, 1, conditions);
@@ -1932,19 +1909,18 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
rolloutManagement.handleRollouts();
final Rollout testRollout = reloadRollout(createdRollout);
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement.findByRollout(Pageable.unpaged(),
testRollout.getId()).getContent();
final List<RolloutGroup> rolloutGroups = rolloutGroupManagement
.findByRollout(Pageable.unpaged(), testRollout.getId()).getContent();
assertThat(testRollout.getStatus()).isEqualTo(RolloutStatus.READY);
assertThat(testRollout.getTotalTargets()).isEqualTo(targets.size());
assertThat(rolloutGroups).hasSize(1);
assertThat(rolloutGroups.get(0).getTotalTargets()).isEqualTo(targets.size());
final List<Target> rolloutGroupTargets = rolloutGroupManagement.findTargetsOfRolloutGroup(Pageable.unpaged(),
rolloutGroups.get(0).getId()).getContent();
final List<Target> rolloutGroupTargets = rolloutGroupManagement
.findTargetsOfRolloutGroup(Pageable.unpaged(), rolloutGroups.get(0).getId()).getContent();
assertThat(rolloutGroupTargets).hasSize(targets.size())
.containsExactlyInAnyOrderElementsOf(targets)
assertThat(rolloutGroupTargets).hasSize(targets.size()).containsExactlyInAnyOrderElementsOf(targets)
.doesNotContainAnyElementsOf(incompatibleTargets);
}
@@ -2049,13 +2025,10 @@ class RolloutManagementTest extends AbstractJpaIntegrationTest {
}
private void awaitRunningState(final Long myRolloutId) {
Awaitility.await()
.atMost(Duration.TEN_SECONDS)
.pollInterval(Duration.FIVE_HUNDRED_MILLISECONDS)
.with()
.until(() -> WithSpringAuthorityRule.runAsPrivileged(
Awaitility.await().atMost(Duration.TEN_SECONDS).pollInterval(Duration.FIVE_HUNDRED_MILLISECONDS).with()
.until(() -> WithSpringAuthorityRule
.runAsPrivileged(
() -> rolloutManagement.get(myRolloutId).orElseThrow(NoSuchElementException::new))
.getStatus()
.equals(RolloutStatus.RUNNING));
.getStatus().equals(RolloutStatus.RUNNING));
}
}

View File

@@ -81,9 +81,8 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
final SoftwareModule module = testdataFactory.createSoftwareModuleApp();
verifyThrownExceptionBy(
() -> softwareModuleManagement
.create(Collections
.singletonList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
() -> softwareModuleManagement.create(Collections
.singletonList(entityFactory.softwareModule().create().name("xxx").type(NOT_EXIST_ID))),
"SoftwareModuleType");
verifyThrownExceptionBy(
() -> softwareModuleManagement
@@ -195,21 +194,20 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "poky", osType.getId()).getContent()).hasSize(1);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "poky", osType.getId()).getContent().get(0))
.isEqualTo(os);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "oracle%", runtimeType.getId()).getContent())
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "oracle", runtimeType.getId()).getContent())
.hasSize(1);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "oracle%", runtimeType.getId()).getContent().get(0))
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "oracle", runtimeType.getId()).getContent().get(0))
.isEqualTo(jvm);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "1.0.1", appType.getId()).getContent()).hasSize(1);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "1.0.1", appType.getId()).getContent().get(0))
.isEqualTo(ah);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "1.0%", appType.getId()).getContent()).hasSize(2);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, ":1.0.1", appType.getId()).getContent()).hasSize(1)
.first().isEqualTo(ah);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, ":1.0", appType.getId()).getContent()).hasSize(2);
// no we search with on entity marked as deleted
softwareModuleManagement.delete(
softwareModuleRepository.findByAssignedToAndType(PAGE, ds, appType).getContent().get(0).getId());
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "1.0%", appType.getId()).getContent()).hasSize(1);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, "1.0%", appType.getId()).getContent().get(0))
assertThat(softwareModuleManagement.findByTextAndType(PAGE, ":1.0", appType.getId()).getContent()).hasSize(1);
assertThat(softwareModuleManagement.findByTextAndType(PAGE, ":1.0", appType.getId()).getContent().get(0))
.isEqualTo(ah);
}
@@ -694,7 +692,7 @@ public class SoftwareModuleManagementTest extends AbstractJpaIntegrationTest {
// add some meta data entries
final SoftwareModule module3 = testdataFactory.createSoftwareModuleApp("m3");
final int firstHalf = Math.round(((float) maxMetaData) / 2.f);
final int firstHalf = Math.round((maxMetaData) / 2.f);
for (int i = 0; i < firstHalf; ++i) {
softwareModuleManagement.createMetaData(
entityFactory.softwareModuleMetadata().create(module3.getId()).key("k" + i).value("v" + i));

View File

@@ -46,6 +46,7 @@ import org.eclipse.hawkbit.repository.test.matcher.ExpectEvents;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
@@ -417,26 +418,33 @@ public class TargetFilterQueryManagementTest extends AbstractJpaIntegrationTest
final Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
.findByAutoAssignDSAndRsql(PageRequest.of(0, 500), distributionSet.getId(), rsql);
assertThat(tfqList.getTotalElements()).isEqualTo(expectedFilterQueries.length);
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
}
private void verifyExpectedFilterQueriesInList(final Page<TargetFilterQuery> tfqList,
private void verifyExpectedFilterQueriesInList(final Slice<TargetFilterQuery> tfqList,
final TargetFilterQuery... expectedFilterQueries) {
assertThat(expectedFilterQueries.length).as("Target filter query count")
.isEqualTo((int) tfqList.getTotalElements());
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
}
@Step
private void verifyFindForAllWithAutoAssignDs(final TargetFilterQuery... expectedFilterQueries) {
final Page<TargetFilterQuery> tfqList = targetFilterQueryManagement
final Slice<TargetFilterQuery> tfqList = targetFilterQueryManagement
.findWithAutoAssignDS(PageRequest.of(0, 500));
assertThat(tfqList.getNumberOfElements()).isEqualTo(expectedFilterQueries.length);
verifyExpectedFilterQueriesInList(tfqList, expectedFilterQueries);
}
private void verifyExpectedFilterQueriesInList(final Page<TargetFilterQuery> tfqList,
final TargetFilterQuery... expectedFilterQueries) {
assertThat(expectedFilterQueries).as("Target filter query count").hasSize((int) tfqList.getTotalElements());
assertThat(tfqList.map(TargetFilterQuery::getId)).containsExactly(
Arrays.stream(expectedFilterQueries).map(TargetFilterQuery::getId).toArray(Long[]::new));
}
@Test
@Description("Creating or updating a target filter query with autoassignment and no-value weight when multi assignment in enabled.")
public void weightNotRequiredInMultiAssignmentMode() {

View File

@@ -15,13 +15,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.UpdateMode;
import org.eclipse.hawkbit.repository.builder.DistributionSetCreate;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status;
@@ -110,19 +107,6 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
final String installedC = targCs.iterator().next().getControllerId();
final Long actionId = getFirstAssignedActionId(assignDistributionSet(installedSet.getId(), assignedC));
// add attributes to match against only attribute value or attribute
// value and name
final Map<String, String> attributes = new HashMap<>();
attributes.put("key", "targ-C-attribute-value");
final Target targAttribute = controllerManagement.updateControllerAttributes(targCs.get(0).getControllerId(),
attributes, UpdateMode.REPLACE);
// prepare one target with an attribute value equal to controller id
Target targAttributeId = targCs.get(15);
final Map<String, String> idAttributes = new HashMap<>();
idAttributes.put("key", targAttributeId.getControllerId());
targAttributeId = controllerManagement.updateControllerAttributes(targAttributeId.getControllerId(),
idAttributes, UpdateMode.REPLACE);
// set one installed DS also
controllerManagement.addUpdateActionStatus(
entityFactory.actionStatus().create(actionId).status(Status.FINISHED).message("message"));
@@ -142,9 +126,6 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
// try to find several targets with different filter settings
verifyThat1TargetHasNameAndId("targ-A-special", targSpecialName.getControllerId());
verifyThat1TargetHasAttributeValue("%c-attribute%", targAttribute.getControllerId());
verifyThat1TargetHasAttributeValue("%" + targAttributeId.getControllerId() + "%",
targAttributeId.getControllerId());
verifyThatRepositoryContains500Targets();
verifyThat200TargetsHaveTagD(targTagW, concat(targBs, targCs));
verifyThat100TargetsContainsGivenTextAndHaveTagAssigned(targTagY, targTagW, targBs);
@@ -183,8 +164,10 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
verifyThat1TargetAIsInStatusPendingAndHasDSInstalled(installedSet, pending,
targetManagement.getByControllerID(installedC).get());
verifyThat1TargetHasTypeAndDSAssigned(targetTypeX, setB, targetManagement.getByControllerID(assignedE).get());
verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(setA, targetManagement.getByControllerID(Arrays.asList(assignedA, assignedB, assignedC)));
verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(installedSet, targetManagement.getByControllerID(Collections.singletonList(installedC)));
verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(setA,
targetManagement.getByControllerID(Arrays.asList(assignedA, assignedB, assignedC)));
verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(installedSet,
targetManagement.getByControllerID(Collections.singletonList(installedC)));
verifyThat100TargetsContainsGivenTextAndHaveTypeAssigned(targetTypeX, targEs);
verifyThat400TargetsContainsGivenTextAndHaveNoTypeAssigned(concat(targAs, targBs, targCs, targDs));
@@ -481,14 +464,6 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
.hasSize(Ints.saturatedCast(targetManagement.countByFilters(filterParamsByControllerId)));
}
@Step
private void verifyThat1TargetHasAttributeValue(final String value, final String controllerId) {
final FilterParams filterParams = new FilterParams(null, null, value, null, Boolean.FALSE);
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
.hasSize(1).as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countByFilters(filterParams)));
}
@Step
private void verifyThat100TargetsContainsGivenTextAndHaveTagAssigned(final TargetTag targTagY,
final TargetTag targTagW, final List<Target> expected) {
@@ -544,7 +519,8 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
}
@Step
private void verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(final DistributionSet set, final List<Target> expected) {
private void verifyThatTargetsHasNoTypeAndDSAssignedOrInstalled(final DistributionSet set,
final List<Target> expected) {
final FilterParams filterParams = new FilterParams(null, set.getId(), Boolean.TRUE, null);
assertThat(targetManagement.findByFilters(PAGE, filterParams).getContent()).as("has number of elements")
.hasSize(expected.size()).as("that number is also returned by count query")
@@ -556,11 +532,12 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
private void verifyThat100TargetsContainsGivenTextAndHaveTypeAssigned(final TargetType targetType,
final List<Target> expected) {
final FilterParams filterParams = new FilterParams("%targ-E%", null, Boolean.FALSE, targetType.getId());
List<Target> filteredTargets = targetManagement.findByFilters(PAGE, filterParams).getContent();
final List<Target> filteredTargets = targetManagement.findByFilters(PAGE, filterParams).getContent();
assertThat(filteredTargets).as("has number of elements").hasSize(100)
.as("that number is also returned by count query")
.hasSize(Ints.saturatedCast(targetManagement.countByFilters(filterParams)));
// Comparing the controller ids, as one of the targets was modified, so a 1:1
// Comparing the controller ids, as one of the targets was modified, so
// a 1:1
// comparison of the objects is not possible
assertThat(filteredTargets.stream().map(Target::getControllerId).collect(Collectors.toList()))
.containsAll(expected.stream().map(Target::getControllerId).collect(Collectors.toList()));
@@ -787,19 +764,18 @@ class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verifies that targets with given target type are returned from repository.")
public void findTargetByTargetType() {
TargetType testType = testdataFactory.createTargetType("testType", Collections.singletonList(standardDsType));
List<Target> unassigned = testdataFactory.createTargets(9, "unassigned");
List<Target> assigned = testdataFactory.createTargetsWithType(11, "assigned", testType);
final TargetType testType = testdataFactory.createTargetType("testType",
Collections.singletonList(standardDsType));
final List<Target> unassigned = testdataFactory.createTargets(9, "unassigned");
final List<Target> assigned = testdataFactory.createTargetsWithType(11, "assigned", testType);
assertThat(targetManagement.findByFilters(PAGE,
new FilterParams(null,null, false, testType.getId())))
assertThat(targetManagement.findByFilters(PAGE, new FilterParams(null, null, false, testType.getId())))
.as("Contains the targets with set type").containsAll(assigned)
.as("and that means the following expected amount").hasSize(11);
assertThat(targetManagement.countByFilters(new FilterParams(null,null, false, testType.getId())))
assertThat(targetManagement.countByFilters(new FilterParams(null, null, false, testType.getId())))
.as("Count the targets with set type").isEqualTo(11);
assertThat(targetManagement.findByFilters(PAGE,
new FilterParams(null, null, true, null)))
assertThat(targetManagement.findByFilters(PAGE, new FilterParams(null, null, true, null)))
.as("Contains the targets without a type").containsAll(unassigned)
.as("and that means the following expected amount").hasSize(9);
assertThat(targetManagement.countByFilters(new FilterParams(null, null, true, null)))

View File

@@ -69,6 +69,7 @@ import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import com.google.common.collect.Iterables;
@@ -160,10 +161,9 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
verifyThrownExceptionBy(() -> targetManagement.deleteMetaData(target.getControllerId(), NOT_EXIST_ID),
"TargetMetadata");
verifyThrownExceptionBy(() -> targetManagement.getMetaDataByControllerId(NOT_EXIST_ID, "xxx"), "Target");
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID),
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerId(PAGE, NOT_EXIST_ID), "Target");
verifyThrownExceptionBy(() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"),
"Target");
verifyThrownExceptionBy(
() -> targetManagement.findMetaDataByControllerIdAndRsql(PAGE, NOT_EXIST_ID, "key==*"), "Target");
verifyThrownExceptionBy(
() -> targetManagement.updateMetadata(NOT_EXIST_ID, entityFactory.generateTargetMetadata("xxx", "xxx")),
"Target");
@@ -222,8 +222,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test
@Description("Verify that a target with with invalid properties cannot be created or updated")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
@Expect(type = TargetUpdatedEvent.class) })
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class) })
void createAndUpdateTargetWithInvalidFields() {
final Target target = testdataFactory.createTarget();
@@ -243,8 +242,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.description(RandomStringUtils.randomAlphanumeric(513))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid description should not be created")
.isThrownBy(() -> targetManagement
.as("target with invalid description should not be created").isThrownBy(() -> targetManagement
.create(entityFactory.target().create().controllerId("a").description(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
@@ -253,9 +251,8 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.description(RandomStringUtils.randomAlphanumeric(513))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid description should not be updated")
.isThrownBy(() -> targetManagement
.update(entityFactory.target().update(target.getControllerId()).description(INVALID_TEXT_HTML)));
.as("target with invalid description should not be updated").isThrownBy(() -> targetManagement.update(
entityFactory.target().update(target.getControllerId()).description(INVALID_TEXT_HTML)));
}
@Step
@@ -267,8 +264,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid name should not be created")
.isThrownBy(() -> targetManagement
.as("target with invalid name should not be created").isThrownBy(() -> targetManagement
.create(entityFactory.target().create().controllerId("a").name(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
@@ -277,14 +273,12 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.name(RandomStringUtils.randomAlphanumeric(NamedEntity.NAME_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid name should not be updated")
.isThrownBy(() -> targetManagement
.as("target with invalid name should not be updated").isThrownBy(() -> targetManagement
.update(entityFactory.target().update(target.getControllerId()).name(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with too short name should not be updated")
.isThrownBy(
() -> targetManagement.update(entityFactory.target().update(target.getControllerId()).name("")));
.as("target with too short name should not be updated").isThrownBy(() -> targetManagement
.update(entityFactory.target().update(target.getControllerId()).name("")));
}
@@ -297,8 +291,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid token should not be created")
.isThrownBy(() -> targetManagement
.as("target with invalid token should not be created").isThrownBy(() -> targetManagement
.create(entityFactory.target().create().controllerId("a").securityToken(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
@@ -307,13 +300,11 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.securityToken(RandomStringUtils.randomAlphanumeric(Target.SECURITY_TOKEN_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid token should not be updated")
.isThrownBy(() -> targetManagement.update(
.as("target with invalid token should not be updated").isThrownBy(() -> targetManagement.update(
entityFactory.target().update(target.getControllerId()).securityToken(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with too short token should not be updated")
.isThrownBy(() -> targetManagement
.as("target with too short token should not be updated").isThrownBy(() -> targetManagement
.update(entityFactory.target().update(target.getControllerId()).securityToken("")));
}
@@ -325,8 +316,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a")
.address(RandomStringUtils.randomAlphanumeric(513))));
assertThatExceptionOfType(InvalidTargetAddressException.class)
.as("target with invalid should not be created")
assertThatExceptionOfType(InvalidTargetAddressException.class).as("target with invalid should not be created")
.isThrownBy(() -> targetManagement
.create(entityFactory.target().create().controllerId("a").address(INVALID_TEXT_HTML)));
@@ -336,8 +326,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.address(RandomStringUtils.randomAlphanumeric(513))));
assertThatExceptionOfType(InvalidTargetAddressException.class)
.as("target with invalid address should not be updated")
.isThrownBy(() -> targetManagement
.as("target with invalid address should not be updated").isThrownBy(() -> targetManagement
.update(entityFactory.target().update(target.getControllerId()).address(INVALID_TEXT_HTML)));
}
@@ -357,24 +346,19 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.controllerId(RandomStringUtils.randomAlphanumeric(Target.CONTROLLER_ID_MAX_SIZE + 1))));
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target with invalid controller id should not be created")
.isThrownBy(
.as("target with invalid controller id should not be created").isThrownBy(
() -> targetManagement.create(entityFactory.target().create().controllerId(INVALID_TEXT_HTML)));
assertThatExceptionOfType(ConstraintViolationException.class)
.as(WHITESPACE_ERROR)
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
assertThatExceptionOfType(ConstraintViolationException.class)
.as(WHITESPACE_ERROR)
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("a b")));
assertThatExceptionOfType(ConstraintViolationException.class)
.as(WHITESPACE_ERROR)
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId(" ")));
assertThatExceptionOfType(ConstraintViolationException.class)
.as(WHITESPACE_ERROR)
assertThatExceptionOfType(ConstraintViolationException.class).as(WHITESPACE_ERROR)
.isThrownBy(() -> targetManagement.create(entityFactory.target().create().controllerId("aaa bbb")));
}
@@ -402,7 +386,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
assignedTargets.forEach(target -> assertThat(
targetTagManagement.findByTarget(PAGE, target.getControllerId()).getNumberOfElements()).isEqualTo(1));
TargetTag findTargetTag = targetTagManagement.getByName("Tag1").orElseThrow(IllegalStateException::new);
final TargetTag findTargetTag = targetTagManagement.getByName("Tag1").orElseThrow(IllegalStateException::new);
assertThat(assignedTargets.size()).as("Assigned targets are wrong")
.isEqualTo(targetManagement.findByTag(PAGE, targetTag.getId()).getNumberOfElements());
@@ -473,20 +457,15 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet testDs2 = testdataFactory.createDistributionSet("test2");
assertThat(targetManagement.countByAssignedDistributionSet(testDs1.getId()))
.as("For newly created distributions sets the assigned target count should be zero")
.isZero();
.as("For newly created distributions sets the assigned target count should be zero").isZero();
assertThat(targetManagement.countByInstalledDistributionSet(testDs1.getId()))
.as("For newly created distributions sets the installed target count should be zero")
.isZero();
.as("For newly created distributions sets the installed target count should be zero").isZero();
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId()))
.as("Exists assigned or installed query should return false for new distribution sets")
.isFalse();
.as("Exists assigned or installed query should return false for new distribution sets").isFalse();
assertThat(targetManagement.countByAssignedDistributionSet(testDs2.getId()))
.as("For newly created distributions sets the assigned target count should be zero")
.isZero();
.as("For newly created distributions sets the assigned target count should be zero").isZero();
assertThat(targetManagement.countByInstalledDistributionSet(testDs2.getId()))
.as("For newly created distributions sets the installed target count should be zero")
.isZero();
.as("For newly created distributions sets the installed target count should be zero").isZero();
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs2.getId()))
.as("For newly created distributions sets the assigned target count should be zero").isFalse();
@@ -508,8 +487,8 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.isZero();
assertThat(targetManagement.countByInstalledDistributionSet(testDs1.getId())).as("Target count is wrong")
.isEqualTo(1);
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId())).as("Target count is wrong")
.isTrue();
assertThat(targetManagement.existsByInstalledOrAssignedDistributionSet(testDs1.getId()))
.as("Target count is wrong").isTrue();
assertThat(targetManagement.countByAssignedDistributionSet(testDs2.getId())).as("Target count is wrong")
.isEqualTo(1);
assertThat(targetManagement.countByInstalledDistributionSet(testDs2.getId())).as("Target count is wrong")
@@ -520,14 +499,11 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet assignedDs = deploymentManagement.getAssignedDistributionSet("4711")
.orElseThrow(NoSuchElementException::new);
assertThat(assignedDs).as("Assigned ds size is wrong")
.isEqualTo(testDs2);
assertThat(assignedDs).as("Assigned ds size is wrong").isEqualTo(testDs2);
final DistributionSet installedDs = deploymentManagement.getInstalledDistributionSet("4711")
.orElseThrow(NoSuchElementException::new);
assertThat(installedDs)
.as("Installed ds is wrong")
.isEqualTo(testDs1);
assertThat(installedDs).as("Installed ds is wrong").isEqualTo(testDs1);
}
@Test
@@ -556,14 +532,14 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
}
/**
* verifies, that all {@link TargetTag} of parameter. NOTE: it's accepted that
* the target have additional tags assigned to them which are not contained
* within parameter tags.
* verifies, that all {@link TargetTag} of parameter. NOTE: it's accepted
* that the target have additional tags assigned to them which are not
* contained within parameter tags.
*
* @param strict
* if true, the given targets MUST contain EXACTLY ALL given tags,
* AND NO OTHERS. If false, the given targets MUST contain ALL given
* tags, BUT MAY CONTAIN FURTHER ONE
* if true, the given targets MUST contain EXACTLY ALL given
* tags, AND NO OTHERS. If false, the given targets MUST contain
* ALL given tags, BUT MAY CONTAIN FURTHER ONE
* @param targets
* targets to be verified
* @param tags
@@ -615,7 +591,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
assertThat(createdAt).as("CreatedAt compared with modifiedAt").isEqualTo(modifiedAt);
Awaitility.await().until( () -> System.currentTimeMillis() > createdAt + 1);
Awaitility.await().until(() -> System.currentTimeMillis() > createdAt + 1);
savedTarget = targetManagement.update(
entityFactory.target().update(savedTarget.getControllerId()).description("changed description"));
@@ -625,7 +601,8 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.isNotEqualTo(savedTarget.getLastModifiedAt());
modifiedAt = savedTarget.getLastModifiedAt();
final Target foundTarget = targetManagement.getByControllerID(savedTarget.getControllerId()).orElseThrow(IllegalStateException::new);
final Target foundTarget = targetManagement.getByControllerID(savedTarget.getControllerId())
.orElseThrow(IllegalStateException::new);
assertThat(foundTarget).as("The target should not be null").isNotNull();
assertThat(myCtrlID).as("ControllerId compared with saved controllerId")
.isEqualTo(foundTarget.getControllerId());
@@ -718,13 +695,15 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
final List<TargetTag> t2Tags = testdataFactory.createTargetTags(noT2Tags, "tag2");
t2Tags.forEach(tag -> targetManagement.assignTag(Collections.singletonList(t2.getControllerId()), tag.getId()));
final Target t11 = targetManagement.getByControllerID(t1.getControllerId()).orElseThrow(IllegalStateException::new);
final Target t11 = targetManagement.getByControllerID(t1.getControllerId())
.orElseThrow(IllegalStateException::new);
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
.hasSize(noT1Tags).containsAll(t1Tags);
assertThat(targetTagManagement.findByTarget(PAGE, t11.getControllerId()).getContent()).as("Tag size is wrong")
.hasSize(noT1Tags).doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
final Target t21 = targetManagement.getByControllerID(t2.getControllerId()).orElseThrow(IllegalStateException::new);
final Target t21 = targetManagement.getByControllerID(t2.getControllerId())
.orElseThrow(IllegalStateException::new);
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
.hasSize(noT2Tags).containsAll(t2Tags);
assertThat(targetTagManagement.findByTarget(PAGE, t21.getControllerId()).getContent()).as("Tag size is wrong")
@@ -909,10 +888,12 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
testdataFactory.createTargets(25, "target-id-B", "first description");
final Page<Target> foundTargets = targetManagement.findByRsql(PAGE, rsqlFilter);
final Slice<Target> foundTargets = targetManagement.findByRsql(PAGE, rsqlFilter);
final long foundTargetsCount = targetManagement.countByRsql(rsqlFilter);
assertThat(targetManagement.count()).as("Total targets").isEqualTo(50L);
assertThat(foundTargets.getTotalElements()).as("Targets in RSQL filter").isEqualTo(27L);
assertThat(foundTargets.getNumberOfElements()).as("Targets in RSQL filter").isEqualTo(foundTargetsCount)
.isEqualTo(27L);
}
@Test
@@ -1033,11 +1014,12 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
// create target meta data entry
insertTargetMetadata(knownKey, knownValue, target);
Target changedLockRevisionTarget = targetManagement.get(target.getId()).orElseThrow(NoSuchElementException::new);
Target changedLockRevisionTarget = targetManagement.get(target.getId())
.orElseThrow(NoSuchElementException::new);
assertThat(changedLockRevisionTarget.getOptLockRevision()).isEqualTo(2);
// Unsure if needed maybe to wait for a db flush?
// Thread.sleep(100);
// Thread.sleep(100);
// update the target metadata
final JpaTargetMetadata updated = (JpaTargetMetadata) targetManagement.updateMetadata(target.getControllerId(),
@@ -1117,7 +1099,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
assertThat(targetFound1.get().getOptLockRevision()).isEqualTo(2);
assertThat(targetFound1.get().getTargetType().getId()).isEqualTo(targetType.getId());
}
@Test
@WithUser(allSpPermissions = true)
@Description("Tests the assignment of types to multiple targets.")
@@ -1150,7 +1132,8 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
checkTargetsHaveType(typeATargets, typeA);
checkTargetsHaveType(typeBTargets, typeB);
// verify that type assignment does not throw an error if target list includes an unknown id
// verify that type assignment does not throw an error if target list
// includes an unknown id
targetManagement.deleteByControllerID(typeATargets.get(0).getControllerId());
final TargetTypeAssignmentResult resultC = initiateTypeAssignment(typeATargets, typeB);
assertThat(resultC.getAssigned()).isEqualTo(9);
@@ -1159,7 +1142,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
}
private void checkTargetsHaveType(final List<Target> targets, final TargetType type) {
List<JpaTarget> foundTargets = targetRepository
final List<JpaTarget> foundTargets = targetRepository
.findAllById(targets.stream().map(Identifiable::getId).collect(Collectors.toList()));
for (final Target target : foundTargets) {
if (!type.getName().equals(type.getName())) {
@@ -1167,7 +1150,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
}
}
}
@Test
@Description("Queries and loads the metadata related to a given target.")
void findAllTargetMetadataByControllerId() {
@@ -1205,14 +1188,13 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
// create a target
final Target target = testdataFactory.createTarget("target1", "testtarget");
// initial opt lock revision must be one
Optional<JpaTarget> targetFound = targetRepository.findById(target.getId());
final Optional<JpaTarget> targetFound = targetRepository.findById(target.getId());
assertThat(targetFound).isPresent();
assertThat(targetFound.get().getOptLockRevision()).isEqualTo(1);
assertThat(targetFound.get().getTargetType()).isNull();
// assign target type to target
assertThatExceptionOfType(ConstraintViolationException.class)
.as("target type with id=null cannot be assigned")
assertThatExceptionOfType(ConstraintViolationException.class).as("target type with id=null cannot be assigned")
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), null));
assertThatExceptionOfType(EntityNotFoundException.class)
@@ -1220,7 +1202,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
.isThrownBy(() -> targetManagement.assignType(targetFound.get().getControllerId(), 114L));
// opt lock revision is not changed
Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
final Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
assertThat(targetFound1).isPresent();
assertThat(targetFound1.get().getOptLockRevision()).isEqualTo(1);
}
@@ -1230,12 +1212,12 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
@Description("Checks that target type can be unassigned from target.")
void unAssignTargetTypeFromTarget() {
// create a target type
TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
final TargetType targetType = testdataFactory.findOrCreateTargetType("targettype");
assertThat(targetType).isNotNull();
// create a target
final Target target = testdataFactory.createTarget("target1", "testtarget", targetType.getId());
// initial opt lock revision must be one
Optional<JpaTarget> targetFound = targetRepository.findById(target.getId());
final Optional<JpaTarget> targetFound = targetRepository.findById(target.getId());
assertThat(targetFound).isPresent();
assertThat(targetFound.get().getOptLockRevision()).isEqualTo(1);
assertThat(targetFound.get().getTargetType().getName()).isEqualTo(targetType.getName());
@@ -1244,7 +1226,7 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
targetManagement.unAssignType(targetFound.get().getControllerId());
// opt lock revision must be changed
Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
final Optional<JpaTarget> targetFound1 = targetRepository.findById(target.getId());
assertThat(targetFound1).isPresent();
assertThat(targetFound1.get().getOptLockRevision()).isEqualTo(2);
assertThat(targetFound1.get().getTargetType()).isNull();
@@ -1275,9 +1257,11 @@ class TargetManagementTest extends AbstractJpaIntegrationTest {
}
private void validateFoundTargetsByRsql(final String rsqlFilter, final String... controllerIds) {
final Page<Target> foundTargetsByMetadataAndControllerId = targetManagement.findByRsql(PAGE, rsqlFilter);
final Slice<Target> foundTargetsByMetadataAndControllerId = targetManagement.findByRsql(PAGE, rsqlFilter);
final long foundTargetsByMetadataAndControllerIdCount = targetManagement.countByRsql(rsqlFilter);
assertThat(foundTargetsByMetadataAndControllerId.getTotalElements()).as("Targets count in RSQL filter is wrong")
assertThat(foundTargetsByMetadataAndControllerId.getNumberOfElements())
.as("Targets count in RSQL filter is wrong").isEqualTo(foundTargetsByMetadataAndControllerIdCount)
.isEqualTo(controllerIds.length);
assertThat(foundTargetsByMetadataAndControllerId.getContent().stream().map(Target::getControllerId))
.as("Targets found by RSQL filter have wrong controller ids").containsExactlyInAnyOrder(controllerIds);

View File

@@ -28,7 +28,7 @@ import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
@@ -88,8 +88,10 @@ class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
assignDistributionSet(ds.getId(), target.getControllerId());
targetType1 = targetTypeManagement.create(entityFactory.targetType().create().name("Type1").description("Desc. Type1"));
targetType2 = targetTypeManagement.create(entityFactory.targetType().create().name("Type2").description("Desc. Type2"));
targetType1 = targetTypeManagement
.create(entityFactory.targetType().create().name("Type1").description("Desc. Type1"));
targetType2 = targetTypeManagement
.create(entityFactory.targetType().create().name("Type2").description("Desc. Type2"));
targetManagement.assignType(target.getControllerId(), targetType1.getId());
targetManagement.assignType(target2.getControllerId(), targetType2.getId());
@@ -317,10 +319,10 @@ class RSQLTargetFieldTest extends AbstractJpaIntegrationTest {
}
private void assertRSQLQuery(final String rsqlParam, final long expectedTargets) {
final Page<Target> findTargetPage = targetManagement.findByRsql(PAGE, rsqlParam);
final long countTargetsAll = findTargetPage.getTotalElements();
final Slice<Target> findTargetPage = targetManagement.findByRsql(PAGE, rsqlParam);
final long countTargetsAll = targetManagement.countByRsql(rsqlParam);
assertThat(findTargetPage).isNotNull();
assertThat(countTargetsAll).isEqualTo(expectedTargets);
assertThat(findTargetPage.getNumberOfElements()).isEqualTo(countTargetsAll).isEqualTo(expectedTargets);
}
private void assertRSQLQueryThrowsException(final String rsqlParam) {

View File

@@ -22,7 +22,6 @@ import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
import org.eclipse.hawkbit.repository.test.util.WithUser;
import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import io.qameta.allure.Description;
@@ -155,11 +154,11 @@ public class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
createDistributionSetForTenant(anotherTenant);
// ensure both tenants see their distribution sets
final Page<DistributionSet> findDistributionSetsForTenant = findDistributionSetForTenant(tenant);
final Slice<DistributionSet> findDistributionSetsForTenant = findDistributionSetForTenant(tenant);
assertThat(findDistributionSetsForTenant).hasSize(1);
assertThat(findDistributionSetsForTenant.getContent().get(0).getTenant().toUpperCase())
.isEqualTo(tenant.toUpperCase());
final Page<DistributionSet> findDistributionSetsForAnotherTenant = findDistributionSetForTenant(anotherTenant);
final Slice<DistributionSet> findDistributionSetsForAnotherTenant = findDistributionSetForTenant(anotherTenant);
assertThat(findDistributionSetsForAnotherTenant).hasSize(1);
assertThat(findDistributionSetsForAnotherTenant.getContent().get(0).getTenant().toUpperCase())
.isEqualTo(anotherTenant.toUpperCase());
@@ -188,7 +187,7 @@ public class MultiTenancyEntityTest extends AbstractJpaIntegrationTest {
return runAsTenant(tenant, () -> testdataFactory.createDistributionSet());
}
private Page<DistributionSet> findDistributionSetForTenant(final String tenant) throws Exception {
private Slice<DistributionSet> findDistributionSetForTenant(final String tenant) throws Exception {
return runAsTenant(tenant, () -> distributionSetManagement.findByCompleted(PAGE, true));
}
}

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.ValidationException;
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
@@ -83,15 +84,15 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Page<Rollout> findModulesAll;
final Page<Rollout> findRolloutsAll;
if (rsqlParam != null) {
findModulesAll = this.rolloutManagement.findByRsql(pageable, rsqlParam, false);
findRolloutsAll = this.rolloutManagement.findByRsql(pageable, rsqlParam, false);
} else {
findModulesAll = this.rolloutManagement.findAll(pageable, false);
findRolloutsAll = this.rolloutManagement.findAll(pageable, false);
}
final List<MgmtRolloutResponseBody> rest = MgmtRolloutMapper.toResponseRollout(findModulesAll.getContent());
return ResponseEntity.ok(new PagedList<>(rest, findModulesAll.getTotalElements()));
final List<MgmtRolloutResponseBody> rest = MgmtRolloutMapper.toResponseRollout(findRolloutsAll.getContent());
return ResponseEntity.ok(new PagedList<>(rest, findRolloutsAll.getTotalElements()));
}
@Override
@@ -114,16 +115,15 @@ public class MgmtRolloutResource implements MgmtRolloutRestApi {
throw new RSQLParameterSyntaxException("Cannot create a Rollout with an empty target query filter!");
}
targetFilterQueryManagement.verifyTargetFilterQuerySyntax(targetFilterQuery);
final DistributionSet distributionSet = distributionSetManagement.getValidAndComplete(
rolloutRequestBody.getDistributionSetId());
final DistributionSet distributionSet = distributionSetManagement
.getValidAndComplete(rolloutRequestBody.getDistributionSetId());
final RolloutGroupConditions rolloutGroupConditions = MgmtRolloutMapper.fromRequest(rolloutRequestBody, true);
final RolloutCreate create = MgmtRolloutMapper.fromRequest(entityFactory, rolloutRequestBody, distributionSet);
Rollout rollout;
if (rolloutRequestBody.getGroups() != null) {
final List<RolloutGroupCreate> rolloutGroups = rolloutRequestBody.getGroups()
.stream()
final List<RolloutGroupCreate> rolloutGroups = rolloutRequestBody.getGroups().stream()
.map(mgmtRolloutGroup -> MgmtRolloutMapper.fromRequest(entityFactory, mgmtRolloutGroup))
.collect(Collectors.toList());
rollout = rolloutManagement.create(create, rolloutGroups, rolloutGroupConditions);

View File

@@ -106,12 +106,11 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
final Slice<Target> findTargetsAll;
final long countTargetsAll;
if (rsqlParam != null) {
final Page<Target> findTargetPage = this.targetManagement.findByRsql(pageable, rsqlParam);
countTargetsAll = findTargetPage.getTotalElements();
findTargetsAll = findTargetPage;
findTargetsAll = targetManagement.findByRsql(pageable, rsqlParam);
countTargetsAll = targetManagement.countByRsql(rsqlParam);
} else {
findTargetsAll = this.targetManagement.findAll(pageable);
countTargetsAll = this.targetManagement.count();
findTargetsAll = targetManagement.findAll(pageable);
countTargetsAll = targetManagement.count();
}
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(findTargetsAll.getContent());
@@ -165,7 +164,8 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
}
@Override
public ResponseEntity<Void> assignTargetType(@PathVariable("targetId") final String targetId, @RequestBody final MgmtId targetTypeId) {
public ResponseEntity<Void> assignTargetType(@PathVariable("targetId") final String targetId,
@RequestBody final MgmtId targetTypeId) {
this.targetManagement.assignType(targetId, targetTypeId.getId());
return ResponseEntity.ok().build();
}
@@ -304,8 +304,8 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
final List<Entry<String, Long>> offlineAssignments = dsAssignments.stream()
.map(dsAssignment -> new SimpleEntry<String, Long>(targetId, dsAssignment.getId()))
.collect(Collectors.toList());
return ResponseEntity.ok(MgmtDistributionSetMapper.toResponse(
deploymentManagement.offlineAssignedDistributionSets(offlineAssignments)));
return ResponseEntity.ok(MgmtDistributionSetMapper
.toResponse(deploymentManagement.offlineAssignedDistributionSets(offlineAssignments)));
}
findTargetWithExceptionIfNotFound(targetId);

View File

@@ -150,18 +150,15 @@ public class MgmtTargetTagResource implements MgmtTargetTagRestApi {
final Sort sorting = PagingUtility.sanitizeTargetSortParam(sortParam);
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
Page<Target> findTargetsAll;
final Page<Target> findTargetsAll;
if (rsqlParam == null) {
findTargetsAll = targetManagement.findByTag(pageable, targetTagId);
} else {
findTargetsAll = targetManagement.findByRsqlAndTag(pageable, rsqlParam, targetTagId);
}
final Long countTargetsAll = findTargetsAll.getTotalElements();
final List<MgmtTarget> rest = MgmtTargetMapper.toResponse(findTargetsAll.getContent());
return ResponseEntity.ok(new PagedList<>(rest, countTargetsAll));
return ResponseEntity.ok(new PagedList<>(rest, findTargetsAll.getTotalElements()));
}
@Override

View File

@@ -19,7 +19,6 @@ import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetTypeRequestBodyP
import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetTypeRequestBodyPut;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.TargetTypeManagement;
@@ -48,7 +47,7 @@ public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi {
private final TargetTypeManagement targetTypeManagement;
private final EntityFactory entityFactory;
public MgmtTargetTypeResource(TargetTypeManagement targetTypeManagement, final EntityFactory entityFactory) {
public MgmtTargetTypeResource(final TargetTypeManagement targetTypeManagement, final EntityFactory entityFactory) {
this.targetTypeManagement = targetTypeManagement;
this.entityFactory = entityFactory;
}
@@ -65,14 +64,15 @@ public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi {
final Sort sorting = PagingUtility.sanitizeTargetTypeSortParam(sortParam);
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Page<TargetType> findTargetTypesAll;
final Slice<TargetType> findTargetTypesAll;
long countTargetTypesAll;
if (rsqlParam != null) {
findTargetTypesAll= targetTypeManagement.findByRsql(pageable, rsqlParam);
findTargetTypesAll = targetTypeManagement.findByRsql(pageable, rsqlParam);
countTargetTypesAll = ((Page<TargetType>) findTargetTypesAll).getTotalElements();
} else {
findTargetTypesAll = targetTypeManagement.findAll(pageable);
countTargetTypesAll = targetTypeManagement.count();
}
countTargetTypesAll = findTargetTypesAll.getTotalElements();
final List<MgmtTargetType> rest = MgmtTargetTypeMapper.toListResponse(findTargetTypesAll.getContent());
return ResponseEntity.ok(new PagedList<>(rest, countTargetTypesAll));
@@ -135,8 +135,8 @@ public class MgmtTargetTypeResource implements MgmtTargetTypeRestApi {
public ResponseEntity<Void> addCompatibleDistributionSets(@PathVariable("targetTypeId") final Long targetTypeId,
@RequestBody final List<MgmtDistributionSetTypeAssignment> distributionSetTypeIds) {
targetTypeManagement.assignCompatibleDistributionSetTypes(targetTypeId,
distributionSetTypeIds.stream().map(MgmtDistributionSetTypeAssignment::getId).collect(Collectors.toList()));
targetTypeManagement.assignCompatibleDistributionSetTypes(targetTypeId, distributionSetTypeIds.stream()
.map(MgmtDistributionSetTypeAssignment::getId).collect(Collectors.toList()));
return ResponseEntity.ok().build();
}

View File

@@ -12,7 +12,6 @@ import java.io.Serializable;
import java.util.Objects;
import org.eclipse.hawkbit.ui.common.data.providers.DistributionSetManagementStateDataProvider;
import org.springframework.util.StringUtils;
import com.google.common.base.MoreObjects;
@@ -65,7 +64,7 @@ public class DsFilterParams implements Serializable {
* String
*/
public void setSearchText(final String searchText) {
this.searchText = !StringUtils.isEmpty(searchText) ? String.format("%%%s%%", searchText) : null;
this.searchText = searchText;
}
@Override

View File

@@ -12,7 +12,6 @@ import java.io.Serializable;
import java.util.Objects;
import org.eclipse.hawkbit.ui.common.data.providers.SoftwareModuleDataProvider;
import org.springframework.util.StringUtils;
import com.google.common.base.MoreObjects;
@@ -78,7 +77,7 @@ public class SwFilterParams implements Serializable {
* String
*/
public void setSearchText(final String searchText) {
this.searchText = !StringUtils.isEmpty(searchText) ? String.format("%%%s%%", searchText) : null;
this.searchText = searchText;
}
/**

View File

@@ -17,8 +17,8 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyAdvancedRolloutGroup;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetFilterQueryInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.util.StringUtils;
/**
@@ -55,9 +55,9 @@ public class RolloutGroupToAdvancedDefinitionMapper {
final String groupTargetFilterQuery = rolloutGroup.getTargetFilterQuery();
if (!StringUtils.isEmpty(groupTargetFilterQuery)) {
advancedGroupRow.setTargetFilterQuery(groupTargetFilterQuery);
final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement.findByQuery(PageRequest.of(0, 1),
final Slice<TargetFilterQuery> filterQueries = targetFilterQueryManagement.findByQuery(PageRequest.of(0, 1),
groupTargetFilterQuery);
if (filterQueries.getTotalElements() == 1) {
if (filterQueries.getNumberOfElements() == 1) {
final TargetFilterQuery tfq = filterQueries.getContent().get(0);
advancedGroupRow.setTargetFilterQueryInfo(
new ProxyTargetFilterQueryInfo(tfq.getId(), tfq.getName(), tfq.getQuery()));

View File

@@ -26,8 +26,7 @@ public class RolloutToProxyRolloutMapper extends AbstractNamedEntityToProxyNamed
mapNamedEntityAttributes(rollout, proxyRollout);
final DistributionSet ds = rollout.getDistributionSet();
proxyRollout.setDsInfo(new ProxyDistributionSetInfo(ds.getId(), ds.getName(), ds.getVersion(),
ds.getType().getId(), ds.isValid()));
proxyRollout.setDsInfo(new ProxyDistributionSetInfo(ds.getId(), ds.getName(), ds.getVersion(), ds.isValid()));
proxyRollout
.setNumberOfGroups(rollout.getRolloutGroupsCreated() > 0 ? rollout.getRolloutGroupsCreated() : null);
proxyRollout.setForcedTime(rollout.getForcedTime() > 0 ? rollout.getForcedTime() : null);

View File

@@ -38,8 +38,7 @@ public class TargetFilterQueryToProxyTargetFilterMapper
if (distributionSet != null) {
proxyTargetFilter.setAutoAssignmentEnabled(true);
proxyTargetFilter.setDistributionSetInfo(new ProxyDistributionSetInfo(distributionSet.getId(),
distributionSet.getName(), distributionSet.getVersion(), distributionSet.getType().getId(),
distributionSet.isValid()));
distributionSet.getName(), distributionSet.getVersion(), distributionSet.isValid()));
proxyTargetFilter.setAutoAssignActionType(targetFilterQuery.getAutoAssignActionType());
}

View File

@@ -61,6 +61,6 @@ public class ActionStatusDataProvider extends AbstractProxyDataProvider<ProxyAct
return 0L;
}
return loadBackendEntities(PageRequest.of(0, 1), actionId).getTotalElements();
return deploymentManagement.countActionStatusByAction(actionId);
}
}

View File

@@ -105,6 +105,6 @@ public class ActionStatusMsgDataProvider extends AbstractGenericDataProvider<Pro
return 0L;
}
return loadBackendEntities(PageRequest.of(0, 1), actionStatusId).getTotalElements();
return deploymentManagement.countMessagesByActionStatusId(actionStatusId);
}
}

View File

@@ -59,6 +59,6 @@ public class ArtifactDataProvider extends AbstractProxyDataProvider<ProxyArtifac
return 0L;
}
return loadBackendEntities(PageRequest.of(0, 1), smId).getTotalElements();
return artifactManagement.countBySoftwareModule(smId);
}
}

View File

@@ -9,15 +9,14 @@
package org.eclipse.hawkbit.ui.common.data.providers;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.ui.common.data.filters.DsDistributionsFilterParams;
import org.eclipse.hawkbit.ui.common.data.mappers.DistributionSetToProxyDistributionMapper;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
/**
* Data provider for {@link DistributionSet}, which dynamically loads a batch of
@@ -30,44 +29,40 @@ public class DistributionSetDistributionsStateDataProvider
private static final long serialVersionUID = 1L;
private final transient DistributionSetManagement distributionSetManagement;
private final transient DistributionSetTypeManagement distributionSetTypeManagement;
/**
* Constructor for DistributionSetDistributionsStateDataProvider
*
* @param distributionSetManagement
* DistributionSetManagement
* @param distributionSetTypeManagement
* DistributionSetTypeManagement
* @param entityMapper
* DistributionSetToProxyDistributionMapper
*/
public DistributionSetDistributionsStateDataProvider(final DistributionSetManagement distributionSetManagement,
final DistributionSetTypeManagement distributionSetTypeManagement,
final DistributionSetToProxyDistributionMapper entityMapper) {
super(entityMapper);
this.distributionSetManagement = distributionSetManagement;
this.distributionSetTypeManagement = distributionSetTypeManagement;
}
@Override
protected Page<DistributionSet> loadBackendEntities(final PageRequest pageRequest,
protected Slice<DistributionSet> loadBackendEntities(final PageRequest pageRequest,
final DsDistributionsFilterParams filter) {
return distributionSetManagement.findByDistributionSetFilter(pageRequest, buildDsFilter(filter));
}
private DistributionSetFilter buildDsFilter(final DsDistributionsFilterParams filter) {
final DistributionSetFilterBuilder builder = new DistributionSetFilterBuilder().setIsDeleted(false);
if (filter != null) {
final DistributionSetType type = filter.getDsTypeId() == null ? null
: distributionSetTypeManagement.get(filter.getDsTypeId()).orElse(null);
builder.setSearchText(filter.getSearchText()).setSelectDSWithNoTag(false).setType(type);
builder.setSearchText(filter.getSearchText()).setSelectDSWithNoTag(false).setTypeId(filter.getDsTypeId());
}
return distributionSetManagement.findByDistributionSetFilter(pageRequest, builder.build());
return builder.build();
}
@Override
protected long sizeInBackEnd(final PageRequest pageRequest, final DsDistributionsFilterParams filter) {
return loadBackendEntities(PageRequest.of(0, 1), filter).getTotalElements();
return distributionSetManagement.countByDistributionSetFilter(buildDsFilter(filter));
}
}

View File

@@ -10,12 +10,13 @@ package org.eclipse.hawkbit.ui.common.data.providers;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.ui.common.data.filters.DsManagementFilterParams;
import org.eclipse.hawkbit.ui.common.data.mappers.DistributionSetToProxyDistributionMapper;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.util.StringUtils;
/**
@@ -46,28 +47,34 @@ public class DistributionSetManagementStateDataProvider
}
@Override
protected Page<DistributionSet> loadBackendEntities(final PageRequest pageRequest,
protected Slice<DistributionSet> loadBackendEntities(final PageRequest pageRequest,
final DsManagementFilterParams filter) {
if (filter == null) {
return distributionSetManagement.findByCompleted(pageRequest, true);
}
final String pinnedControllerId = filter.getPinnedTargetControllerId();
final DistributionSetFilterBuilder builder = new DistributionSetFilterBuilder().setIsDeleted(false)
.setIsComplete(true).setSearchText(filter.getSearchText()).setSelectDSWithNoTag(filter.isNoTagClicked())
.setTagNames(filter.getDistributionSetTags());
if (!StringUtils.isEmpty(pinnedControllerId)) {
return distributionSetManagement.findByFilterAndAssignedInstalledDsOrderedByLinkTarget(pageRequest, builder,
pinnedControllerId);
return distributionSetManagement.findByDistributionSetFilterOrderByLinkedTarget(pageRequest,
buildDsFilter(filter), pinnedControllerId);
}
return distributionSetManagement.findByDistributionSetFilter(pageRequest, builder.build());
return distributionSetManagement.findByDistributionSetFilter(pageRequest, buildDsFilter(filter));
}
private DistributionSetFilter buildDsFilter(final DsManagementFilterParams filter) {
return new DistributionSetFilterBuilder().setIsDeleted(false).setIsComplete(true)
.setSearchText(filter.getSearchText()).setSelectDSWithNoTag(filter.isNoTagClicked())
.setTagNames(filter.getDistributionSetTags()).build();
}
@Override
protected long sizeInBackEnd(final PageRequest pageRequest, final DsManagementFilterParams filter) {
return loadBackendEntities(PageRequest.of(0, 1), filter).getTotalElements();
if (filter == null) {
return distributionSetManagement.countByCompleted(true);
}
return distributionSetManagement.countByDistributionSetFilter(buildDsFilter(filter));
}
}

View File

@@ -10,11 +10,12 @@ package org.eclipse.hawkbit.ui.common.data.providers;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
import org.eclipse.hawkbit.ui.common.data.mappers.DistributionSetToProxyDistributionMapper;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.util.StringUtils;
@@ -47,19 +48,22 @@ public class DistributionSetStatelessDataProvider
}
@Override
protected Page<DistributionSet> loadBackendEntities(final PageRequest pageRequest, final String filter) {
final DistributionSetFilterBuilder builder = new DistributionSetFilterBuilder().setIsDeleted(false)
.setIsComplete(true).setIsValid(true);
protected Slice<DistributionSet> loadBackendEntities(final PageRequest pageRequest, final String filter) {
return distributionSetManagement.findByDistributionSetFilter(pageRequest, buildDsFilter(filter));
}
private DistributionSetFilter buildDsFilter(final String filter) {
final DistributionSetFilterBuilder dsFilterBuilder = new DistributionSetFilterBuilder().setIsDeleted(false)
.setIsComplete(true).setIsValid(true);
if (!StringUtils.isEmpty(filter)) {
builder.setFilterString(filter);
dsFilterBuilder.setSearchText(filter);
}
return distributionSetManagement.findByDistributionSetFilter(pageRequest, builder.build());
return dsFilterBuilder.build();
}
@Override
protected long sizeInBackEnd(final PageRequest pageRequest, final String filter) {
return loadBackendEntities(PageRequest.of(0, 1), filter).getTotalElements();
return distributionSetManagement.countByDistributionSetFilter(buildDsFilter(filter));
}
}

View File

@@ -51,6 +51,6 @@ public class DsMetaDataDataProvider extends AbstractMetaDataDataProvider<Distrib
return 0L;
}
return loadBackendEntities(PageRequest.of(0, 1), dsId).getTotalElements();
return distributionSetManagement.countMetaDataByDistributionSetId(dsId);
}
}

View File

@@ -59,6 +59,6 @@ public class SmMetaDataDataProvider extends AbstractMetaDataDataProvider<Softwar
return 0L;
}
return loadBackendEntities(PageRequest.of(0, 1), smId).getTotalElements();
return softwareModuleManagement.countMetaDataBySoftwareModuleId(smId);
}
}

View File

@@ -59,6 +59,6 @@ public class TargetFilterQueryDataProvider
return targetFilterQueryManagement.count();
}
return targetFilterQueryManagement.findByName(PageRequest.of(0, 1), filter).getTotalElements();
return targetFilterQueryManagement.countByName(filter);
}
}

View File

@@ -14,6 +14,7 @@ import org.eclipse.hawkbit.ui.common.data.mappers.TargetFilterQueryToProxyTarget
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetFilterQuery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
@@ -44,12 +45,12 @@ public class TargetFilterQueryDetailsDataProvider
}
@Override
protected Page<TargetFilterQuery> loadBackendEntities(final PageRequest pageRequest, final Long dsId) {
protected Slice<TargetFilterQuery> loadBackendEntities(final PageRequest pageRequest, final Long dsId) {
if (dsId == null) {
return Page.empty(pageRequest);
}
return targetFilterQueryManagement.findByAutoAssignDSAndRsql(pageRequest, dsId, null);
return targetFilterQueryManagement.findByAutoAssignDistributionSetId(pageRequest, dsId);
}
@Override
@@ -58,6 +59,6 @@ public class TargetFilterQueryDetailsDataProvider
return 0L;
}
return loadBackendEntities(PageRequest.of(0, 1), dsId).getTotalElements();
return targetFilterQueryManagement.countByAutoAssignDistributionSetId(dsId);
}
}

View File

@@ -52,7 +52,6 @@ public class TargetMetaDataDataProvider extends AbstractMetaDataDataProvider<Tar
return 0L;
}
return targetManagement.findMetaDataByControllerId(PageRequest.of(0, 1), currentlySelectedControllerId)
.getTotalElements();
return targetManagement.countMetaDataByControllerId(currentlySelectedControllerId);
}
}

View File

@@ -49,7 +49,7 @@ public class TargetTagDataProvider extends AbstractProxyDataProvider<ProxyTag, T
@Override
protected long sizeInBackEnd(final PageRequest pageRequest, final Void filter) {
return loadBackendEntities(PageRequest.of(0, 1), filter).getTotalElements();
return tagManagementService.count();
}
}

View File

@@ -12,8 +12,8 @@ import org.eclipse.hawkbit.repository.TargetTypeManagement;
import org.eclipse.hawkbit.repository.model.TargetType;
import org.eclipse.hawkbit.ui.common.data.mappers.IdentifiableEntityToProxyIdentifiableEntityMapper;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyIdentifiableEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.util.StringUtils;
@@ -35,26 +35,32 @@ public class TargetTypeDataProvider<T extends ProxyIdentifiableEntity>
* Constructor
*
* @param targetTypeManagement
* TargetTypeManagement
* TargetTypeManagement
* @param mapper
* Mapper
* Mapper
*/
public TargetTypeDataProvider(final TargetTypeManagement targetTypeManagement, IdentifiableEntityToProxyIdentifiableEntityMapper<T, TargetType> mapper) {
public TargetTypeDataProvider(final TargetTypeManagement targetTypeManagement,
final IdentifiableEntityToProxyIdentifiableEntityMapper<T, TargetType> mapper) {
super(mapper, Sort.by(Direction.ASC, "name"));
this.targetTypeManagement = targetTypeManagement;
}
@Override
protected Page<TargetType> loadBackendEntities(PageRequest pageRequest, String filter) {
if (!StringUtils.isEmpty(filter)){
return targetTypeManagement.findByName(pageRequest, filter);
protected Slice<TargetType> loadBackendEntities(final PageRequest pageRequest, final String filter) {
if (StringUtils.isEmpty(filter)) {
return targetTypeManagement.findAll(pageRequest);
}
return targetTypeManagement.findAll(pageRequest);
return targetTypeManagement.findByName(pageRequest, filter);
}
@Override
protected long sizeInBackEnd(PageRequest pageRequest, String filter) {
return loadBackendEntities(PageRequest.of(0, 1), filter).getTotalElements();
protected long sizeInBackEnd(final PageRequest pageRequest, final String filter) {
if (StringUtils.isEmpty(filter)) {
return targetTypeManagement.count();
}
return targetTypeManagement.countByName(filter);
}
}

View File

@@ -162,7 +162,6 @@ public class ProxyDistributionSet extends ProxyNamedEntity implements VersionAwa
ds.setId(dsInfo.getId());
ds.setName(dsInfo.getName());
ds.setVersion(dsInfo.getVersion());
ds.setTypeInfo(new ProxyTypeInfo(dsInfo.getDsTypeId(), null));
ds.setNameVersion(dsInfo.getNameVersion());
ds.setIsValid(dsInfo.isValid());
@@ -170,12 +169,12 @@ public class ProxyDistributionSet extends ProxyNamedEntity implements VersionAwa
}
/**
* Gets the Id, name, version, dsTypeId and invalidation state of distribution
* set
* Gets the Id, name, version, dsTypeId and invalidation state of
* distribution set
*
* @return proxy of Id, name, version, dsTypeId and invalidation state
*/
public ProxyDistributionSetInfo getInfo() {
return new ProxyDistributionSetInfo(getId(), getName(), getVersion(), getTypeInfo().getId(), getIsValid());
return new ProxyDistributionSetInfo(getId(), getName(), getVersion(), getIsValid());
}
}

View File

@@ -21,7 +21,6 @@ public class ProxyDistributionSetInfo extends ProxyIdentifiableEntity {
private String name;
private String version;
private String nameVersion;
private Long dsTypeId;
private boolean isValid;
/**
@@ -40,18 +39,14 @@ public class ProxyDistributionSetInfo extends ProxyIdentifiableEntity {
* distribution set name
* @param version
* distribution set version
* @param dsTypeId
* ID of the assigned dsType
* @param isValid
* invalidation state
*/
public ProxyDistributionSetInfo(final Long id, final String name, final String version, final Long dsTypeId,
final boolean isValid) {
public ProxyDistributionSetInfo(final Long id, final String name, final String version, final boolean isValid) {
super(id);
this.name = name;
this.version = version;
this.dsTypeId = dsTypeId;
this.isValid = isValid;
this.nameVersion = HawkbitCommonUtil.getFormattedNameVersion(name, version);
}
@@ -88,19 +83,11 @@ public class ProxyDistributionSetInfo extends ProxyIdentifiableEntity {
this.isValid = isValid;
}
public Long getDsTypeId() {
return dsTypeId;
}
public void setDsTypeId(final Long dsTypeId) {
this.dsTypeId = dsTypeId;
}
@Override
public int hashCode() {
// nameVersion is ignored because it is a composition of name and
// version
return Objects.hash(getId(), getName(), getVersion(), getDsTypeId(), isValid());
return Objects.hash(getId(), getName(), getVersion(), isValid());
}
// equals method requires all of the used conditions
@@ -119,7 +106,6 @@ public class ProxyDistributionSetInfo extends ProxyIdentifiableEntity {
// version
return Objects.equals(this.getId(), other.getId()) && Objects.equals(this.getName(), other.getName())
&& Objects.equals(this.getVersion(), other.getVersion())
&& Objects.equals(this.getDsTypeId(), other.getDsTypeId())
&& Objects.equals(this.isValid(), other.isValid());
}
}

View File

@@ -115,7 +115,7 @@ public class SwModulesToDistributionSetAssignmentSupport
return false;
}
if (!ds.getIsValid()) {
if (Boolean.FALSE.equals(ds.getIsValid())) {
/* Distribution is invalidated */
addSpecificValidationErrorMessage(
i18n.getMessage(UIMessageIdProvider.MESSAGE_ERROR_DISTRIBUTIONSET_INVALID, ds.getNameVersion()));
@@ -145,8 +145,8 @@ public class SwModulesToDistributionSetAssignmentSupport
private boolean checkDuplicateSmToDsAssignment(final ProxySoftwareModule sm, final ProxyDistributionSet ds,
final Collection<Long> smIdsAlreadyAssignedToDs) {
if (!CollectionUtils.isEmpty(smIdsAlreadyAssignedToDs) && smIdsAlreadyAssignedToDs.contains(sm.getId())) {
addSpecificValidationErrorMessage(i18n.getMessage("message.software.dist.already.assigned", sm.getNameAndVersion(),
ds.getNameVersion()));
addSpecificValidationErrorMessage(i18n.getMessage("message.software.dist.already.assigned",
sm.getNameAndVersion(), ds.getNameVersion()));
return false;
}
@@ -158,8 +158,8 @@ public class SwModulesToDistributionSetAssignmentSupport
if (!dsType.containsModuleType(sm.getTypeInfo().getId())) {
final String smTypeName = smTypeManagement.get(sm.getTypeInfo().getId()).map(SoftwareModuleType::getName)
.orElse("");
addSpecificValidationErrorMessage(i18n.getMessage("message.software.dist.type.notallowed", sm.getNameAndVersion(),
ds.getNameVersion(), smTypeName));
addSpecificValidationErrorMessage(i18n.getMessage("message.software.dist.type.notallowed",
sm.getNameAndVersion(), ds.getNameVersion(), smTypeName));
return false;
}

View File

@@ -82,8 +82,7 @@ public class DistributionSetGrid extends AbstractDsGrid<DsDistributionsFilterPar
}
setFilterSupport(new FilterSupport<>(
new DistributionSetDistributionsStateDataProvider(dsManagement, dsTypeManagement,
dsToProxyDistributionMapper),
new DistributionSetDistributionsStateDataProvider(dsManagement, dsToProxyDistributionMapper),
DsDistributionsFilterParams::new, getSelectionSupport()::deselectAll));
initFilterMappings();
getFilterSupport().setFilter(new DsDistributionsFilterParams());
@@ -105,10 +104,10 @@ public class DistributionSetGrid extends AbstractDsGrid<DsDistributionsFilterPar
private static String getRowStyle(final ProxyDistributionSet ds) {
final StringBuilder style = new StringBuilder();
if (!ds.getIsComplete()) {
if (Boolean.FALSE.equals(ds.getIsComplete())) {
style.append(SPUIDefinitions.INCOMPLETE_DISTRIBUTION);
}
if (!ds.getIsValid()) {
if (Boolean.FALSE.equals(ds.getIsValid())) {
style.append(" ");
style.append(SPUIDefinitions.INVALID_DISTRIBUTION);
}

View File

@@ -72,8 +72,8 @@ public class RolloutFormLayout extends ValidatableLayout {
private Long rolloutId;
private Long totalTargets;
private Consumer<String> filterQueryChangedListener;
private Consumer<Long> distSetChangedListener;
private Consumer<ProxyTargetFilterQuery> filterQueryChangedListener;
private Consumer<ProxyDistributionSet> distSetChangedListener;
/**
* Constructor for RolloutFormLayout
@@ -204,7 +204,7 @@ public class RolloutFormLayout extends ValidatableLayout {
private HasValue.ValueChangeListener<ProxyTargetFilterQuery> filterQueryChangedListener() {
return event -> {
if (filterQueryChangedListener != null) {
filterQueryChangedListener.accept(event.getValue() != null ? event.getValue().getQuery() : null);
filterQueryChangedListener.accept(event.getValue());
}
};
}
@@ -212,11 +212,7 @@ public class RolloutFormLayout extends ValidatableLayout {
private HasValue.ValueChangeListener<ProxyDistributionSet> distSetChangedListener() {
return event -> {
if (distSetChangedListener != null) {
if (event.getValue() != null && event.getValue().getTypeInfo() != null) {
distSetChangedListener.accept(event.getValue().getTypeInfo().getId());
} else {
distSetChangedListener.accept(null);
}
distSetChangedListener.accept(event.getValue());
}
};
}
@@ -300,7 +296,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* @param filterQueryChangedListener
* Changed listener
*/
public void setFilterQueryChangedListener(final Consumer<String> filterQueryChangedListener) {
public void setFilterQueryChangedListener(final Consumer<ProxyTargetFilterQuery> filterQueryChangedListener) {
this.filterQueryChangedListener = filterQueryChangedListener;
}
@@ -310,7 +306,7 @@ public class RolloutFormLayout extends ValidatableLayout {
* @param distSetChangedListener
* Changed listener
*/
public void setDistSetChangedListener(final Consumer<Long> distSetChangedListener) {
public void setDistSetChangedListener(final Consumer<ProxyDistributionSet> distSetChangedListener) {
this.distSetChangedListener = distSetChangedListener;
}

View File

@@ -25,8 +25,8 @@ import org.eclipse.hawkbit.ui.rollout.window.RolloutWindowDependencies;
import org.eclipse.hawkbit.ui.rollout.window.components.AutoStartOptionGroupLayout.AutoStartOption;
import org.eclipse.hawkbit.ui.rollout.window.layouts.AddRolloutWindowLayout;
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Slice;
import org.springframework.util.CollectionUtils;
/**
@@ -94,9 +94,9 @@ public class CopyRolloutWindowController extends AddRolloutWindowController {
}
private void setTargetFilterId(final ProxyRolloutWindow proxyRolloutWindow) {
final Page<TargetFilterQuery> filterQueries = targetFilterQueryManagement.findByQuery(PageRequest.of(0, 1),
final Slice<TargetFilterQuery> filterQueries = targetFilterQueryManagement.findByQuery(PageRequest.of(0, 1),
proxyRolloutWindow.getTargetFilterQuery());
if (filterQueries.getTotalElements() > 0) {
if (filterQueries.getNumberOfElements() > 0) {
final TargetFilterQuery tfq = filterQueries.getContent().get(0);
proxyRolloutWindow
.setTargetFilterInfo(new ProxyTargetFilterQueryInfo(tfq.getId(), tfq.getName(), tfq.getQuery()));

View File

@@ -11,10 +11,15 @@ package org.eclipse.hawkbit.ui.rollout.window.layouts;
import java.util.Arrays;
import java.util.List;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyAdvancedRolloutGroup;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyDistributionSet;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyRolloutWindow;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyRolloutWindow.GroupDefinitionMode;
import org.eclipse.hawkbit.ui.common.data.proxies.ProxyTargetFilterQuery;
import org.eclipse.hawkbit.ui.rollout.window.RolloutWindowDependencies;
import org.eclipse.hawkbit.ui.rollout.window.components.AdvancedGroupsLayout;
import org.eclipse.hawkbit.ui.rollout.window.components.RolloutFormLayout;
@@ -34,6 +39,7 @@ import com.vaadin.ui.TabSheet;
public class AddRolloutWindowLayout extends AbstractRolloutWindowLayout {
private final TargetManagement targetManagement;
private final DistributionSetManagement dsManagement;
private final RolloutFormLayout rolloutFormLayout;
private final SimpleGroupsLayout simpleGroupsLayout;
@@ -57,6 +63,7 @@ public class AddRolloutWindowLayout extends AbstractRolloutWindowLayout {
super(dependencies);
this.targetManagement = dependencies.getTargetManagement();
this.dsManagement = dependencies.getDistributionSetManagement();
this.rolloutFormLayout = rolloutComponentBuilder.createRolloutFormLayout();
this.simpleGroupsLayout = rolloutComponentBuilder.createSimpleGroupsLayout();
@@ -90,8 +97,8 @@ public class AddRolloutWindowLayout extends AbstractRolloutWindowLayout {
advancedGroupsLayout.setAdvancedGroupDefinitionsChangedListener(this::onAdvancedGroupsChanged);
}
private void onFilterQueryChange(final String filterQuery) {
this.filterQuery = filterQuery;
private void onFilterQueryChange(final ProxyTargetFilterQuery targetFilterQuery) {
filterQuery = targetFilterQuery != null ? targetFilterQuery.getQuery() : null;
updateTotalTargets();
if (isAdvancedGroupsTabSelected()) {
@@ -99,8 +106,8 @@ public class AddRolloutWindowLayout extends AbstractRolloutWindowLayout {
}
}
private void onDistSetTypeChange(final Long dsTypeId) {
this.dsTypeId = dsTypeId;
private void onDistSetTypeChange(final ProxyDistributionSet ds) {
dsTypeId = ds != null ? getDsTypeId(ds) : null;
updateTotalTargets();
if (isAdvancedGroupsTabSelected()) {
@@ -108,8 +115,16 @@ public class AddRolloutWindowLayout extends AbstractRolloutWindowLayout {
}
}
private Long getDsTypeId(final @NotNull ProxyDistributionSet ds) {
if (ds.getTypeInfo() != null) {
return ds.getTypeInfo().getId();
}
return dsManagement.get(ds.getId()).map(dist -> dist.getType().getId()).orElse(null);
}
private void updateTotalTargets() {
this.totalTargets = getTotalTargets(filterQuery, dsTypeId);
totalTargets = getTotalTargets(filterQuery, dsTypeId);
rolloutFormLayout.setTotalTargets(totalTargets);
visualGroupDefinitionLayout.setTotalTargets(totalTargets);
if (isSimpleGroupsTabSelected()) {