Merge pull request #298 from bsinno/feature_target_filtering_supports_overdue
Feature target filtering supports overdue
This commit is contained in:
@@ -9,12 +9,16 @@
|
|||||||
package org.eclipse.hawkbit.autoconfigure.repository;
|
package org.eclipse.hawkbit.autoconfigure.repository;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.EnableJpaRepository;
|
import org.eclipse.hawkbit.EnableJpaRepository;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyResolver;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Auto-Configuration for enabling the REST-Resources.
|
* Auto-Configuration for enabling JPA repository.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -22,4 +26,14 @@ import org.springframework.context.annotation.Import;
|
|||||||
@Import({ EnableJpaRepository.class })
|
@Import({ EnableJpaRepository.class })
|
||||||
public class JpaRepositoryAutoConfiguration {
|
public class JpaRepositoryAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return returns a VirtualPropertyReplacer
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public VirtualPropertyReplacer virtualPropertyReplacer() {
|
||||||
|
return new VirtualPropertyResolver();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates a set of filters that may be specified (optionally). Properties
|
||||||
|
* that are not specified (e.g. <code>null</code> for simple properties) When
|
||||||
|
* applied, these filters are AND-gated.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FilterParams {
|
||||||
|
|
||||||
|
private Collection<TargetUpdateStatus> filterByStatus;
|
||||||
|
private Boolean overdueState;
|
||||||
|
private String filterBySearchText;
|
||||||
|
private Boolean selectTargetWithNoTag;
|
||||||
|
private String[] filterByTagNames;
|
||||||
|
private Long filterByDistributionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param filterByDistributionId
|
||||||
|
* if set, a filter is added for the given
|
||||||
|
* {@link DistributionSet#getId()}
|
||||||
|
* @param filterByStatus
|
||||||
|
* if set, a filter is added for target states included by the
|
||||||
|
* collection
|
||||||
|
* @param overdueState
|
||||||
|
* if set, a filter is added for overdued devices
|
||||||
|
* @param filterBySearchText
|
||||||
|
* if set, a filter is added for the given search text
|
||||||
|
* @param selectTargetWithNoTag
|
||||||
|
* if set, tag-filtering is enabled
|
||||||
|
* @param filterByTagNames
|
||||||
|
* if tag-filtering is enabled, a filter is added for the given
|
||||||
|
* tag-names
|
||||||
|
*/
|
||||||
|
public FilterParams(Long filterByDistributionId, Collection<TargetUpdateStatus> filterByStatus,
|
||||||
|
Boolean overdueState, String filterBySearchText, Boolean selectTargetWithNoTag,
|
||||||
|
String... filterByTagNames) {
|
||||||
|
this.filterByStatus = filterByStatus;
|
||||||
|
this.overdueState = overdueState;
|
||||||
|
this.filterBySearchText = filterBySearchText;
|
||||||
|
this.filterByDistributionId = filterByDistributionId;
|
||||||
|
this.selectTargetWithNoTag = selectTargetWithNoTag;
|
||||||
|
this.filterByTagNames = filterByTagNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets {@link DistributionSet#getId()} to filter the result. <br>
|
||||||
|
* If set to <code>null</code> this filter is disabled.
|
||||||
|
*
|
||||||
|
* @return {@link DistributionSet#getId()} to filter the result
|
||||||
|
*/
|
||||||
|
public Long getFilterByDistributionId() {
|
||||||
|
return filterByDistributionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets {@link DistributionSet#getId()} to filter the result.
|
||||||
|
*
|
||||||
|
* @param filterByDistributionId
|
||||||
|
* the distribution set id
|
||||||
|
*/
|
||||||
|
public void setFilterByDistributionId(Long filterByDistributionId) {
|
||||||
|
this.filterByDistributionId = filterByDistributionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a collection of target states to filter for. <br>
|
||||||
|
* If set to <code>null</code> this filter is disabled.
|
||||||
|
*
|
||||||
|
* @return collection of target states to filter for
|
||||||
|
*/
|
||||||
|
public Collection<TargetUpdateStatus> getFilterByStatus() {
|
||||||
|
return filterByStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the collection of target states to filter for.
|
||||||
|
*
|
||||||
|
* @param filterByStatus
|
||||||
|
* collection of target update status
|
||||||
|
*/
|
||||||
|
public void setFilterByStatus(Collection<TargetUpdateStatus> filterByStatus) {
|
||||||
|
this.filterByStatus = filterByStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the flag for overdue filter; if set to <code>true</code>, the
|
||||||
|
* overdue filter is activated. Overdued targets a targets that did not
|
||||||
|
* respond during the configured intervals: poll_itvl + overdue_itvl. <br>
|
||||||
|
* If set to <code>null</code> this filter is disabled.
|
||||||
|
*
|
||||||
|
* @return flag for overdue filter activation
|
||||||
|
*/
|
||||||
|
public Boolean getOverdueState() {
|
||||||
|
return overdueState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the flag for overdue filter; if set to <code>true</code>, the
|
||||||
|
* overdue filter is activated.
|
||||||
|
*
|
||||||
|
* @param overdueState
|
||||||
|
* if the overdue filter should be activates
|
||||||
|
*/
|
||||||
|
public void setOverdueState(Boolean overdueState) {
|
||||||
|
this.overdueState = overdueState;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the search text to filter for. This is used to find targets having
|
||||||
|
* the text anywhere in name or description <br>
|
||||||
|
* If set to <code>null</code> this filter is disabled.
|
||||||
|
*
|
||||||
|
* @return the search text to filter for
|
||||||
|
*/
|
||||||
|
public String getFilterBySearchText() {
|
||||||
|
return filterBySearchText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the search text to filter for.
|
||||||
|
*
|
||||||
|
* @param filterBySearchText
|
||||||
|
* search text
|
||||||
|
*/
|
||||||
|
public void setFilterBySearchText(String filterBySearchText) {
|
||||||
|
this.filterBySearchText = filterBySearchText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the flag indicating if tagging filter is used. <br>
|
||||||
|
* If set to <code>null</code> this filter is disabled.
|
||||||
|
*
|
||||||
|
* @return the flag indicating if tagging filter is used
|
||||||
|
*/
|
||||||
|
public Boolean getSelectTargetWithNoTag() {
|
||||||
|
return selectTargetWithNoTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the flag indicating if tagging filter is used.
|
||||||
|
*
|
||||||
|
* @param selectTargetWithNoTag
|
||||||
|
* should the tagging filter be used?
|
||||||
|
*/
|
||||||
|
public void setSelectTargetWithNoTag(Boolean selectTargetWithNoTag) {
|
||||||
|
this.selectTargetWithNoTag = selectTargetWithNoTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the tags that are used to filter for. The activation of this filter
|
||||||
|
* is done by {@link #setSelectTargetWithNoTag(Boolean)}.
|
||||||
|
*
|
||||||
|
* @return the tags that are used to filter for
|
||||||
|
*/
|
||||||
|
public String[] getFilterByTagNames() {
|
||||||
|
return filterByTagNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the tags that are used to filter for.
|
||||||
|
*
|
||||||
|
* @param filterByTagNames
|
||||||
|
* array of tag names
|
||||||
|
*/
|
||||||
|
public void setFilterByTagNames(String[] filterByTagNames) {
|
||||||
|
this.filterByTagNames = filterByTagNames;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -67,7 +67,11 @@ public interface TargetManagement {
|
|||||||
* Count {@link Target}s for all the given filter parameters.
|
* Count {@link Target}s for all the given filter parameters.
|
||||||
*
|
*
|
||||||
* @param status
|
* @param status
|
||||||
* find targets having on of these {@link TargetUpdateStatus}s.
|
* find targets having one of these {@link TargetUpdateStatus}s.
|
||||||
|
* Set to <code>null</code> in case this is not required.
|
||||||
|
* @param overdueState
|
||||||
|
* find targets that are overdue (targets that did not respond
|
||||||
|
* during the configured intervals: poll_itvl + overdue_itvl).
|
||||||
* Set to <code>null</code> in case this is not required.
|
* Set to <code>null</code> in case this is not required.
|
||||||
* @param searchText
|
* @param searchText
|
||||||
* to find targets having the text anywhere in name or
|
* to find targets having the text anywhere in name or
|
||||||
@@ -86,7 +90,7 @@ public interface TargetManagement {
|
|||||||
* @return the found number {@link Target}s
|
* @return the found number {@link Target}s
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
Long countTargetByFilters(Collection<TargetUpdateStatus> status, String searchText,
|
Long countTargetByFilters(Collection<TargetUpdateStatus> status, Boolean overdueState, String searchText,
|
||||||
Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag, String... tagNames);
|
Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag, String... tagNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,10 +216,12 @@ public interface TargetManagement {
|
|||||||
*
|
*
|
||||||
* @param pageRequest
|
* @param pageRequest
|
||||||
* the pageRequest to enhance the query for paging and sorting
|
* the pageRequest to enhance the query for paging and sorting
|
||||||
*
|
|
||||||
* @param filterByStatus
|
* @param filterByStatus
|
||||||
* find targets having this {@link TargetUpdateStatus}s. Set to
|
* find targets having this {@link TargetUpdateStatus}s. Set to
|
||||||
* <code>null</code> in case this is not required.
|
* <code>null</code> in case this is not required.
|
||||||
|
* @param overdueState
|
||||||
|
* find targets that are overdue (targets that did not respond
|
||||||
|
* during the configured intervals: poll_itvl + overdue_itvl).
|
||||||
* @param filterBySearchText
|
* @param filterBySearchText
|
||||||
* to find targets having the text anywhere in name or
|
* to find targets having the text anywhere in name or
|
||||||
* description. Set <code>null</code> in case this is not
|
* description. Set <code>null</code> in case this is not
|
||||||
@@ -234,7 +240,7 @@ public interface TargetManagement {
|
|||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
List<TargetIdName> findAllTargetIdsByFilters(@NotNull Pageable pageRequest,
|
List<TargetIdName> findAllTargetIdsByFilters(@NotNull Pageable pageRequest,
|
||||||
Collection<TargetUpdateStatus> filterByStatus, String filterBySearchText,
|
Collection<TargetUpdateStatus> filterByStatus, Boolean overdueState, String filterBySearchText,
|
||||||
Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag, String... filterByTagNames);
|
Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag, String... filterByTagNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -314,7 +320,7 @@ public interface TargetManagement {
|
|||||||
* given {@code fieldNameProvider}
|
* given {@code fieldNameProvider}
|
||||||
* @throws RSQLParameterSyntaxException
|
* @throws RSQLParameterSyntaxException
|
||||||
* if the RSQL syntax is wrong
|
* if the RSQL syntax is wrong
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET)
|
||||||
Page<Target> findTargetByAssignedDistributionSet(@NotNull Long distributionSetID, @NotNull String rsqlParam,
|
Page<Target> findTargetByAssignedDistributionSet(@NotNull Long distributionSetID, @NotNull String rsqlParam,
|
||||||
@@ -368,6 +374,9 @@ public interface TargetManagement {
|
|||||||
* @param status
|
* @param status
|
||||||
* find targets having this {@link TargetUpdateStatus}s. Set to
|
* find targets having this {@link TargetUpdateStatus}s. Set to
|
||||||
* <code>null</code> in case this is not required.
|
* <code>null</code> in case this is not required.
|
||||||
|
* @param overdueState
|
||||||
|
* find targets that are overdue (targets that did not respond
|
||||||
|
* during the configured intervals: poll_itvl + overdue_itvl).
|
||||||
* @param searchText
|
* @param searchText
|
||||||
* to find targets having the text anywhere in name or
|
* to find targets having the text anywhere in name or
|
||||||
* description. Set <code>null</code> in case this is not
|
* description. Set <code>null</code> in case this is not
|
||||||
@@ -386,7 +395,7 @@ public interface TargetManagement {
|
|||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
Slice<Target> findTargetByFilters(@NotNull Pageable pageable, Collection<TargetUpdateStatus> status,
|
Slice<Target> findTargetByFilters(@NotNull Pageable pageable, Collection<TargetUpdateStatus> status,
|
||||||
String searchText, Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag,
|
Boolean overdueState, String searchText, Long installedOrAssignedDistributionSetId, Boolean selectTargetWithNoTag,
|
||||||
String... tagNames);
|
String... tagNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -415,7 +424,7 @@ public interface TargetManagement {
|
|||||||
* @param pageable
|
* @param pageable
|
||||||
* page parameter
|
* page parameter
|
||||||
* @return the found {@link Target}s, never {@code null}
|
* @return the found {@link Target}s, never {@code null}
|
||||||
*
|
*
|
||||||
* @throws RSQLParameterUnsupportedFieldException
|
* @throws RSQLParameterUnsupportedFieldException
|
||||||
* if a field in the RSQL string is used but not provided by the
|
* if a field in the RSQL string is used but not provided by the
|
||||||
* given {@code fieldNameProvider}
|
* given {@code fieldNameProvider}
|
||||||
@@ -460,9 +469,9 @@ public interface TargetManagement {
|
|||||||
* in string notation
|
* in string notation
|
||||||
* @param pageable
|
* @param pageable
|
||||||
* pagination parameter
|
* pagination parameter
|
||||||
*
|
*
|
||||||
* @return the found {@link Target}s, never {@code null}
|
* @return the found {@link Target}s, never {@code null}
|
||||||
*
|
*
|
||||||
* @throws RSQLParameterUnsupportedFieldException
|
* @throws RSQLParameterUnsupportedFieldException
|
||||||
* if a field in the RSQL string is used but not provided by the
|
* if a field in the RSQL string is used but not provided by the
|
||||||
* given {@code fieldNameProvider}
|
* given {@code fieldNameProvider}
|
||||||
@@ -481,9 +490,9 @@ public interface TargetManagement {
|
|||||||
* the specification for the query
|
* the specification for the query
|
||||||
* @param pageable
|
* @param pageable
|
||||||
* pagination parameter
|
* pagination parameter
|
||||||
*
|
*
|
||||||
* @return the found {@link Target}s, never {@code null}
|
* @return the found {@link Target}s, never {@code null}
|
||||||
*
|
*
|
||||||
* @throws RSQLParameterUnsupportedFieldException
|
* @throws RSQLParameterUnsupportedFieldException
|
||||||
* if a field in the RSQL string is used but not provided by the
|
* if a field in the RSQL string is used but not provided by the
|
||||||
* given {@code fieldNameProvider}
|
* given {@code fieldNameProvider}
|
||||||
@@ -511,33 +520,15 @@ public interface TargetManagement {
|
|||||||
* the page request to page the result set
|
* the page request to page the result set
|
||||||
* @param orderByDistributionId
|
* @param orderByDistributionId
|
||||||
* {@link DistributionSet#getId()} to be ordered by
|
* {@link DistributionSet#getId()} to be ordered by
|
||||||
* @param filterByDistributionId
|
* @param filterParams
|
||||||
* {@link DistributionSet#getId()} to be filter the result. Set
|
* the filters to apply; only filters are enabled that have
|
||||||
* to <code>null</code> in case this is not required.
|
* non-null value; filters are AND-gated
|
||||||
* @param filterByStatus
|
|
||||||
* find targets having this {@link TargetUpdateStatus}s. Set to
|
|
||||||
* <code>null</code> in case this is not required.
|
|
||||||
* @param filterBySearchText
|
|
||||||
* to find targets having the text anywhere in name or
|
|
||||||
* description. Set <code>null</code> in case this is not
|
|
||||||
* required.
|
|
||||||
* @param installedOrAssignedDistributionSetId
|
|
||||||
* to find targets having the {@link DistributionSet} as
|
|
||||||
* installed or assigned. Set to <code>null</code> in case this
|
|
||||||
* is not required.
|
|
||||||
* @param filterByTagNames
|
|
||||||
* to find targets which are having any one in this tag names.
|
|
||||||
* Set <code>null</code> in case this is not required.
|
|
||||||
* @param selectTargetWithNoTag
|
|
||||||
* flag to select targets with no tag assigned
|
|
||||||
* @return a paged result {@link Page} of the {@link Target}s in a defined
|
* @return a paged result {@link Page} of the {@link Target}s in a defined
|
||||||
* order.
|
* order.
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
Slice<Target> findTargetsAllOrderByLinkedDistributionSet(@NotNull Pageable pageable,
|
Slice<Target> findTargetsAllOrderByLinkedDistributionSet(@NotNull Pageable pageable,
|
||||||
@NotNull Long orderByDistributionId, Long filterByDistributionId,
|
@NotNull Long orderByDistributionId, FilterParams filterParams);
|
||||||
Collection<TargetUpdateStatus> filterByStatus, String filterBySearchText, Boolean selectTargetWithNoTag,
|
|
||||||
String... filterByTagNames);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieves a list of {@link Target}s by their controller ID with details,
|
* retrieves a list of {@link Target}s by their controller ID with details,
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* 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.rsql;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementations map a placeholder to the associated value.
|
||||||
|
* <p>
|
||||||
|
* This is used in context of string replacement.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface VirtualPropertyReplacer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a placeholders and replaces them
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* the input string in which virtual properties should be
|
||||||
|
* replaced
|
||||||
|
* @return the result of the replacement
|
||||||
|
*/
|
||||||
|
String replace(String input);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* 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.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates non-persistent timestamps , e.g. the point a time a
|
||||||
|
* target is declared as overdue.<br>
|
||||||
|
* Therefore tenant specific configuration may be considered.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public final class TimestampCalculator {
|
||||||
|
|
||||||
|
private TimestampCalculator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the overdue timestamp (<em>overdue_ts</em>) based on the
|
||||||
|
* current timestamp and the intervals for polling and poll-overdue:
|
||||||
|
* <p>
|
||||||
|
* <em>overdue_ts = now_ts - pollingInterval -
|
||||||
|
* pollingOverdueInterval</em>;<br>
|
||||||
|
* <em>pollingInterval</em> and <em>pollingOverdueInterval</em> are
|
||||||
|
* retrieved from tenant-specific system configuration.
|
||||||
|
*
|
||||||
|
* @return <em>overdue_ts</em> in milliseconds since Unix epoch as long
|
||||||
|
* value
|
||||||
|
*/
|
||||||
|
public static long calculateOverdueTimestamp() {
|
||||||
|
return Instant.now().toEpochMilli() - getDurationForKey(TenantConfigurationKey.POLLING_TIME_INTERVAL).toMillis()
|
||||||
|
- getDurationForKey(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL).toMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Duration getDurationForKey(TenantConfigurationKey key) {
|
||||||
|
return DurationHelper.formattedStringToDuration(getRawStringForKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getRawStringForKey(TenantConfigurationKey key) {
|
||||||
|
return getTenantConfigurationManagement().getConfigurationValue(key, String.class).getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TenantConfigurationManagement getTenantConfigurationManagement() {
|
||||||
|
return TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* 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.rsql;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.text.StrLookup;
|
||||||
|
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds macro capabilities to RSQL expressions that are used to filter for
|
||||||
|
* targets.
|
||||||
|
* <p>
|
||||||
|
* Some (virtual) properties do not have a representation in the database (in
|
||||||
|
* general these properties are time-related, or more explicitly, they deal with
|
||||||
|
* time intervals).<br>
|
||||||
|
* Such a virtual property needs to be calculated on Java-side before it may be
|
||||||
|
* used in a target filter query that is passed to the database. Therefore a
|
||||||
|
* placeholder is used in the RSQL expression that is expanded when the RSQL is
|
||||||
|
* parsed
|
||||||
|
* <p>
|
||||||
|
* A virtual property may either be a system value like the current date (aka
|
||||||
|
* <em>now_ts</em>) or a value derived from (tenant-specific) system
|
||||||
|
* configuration (e.g. <em>overdue_ts</em>).
|
||||||
|
* <p>
|
||||||
|
* Known values are:<br>
|
||||||
|
* <ul>
|
||||||
|
* <li><em>now_ts</em>: maps to system UTC time in milliseconds since Unix epoch
|
||||||
|
* as long value</li>
|
||||||
|
* <li><em>overdue_ts</em>: is a calculated value: <em>overdue_ts = now_ts -
|
||||||
|
* pollingInterval - pollingOverdueInterval</em>; pollingInterval and
|
||||||
|
* pollingOverdueInterval are retrieved from tenant-specific system
|
||||||
|
* configuration.</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class VirtualPropertyResolver extends StrLookup<String> implements VirtualPropertyReplacer {
|
||||||
|
|
||||||
|
private StrSubstitutor substitutor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String lookup(String rhs) {
|
||||||
|
String resolved = null;
|
||||||
|
|
||||||
|
if ("now_ts".equalsIgnoreCase(rhs)) {
|
||||||
|
resolved = String.valueOf(Instant.now().toEpochMilli());
|
||||||
|
} else if ("overdue_ts".equalsIgnoreCase(rhs)) {
|
||||||
|
resolved = String.valueOf(TimestampCalculator.calculateOverdueTimestamp());
|
||||||
|
}
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String replace(String input) {
|
||||||
|
if (substitutor == null) {
|
||||||
|
substitutor = new StrSubstitutor(this, StrSubstitutor.DEFAULT_PREFIX, StrSubstitutor.DEFAULT_SUFFIX,
|
||||||
|
StrSubstitutor.DEFAULT_ESCAPE);
|
||||||
|
}
|
||||||
|
return substitutor.replace(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -141,6 +141,16 @@
|
|||||||
<artifactId>fest-assert</artifactId>
|
<artifactId>fest-assert</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-module-junit4</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-api-mockito</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return the singleton instance of the
|
* @return the singleton instance of the
|
||||||
* {@link AfterTransactionCommitExecutorHolder}
|
* {@link AfterTransactionCommitExecutorHolder}
|
||||||
*/
|
*/
|
||||||
@@ -234,7 +234,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaSystemManagement} bean.
|
* {@link JpaSystemManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link SystemManagement}
|
* @return a new {@link SystemManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -245,7 +245,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaReportManagement} bean.
|
* {@link JpaReportManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link ReportManagement}
|
* @return a new {@link ReportManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -256,7 +256,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaDistributionSetManagement} bean.
|
* {@link JpaDistributionSetManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link DistributionSetManagement}
|
* @return a new {@link DistributionSetManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -267,7 +267,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaTenantStatsManagement} bean.
|
* {@link JpaTenantStatsManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link TenantStatsManagement}
|
* @return a new {@link TenantStatsManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -280,7 +280,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaTenantConfigurationManagement} bean.
|
* {@link JpaTenantConfigurationManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link TenantConfigurationManagement}
|
* @return a new {@link TenantConfigurationManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -291,7 +291,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaTenantConfigurationManagement} bean.
|
* {@link JpaTenantConfigurationManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link TenantConfigurationManagement}
|
* @return a new {@link TenantConfigurationManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -302,7 +302,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaTargetFilterQueryManagement} bean.
|
* {@link JpaTargetFilterQueryManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link TargetFilterQueryManagement}
|
* @return a new {@link TargetFilterQueryManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -313,7 +313,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaTagManagement} bean.
|
* {@link JpaTagManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link TagManagement}
|
* @return a new {@link TagManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -324,7 +324,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaSoftwareManagement} bean.
|
* {@link JpaSoftwareManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link SoftwareManagement}
|
* @return a new {@link SoftwareManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -335,7 +335,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaRolloutManagement} bean.
|
* {@link JpaRolloutManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link RolloutManagement}
|
* @return a new {@link RolloutManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -346,7 +346,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaRolloutGroupManagement} bean.
|
* {@link JpaRolloutGroupManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link RolloutGroupManagement}
|
* @return a new {@link RolloutGroupManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -357,7 +357,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaDeploymentManagement} bean.
|
* {@link JpaDeploymentManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link DeploymentManagement}
|
* @return a new {@link DeploymentManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -368,7 +368,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaControllerManagement} bean.
|
* {@link JpaControllerManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link ControllerManagement}
|
* @return a new {@link ControllerManagement}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@@ -379,7 +379,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaArtifactManagement} bean.
|
* {@link JpaArtifactManagement} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link ArtifactManagement}
|
* @return a new {@link ArtifactManagement}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -391,7 +391,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link JpaEntityFactory} bean.
|
* {@link JpaEntityFactory} bean.
|
||||||
*
|
*
|
||||||
* @return a new {@link EntityFactory}
|
* @return a new {@link EntityFactory}
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
@@ -135,6 +136,9 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemSecurityContext systemSecurityContext;
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(isolation = Isolation.READ_COMMITTED)
|
@Transactional(isolation = Isolation.READ_COMMITTED)
|
||||||
@Modifying
|
@Modifying
|
||||||
@@ -607,8 +611,8 @@ public class JpaDeploymentManagement implements DeploymentManagement {
|
|||||||
return convertAcPage(actions, pageable);
|
return convertAcPage(actions, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Specification<JpaAction> createSpecificationFor(final Target target, final String rsqlParam) {
|
private Specification<JpaAction> createSpecificationFor(final Target target, final String rsqlParam) {
|
||||||
final Specification<JpaAction> spec = RSQLUtility.parse(rsqlParam, ActionFields.class);
|
final Specification<JpaAction> spec = RSQLUtility.parse(rsqlParam, ActionFields.class, virtualPropertyReplacer);
|
||||||
return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb),
|
return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb),
|
||||||
cb.equal(root.get(JpaAction_.target), target));
|
cb.equal(root.get(JpaAction_.target), target));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata_;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetSpecification;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.DistributionSetTypeSpecification;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
||||||
@@ -110,6 +111,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DistributionSet findDistributionSetByIdWithDetails(final Long distid) {
|
public DistributionSet findDistributionSetByIdWithDetails(final Long distid) {
|
||||||
return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid));
|
return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid));
|
||||||
@@ -286,7 +290,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<DistributionSetType> findDistributionSetTypesAll(final String rsqlParam, final Pageable pageable) {
|
public Page<DistributionSetType> findDistributionSetTypesAll(final String rsqlParam, final Pageable pageable) {
|
||||||
final Specification<JpaDistributionSetType> spec = RSQLUtility.parse(rsqlParam,
|
final Specification<JpaDistributionSetType> spec = RSQLUtility.parse(rsqlParam,
|
||||||
DistributionSetTypeFields.class);
|
DistributionSetTypeFields.class, virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertDsTPage(distributionSetTypeRepository.findAll(spec, pageable));
|
return convertDsTPage(distributionSetTypeRepository.findAll(spec, pageable));
|
||||||
}
|
}
|
||||||
@@ -352,7 +356,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
public Page<DistributionSet> findDistributionSetsAll(final String rsqlParam, final Pageable pageReq,
|
public Page<DistributionSet> findDistributionSetsAll(final String rsqlParam, final Pageable pageReq,
|
||||||
final Boolean deleted) {
|
final Boolean deleted) {
|
||||||
|
|
||||||
final Specification<JpaDistributionSet> spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class);
|
final Specification<JpaDistributionSet> spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(2);
|
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(2);
|
||||||
if (deleted != null) {
|
if (deleted != null) {
|
||||||
@@ -528,7 +533,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
/**
|
/**
|
||||||
* Method to get the latest distribution set based on ds ID after the
|
* Method to get the latest distribution set based on ds ID after the
|
||||||
* metadata changes for that distribution set.
|
* metadata changes for that distribution set.
|
||||||
*
|
*
|
||||||
* @param distributionSet
|
* @param distributionSet
|
||||||
* Distribution set
|
* Distribution set
|
||||||
*/
|
*/
|
||||||
@@ -564,7 +569,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
final String rsqlParam, final Pageable pageable) {
|
final String rsqlParam, final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaDistributionSetMetadata> spec = RSQLUtility.parse(rsqlParam,
|
final Specification<JpaDistributionSetMetadata> spec = RSQLUtility.parse(rsqlParam,
|
||||||
DistributionSetMetadataFields.class);
|
DistributionSetMetadataFields.class, virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertMdPage(
|
return convertMdPage(
|
||||||
distributionSetMetadataRepository
|
distributionSetMetadataRepository
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
|
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup_;
|
import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
||||||
@@ -70,6 +71,9 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EntityManager entityManager;
|
private EntityManager entityManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RolloutGroup findRolloutGroupById(final Long rolloutGroupId) {
|
public RolloutGroup findRolloutGroupById(final Long rolloutGroupId) {
|
||||||
return rolloutGroupRepository.findOne(rolloutGroupId);
|
return rolloutGroupRepository.findOne(rolloutGroupId);
|
||||||
@@ -92,7 +96,8 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
public Page<RolloutGroup> findRolloutGroupsAll(final Rollout rollout, final String rsqlParam,
|
public Page<RolloutGroup> findRolloutGroupsAll(final Rollout rollout, final String rsqlParam,
|
||||||
final Pageable pageable) {
|
final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaRolloutGroup> specification = RSQLUtility.parse(rsqlParam, RolloutGroupFields.class);
|
final Specification<JpaRolloutGroup> specification = RSQLUtility.parse(rsqlParam, RolloutGroupFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertPage(
|
return convertPage(
|
||||||
rolloutGroupRepository
|
rolloutGroupRepository
|
||||||
@@ -145,7 +150,8 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
public Page<Target> findRolloutGroupTargets(final RolloutGroup rolloutGroup, final String rsqlParam,
|
public Page<Target> findRolloutGroupTargets(final RolloutGroup rolloutGroup, final String rsqlParam,
|
||||||
final Pageable pageable) {
|
final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaTarget> rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class);
|
final Specification<JpaTarget> rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertTPage(targetRepository.findAll((root, query, criteriaBuilder) -> {
|
return convertTPage(targetRepository.findAll((root, query, criteriaBuilder) -> {
|
||||||
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup);
|
final ListJoin<JpaTarget, RolloutTargetGroup> rolloutTargetJoin = root.join(JpaTarget_.rolloutTargetGroup);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.eclipse.hawkbit.repository.jpa.model.RolloutTargetGroup;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupActionEvaluator;
|
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupActionEvaluator;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditionEvaluator;
|
import org.eclipse.hawkbit.repository.jpa.rollout.condition.RolloutGroupConditionEvaluator;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -114,6 +115,9 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CacheWriteNotify cacheWriteNotify;
|
private CacheWriteNotify cacheWriteNotify;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier("asyncExecutor")
|
@Qualifier("asyncExecutor")
|
||||||
private Executor executor;
|
private Executor executor;
|
||||||
@@ -150,7 +154,8 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<Rollout> findAllWithDetailedStatusByPredicate(final String rsqlParam, final Pageable pageable) {
|
public Page<Rollout> findAllWithDetailedStatusByPredicate(final String rsqlParam, final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaRollout> specification = RSQLUtility.parse(rsqlParam, RolloutFields.class);
|
final Specification<JpaRollout> specification = RSQLUtility.parse(rsqlParam, RolloutFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
final Page<JpaRollout> findAll = rolloutRepository.findAll(specification, pageable);
|
final Page<JpaRollout> findAll = rolloutRepository.findAll(specification, pageable);
|
||||||
setRolloutStatusDetails(findAll);
|
setRolloutStatusDetails(findAll);
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey;
|
import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
||||||
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
|
import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule;
|
||||||
@@ -106,6 +107,9 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ArtifactManagement artifactManagement;
|
private ArtifactManagement artifactManagement;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Modifying
|
@Modifying
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@@ -312,7 +316,8 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<SoftwareModule> findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) {
|
public Page<SoftwareModule> findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) {
|
||||||
final Specification<JpaSoftwareModule> spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class);
|
final Specification<JpaSoftwareModule> spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable);
|
return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable);
|
||||||
}
|
}
|
||||||
@@ -320,7 +325,8 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<SoftwareModuleType> findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) {
|
public Page<SoftwareModuleType> findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaSoftwareModuleType> spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class);
|
final Specification<JpaSoftwareModuleType> spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable);
|
return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable);
|
||||||
}
|
}
|
||||||
@@ -606,7 +612,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
|||||||
final String rsqlParam, final Pageable pageable) {
|
final String rsqlParam, final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaSoftwareModuleMetadata> spec = RSQLUtility.parse(rsqlParam,
|
final Specification<JpaSoftwareModuleMetadata> spec = RSQLUtility.parse(rsqlParam,
|
||||||
SoftwareModuleMetadataFields.class);
|
SoftwareModuleMetadataFields.class, virtualPropertyReplacer);
|
||||||
return convertSmMdPage(
|
return convertSmMdPage(
|
||||||
softwareModuleMetadataRepository
|
softwareModuleMetadataRepository
|
||||||
.findAll(
|
.findAll(
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
@@ -74,6 +75,9 @@ public class JpaTagManagement implements TagManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AfterTransactionCommitExecutor afterCommit;
|
private AfterTransactionCommitExecutor afterCommit;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetTag findTargetTag(final String name) {
|
public TargetTag findTargetTag(final String name) {
|
||||||
return targetTagRepository.findByNameEquals(name);
|
return targetTagRepository.findByNameEquals(name);
|
||||||
@@ -145,7 +149,7 @@ public class JpaTagManagement implements TagManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Page<TargetTag> findAllTargetTags(final String rsqlParam, final Pageable pageable) {
|
public Page<TargetTag> findAllTargetTags(final String rsqlParam, final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaTargetTag> spec = RSQLUtility.parse(rsqlParam, TagFields.class);
|
final Specification<JpaTargetTag> spec = RSQLUtility.parse(rsqlParam, TagFields.class, virtualPropertyReplacer);
|
||||||
return convertTPage(targetTagRepository.findAll(spec, pageable), pageable);
|
return convertTPage(targetTagRepository.findAll(spec, pageable), pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +280,8 @@ public class JpaTagManagement implements TagManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<DistributionSetTag> findAllDistributionSetTags(final String rsqlParam, final Pageable pageable) {
|
public Page<DistributionSetTag> findAllDistributionSetTags(final String rsqlParam, final Pageable pageable) {
|
||||||
final Specification<JpaDistributionSetTag> spec = RSQLUtility.parse(rsqlParam, TagFields.class);
|
final Specification<JpaDistributionSetTag> spec = RSQLUtility.parse(rsqlParam, TagFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertDsPage(distributionSetTagRepository.findAll(spec, pageable), pageable);
|
return convertDsPage(distributionSetTagRepository.findAll(spec, pageable), pageable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
|||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetFilterQuerySpecification;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -49,6 +50,9 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TargetFilterQueryRepository targetFilterQueryRepository;
|
private TargetFilterQueryRepository targetFilterQueryRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Modifying
|
@Modifying
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@@ -95,7 +99,8 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull Pageable pageable, String rsqlFilter) {
|
public Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull Pageable pageable, String rsqlFilter) {
|
||||||
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
|
List<Specification<JpaTargetFilterQuery>> specList = Collections.emptyList();
|
||||||
if (!Strings.isNullOrEmpty(rsqlFilter)) {
|
if (!Strings.isNullOrEmpty(rsqlFilter)) {
|
||||||
specList = Collections.singletonList(RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class));
|
specList = Collections.singletonList(
|
||||||
|
RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class, virtualPropertyReplacer));
|
||||||
}
|
}
|
||||||
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
||||||
}
|
}
|
||||||
@@ -114,7 +119,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
|
specList.add(TargetFilterQuerySpecification.byAutoAssignDS(distributionSet));
|
||||||
}
|
}
|
||||||
if (!Strings.isNullOrEmpty(rsqlFilter)) {
|
if (!Strings.isNullOrEmpty(rsqlFilter)) {
|
||||||
specList.add(RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class));
|
specList.add(RSQLUtility.parse(rsqlFilter, TargetFilterQueryFields.class, virtualPropertyReplacer));
|
||||||
}
|
}
|
||||||
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
return convertPage(findTargetFilterQueryByCriteriaAPI(pageable, specList), pageable);
|
||||||
}
|
}
|
||||||
@@ -156,7 +161,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verifyTargetFilterQuerySyntax(final String query) {
|
public boolean verifyTargetFilterQuerySyntax(final String query) {
|
||||||
RSQLUtility.parse(query, TargetFields.class);
|
RSQLUtility.parse(query, TargetFields.class, virtualPropertyReplacer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -29,6 +28,8 @@ import javax.persistence.criteria.Predicate;
|
|||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.eclipse.hawkbit.repository.FilterParams;
|
||||||
import org.eclipse.hawkbit.repository.TargetFields;
|
import org.eclipse.hawkbit.repository.TargetFields;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
||||||
@@ -43,6 +44,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo_;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget_;
|
||||||
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder;
|
||||||
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
@@ -68,7 +70,6 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
@@ -104,6 +105,9 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AfterTransactionCommitExecutor afterCommit;
|
private AfterTransactionCommitExecutor afterCommit;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Target findTargetByControllerID(final String controllerId) {
|
public Target findTargetByControllerID(final String controllerId) {
|
||||||
return targetRepository.findByControllerId(controllerId);
|
return targetRepository.findByControllerId(controllerId);
|
||||||
@@ -154,12 +158,15 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Slice<Target> findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) {
|
public Slice<Target> findTargetsAll(final TargetFilterQuery targetFilterQuery, final Pageable pageable) {
|
||||||
return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class), pageable);
|
return findTargetsBySpec(
|
||||||
|
RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyReplacer),
|
||||||
|
pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<Target> findTargetsAll(final String targetFilterQuery, final Pageable pageable) {
|
public Page<Target> findTargetsAll(final String targetFilterQuery, final Pageable pageable) {
|
||||||
return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery, TargetFields.class), pageable);
|
return findTargetsBySpec(RSQLUtility.parse(targetFilterQuery, TargetFields.class, virtualPropertyReplacer),
|
||||||
|
pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Page<Target> findTargetsBySpec(final Specification<JpaTarget> spec, final Pageable pageable) {
|
private Page<Target> findTargetsBySpec(final Specification<JpaTarget> spec, final Pageable pageable) {
|
||||||
@@ -223,7 +230,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
public Page<Target> findTargetByAssignedDistributionSet(final Long distributionSetID, final String rsqlParam,
|
public Page<Target> findTargetByAssignedDistributionSet(final Long distributionSetID, final String rsqlParam,
|
||||||
final Pageable pageReq) {
|
final Pageable pageReq) {
|
||||||
|
|
||||||
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class);
|
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertPage(
|
return convertPage(
|
||||||
targetRepository
|
targetRepository
|
||||||
@@ -251,7 +259,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId, final String rsqlParam,
|
public Page<Target> findTargetByInstalledDistributionSet(final Long distributionSetId, final String rsqlParam,
|
||||||
final Pageable pageable) {
|
final Pageable pageable) {
|
||||||
|
|
||||||
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class);
|
final Specification<JpaTarget> spec = RSQLUtility.parse(rsqlParam, TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return convertPage(
|
return convertPage(
|
||||||
targetRepository
|
targetRepository
|
||||||
@@ -269,42 +278,56 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Slice<Target> findTargetByFilters(final Pageable pageable, final Collection<TargetUpdateStatus> status,
|
public Slice<Target> findTargetByFilters(final Pageable pageable, final Collection<TargetUpdateStatus> status,
|
||||||
final String searchText, final Long installedOrAssignedDistributionSetId,
|
final Boolean overdueState, final String searchText, final Long installedOrAssignedDistributionSetId,
|
||||||
final Boolean selectTargetWithNoTag, final String... tagNames) {
|
final Boolean selectTargetWithNoTag, final String... tagNames) {
|
||||||
final List<Specification<JpaTarget>> specList = buildSpecificationList(status, searchText,
|
final List<Specification<JpaTarget>> specList = buildSpecificationList(
|
||||||
installedOrAssignedDistributionSetId, selectTargetWithNoTag, true, tagNames);
|
new FilterParams(installedOrAssignedDistributionSetId, status, overdueState, searchText,
|
||||||
|
selectTargetWithNoTag, tagNames),
|
||||||
|
true);
|
||||||
return findByCriteriaAPI(pageable, specList);
|
return findByCriteriaAPI(pageable, specList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long countTargetByFilters(final Collection<TargetUpdateStatus> status, final String searchText,
|
public Long countTargetByFilters(final Collection<TargetUpdateStatus> status, final Boolean overdueState,
|
||||||
final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag,
|
final String searchText, final Long installedOrAssignedDistributionSetId,
|
||||||
final String... tagNames) {
|
final Boolean selectTargetWithNoTag, final String... tagNames) {
|
||||||
final List<Specification<JpaTarget>> specList = buildSpecificationList(status, searchText,
|
final List<Specification<JpaTarget>> specList = buildSpecificationList(
|
||||||
installedOrAssignedDistributionSetId, selectTargetWithNoTag, true, tagNames);
|
new FilterParams(installedOrAssignedDistributionSetId, status, overdueState, searchText,
|
||||||
|
selectTargetWithNoTag, tagNames),
|
||||||
|
true);
|
||||||
return countByCriteriaAPI(specList);
|
return countByCriteriaAPI(specList);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Specification<JpaTarget>> buildSpecificationList(final Collection<TargetUpdateStatus> status,
|
private static List<Specification<JpaTarget>> buildSpecificationList(final FilterParams filterParams,
|
||||||
final String searchText, final Long installedOrAssignedDistributionSetId,
|
final boolean fetch) {
|
||||||
final Boolean selectTargetWithNoTag, final boolean fetch, final String... tagNames) {
|
final List<Specification<JpaTarget>> specList = new ArrayList<>();
|
||||||
final List<Specification<JpaTarget>> specList = new LinkedList<>();
|
if (filterParams.getFilterByStatus() != null && !filterParams.getFilterByStatus().isEmpty()) {
|
||||||
if (status != null && !status.isEmpty()) {
|
specList.add(TargetSpecifications.hasTargetUpdateStatus(filterParams.getFilterByStatus(), fetch));
|
||||||
specList.add(TargetSpecifications.hasTargetUpdateStatus(status, fetch));
|
|
||||||
}
|
}
|
||||||
if (installedOrAssignedDistributionSetId != null) {
|
if (filterParams.getOverdueState() != null) {
|
||||||
specList.add(
|
specList.add(
|
||||||
TargetSpecifications.hasInstalledOrAssignedDistributionSet(installedOrAssignedDistributionSetId));
|
TargetSpecifications.isOverdue(TimestampCalculator.calculateOverdueTimestamp()));
|
||||||
}
|
}
|
||||||
if (!Strings.isNullOrEmpty(searchText)) {
|
if (filterParams.getFilterByDistributionId() != null) {
|
||||||
specList.add(TargetSpecifications.likeNameOrDescriptionOrIp(searchText));
|
specList.add(
|
||||||
|
TargetSpecifications
|
||||||
|
.hasInstalledOrAssignedDistributionSet(filterParams.getFilterByDistributionId()));
|
||||||
}
|
}
|
||||||
if (selectTargetWithNoTag != null && (selectTargetWithNoTag || (tagNames != null && tagNames.length > 0))) {
|
if (StringUtils.isNotEmpty(filterParams.getFilterBySearchText())) {
|
||||||
specList.add(TargetSpecifications.hasTags(tagNames, selectTargetWithNoTag));
|
specList.add(TargetSpecifications.likeNameOrDescriptionOrIp(filterParams.getFilterBySearchText()));
|
||||||
|
}
|
||||||
|
if (isHasTagsFilterActive(filterParams)) {
|
||||||
|
specList.add(TargetSpecifications.hasTags(filterParams.getFilterByTagNames(),
|
||||||
|
filterParams.getSelectTargetWithNoTag()));
|
||||||
}
|
}
|
||||||
return specList;
|
return specList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isHasTagsFilterActive(final FilterParams filterParams) {
|
||||||
|
return filterParams.getSelectTargetWithNoTag() != null && (filterParams.getSelectTargetWithNoTag()
|
||||||
|
|| (filterParams.getFilterByTagNames() != null && filterParams.getFilterByTagNames().length > 0));
|
||||||
|
}
|
||||||
|
|
||||||
private Slice<Target> findByCriteriaAPI(final Pageable pageable, final List<Specification<JpaTarget>> specList) {
|
private Slice<Target> findByCriteriaAPI(final Pageable pageable, final List<Specification<JpaTarget>> specList) {
|
||||||
if (specList == null || specList.isEmpty()) {
|
if (specList == null || specList.isEmpty()) {
|
||||||
return convertPage(criteriaNoCountDao.findAll(pageable, JpaTarget.class), pageable);
|
return convertPage(criteriaNoCountDao.findAll(pageable, JpaTarget.class), pageable);
|
||||||
@@ -418,9 +441,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Slice<Target> findTargetsAllOrderByLinkedDistributionSet(final Pageable pageable,
|
public Slice<Target> findTargetsAllOrderByLinkedDistributionSet(final Pageable pageable,
|
||||||
final Long orderByDistributionId, final Long filterByDistributionId,
|
final Long orderByDistributionId, final FilterParams filterParams) {
|
||||||
final Collection<TargetUpdateStatus> filterByStatus, final String filterBySearchText,
|
|
||||||
final Boolean selectTargetWithNoTag, final String... filterByTagNames) {
|
|
||||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
final CriteriaQuery<JpaTarget> query = cb.createQuery(JpaTarget.class);
|
final CriteriaQuery<JpaTarget> query = cb.createQuery(JpaTarget.class);
|
||||||
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
|
final Root<JpaTarget> targetRoot = query.from(JpaTarget.class);
|
||||||
@@ -443,8 +465,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
// build the specifications and then to predicates necessary by the
|
// build the specifications and then to predicates necessary by the
|
||||||
// given filters
|
// given filters
|
||||||
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
|
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
|
||||||
buildSpecificationList(filterByStatus, filterBySearchText, filterByDistributionId,
|
buildSpecificationList(filterParams, true),
|
||||||
selectTargetWithNoTag, true, filterByTagNames),
|
|
||||||
targetRoot, query, cb);
|
targetRoot, query, cb);
|
||||||
|
|
||||||
// if we have some predicates then add it to the where clause of the
|
// if we have some predicates then add it to the where clause of the
|
||||||
@@ -500,7 +521,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TargetIdName> findAllTargetIdsByFilters(final Pageable pageRequest,
|
public List<TargetIdName> findAllTargetIdsByFilters(final Pageable pageRequest,
|
||||||
final Collection<TargetUpdateStatus> filterByStatus, final String filterBySearchText,
|
final Collection<TargetUpdateStatus> filterByStatus, final Boolean overdueState,
|
||||||
|
final String filterBySearchText,
|
||||||
final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag,
|
final Long installedOrAssignedDistributionSetId, final Boolean selectTargetWithNoTag,
|
||||||
final String... filterByTagNames) {
|
final String... filterByTagNames) {
|
||||||
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||||
@@ -517,8 +539,9 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
|
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
|
||||||
|
|
||||||
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
|
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(
|
||||||
buildSpecificationList(filterByStatus, filterBySearchText, installedOrAssignedDistributionSetId,
|
buildSpecificationList(new FilterParams(installedOrAssignedDistributionSetId, filterByStatus,
|
||||||
selectTargetWithNoTag, false, filterByTagNames),
|
overdueState, filterBySearchText,
|
||||||
|
selectTargetWithNoTag, filterByTagNames), false),
|
||||||
targetRoot, multiselect, cb);
|
targetRoot, multiselect, cb);
|
||||||
|
|
||||||
// if we have some predicates then add it to the where clause of the
|
// if we have some predicates then add it to the where clause of the
|
||||||
@@ -547,7 +570,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id),
|
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id),
|
||||||
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
|
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
|
||||||
|
|
||||||
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
|
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(Lists.newArrayList(spec), targetRoot,
|
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(Lists.newArrayList(spec), targetRoot,
|
||||||
multiselect, cb);
|
multiselect, cb);
|
||||||
|
|
||||||
@@ -565,7 +589,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull final Pageable pageRequest,
|
public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull final Pageable pageRequest,
|
||||||
final Long distributionSetId, @NotNull final TargetFilterQuery targetFilterQuery) {
|
final Long distributionSetId, @NotNull final TargetFilterQuery targetFilterQuery) {
|
||||||
|
|
||||||
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
|
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
|
|
||||||
return findTargetsBySpec(
|
return findTargetsBySpec(
|
||||||
(root, cq,
|
(root, cq,
|
||||||
@@ -578,7 +603,8 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
@Override
|
@Override
|
||||||
public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId,
|
public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId,
|
||||||
@NotNull final TargetFilterQuery targetFilterQuery) {
|
@NotNull final TargetFilterQuery targetFilterQuery) {
|
||||||
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
|
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
|
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
|
||||||
specList.add(spec);
|
specList.add(spec);
|
||||||
specList.add(TargetSpecifications.hasNotDistributionSetInActions(distributionSetId));
|
specList.add(TargetSpecifications.hasNotDistributionSetInActions(distributionSetId));
|
||||||
@@ -650,13 +676,15 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long countTargetByTargetFilterQuery(final TargetFilterQuery targetFilterQuery) {
|
public Long countTargetByTargetFilterQuery(final TargetFilterQuery targetFilterQuery) {
|
||||||
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
|
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
return targetRepository.count(specs);
|
return targetRepository.count(specs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long countTargetByTargetFilterQuery(final String targetFilterQuery) {
|
public Long countTargetByTargetFilterQuery(final String targetFilterQuery) {
|
||||||
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class);
|
final Specification<JpaTarget> specs = RSQLUtility.parse(targetFilterQuery, TargetFields.class,
|
||||||
|
virtualPropertyReplacer);
|
||||||
return targetRepository.count(specs);
|
return targetRepository.count(specs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,12 @@ import javax.persistence.criteria.Path;
|
|||||||
import javax.persistence.criteria.Predicate;
|
import javax.persistence.criteria.Predicate;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.text.StrLookup;
|
||||||
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||||
import org.eclipse.hawkbit.repository.FieldValueConverter;
|
import org.eclipse.hawkbit.repository.FieldValueConverter;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.SimpleTypeConverter;
|
import org.springframework.beans.SimpleTypeConverter;
|
||||||
@@ -47,9 +49,8 @@ import cz.jirutka.rsql.parser.ast.RSQLOperators;
|
|||||||
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A utility class which is able to parse RSQL strings into an spring data
|
* A utility class which is able to parse RSQL strings into an spring data {@link Specification} which then can be
|
||||||
* {@link Specification} which then can be enhanced sql queries to filter
|
* enhanced sql queries to filter entities. RSQL parser library: https://github.com/jirutka/rsql-parser
|
||||||
* entities. RSQL parser library: https://github.com/jirutka/rsql-parser
|
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Equal to : ==</li>
|
* <li>Equal to : ==</li>
|
||||||
@@ -59,16 +60,24 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor;
|
|||||||
* <li>Greater than operator : =gt= or ></li>
|
* <li>Greater than operator : =gt= or ></li>
|
||||||
* <li>Greater than or equal to : =ge= or >=</li>
|
* <li>Greater than or equal to : =ge= or >=</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
* <p>
|
||||||
* Examples of RSQL expressions in both FIQL-like and alternative notation:
|
* Examples of RSQL expressions in both FIQL-like and alternative notation:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>version==2.0.0</li>
|
* <li>version==2.0.0</li>
|
||||||
* <li>name==targetId1;description==plugAndPlay</li>
|
* <li>name==targetId1;description==plugAndPlay</li>
|
||||||
* <li>name==targetId1 and description==plugAndPlay</li>
|
* <li>name==targetId1 and description==plugAndPlay</li>
|
||||||
* <li>name==targetId1;description==plugAndPlay</li>
|
|
||||||
* <li>name==targetId1 and description==plugAndPlay</li>
|
|
||||||
* <li>name==targetId1,description==plugAndPlay,updateStatus==UNKNOWN</li>
|
* <li>name==targetId1,description==plugAndPlay,updateStatus==UNKNOWN</li>
|
||||||
* <li>name==targetId1 or description==plugAndPlay or updateStatus==UNKNOWN</li>
|
* <li>name==targetId1 or description==plugAndPlay or updateStatus==UNKNOWN</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* There is also a mechanism that allows to refer to known macros that can resolved by an optional {@link StrLookup}
|
||||||
|
* (cp. {@link VirtualPropertyResolver}).<br>
|
||||||
|
* An example that queries for all overdue targets using the ${OVERDUE_TS} placeholder introduced by
|
||||||
|
* {@link VirtualPropertyResolver} looks like this:<br>
|
||||||
|
* <em>lastControllerRequestAt=le=${OVERDUE_TS}</em><br>
|
||||||
|
* It is possible to escape a macro expression by using a second '$': $${OVERDUE_TS} would prevent the ${OVERDUE_TS}
|
||||||
|
* token from being expanded.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public final class RSQLUtility {
|
public final class RSQLUtility {
|
||||||
|
|
||||||
@@ -90,6 +99,9 @@ public final class RSQLUtility {
|
|||||||
* @param fieldNameProvider
|
* @param fieldNameProvider
|
||||||
* the enum class type which implements the
|
* the enum class type which implements the
|
||||||
* {@link FieldNameProvider}
|
* {@link FieldNameProvider}
|
||||||
|
* @param virtualPropertyReplacer
|
||||||
|
* holds the logic how the known macros have to be resolved; may
|
||||||
|
* be <code>null</code>
|
||||||
* @return an specification which can be used with JPA
|
* @return an specification which can be used with JPA
|
||||||
* @throws RSQLParameterUnsupportedFieldException
|
* @throws RSQLParameterUnsupportedFieldException
|
||||||
* if a field in the RSQL string is used but not provided by the
|
* if a field in the RSQL string is used but not provided by the
|
||||||
@@ -98,8 +110,8 @@ public final class RSQLUtility {
|
|||||||
* if the RSQL syntax is wrong
|
* if the RSQL syntax is wrong
|
||||||
*/
|
*/
|
||||||
public static <A extends Enum<A> & FieldNameProvider, T> Specification<T> parse(final String rsql,
|
public static <A extends Enum<A> & FieldNameProvider, T> Specification<T> parse(final String rsql,
|
||||||
final Class<A> fieldNameProvider) {
|
final Class<A> fieldNameProvider, VirtualPropertyReplacer virtualPropertyReplacer) {
|
||||||
return new RSQLSpecification<>(rsql.toLowerCase(), fieldNameProvider);
|
return new RSQLSpecification<>(rsql.toLowerCase(), fieldNameProvider, virtualPropertyReplacer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,10 +142,13 @@ public final class RSQLUtility {
|
|||||||
|
|
||||||
private final String rsql;
|
private final String rsql;
|
||||||
private final Class<A> enumType;
|
private final Class<A> enumType;
|
||||||
|
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
private RSQLSpecification(final String rsql, final Class<A> enumType) {
|
private RSQLSpecification(final String rsql, final Class<A> enumType,
|
||||||
|
VirtualPropertyReplacer virtualPropertyReplacer) {
|
||||||
this.rsql = rsql;
|
this.rsql = rsql;
|
||||||
this.enumType = enumType;
|
this.enumType = enumType;
|
||||||
|
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -141,7 +156,8 @@ public final class RSQLUtility {
|
|||||||
|
|
||||||
final Node rootNode = parseRsql(rsql);
|
final Node rootNode = parseRsql(rsql);
|
||||||
|
|
||||||
final JpqQueryRSQLVisitor<A, T> jpqQueryRSQLVisitor = new JpqQueryRSQLVisitor<>(root, cb, enumType);
|
final JpqQueryRSQLVisitor<A, T> jpqQueryRSQLVisitor = new JpqQueryRSQLVisitor<>(root, cb, enumType,
|
||||||
|
virtualPropertyReplacer);
|
||||||
final List<Predicate> accept = rootNode.<List<Predicate>, String> accept(jpqQueryRSQLVisitor);
|
final List<Predicate> accept = rootNode.<List<Predicate>, String> accept(jpqQueryRSQLVisitor);
|
||||||
|
|
||||||
if (accept != null && !accept.isEmpty()) {
|
if (accept != null && !accept.isEmpty()) {
|
||||||
@@ -171,13 +187,16 @@ public final class RSQLUtility {
|
|||||||
private final Root<T> root;
|
private final Root<T> root;
|
||||||
private final CriteriaBuilder cb;
|
private final CriteriaBuilder cb;
|
||||||
private final Class<A> enumType;
|
private final Class<A> enumType;
|
||||||
|
private final VirtualPropertyReplacer virtualPropertyReplacer;
|
||||||
|
|
||||||
private final SimpleTypeConverter simpleTypeConverter;
|
private final SimpleTypeConverter simpleTypeConverter;
|
||||||
|
|
||||||
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType) {
|
private JpqQueryRSQLVisitor(final Root<T> root, final CriteriaBuilder cb, final Class<A> enumType,
|
||||||
|
VirtualPropertyReplacer virtualPropertyReplacer) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
this.cb = cb;
|
this.cb = cb;
|
||||||
this.enumType = enumType;
|
this.enumType = enumType;
|
||||||
|
this.virtualPropertyReplacer = virtualPropertyReplacer;
|
||||||
simpleTypeConverter = new SimpleTypeConverter();
|
simpleTypeConverter = new SimpleTypeConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +218,7 @@ public final class RSQLUtility {
|
|||||||
return toSingleList(cb.conjunction());
|
return toSingleList(cb.conjunction());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Predicate> toSingleList(final Predicate predicate) {
|
private static List<Predicate> toSingleList(final Predicate predicate) {
|
||||||
return Collections.singletonList(predicate);
|
return Collections.singletonList(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,13 +367,10 @@ public final class RSQLUtility {
|
|||||||
private Object convertValueIfNecessary(final ComparisonNode node, final A fieldName, final String value,
|
private Object convertValueIfNecessary(final ComparisonNode node, final A fieldName, final String value,
|
||||||
final Path<Object> fieldPath) {
|
final Path<Object> fieldPath) {
|
||||||
// in case the value of an rsql query e.g. type==application is an
|
// in case the value of an rsql query e.g. type==application is an
|
||||||
// enum we need to
|
// enum we need to handle it separately because JPA needs the
|
||||||
// handle it separately because JPA needs the correct java-type to
|
// correct java-type to build an expression. So String and numeric
|
||||||
// build an
|
// values JPA can do it by it's own but not for classes like enums.
|
||||||
// expression. So String and numeric values JPA can do it by it's
|
// So we need to transform the given value string into the enum
|
||||||
// own but not for
|
|
||||||
// classes like enums. So we need to transform the given value
|
|
||||||
// string into the enum
|
|
||||||
// class.
|
// class.
|
||||||
final Class<? extends Object> javaType = fieldPath.getJavaType();
|
final Class<? extends Object> javaType = fieldPath.getJavaType();
|
||||||
if (javaType != null && javaType.isEnum()) {
|
if (javaType != null && javaType.isEnum()) {
|
||||||
@@ -399,15 +415,14 @@ public final class RSQLUtility {
|
|||||||
// Exception squid:S2095 - see
|
// Exception squid:S2095 - see
|
||||||
// https://jira.sonarsource.com/browse/SONARJAVA-1478
|
// https://jira.sonarsource.com/browse/SONARJAVA-1478
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked", "squid:S2095" })
|
@SuppressWarnings({ "rawtypes", "unchecked", "squid:S2095" })
|
||||||
private Object transformEnumValue(final ComparisonNode node, final String value,
|
private static Object transformEnumValue(final ComparisonNode node, final String value,
|
||||||
final Class<? extends Object> javaType) {
|
final Class<? extends Object> javaType) {
|
||||||
final Class<? extends Enum> tmpEnumType = (Class<? extends Enum>) javaType;
|
final Class<? extends Enum> tmpEnumType = (Class<? extends Enum>) javaType;
|
||||||
try {
|
try {
|
||||||
return Enum.valueOf(tmpEnumType, value.toUpperCase());
|
return Enum.valueOf(tmpEnumType, value.toUpperCase());
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
// we could not transform the given string value into the enum
|
// we could not transform the given string value into the enum
|
||||||
// type, so ignore
|
// type, so ignore it and return null and do not filter
|
||||||
// it and return null and do not filter
|
|
||||||
LOGGER.info("given value {} cannot be transformed into the correct enum type {}", value.toUpperCase(),
|
LOGGER.info("given value {} cannot be transformed into the correct enum type {}", value.toUpperCase(),
|
||||||
javaType);
|
javaType);
|
||||||
LOGGER.debug("value cannot be transformed to an enum", e);
|
LOGGER.debug("value cannot be transformed to an enum", e);
|
||||||
@@ -422,10 +437,16 @@ public final class RSQLUtility {
|
|||||||
private List<Predicate> mapToPredicate(final ComparisonNode node, final Path<Object> fieldPath,
|
private List<Predicate> mapToPredicate(final ComparisonNode node, final Path<Object> fieldPath,
|
||||||
final List<String> values, final List<Object> transformedValues, final A enumField) {
|
final List<String> values, final List<Object> transformedValues, final A enumField) {
|
||||||
// only 'equal' and 'notEqual' can handle transformed value like
|
// only 'equal' and 'notEqual' can handle transformed value like
|
||||||
// enums. The JPA API
|
// enums. The JPA API cannot handle object types for greaterThan etc
|
||||||
// cannot handle object types for greaterThan etc methods.
|
// methods.
|
||||||
final Object transformedValue = transformedValues.get(0);
|
final Object transformedValue = transformedValues.get(0);
|
||||||
final String value = values.get(0);
|
|
||||||
|
String value = values.get(0);
|
||||||
|
// if lookup is available, replace macros ...
|
||||||
|
if (virtualPropertyReplacer != null) {
|
||||||
|
value = virtualPropertyReplacer.replace(value);
|
||||||
|
}
|
||||||
|
|
||||||
final List<Predicate> singleList = new ArrayList<>();
|
final List<Predicate> singleList = new ArrayList<>();
|
||||||
|
|
||||||
final Predicate mapPredicate = mapToMapPredicate(node, fieldPath, enumField);
|
final Predicate mapPredicate = mapToMapPredicate(node, fieldPath, enumField);
|
||||||
@@ -541,12 +562,12 @@ public final class RSQLUtility {
|
|||||||
return cb.notEqual(fieldPath, transformedValue);
|
return cb.notEqual(fieldPath, transformedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String escapeValueToSQL(final String transformedValue) {
|
private static String escapeValueToSQL(final String transformedValue) {
|
||||||
return transformedValue.replace("%", "\\%").replace(LIKE_WILDCARD, '%');
|
return transformedValue.replace("%", "\\%").replace(LIKE_WILDCARD, '%');
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <Y> Path<Y> pathOfString(final Path<?> path) {
|
private static <Y> Path<Y> pathOfString(final Path<?> path) {
|
||||||
return (Path<Y>) path;
|
return (Path<Y>) path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,4 +586,5 @@ public final class RSQLUtility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public final class TargetSpecifications {
|
|||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link Target}s by "equal to given
|
* {@link Specification} for retrieving {@link Target}s by "equal to given
|
||||||
* {@link TargetUpdateStatus}".
|
* {@link TargetUpdateStatus}".
|
||||||
*
|
*
|
||||||
* @param updateStatus
|
* @param updateStatus
|
||||||
* to be filtered on
|
* to be filtered on
|
||||||
* @param fetch
|
* @param fetch
|
||||||
@@ -113,10 +113,34 @@ 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>
|
||||||
|
* <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>
|
||||||
|
* <em>overdueTimestamp = nowTimestamp - poll_itvl -
|
||||||
|
* overdue_itvl</em>
|
||||||
|
*
|
||||||
|
* @return the {@link Target} {@link Specification}
|
||||||
|
*/
|
||||||
|
public static Specification<JpaTarget> isOverdue(final long overdueTimestamp) {
|
||||||
|
return (targetRoot, query, cb) -> {
|
||||||
|
final Join<JpaTarget, JpaTargetInfo> targetInfoJoin = targetRoot.join(JpaTarget_.targetInfo);
|
||||||
|
return cb.lessThanOrEqualTo(
|
||||||
|
targetInfoJoin.get(JpaTargetInfo_.lastTargetQuery), overdueTimestamp);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link Target}s by
|
* {@link Specification} for retrieving {@link Target}s by
|
||||||
* "like controllerId or like description or like ip address".
|
* "like controllerId or like description or like ip address".
|
||||||
*
|
*
|
||||||
* @param searchText
|
* @param searchText
|
||||||
* to be filtered on
|
* to be filtered on
|
||||||
* @return the {@link Target} {@link Specification}
|
* @return the {@link Target} {@link Specification}
|
||||||
@@ -132,7 +156,7 @@ public final class TargetSpecifications {
|
|||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link Target}s by
|
* {@link Specification} for retrieving {@link Target}s by
|
||||||
* "like controllerId".
|
* "like controllerId".
|
||||||
*
|
*
|
||||||
* @param distributionId
|
* @param distributionId
|
||||||
* to be filtered on
|
* to be filtered on
|
||||||
* @return the {@link Target} {@link Specification}
|
* @return the {@link Target} {@link Specification}
|
||||||
@@ -169,7 +193,7 @@ public final class TargetSpecifications {
|
|||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link Target}s by
|
* {@link Specification} for retrieving {@link Target}s by
|
||||||
* "has no tag names"or "has at least on of the given tag names".
|
* "has no tag names"or "has at least on of the given tag names".
|
||||||
*
|
*
|
||||||
* @param tagNames
|
* @param tagNames
|
||||||
* to be filtered on
|
* to be filtered on
|
||||||
* @param selectTargetWithNoTag
|
* @param selectTargetWithNoTag
|
||||||
@@ -202,7 +226,7 @@ public final class TargetSpecifications {
|
|||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link Target}s by assigned
|
* {@link Specification} for retrieving {@link Target}s by assigned
|
||||||
* distribution set.
|
* distribution set.
|
||||||
*
|
*
|
||||||
* @param distributionSetId
|
* @param distributionSetId
|
||||||
* the ID of the distribution set which must be assigned
|
* the ID of the distribution set which must be assigned
|
||||||
* @return the {@link Target} {@link Specification}
|
* @return the {@link Target} {@link Specification}
|
||||||
@@ -234,7 +258,7 @@ public final class TargetSpecifications {
|
|||||||
/**
|
/**
|
||||||
* {@link Specification} for retrieving {@link Target}s by assigned
|
* {@link Specification} for retrieving {@link Target}s by assigned
|
||||||
* distribution set.
|
* distribution set.
|
||||||
*
|
*
|
||||||
* @param distributionSetId
|
* @param distributionSetId
|
||||||
* the ID of the distribution set which must be assigned
|
* the ID of the distribution set which must be assigned
|
||||||
* @return the {@link Target} {@link Specification}
|
* @return the {@link Target} {@link Specification}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
|
|||||||
|
|
||||||
import static org.fest.assertions.api.Assertions.assertThat;
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -17,6 +18,7 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.FilterParams;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
@@ -53,26 +55,42 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
final DistributionSet installedSet = testdataFactory.createDistributionSet("another");
|
final DistributionSet installedSet = testdataFactory.createDistributionSet("another");
|
||||||
|
|
||||||
|
final Long lastTargetQueryNotOverdue = Instant.now().toEpochMilli();
|
||||||
|
final Long lastTargetQueryAlwaysOverdue = 0L;
|
||||||
|
final Long lastTargetNull = null;
|
||||||
|
|
||||||
final String targetDsAIdPref = "targ-A";
|
final String targetDsAIdPref = "targ-A";
|
||||||
List<Target> targAs = targetManagement.createTargets(
|
List<Target> targAs = new ArrayList<Target>();
|
||||||
testdataFactory.generateTargets(100, targetDsAIdPref, targetDsAIdPref.concat(" description")));
|
for (Target t : testdataFactory.generateTargets(100, targetDsAIdPref, targetDsAIdPref.concat(" description"))) {
|
||||||
|
targAs.add(targetManagement.createTarget(t, TargetUpdateStatus.UNKNOWN, lastTargetQueryNotOverdue,
|
||||||
|
t.getTargetInfo().getAddress()));
|
||||||
|
}
|
||||||
targAs = targetManagement.toggleTagAssignment(targAs, targTagX).getAssignedEntity();
|
targAs = targetManagement.toggleTagAssignment(targAs, targTagX).getAssignedEntity();
|
||||||
|
|
||||||
final String targetDsBIdPref = "targ-B";
|
final String targetDsBIdPref = "targ-B";
|
||||||
List<Target> targBs = targetManagement.createTargets(
|
List<Target> targBs = new ArrayList<Target>();
|
||||||
testdataFactory.generateTargets(100, targetDsBIdPref, targetDsBIdPref.concat(" description")));
|
for (Target t : testdataFactory.generateTargets(100, targetDsBIdPref, targetDsBIdPref.concat(" description"))) {
|
||||||
|
targBs.add(targetManagement.createTarget(t, TargetUpdateStatus.UNKNOWN, lastTargetQueryAlwaysOverdue,
|
||||||
|
t.getTargetInfo().getAddress()));
|
||||||
|
}
|
||||||
targBs = targetManagement.toggleTagAssignment(targBs, targTagY).getAssignedEntity();
|
targBs = targetManagement.toggleTagAssignment(targBs, targTagY).getAssignedEntity();
|
||||||
targBs = targetManagement.toggleTagAssignment(targBs, targTagW).getAssignedEntity();
|
targBs = targetManagement.toggleTagAssignment(targBs, targTagW).getAssignedEntity();
|
||||||
|
|
||||||
final String targetDsCIdPref = "targ-C";
|
final String targetDsCIdPref = "targ-C";
|
||||||
List<Target> targCs = targetManagement.createTargets(
|
List<Target> targCs = new ArrayList<Target>();
|
||||||
testdataFactory.generateTargets(100, targetDsCIdPref, targetDsCIdPref.concat(" description")));
|
for (Target t : testdataFactory.generateTargets(100, targetDsCIdPref, targetDsCIdPref.concat(" description"))) {
|
||||||
|
targCs.add(targetManagement.createTarget(t, TargetUpdateStatus.UNKNOWN, lastTargetQueryAlwaysOverdue,
|
||||||
|
t.getTargetInfo().getAddress()));
|
||||||
|
}
|
||||||
targCs = targetManagement.toggleTagAssignment(targCs, targTagZ).getAssignedEntity();
|
targCs = targetManagement.toggleTagAssignment(targCs, targTagZ).getAssignedEntity();
|
||||||
targCs = targetManagement.toggleTagAssignment(targCs, targTagW).getAssignedEntity();
|
targCs = targetManagement.toggleTagAssignment(targCs, targTagW).getAssignedEntity();
|
||||||
|
|
||||||
final String targetDsDIdPref = "targ-D";
|
final String targetDsDIdPref = "targ-D";
|
||||||
final List<Target> targDs = targetManagement.createTargets(
|
List<Target> targDs = new ArrayList<Target>();
|
||||||
testdataFactory.generateTargets(100, targetDsDIdPref, targetDsDIdPref.concat(" description")));
|
for (Target t : testdataFactory.generateTargets(100, targetDsDIdPref, targetDsDIdPref.concat(" description"))) {
|
||||||
|
targDs.add(targetManagement.createTarget(t, TargetUpdateStatus.UNKNOWN, lastTargetNull,
|
||||||
|
t.getTargetInfo().getAddress()));
|
||||||
|
}
|
||||||
|
|
||||||
final String assignedC = targCs.iterator().next().getControllerId();
|
final String assignedC = targCs.iterator().next().getControllerId();
|
||||||
deploymentManagement.assignDistributionSet(setA.getId(), assignedC);
|
deploymentManagement.assignDistributionSet(setA.getId(), assignedC);
|
||||||
@@ -148,6 +166,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
verifyThat200targetsWithGivenTagAreInStatusPendingorUnknown(targTagW, both, concat(targBs, targCs));
|
verifyThat200targetsWithGivenTagAreInStatusPendingorUnknown(targTagW, both, concat(targBs, targCs));
|
||||||
verfiyThat1TargetAIsInStatusPendingAndHasDSInstalled(installedSet, pending,
|
verfiyThat1TargetAIsInStatusPendingAndHasDSInstalled(installedSet, pending,
|
||||||
targetManagement.findTargetByControllerID(installedC));
|
targetManagement.findTargetByControllerID(installedC));
|
||||||
|
|
||||||
|
expected = concat(targBs, targCs);
|
||||||
|
expected.removeAll(targetManagement.findTargetByControllerID(Lists.newArrayList(assignedB, assignedC)));
|
||||||
|
verifyThat198TargetsAreInStatusUnknownAndOverdue(unknown, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -157,10 +179,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "updatestatus==pending and installedds.name==" + installedSet.getName();
|
final String query = "updatestatus==pending and installedds.name==" + installedSet.getName();
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, pending, null, installedSet.getId(), Boolean.FALSE, new String[0])
|
.findTargetByFilters(pageReq, pending, null, null, installedSet.getId(), Boolean.FALSE, new String[0])
|
||||||
.getContent()).as("has number of elements").hasSize(1)
|
.getContent()).as("has number of elements").hasSize(1)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
|
||||||
installedSet.getId(), Boolean.FALSE, new String[0])))
|
installedSet.getId(), Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsExactly(expected)
|
.as("and contains the following elements").containsExactly(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -168,7 +190,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, installedSet.getId(),
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, installedSet.getId(),
|
||||||
Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1)
|
Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1)
|
||||||
.as("and contains the following elements").containsExactly(expectedIdName)
|
.as("and contains the following elements").containsExactly(expectedIdName)
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
@@ -183,10 +205,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
final String query = "(updatestatus==pending or updatestatus==unknown) and tag==" + targTagW.getName();
|
final String query = "(updatestatus==pending or updatestatus==unknown) and tag==" + targTagW.getName();
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, both, null, null, Boolean.FALSE, targTagW.getName())
|
assertThat(targetManagement
|
||||||
.getContent()).as("has number of elements").hasSize(200)
|
.findTargetByFilters(pageReq, both, null, null, null, Boolean.FALSE, targTagW.getName()).getContent())
|
||||||
.as("that number is also returned by count query")
|
.as("has number of elements").hasSize(200).as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(both, null, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(both, null, null, null,
|
||||||
Boolean.FALSE, targTagW.getName())))
|
Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -194,7 +216,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, both, null, null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, both, null, null, null, Boolean.FALSE,
|
||||||
targTagW.getName())).as("has number of elements").hasSize(200).as("and contains the following elements")
|
targTagW.getName())).as("has number of elements").hasSize(200).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -217,10 +239,11 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
final String query = "updatestatus==pending and tag==" + targTagW.getName();
|
final String query = "updatestatus==pending and tag==" + targTagW.getName();
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, pending, null, null, Boolean.FALSE, targTagW.getName())
|
assertThat(targetManagement
|
||||||
|
.findTargetByFilters(pageReq, pending, null, null, null, Boolean.FALSE, targTagW.getName())
|
||||||
.getContent()).as("has number of elements").hasSize(2)
|
.getContent()).as("has number of elements").hasSize(2)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null, null,
|
||||||
Boolean.FALSE, targTagW.getName())))
|
Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -228,7 +251,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, null, Boolean.FALSE,
|
||||||
targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements")
|
targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -243,18 +266,18 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
+ setA.getName() + ") and tag==" + targTagW.getName();
|
+ setA.getName() + ") and tag==" + targTagW.getName();
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE, targTagW.getName())
|
.findTargetByFilters(pageReq, pending, null, null, setA.getId(), Boolean.FALSE, targTagW.getName())
|
||||||
.getContent()).as("has number of elements").hasSize(2)
|
.getContent()).as("has number of elements").hasSize(2)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, setA.getId(),
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
|
||||||
Boolean.FALSE, targTagW.getName())))
|
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, null, Boolean.FALSE,
|
||||||
targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements")
|
targTagW.getName())).as("has number of elements").hasSize(2).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -268,11 +291,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
final String query = "updatestatus==pending and (assignedds.name==" + setA.getName() + " or installedds.name=="
|
||||||
+ setA.getName() + ") and (name==*targ-B* or description==*targ-B*) and tag==" + targTagW.getName();
|
+ setA.getName() + ") and (name==*targ-B* or description==*targ-B*) and tag==" + targTagW.getName();
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement.findTargetByFilters(pageReq, pending, null, "%targ-B%", setA.getId(), Boolean.FALSE,
|
||||||
.findTargetByFilters(pageReq, pending, "%targ-B%", setA.getId(), Boolean.FALSE, targTagW.getName())
|
targTagW.getName()).getContent()).as("has number of elements").hasSize(1)
|
||||||
.getContent()).as("has number of elements").hasSize(1)
|
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, "%targ-B%",
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, "%targ-B%",
|
||||||
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and contains the following elements").containsExactly(expected)
|
.as("and contains the following elements").containsExactly(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -280,11 +302,11 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, "%targ-B%", setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, "%targ-B%", setA.getId(),
|
||||||
targTagW.getName())).as("has number of elements").hasSize(1).as("and contains the following elements")
|
Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(1)
|
||||||
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
|
.as("and contains the following elements").containsExactly(expectedIdName)
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -295,10 +317,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
+ setA.getName() + ") and (name==*targ-A* or description==*targ-A*)";
|
+ setA.getName() + ") and (name==*targ-A* or description==*targ-A*)";
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, pending, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])
|
.findTargetByFilters(pageReq, pending, null, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])
|
||||||
.getContent()).as("has number of elements").hasSize(1)
|
.getContent()).as("has number of elements").hasSize(1)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, "%targ-A%",
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, "%targ-A%",
|
||||||
setA.getId(), Boolean.FALSE, new String[0])))
|
setA.getId(), Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsExactly(expected)
|
.as("and contains the following elements").containsExactly(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -306,11 +328,11 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, "%targ-A%", setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, "%targ-A%", setA.getId(),
|
||||||
new String[0])).as("has number of elements").hasSize(1).as("and contains the following elements")
|
Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1)
|
||||||
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
|
.as("and contains the following elements").containsExactly(expectedIdName)
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -321,17 +343,17 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
+ setA.getName() + ")";
|
+ setA.getName() + ")";
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE, new String[0]).getContent())
|
.findTargetByFilters(pageReq, pending, null, null, setA.getId(), Boolean.FALSE, new String[0])
|
||||||
.as("has number of elements").hasSize(3).as("that number is also returned by count query")
|
.getContent()).as("has number of elements").hasSize(3).as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, setA.getId(),
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
|
||||||
Boolean.FALSE, new String[0])))
|
setA.getId(), Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, setA.getId(), Boolean.FALSE,
|
||||||
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
|
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -344,10 +366,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
final String query = "updatestatus==pending";
|
final String query = "updatestatus==pending";
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, pending, null, null, Boolean.FALSE, new String[0])
|
assertThat(targetManagement
|
||||||
.getContent()).as("has number of elements").hasSize(3)
|
.findTargetByFilters(pageReq, pending, null, null, null, Boolean.FALSE, new String[0]).getContent())
|
||||||
.as("that number is also returned by count query")
|
.as("has number of elements").hasSize(3).as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(pending, null, null, null,
|
||||||
Boolean.FALSE, new String[0])))
|
Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -355,9 +377,8 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, null, Boolean.FALSE,
|
||||||
targetManagement.findAllTargetIdsByFilters(pageReq, pending, null, null, Boolean.FALSE, new String[0]))
|
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
|
||||||
.as("has number of elements").hasSize(3).as("and contains the following elements")
|
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
new JpaTargetFilterQuery("test", query)));
|
new JpaTargetFilterQuery("test", query)));
|
||||||
@@ -371,18 +392,18 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
+ targTagW.getName();
|
+ targTagW.getName();
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, unknown, "%targ-B%", null, Boolean.FALSE, targTagW.getName())
|
.findTargetByFilters(pageReq, unknown, null, "%targ-B%", null, Boolean.FALSE, targTagW.getName())
|
||||||
.getContent()).as("has number of elements").hasSize(99)
|
.getContent()).as("has number of elements").hasSize(99)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, "%targ-B%", null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, "%targ-B%",
|
||||||
Boolean.FALSE, targTagW.getName())))
|
null, Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, "%targ-B%", null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, "%targ-B%", null, Boolean.FALSE,
|
||||||
targTagW.getName())).as("has number of elements").hasSize(99).as("and contains the following elements")
|
targTagW.getName())).as("has number of elements").hasSize(99).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -396,17 +417,17 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "updatestatus==unknown and (name==*targ-A* or description==*targ-A*)";
|
final String query = "updatestatus==unknown and (name==*targ-A* or description==*targ-A*)";
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, unknown, "%targ-A%", null, Boolean.FALSE, new String[0]).getContent())
|
.findTargetByFilters(pageReq, unknown, null, "%targ-A%", null, Boolean.FALSE, new String[0])
|
||||||
.as("has number of elements").hasSize(99).as("that number is also returned by count query")
|
.getContent()).as("has number of elements").hasSize(99)
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, "%targ-A%", null,
|
.as("that number is also returned by count query").hasSize(Ints.saturatedCast(targetManagement
|
||||||
Boolean.FALSE, new String[0])))
|
.countTargetByFilters(unknown, null, "%targ-A%", null, Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, "%targ-A%", null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, "%targ-A%", null, Boolean.FALSE,
|
||||||
new String[0])).as("has number of elements").hasSize(99).as("and contains the following elements")
|
new String[0])).as("has number of elements").hasSize(99).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -420,16 +441,16 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
+ setA.getName() + ")";
|
+ setA.getName() + ")";
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, unknown, null, setA.getId(), Boolean.FALSE, new String[0]).getContent())
|
.findTargetByFilters(pageReq, unknown, null, null, setA.getId(), Boolean.FALSE, new String[0])
|
||||||
.as("has number of elements").hasSize(0).as("that number is also returned by count query")
|
.getContent()).as("has number of elements").hasSize(0).as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, setA.getId(),
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null,
|
||||||
Boolean.FALSE, new String[0])))
|
setA.getId(), Boolean.FALSE, new String[0])))
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
|
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
|
||||||
.as("and NAMED filter query returns the same result").hasSize(targetManagement
|
.as("and NAMED filter query returns the same result").hasSize(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, setA.getId(), Boolean.FALSE,
|
||||||
new String[0])).as("has number of elements").hasSize(0)
|
new String[0])).as("has number of elements").hasSize(0)
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
@@ -442,10 +463,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "updatestatus==unknown and (tag==" + targTagY.getName() + " or tag==" + targTagW.getName()
|
final String query = "updatestatus==unknown and (tag==" + targTagY.getName() + " or tag==" + targTagW.getName()
|
||||||
+ ")";
|
+ ")";
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, unknown, null, null, Boolean.FALSE, targTagY.getName(),
|
assertThat(targetManagement.findTargetByFilters(pageReq, unknown, null, null, null, Boolean.FALSE,
|
||||||
targTagW.getName()).getContent()).as("has number of elements").hasSize(198)
|
targTagY.getName(), targTagW.getName()).getContent()).as("has number of elements").hasSize(198)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null, null,
|
||||||
Boolean.FALSE, targTagY.getName(), targTagW.getName())))
|
Boolean.FALSE, targTagY.getName(), targTagW.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -453,7 +474,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, null, Boolean.FALSE,
|
||||||
targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(198)
|
targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(198)
|
||||||
.as("and contains the following elements").containsAll(expectedIdNames)
|
.as("and contains the following elements").containsAll(expectedIdNames)
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
@@ -466,10 +487,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
final String query = "updatestatus==unknown";
|
final String query = "updatestatus==unknown";
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, unknown, null, null, Boolean.FALSE, new String[0])
|
assertThat(targetManagement
|
||||||
.getContent()).as("has number of elements").hasSize(397)
|
.findTargetByFilters(pageReq, unknown, null, null, null, Boolean.FALSE, new String[0]).getContent())
|
||||||
.as("that number is also returned by count query")
|
.as("has number of elements").hasSize(397).as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, null, null, null,
|
||||||
Boolean.FALSE, new String[0])))
|
Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -477,9 +498,34 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, null, Boolean.FALSE,
|
||||||
targetManagement.findAllTargetIdsByFilters(pageReq, unknown, null, null, Boolean.FALSE, new String[0]))
|
new String[0])).as("has number of elements").hasSize(397).as("and contains the following elements")
|
||||||
.as("has number of elements").hasSize(397).as("and contains the following elements")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
|
new JpaTargetFilterQuery("test", query)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Step
|
||||||
|
private void verifyThat198TargetsAreInStatusUnknownAndOverdue(final List<TargetUpdateStatus> unknown,
|
||||||
|
final List<Target> expected) {
|
||||||
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
|
// be careful: simple filters are concatenated using AND-gating
|
||||||
|
final String query = "lastcontrollerrequestat=le=${overdue_ts};updatestatus==UNKNOWN";
|
||||||
|
|
||||||
|
assertThat(targetManagement
|
||||||
|
.findTargetByFilters(pageReq, unknown, Boolean.TRUE, null, null, Boolean.FALSE, new String[0])
|
||||||
|
.getContent()).as("has number of elements").hasSize(198)
|
||||||
|
.as("that number is also returned by count query")
|
||||||
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(unknown, Boolean.TRUE, null,
|
||||||
|
null, Boolean.FALSE, new String[0])))
|
||||||
|
.as("and contains the following elements").containsAll(expected)
|
||||||
|
.as("and filter query returns the same result")
|
||||||
|
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
||||||
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, unknown, Boolean.TRUE, null, null, Boolean.FALSE,
|
||||||
|
new String[0])).as("has number of elements").hasSize(198).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
new JpaTargetFilterQuery("test", query)));
|
new JpaTargetFilterQuery("test", query)));
|
||||||
@@ -492,10 +538,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
+ " or installedds.name==" + setA.getName() + ")";
|
+ " or installedds.name==" + setA.getName() + ")";
|
||||||
|
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])
|
.findTargetByFilters(pageReq, null, null, "%targ-A%", setA.getId(), Boolean.FALSE, new String[0])
|
||||||
.getContent()).as("has number of elements").hasSize(1)
|
.getContent()).as("has number of elements").hasSize(1)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-A%",
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, "%targ-A%",
|
||||||
setA.getId(), Boolean.FALSE, new String[0])))
|
setA.getId(), Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsExactly(expected)
|
.as("and contains the following elements").containsExactly(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -503,11 +549,11 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, "%targ-A%", setA.getId(),
|
||||||
new String[0])).as("has number of elements").hasSize(1).as("and contains the following elements")
|
Boolean.FALSE, new String[0])).as("has number of elements").hasSize(1)
|
||||||
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
|
.as("and contains the following elements").containsExactly(expectedIdName)
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -515,18 +561,19 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
final String query = "assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName();
|
final String query = "assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName();
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, setA.getId(), Boolean.FALSE, new String[0])
|
assertThat(targetManagement
|
||||||
|
.findTargetByFilters(pageReq, null, null, null, setA.getId(), Boolean.FALSE, new String[0])
|
||||||
.getContent()).as("has number of elements").hasSize(3)
|
.getContent()).as("has number of elements").hasSize(3)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, setA.getId(),
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, null,
|
||||||
Boolean.FALSE, new String[0])))
|
setA.getId(), Boolean.FALSE, new String[0])))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
.containsAll(targetManagement.findTargetsAll(query, pageReq).getContent())
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, null, setA.getId(), Boolean.FALSE,
|
||||||
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
|
new String[0])).as("has number of elements").hasSize(3).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -538,18 +585,18 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "(name==*targ-C* or description==*targ-C*) and tag==" + targTagX.getName()
|
final String query = "(name==*targ-C* or description==*targ-C*) and tag==" + targTagX.getName()
|
||||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagX.getName())
|
.findTargetByFilters(pageReq, null, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagX.getName())
|
||||||
.getContent()).as("has number of elements").hasSize(0)
|
.getContent()).as("has number of elements").hasSize(0)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-C%",
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, "%targ-C%",
|
||||||
setA.getId(), Boolean.FALSE, targTagX.getName())))
|
setA.getId(), Boolean.FALSE, targTagX.getName())))
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
|
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
|
||||||
.as("and NAMED filter query returns the same result").hasSize(targetManagement
|
.as("and NAMED filter query returns the same result").hasSize(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, "%targ-C%", setA.getId(),
|
||||||
targTagX.getName())).as("has number of elements").hasSize(0)
|
Boolean.FALSE, targTagX.getName())).as("has number of elements").hasSize(0)
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
}
|
}
|
||||||
@@ -559,18 +606,18 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "(name==*targ-A* or description==*targ-A*) and tag==" + targTagW.getName()
|
final String query = "(name==*targ-A* or description==*targ-A*) and tag==" + targTagW.getName()
|
||||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE, targTagW.getName())
|
.findTargetByFilters(pageReq, null, null, "%targ-A%", setA.getId(), Boolean.FALSE, targTagW.getName())
|
||||||
.getContent()).as("has number of elements").hasSize(0)
|
.getContent()).as("has number of elements").hasSize(0)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-A%",
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, "%targ-A%",
|
||||||
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
|
.hasSize(targetManagement.findTargetsAll(query, pageReq).getContent().size())
|
||||||
.as("and NAMED filter query returns the same result").hasSize(targetManagement
|
.as("and NAMED filter query returns the same result").hasSize(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent().size());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-A%", setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, "%targ-A%", setA.getId(),
|
||||||
targTagW.getName())).as("has number of elements").hasSize(0)
|
Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(0)
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
}
|
}
|
||||||
@@ -582,10 +629,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final String query = "(name==*targ-c* or description==*targ-C*) and tag==" + targTagW.getName()
|
final String query = "(name==*targ-c* or description==*targ-C*) and tag==" + targTagW.getName()
|
||||||
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
+ " and (assignedds.name==" + setA.getName() + " or installedds.name==" + setA.getName() + ")";
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagW.getName())
|
.findTargetByFilters(pageReq, null, null, "%targ-C%", setA.getId(), Boolean.FALSE, targTagW.getName())
|
||||||
.getContent()).as("has number of elements").hasSize(1)
|
.getContent()).as("has number of elements").hasSize(1)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-C%",
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, "%targ-C%",
|
||||||
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
setA.getId(), Boolean.FALSE, targTagW.getName())))
|
||||||
.as("and contains the following elements").containsExactly(expected)
|
.as("and contains the following elements").containsExactly(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -593,11 +640,11 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-C%", setA.getId(), Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, "%targ-C%", setA.getId(),
|
||||||
targTagW.getName())).as("has number of elements").hasSize(1).as("and contains the following elements")
|
Boolean.FALSE, targTagW.getName())).as("has number of elements").hasSize(1)
|
||||||
.containsExactly(expectedIdName).as("and NAMED filter query returns the same result")
|
.as("and contains the following elements").containsExactly(expectedIdName)
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
new JpaTargetFilterQuery("test", query)));
|
.findAllTargetIdsByTargetFilterQuery(pageReq, new JpaTargetFilterQuery("test", query)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Step
|
@Step
|
||||||
@@ -606,10 +653,10 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
final String query = "(name==*targ-B* or description==*targ-B*) and (tag==" + targTagY.getName() + " or tag=="
|
final String query = "(name==*targ-B* or description==*targ-B*) and (tag==" + targTagY.getName() + " or tag=="
|
||||||
+ targTagW.getName() + ")";
|
+ targTagW.getName() + ")";
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, null, "%targ-B%", null, Boolean.FALSE,
|
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, "%targ-B%", null, Boolean.FALSE,
|
||||||
targTagY.getName(), targTagW.getName()).getContent()).as("has number of elements").hasSize(100)
|
targTagY.getName(), targTagW.getName()).getContent()).as("has number of elements").hasSize(100)
|
||||||
.as("that number is also returned by count query")
|
.as("that number is also returned by count query")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, "%targ-B%", null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, "%targ-B%", null,
|
||||||
Boolean.FALSE, targTagY.getName(), targTagW.getName())))
|
Boolean.FALSE, targTagY.getName(), targTagW.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -617,7 +664,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, "%targ-B%", null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, "%targ-B%", null, Boolean.FALSE,
|
||||||
targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(100)
|
targTagY.getName(), targTagW.getName())).as("has number of elements").hasSize(100)
|
||||||
.as("and contains the following elements").containsAll(expectedIdNames)
|
.as("and contains the following elements").containsAll(expectedIdNames)
|
||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
@@ -636,10 +683,11 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
private void verifyThat200TargetsHaveTagD(final TargetTag targTagD, final List<Target> expected) {
|
private void verifyThat200TargetsHaveTagD(final TargetTag targTagD, final List<Target> expected) {
|
||||||
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
final List<TargetIdName> expectedIdNames = convertToIdNames(expected);
|
||||||
final String query = "tag==" + targTagD.getName();
|
final String query = "tag==" + targTagD.getName();
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, null, Boolean.FALSE, targTagD.getName())
|
assertThat(targetManagement
|
||||||
.getContent()).as("Expected number of results is").hasSize(200)
|
.findTargetByFilters(pageReq, null, null, null, null, Boolean.FALSE, targTagD.getName()).getContent())
|
||||||
|
.as("Expected number of results is").hasSize(200)
|
||||||
.as("and is expected number of results is equal to ")
|
.as("and is expected number of results is equal to ")
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, null,
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetByFilters(null, null, null, null,
|
||||||
Boolean.FALSE, targTagD.getName())))
|
Boolean.FALSE, targTagD.getName())))
|
||||||
.as("and contains the following elements").containsAll(expected)
|
.as("and contains the following elements").containsAll(expected)
|
||||||
.as("and filter query returns the same result")
|
.as("and filter query returns the same result")
|
||||||
@@ -647,7 +695,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
.as("and NAMED filter query returns the same result").containsAll(targetManagement
|
||||||
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
.findTargetsAll(new JpaTargetFilterQuery("test", query), pageReq).getContent());
|
||||||
|
|
||||||
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, null, Boolean.FALSE,
|
assertThat(targetManagement.findAllTargetIdsByFilters(pageReq, null, null, null, null, Boolean.FALSE,
|
||||||
targTagD.getName())).as("has number of elements").hasSize(200).as("and contains the following elements")
|
targTagD.getName())).as("has number of elements").hasSize(200).as("and contains the following elements")
|
||||||
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
.containsAll(expectedIdNames).as("and NAMED filter query returns the same result")
|
||||||
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
.containsAll(targetManagement.findAllTargetIdsByTargetFilterQuery(pageReq,
|
||||||
@@ -657,12 +705,13 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
@Step
|
@Step
|
||||||
private void verifyThatRepositoryContains400Targets() {
|
private void verifyThatRepositoryContains400Targets() {
|
||||||
assertThat(targetManagement.findTargetByFilters(pageReq, null, null, null, null, new String[0]).getContent())
|
assertThat(
|
||||||
.as("Overall we expect that many targets in the repository").hasSize(400)
|
targetManagement.findTargetByFilters(pageReq, null, null, null, null, null, new String[0]).getContent())
|
||||||
.as("which is also reflected by repository count")
|
.as("Overall we expect that many targets in the repository").hasSize(400)
|
||||||
.hasSize(Ints.saturatedCast(targetManagement.countTargetsAll()))
|
.as("which is also reflected by repository count")
|
||||||
.as("which is also reflected by call without specification")
|
.hasSize(Ints.saturatedCast(targetManagement.countTargetsAll()))
|
||||||
.containsAll(targetManagement.findTargetsAll(pageReq).getContent());
|
.as("which is also reflected by call without specification")
|
||||||
|
.containsAll(targetManagement.findTargetsAll(pageReq).getContent());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,7 +734,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed");
|
targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed");
|
||||||
|
|
||||||
final Slice<Target> result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(),
|
final Slice<Target> result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(),
|
||||||
null, null, null, Boolean.FALSE, new String[0]);
|
new FilterParams(null, null, null, null, Boolean.FALSE, new String[0]));
|
||||||
|
|
||||||
final Comparator<TenantAwareBaseEntity> byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId());
|
final Comparator<TenantAwareBaseEntity> byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId());
|
||||||
|
|
||||||
@@ -702,6 +751,64 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests the correct order of targets with applied overdue filter based on selected distribution set. The system expects to have an order based on installed, assigned DS.")
|
||||||
|
public void targetSearchWithOverdueFilterAndOrderByDistributionSet() {
|
||||||
|
|
||||||
|
final Long lastTargetQueryAlwaysOverdue = 0L;
|
||||||
|
final Long lastTargetQueryNotOverdue = Instant.now().toEpochMilli();
|
||||||
|
final Long lastTargetNull = null;
|
||||||
|
|
||||||
|
final Long[] overdueMix = { lastTargetQueryAlwaysOverdue, lastTargetQueryNotOverdue,
|
||||||
|
lastTargetQueryAlwaysOverdue, lastTargetNull, lastTargetQueryAlwaysOverdue };
|
||||||
|
|
||||||
|
List<Target> notAssignedToBeCreated = testdataFactory.generateTargets(overdueMix.length, "not",
|
||||||
|
"first description");
|
||||||
|
List<Target> targAssignedToBeCreated = testdataFactory.generateTargets(overdueMix.length, "assigned",
|
||||||
|
"first description");
|
||||||
|
List<Target> targInstalledToBeCreated = testdataFactory.generateTargets(overdueMix.length, "installed",
|
||||||
|
"first description");
|
||||||
|
|
||||||
|
List<Target> notAssigned = new ArrayList<>();
|
||||||
|
List<Target> targAssigned = new ArrayList<>();
|
||||||
|
List<Target> targInstalled = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < overdueMix.length; i++) {
|
||||||
|
notAssigned.add(targetManagement.createTarget(notAssignedToBeCreated.get(i), TargetUpdateStatus.UNKNOWN,
|
||||||
|
overdueMix[i], notAssignedToBeCreated.get(i).getTargetInfo().getAddress()));
|
||||||
|
targAssigned.add(targetManagement.createTarget(targAssignedToBeCreated.get(i), TargetUpdateStatus.UNKNOWN,
|
||||||
|
overdueMix[i], targAssignedToBeCreated.get(i).getTargetInfo().getAddress()));
|
||||||
|
targInstalled.add(targetManagement.createTarget(targInstalledToBeCreated.get(i), TargetUpdateStatus.UNKNOWN,
|
||||||
|
overdueMix[i], targInstalledToBeCreated.get(i).getTargetInfo().getAddress()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final DistributionSet ds = testdataFactory.createDistributionSet("a");
|
||||||
|
|
||||||
|
targAssigned = deploymentManagement.assignDistributionSet(ds, targAssigned).getAssignedEntity();
|
||||||
|
targInstalled = deploymentManagement.assignDistributionSet(ds, targInstalled).getAssignedEntity();
|
||||||
|
targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed");
|
||||||
|
|
||||||
|
final Slice<Target> result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(),
|
||||||
|
new FilterParams(null, null, Boolean.TRUE, null, Boolean.FALSE, new String[0]));
|
||||||
|
|
||||||
|
final Comparator<TenantAwareBaseEntity> byId = (e1, e2) -> Long.compare(e2.getId(), e1.getId());
|
||||||
|
|
||||||
|
assertThat(result.getNumberOfElements()).isEqualTo(9);
|
||||||
|
final List<Target> expected = new ArrayList<>();
|
||||||
|
expected.addAll(targInstalled.stream().sorted(byId)
|
||||||
|
.filter(item -> lastTargetQueryAlwaysOverdue.equals(item.getTargetInfo().getLastTargetQuery()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
expected.addAll(targAssigned.stream().sorted(byId)
|
||||||
|
.filter(item -> lastTargetQueryAlwaysOverdue.equals(item.getTargetInfo().getLastTargetQuery()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
expected.addAll(notAssigned.stream().sorted(byId)
|
||||||
|
.filter(item -> lastTargetQueryAlwaysOverdue.equals(item.getTargetInfo().getLastTargetQuery()))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
|
assertThat(result.getContent()).containsExactly(expected.toArray(new Target[0]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that targets with given assigned DS are returned from repository.")
|
@Description("Verfies that targets with given assigned DS are returned from repository.")
|
||||||
public void findTargetByAssignedDistributionSet() {
|
public void findTargetByAssignedDistributionSet() {
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
targetManagement.toggleTagAssignment(tagABCTargets, tagB);
|
targetManagement.toggleTagAssignment(tagABCTargets, tagB);
|
||||||
targetManagement.toggleTagAssignment(tagABCTargets, tagC);
|
targetManagement.toggleTagAssignment(tagABCTargets, tagC);
|
||||||
|
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "X"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, null, Boolean.FALSE, "X"))
|
||||||
.as("Target count is wrong").isEqualTo(0);
|
.as("Target count is wrong").isEqualTo(0);
|
||||||
|
|
||||||
// search for targets with tag tagA
|
// search for targets with tag tagA
|
||||||
@@ -631,11 +631,11 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
checkTargetHasNotTags(tagCTargets, tagA, tagB);
|
checkTargetHasNotTags(tagCTargets, tagA, tagB);
|
||||||
|
|
||||||
// check again target lists refreshed from DB
|
// check again target lists refreshed from DB
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "A"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, null, Boolean.FALSE, "A"))
|
||||||
.as("Target count is wrong").isEqualTo(targetWithTagA.size());
|
.as("Target count is wrong").isEqualTo(targetWithTagA.size());
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "B"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, null, Boolean.FALSE, "B"))
|
||||||
.as("Target count is wrong").isEqualTo(targetWithTagB.size());
|
.as("Target count is wrong").isEqualTo(targetWithTagB.size());
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "C"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, null, Boolean.FALSE, "C"))
|
||||||
.as("Target count is wrong").isEqualTo(targetWithTagC.size());
|
.as("Target count is wrong").isEqualTo(targetWithTagC.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,7 +752,8 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
|
|
||||||
final String[] tagNames = null;
|
final String[] tagNames = null;
|
||||||
final List<Target> targetsListWithNoTag = targetManagement
|
final List<Target> targetsListWithNoTag = targetManagement
|
||||||
.findTargetByFilters(new PageRequest(0, 500), null, null, null, Boolean.TRUE, tagNames).getContent();
|
.findTargetByFilters(new PageRequest(0, 500), null, null, null, null, Boolean.TRUE, tagNames)
|
||||||
|
.getContent();
|
||||||
|
|
||||||
assertThat(50).as("Total targets").isEqualTo(targetManagement.findAllTargetIds().size());
|
assertThat(50).as("Total targets").isEqualTo(targetManagement.findAllTargetIds().size());
|
||||||
assertThat(25).as("Targets with no tag").isEqualTo(targetsListWithNoTag.size());
|
assertThat(25).as("Targets with no tag").isEqualTo(targetsListWithNoTag.size());
|
||||||
|
|||||||
@@ -9,14 +9,9 @@
|
|||||||
package org.eclipse.hawkbit.repository.jpa.rsql;
|
package org.eclipse.hawkbit.repository.jpa.rsql;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.*;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Mockito.*;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.powermock.api.mockito.PowerMockito.mockStatic;
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.reset;
|
|
||||||
import static org.mockito.Mockito.times;
|
|
||||||
import static org.mockito.Mockito.verify;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.CriteriaBuilder;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
import javax.persistence.criteria.CriteriaQuery;
|
||||||
@@ -30,24 +25,39 @@ import org.eclipse.hawkbit.repository.DistributionSetFields;
|
|||||||
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
import org.eclipse.hawkbit.repository.FieldNameProvider;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
import org.eclipse.hawkbit.repository.SoftwareModuleFields;
|
||||||
import org.eclipse.hawkbit.repository.TargetFields;
|
import org.eclipse.hawkbit.repository.TargetFields;
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException;
|
||||||
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.Spy;
|
||||||
|
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(PowerMockRunner.class)
|
||||||
@Features("Component Tests - Repository")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL search utility")
|
@Stories("RSQL search utility")
|
||||||
|
@PrepareForTest(TimestampCalculator.class)
|
||||||
// TODO: fully document tests -> @Description for long text and reasonable
|
// TODO: fully document tests -> @Description for long text and reasonable
|
||||||
// method name as short text
|
// method name as short text
|
||||||
public class RSQLUtilityTest {
|
public class RSQLUtilityTest {
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
private VirtualPropertyResolver macroResolver = new VirtualPropertyResolver();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private TenantConfigurationManagement confMgmt;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private Root<Object> baseSoftwareModuleRootMock;
|
private Root<Object> baseSoftwareModuleRootMock;
|
||||||
|
|
||||||
@@ -59,11 +69,16 @@ public class RSQLUtilityTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private Attribute attribute;
|
private Attribute attribute;
|
||||||
|
|
||||||
|
private static final TenantConfigurationValue<String> TEST_POLLING_TIME_INTERVAL = TenantConfigurationValue
|
||||||
|
.<String>builder().value("00:05:00").build();
|
||||||
|
private static final TenantConfigurationValue<String> TEST_POLLING_OVERDUE_TIME_INTERVAL = TenantConfigurationValue
|
||||||
|
.<String>builder().value("00:07:37").build();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void wrongRsqlSyntaxThrowSyntaxException() {
|
public void wrongRsqlSyntaxThrowSyntaxException() {
|
||||||
final String wrongRSQL = "name==abc;d";
|
final String wrongRSQL = "name==abc;d";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterSyntaxException e) {
|
} catch (final RSQLParameterSyntaxException e) {
|
||||||
@@ -75,7 +90,7 @@ public class RSQLUtilityTest {
|
|||||||
final String wrongRSQL = "unknownField==abc";
|
final String wrongRSQL = "unknownField==abc";
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(wrongRSQL, SoftwareModuleFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
fail("Missing an expected RSQLParameterUnsupportedFieldException because of unknown RSQL field");
|
fail("Missing an expected RSQLParameterUnsupportedFieldException because of unknown RSQL field");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -87,7 +102,8 @@ public class RSQLUtilityTest {
|
|||||||
public void wrongRsqlMapSyntaxThrowSyntaxException() {
|
public void wrongRsqlMapSyntaxThrowSyntaxException() {
|
||||||
String wrongRSQL = TargetFields.ATTRIBUTE + "==abc";
|
String wrongRSQL = TargetFields.ATTRIBUTE + "==abc";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
|
RSQLUtility.parse(wrongRSQL, TargetFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
|
criteriaQueryMock,
|
||||||
criteriaBuilderMock);
|
criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -95,7 +111,8 @@ public class RSQLUtilityTest {
|
|||||||
|
|
||||||
wrongRSQL = TargetFields.ATTRIBUTE + ".unkwon.wrong==abc";
|
wrongRSQL = TargetFields.ATTRIBUTE + ".unkwon.wrong==abc";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
|
RSQLUtility.parse(wrongRSQL, TargetFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
|
criteriaQueryMock,
|
||||||
criteriaBuilderMock);
|
criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -103,7 +120,7 @@ public class RSQLUtilityTest {
|
|||||||
|
|
||||||
wrongRSQL = DistributionSetFields.METADATA + "==abc";
|
wrongRSQL = DistributionSetFields.METADATA + "==abc";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, DistributionSetFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(wrongRSQL, DistributionSetFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -115,7 +132,8 @@ public class RSQLUtilityTest {
|
|||||||
public void wrongRsqlSubEntitySyntaxThrowSyntaxException() {
|
public void wrongRsqlSubEntitySyntaxThrowSyntaxException() {
|
||||||
String wrongRSQL = TargetFields.ASSIGNEDDS + "==abc";
|
String wrongRSQL = TargetFields.ASSIGNEDDS + "==abc";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
|
RSQLUtility.parse(wrongRSQL, TargetFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
|
criteriaQueryMock,
|
||||||
criteriaBuilderMock);
|
criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -123,7 +141,8 @@ public class RSQLUtilityTest {
|
|||||||
|
|
||||||
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField==abc";
|
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField==abc";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
|
RSQLUtility.parse(wrongRSQL, TargetFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
|
criteriaQueryMock,
|
||||||
criteriaBuilderMock);
|
criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -131,7 +150,8 @@ public class RSQLUtilityTest {
|
|||||||
|
|
||||||
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField.ToMuch==abc";
|
wrongRSQL = TargetFields.ASSIGNEDDS + ".unknownField.ToMuch==abc";
|
||||||
try {
|
try {
|
||||||
RSQLUtility.parse(wrongRSQL, TargetFields.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
|
RSQLUtility.parse(wrongRSQL, TargetFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
|
criteriaQueryMock,
|
||||||
criteriaBuilderMock);
|
criteriaBuilderMock);
|
||||||
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
fail("Missing expected RSQLParameterSyntaxException because of wrong RSQL syntax");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -146,11 +166,11 @@ public class RSQLUtilityTest {
|
|||||||
when(baseSoftwareModuleRootMock.get("version")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("version")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
||||||
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
when(criteriaBuilderMock.<String>greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
||||||
.thenReturn(mock(Predicate.class));
|
.thenReturn(mock(Predicate.class));
|
||||||
|
|
||||||
// test
|
// test
|
||||||
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
|
||||||
// verfication
|
// verfication
|
||||||
@@ -164,12 +184,12 @@ public class RSQLUtilityTest {
|
|||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
||||||
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
when(criteriaBuilderMock.<String>greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
||||||
.thenReturn(mock(Predicate.class));
|
.thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
|
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
|
||||||
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
|
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
|
||||||
// test
|
// test
|
||||||
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
|
||||||
// verfication
|
// verfication
|
||||||
@@ -185,12 +205,12 @@ public class RSQLUtilityTest {
|
|||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
||||||
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
when(criteriaBuilderMock.<String>greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
||||||
.thenReturn(mock(Predicate.class));
|
.thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
|
when(criteriaBuilderMock.upper(eq(pathOfString(baseSoftwareModuleRootMock))))
|
||||||
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
|
.thenReturn(pathOfString(baseSoftwareModuleRootMock));
|
||||||
// test
|
// test
|
||||||
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
|
||||||
// verfication
|
// verfication
|
||||||
@@ -206,10 +226,10 @@ public class RSQLUtilityTest {
|
|||||||
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
when(baseSoftwareModuleRootMock.get("name")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class);
|
||||||
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
when(criteriaBuilderMock.<String> greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
when(criteriaBuilderMock.<String>greaterThanOrEqualTo(any(Expression.class), any(String.class)))
|
||||||
.thenReturn(mock(Predicate.class));
|
.thenReturn(mock(Predicate.class));
|
||||||
// test
|
// test
|
||||||
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(correctRsql, SoftwareModuleFields.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
|
||||||
// verfication
|
// verfication
|
||||||
@@ -226,7 +246,8 @@ public class RSQLUtilityTest {
|
|||||||
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
|
|
||||||
// test
|
// test
|
||||||
RSQLUtility.parse(correctRsql, TestFieldEnum.class).toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock,
|
RSQLUtility.parse(correctRsql, TestFieldEnum.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
|
criteriaQueryMock,
|
||||||
criteriaBuilderMock);
|
criteriaBuilderMock);
|
||||||
|
|
||||||
// verfication
|
// verfication
|
||||||
@@ -244,7 +265,7 @@ public class RSQLUtilityTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// test
|
// test
|
||||||
RSQLUtility.parse(correctRsql, TestFieldEnum.class).toPredicate(baseSoftwareModuleRootMock,
|
RSQLUtility.parse(correctRsql, TestFieldEnum.class, null).toPredicate(baseSoftwareModuleRootMock,
|
||||||
criteriaQueryMock, criteriaBuilderMock);
|
criteriaQueryMock, criteriaBuilderMock);
|
||||||
fail("missing RSQLParameterUnsupportedFieldException for wrong enum value");
|
fail("missing RSQLParameterUnsupportedFieldException for wrong enum value");
|
||||||
} catch (final RSQLParameterUnsupportedFieldException e) {
|
} catch (final RSQLParameterUnsupportedFieldException e) {
|
||||||
@@ -252,6 +273,67 @@ public class RSQLUtilityTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests the resolution of overdue_ts placeholder in context of a RSQL expression.")
|
||||||
|
public void correctRsqlWithOverdueMacro() {
|
||||||
|
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
final String overdueProp = "overdue_ts";
|
||||||
|
final String overduePropPlaceholder = "${" + overdueProp + "}";
|
||||||
|
final String correctRsql = "testfield=le=" + overduePropPlaceholder;
|
||||||
|
when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
|
when(criteriaBuilderMock.<String>lessThanOrEqualTo(any(Expression.class), eq(overduePropPlaceholder)))
|
||||||
|
.thenReturn(mock(Predicate.class));
|
||||||
|
|
||||||
|
// test
|
||||||
|
RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMacroLookup())
|
||||||
|
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
|
||||||
|
// verification
|
||||||
|
verify(macroResolver).lookup(overdueProp);
|
||||||
|
// the macro is already replaced when passed to #lessThanOrEqualTo -> the method is never invoked with the
|
||||||
|
// placeholder:
|
||||||
|
verify(criteriaBuilderMock, never()).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)),
|
||||||
|
eq(overduePropPlaceholder));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests RSQL expression with an unknown placeholder.")
|
||||||
|
public void correctRsqlWithUnknownMacro() {
|
||||||
|
reset(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
final String overdueProp = "unknown";
|
||||||
|
final String overduePropPlaceholder = "${" + overdueProp + "}";
|
||||||
|
final String correctRsql = "testfield=le=" + overduePropPlaceholder;
|
||||||
|
when(baseSoftwareModuleRootMock.get("testfield")).thenReturn(baseSoftwareModuleRootMock);
|
||||||
|
when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) String.class);
|
||||||
|
when(criteriaBuilderMock.equal(any(Root.class), anyString())).thenReturn(mock(Predicate.class));
|
||||||
|
when(criteriaBuilderMock.<String>lessThanOrEqualTo(any(Expression.class), eq(overduePropPlaceholder)))
|
||||||
|
.thenReturn(mock(Predicate.class));
|
||||||
|
|
||||||
|
// test
|
||||||
|
Predicate result = RSQLUtility.parse(correctRsql, TestFieldEnum.class, setupMacroLookup())
|
||||||
|
.toPredicate(baseSoftwareModuleRootMock, criteriaQueryMock, criteriaBuilderMock);
|
||||||
|
|
||||||
|
// verification
|
||||||
|
verify(macroResolver).lookup(overdueProp);
|
||||||
|
// the macro is unknown and hence never replaced -> #lessThanOrEqualTo is invoked with the placeholder:
|
||||||
|
verify(criteriaBuilderMock).lessThanOrEqualTo(eq(pathOfString(baseSoftwareModuleRootMock)),
|
||||||
|
eq(overduePropPlaceholder));
|
||||||
|
}
|
||||||
|
|
||||||
|
public VirtualPropertyReplacer setupMacroLookup() {
|
||||||
|
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class))
|
||||||
|
.thenReturn(TEST_POLLING_TIME_INTERVAL);
|
||||||
|
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class))
|
||||||
|
.thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL);
|
||||||
|
|
||||||
|
mockStatic(TimestampCalculator.class);
|
||||||
|
when(TimestampCalculator.getTenantConfigurationManagement()).thenReturn(confMgmt);
|
||||||
|
|
||||||
|
return macroResolver;
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <Y> Path<Y> pathOfString(final Path<?> path) {
|
private <Y> Path<Y> pathOfString(final Path<?> path) {
|
||||||
return (Path<Y>) path;
|
return (Path<Y>) path;
|
||||||
@@ -262,10 +344,8 @@ public class RSQLUtilityTest {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see
|
* @see org.eclipse.hawkbit.server.rest.resource.model.FieldNameProvider# getFieldName()
|
||||||
* org.eclipse.hawkbit.server.rest.resource.model.FieldNameProvider#
|
|
||||||
* getFieldName()
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getFieldName() {
|
public String getFieldName() {
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/**
|
||||||
|
* 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.rsql;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
|
import static org.powermock.api.mockito.PowerMockito.mockStatic;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.TimestampCalculator;
|
||||||
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Spy;
|
||||||
|
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Repository")
|
||||||
|
@Stories("Placeholder resolution for virtual properties")
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest(TimestampCalculator.class)
|
||||||
|
public class VirtualPropertyResolverTest {
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
private VirtualPropertyResolver resolverUnderTest = new VirtualPropertyResolver();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private TenantConfigurationManagement confMgmt;
|
||||||
|
|
||||||
|
private StrSubstitutor substitutor;
|
||||||
|
|
||||||
|
private Long nowTestTime;
|
||||||
|
|
||||||
|
private static final TenantConfigurationValue<String> TEST_POLLING_TIME_INTERVAL = TenantConfigurationValue
|
||||||
|
.<String> builder().value("00:05:00").build();
|
||||||
|
private static final TenantConfigurationValue<String> TEST_POLLING_OVERDUE_TIME_INTERVAL = TenantConfigurationValue
|
||||||
|
.<String> builder().value("00:07:37").build();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
nowTestTime = Instant.now().toEpochMilli();
|
||||||
|
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class))
|
||||||
|
.thenReturn(TEST_POLLING_TIME_INTERVAL);
|
||||||
|
when(confMgmt.getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class))
|
||||||
|
.thenReturn(TEST_POLLING_OVERDUE_TIME_INTERVAL);
|
||||||
|
|
||||||
|
mockStatic(TimestampCalculator.class);
|
||||||
|
when(TimestampCalculator.getTenantConfigurationManagement()).thenReturn(confMgmt);
|
||||||
|
|
||||||
|
substitutor = new StrSubstitutor(resolverUnderTest,
|
||||||
|
StrSubstitutor.DEFAULT_PREFIX,
|
||||||
|
StrSubstitutor.DEFAULT_SUFFIX, StrSubstitutor.DEFAULT_ESCAPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests resolution of NOW_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
||||||
|
public void resolveNowTimestampPlaceholder() {
|
||||||
|
String placeholder = "${NOW_TS}";
|
||||||
|
String testString = "lhs=lt=" + placeholder;
|
||||||
|
|
||||||
|
String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
|
assertThat("NOW_TS has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests resolution of OVERDUE_TS by using a StrSubstitutor configured with the VirtualPropertyResolver.")
|
||||||
|
public void resolveOverdueTimestampPlaceholder() {
|
||||||
|
String placeholder = "${OVERDUE_TS}";
|
||||||
|
String testString = "lhs=lt=" + placeholder;
|
||||||
|
|
||||||
|
String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
|
assertThat("OVERDUE_TS has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests case insensititity of VirtualPropertyResolver.")
|
||||||
|
public void resolveOverdueTimestampPlaceholderLowerCase() {
|
||||||
|
String placeholder = "${overdue_ts}";
|
||||||
|
String testString = "lhs=lt=" + placeholder;
|
||||||
|
|
||||||
|
String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
|
assertThat("overdue_ts has to be resolved!", resolvedPlaceholders, not(containsString(placeholder)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests VirtualPropertyResolver with a placeholder unknown to VirtualPropertyResolver.")
|
||||||
|
public void handleUnknownPlaceholder() {
|
||||||
|
String placeholder = "${unknown}";
|
||||||
|
String testString = "lhs=lt=" + placeholder;
|
||||||
|
|
||||||
|
String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
|
assertThat("unknown should not be resolved!", resolvedPlaceholders, containsString(placeholder));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Tests escape mechanism for placeholders (syntax is $${SOME_PLACEHOLDER}).")
|
||||||
|
public void handleEscapedPlaceholder() {
|
||||||
|
String placeholder = "${OVERDUE_TS}";
|
||||||
|
String escaptedPlaceholder = StrSubstitutor.DEFAULT_ESCAPE + placeholder;
|
||||||
|
String testString = "lhs=lt=" + escaptedPlaceholder;
|
||||||
|
|
||||||
|
String resolvedPlaceholders = substitutor.replace(testString);
|
||||||
|
assertThat("Escaped OVERDUE_TS should not be resolved!", resolvedPlaceholders, containsString(placeholder));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@ import org.eclipse.hawkbit.cache.CacheConstants;
|
|||||||
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
||||||
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
|
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.rsql.VirtualPropertyResolver;
|
||||||
|
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
|
||||||
import org.eclipse.hawkbit.repository.test.util.JpaTestRepositoryManagement;
|
import org.eclipse.hawkbit.repository.test.util.JpaTestRepositoryManagement;
|
||||||
import org.eclipse.hawkbit.repository.test.util.TestRepositoryManagement;
|
import org.eclipse.hawkbit.repository.test.util.TestRepositoryManagement;
|
||||||
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
import org.eclipse.hawkbit.repository.test.util.TestdataFactory;
|
||||||
@@ -129,4 +131,13 @@ public class TestConfiguration implements AsyncConfigurer {
|
|||||||
return new SimpleAsyncUncaughtExceptionHandler();
|
return new SimpleAsyncUncaughtExceptionHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return returns a VirtualPropertyReplacer
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public VirtualPropertyReplacer virtualPropertyReplacer() {
|
||||||
|
return new VirtualPropertyResolver();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateSoftwareModule(final SoftwareModule sm, final DistributionSet ds) {
|
private boolean validateSoftwareModule(final SoftwareModule sm, final DistributionSet ds) {
|
||||||
if (targetManagement.countTargetByFilters(null, null, ds.getId(), Boolean.FALSE, new String[] {}) > 0) {
|
if (targetManagement.countTargetByFilters(null, null, null, ds.getId(), Boolean.FALSE, new String[] {}) > 0) {
|
||||||
/* Distribution is already assigned */
|
/* Distribution is already assigned */
|
||||||
notification.displayValidationError(i18n.get("message.dist.inuse",
|
notification.displayValidationError(i18n.get("message.dist.inuse",
|
||||||
HawkbitCommonUtil.concatStrings(":", ds.getName(), ds.getVersion())));
|
HawkbitCommonUtil.concatStrings(":", ds.getName(), ds.getVersion())));
|
||||||
|
|||||||
@@ -14,5 +14,39 @@ package org.eclipse.hawkbit.ui.management.event;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public enum ManagementUIEvent {
|
public enum ManagementUIEvent {
|
||||||
SHOW_COUNT_MESSAGE, UPDATE_COUNT, UPDATE_FILTERCOUNT_MESSAGE, HIDE_TARGET_TAG_LAYOUT, SHOW_TARGET_TAG_LAYOUT, HIDE_DISTRIBUTION_TAG_LAYOUT, SHOW_DISTRIBUTION_TAG_LAYOUT, MAX_ACTION_HISTORY, MIN_ACTION_HISTORY, CLOSE_SAVE_ACTIONS_WINDOW, UNASSIGN_TARGET_TAG, UNASSIGN_DISTRIBUTION_TAG, ASSIGN_TARGET_TAG, ASSIGN_DISTRIBUTION_TAG, TARGET_TABLE_FILTER, RESET_SIMPLE_FILTERS, RESET_TARGET_FILTER_QUERY
|
//
|
||||||
|
SHOW_COUNT_MESSAGE,
|
||||||
|
//
|
||||||
|
UPDATE_COUNT,
|
||||||
|
//
|
||||||
|
UPDATE_FILTERCOUNT_MESSAGE,
|
||||||
|
//
|
||||||
|
HIDE_TARGET_TAG_LAYOUT,
|
||||||
|
//
|
||||||
|
SHOW_TARGET_TAG_LAYOUT,
|
||||||
|
//
|
||||||
|
HIDE_DISTRIBUTION_TAG_LAYOUT,
|
||||||
|
//
|
||||||
|
SHOW_DISTRIBUTION_TAG_LAYOUT,
|
||||||
|
//
|
||||||
|
MAX_ACTION_HISTORY,
|
||||||
|
//
|
||||||
|
MIN_ACTION_HISTORY,
|
||||||
|
//
|
||||||
|
CLOSE_SAVE_ACTIONS_WINDOW,
|
||||||
|
//
|
||||||
|
UNASSIGN_TARGET_TAG,
|
||||||
|
//
|
||||||
|
UNASSIGN_DISTRIBUTION_TAG,
|
||||||
|
//
|
||||||
|
ASSIGN_TARGET_TAG,
|
||||||
|
//
|
||||||
|
ASSIGN_DISTRIBUTION_TAG,
|
||||||
|
//
|
||||||
|
TARGET_TABLE_FILTER,
|
||||||
|
//
|
||||||
|
RESET_SIMPLE_FILTERS,
|
||||||
|
//
|
||||||
|
RESET_TARGET_FILTER_QUERY
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,24 @@ package org.eclipse.hawkbit.ui.management.event;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public enum TargetFilterEvent {
|
public enum TargetFilterEvent {
|
||||||
FILTER_BY_TEXT, FILTER_BY_TAG, REMOVE_FILTER_BY_TEXT, REMOVE_FILTER_BY_TAG, FILTER_BY_STATUS, FILTER_BY_DISTRIBUTION, REMOVE_FILTER_BY_STATUS, REMOVE_FILTER_BY_DISTRIBUTION, FILTER_BY_TARGET_FILTER_QUERY, REMOVE_FILTER_BY_TARGET_FILTER_QUERY
|
//
|
||||||
|
FILTER_BY_TEXT,
|
||||||
|
//
|
||||||
|
FILTER_BY_TAG,
|
||||||
|
//
|
||||||
|
REMOVE_FILTER_BY_TEXT,
|
||||||
|
//
|
||||||
|
REMOVE_FILTER_BY_TAG,
|
||||||
|
//
|
||||||
|
FILTER_BY_STATUS,
|
||||||
|
//
|
||||||
|
FILTER_BY_DISTRIBUTION,
|
||||||
|
//
|
||||||
|
REMOVE_FILTER_BY_STATUS,
|
||||||
|
//
|
||||||
|
REMOVE_FILTER_BY_DISTRIBUTION,
|
||||||
|
//
|
||||||
|
FILTER_BY_TARGET_FILTER_QUERY,
|
||||||
|
//
|
||||||
|
REMOVE_FILTER_BY_TARGET_FILTER_QUERY
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ public class CountMessageLabel extends Label {
|
|||||||
}
|
}
|
||||||
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
|
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
|
||||||
final String status = i18n.get("label.filter.status");
|
final String status = i18n.get("label.filter.status");
|
||||||
|
final String overdue = i18n.get("label.filter.overdue");
|
||||||
final String tags = i18n.get("label.filter.tags");
|
final String tags = i18n.get("label.filter.tags");
|
||||||
final String text = i18n.get("label.filter.text");
|
final String text = i18n.get("label.filter.text");
|
||||||
final String dists = i18n.get("label.filter.dist");
|
final String dists = i18n.get("label.filter.dist");
|
||||||
@@ -148,6 +149,7 @@ public class CountMessageLabel extends Label {
|
|||||||
final StringBuilder filterMesgBuf = new StringBuilder(i18n.get("label.filter"));
|
final StringBuilder filterMesgBuf = new StringBuilder(i18n.get("label.filter"));
|
||||||
filterMesgBuf.append(HawkbitCommonUtil.SP_STRING_SPACE);
|
filterMesgBuf.append(HawkbitCommonUtil.SP_STRING_SPACE);
|
||||||
filterMesgBuf.append(getStatusMsg(targFilParams.getClickedStatusTargetTags(), status));
|
filterMesgBuf.append(getStatusMsg(targFilParams.getClickedStatusTargetTags(), status));
|
||||||
|
filterMesgBuf.append(getOverdueStateMsg(targFilParams.isOverdueFilterEnabled(), overdue));
|
||||||
filterMesgBuf
|
filterMesgBuf
|
||||||
.append(getTagsMsg(targFilParams.isNoTagSelected(), targFilParams.getClickedTargetTags(), tags));
|
.append(getTagsMsg(targFilParams.isNoTagSelected(), targFilParams.getClickedTargetTags(), tags));
|
||||||
filterMesgBuf.append(
|
filterMesgBuf.append(
|
||||||
@@ -220,6 +222,17 @@ public class CountMessageLabel extends Label {
|
|||||||
return status.isEmpty() ? HawkbitCommonUtil.SP_STRING_SPACE : param;
|
return status.isEmpty() ? HawkbitCommonUtil.SP_STRING_SPACE : param;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Overdue State Message.
|
||||||
|
*
|
||||||
|
* @param overdueState
|
||||||
|
* as flag
|
||||||
|
* @return String as msg.
|
||||||
|
*/
|
||||||
|
private static String getOverdueStateMsg(final boolean overdueState, final String param) {
|
||||||
|
return !overdueState ? HawkbitCommonUtil.SP_STRING_SPACE : param;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Tags Message.
|
* Get Tags Message.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ public class TargetTableFilters implements Serializable {
|
|||||||
|
|
||||||
private final List<String> clickedTargetTags = new ArrayList<>();
|
private final List<String> clickedTargetTags = new ArrayList<>();
|
||||||
private final List<TargetUpdateStatus> clickedStatusTargetTags = new ArrayList<>();
|
private final List<TargetUpdateStatus> clickedStatusTargetTags = new ArrayList<>();
|
||||||
|
private boolean isOverdueFilterEnabled = Boolean.FALSE;
|
||||||
|
|
||||||
private String searchText;
|
private String searchText;
|
||||||
private DistributionSetIdName distributionSet;
|
private DistributionSetIdName distributionSet;
|
||||||
private Long pinnedDistId;
|
private Long pinnedDistId;
|
||||||
@@ -130,7 +132,8 @@ public class TargetTableFilters implements Serializable {
|
|||||||
* {@code false}
|
* {@code false}
|
||||||
*/
|
*/
|
||||||
public boolean hasFilter() {
|
public boolean hasFilter() {
|
||||||
return isFilteredByTextOrDs() || hasTagsSelected() || isFilteredByStatusOrCustomFilter();
|
return isFilteredByTextOrDs() || hasTagsSelected() || isFilteredByStatusOrCustomFilter()
|
||||||
|
|| isOverdueFilterEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasTagsSelected() {
|
private boolean hasTagsSelected() {
|
||||||
@@ -160,4 +163,12 @@ public class TargetTableFilters implements Serializable {
|
|||||||
this.targetFilterQuery = targetFilterQuery;
|
this.targetFilterQuery = targetFilterQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOverdueFilterEnabled() {
|
||||||
|
return isOverdueFilterEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOverdueFilterEnabled(boolean isOverdueFilterEnabled) {
|
||||||
|
this.isOverdueFilterEnabled = isOverdueFilterEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.management.targettable;
|
package org.eclipse.hawkbit.ui.management.targettable;
|
||||||
|
|
||||||
|
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||||
import static org.apache.commons.lang3.ArrayUtils.isEmpty;
|
import static org.apache.commons.lang3.ArrayUtils.isEmpty;
|
||||||
import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.isNotNullOrEmpty;
|
import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.isNotNullOrEmpty;
|
||||||
import static org.eclipse.hawkbit.ui.utils.SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER;
|
import static org.eclipse.hawkbit.ui.utils.SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER;
|
||||||
@@ -19,6 +20,7 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.FilterParams;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
@@ -52,6 +54,7 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
|
|
||||||
private Sort sort = new Sort(TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
|
private Sort sort = new Sort(TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
|
||||||
private transient Collection<TargetUpdateStatus> status;
|
private transient Collection<TargetUpdateStatus> status;
|
||||||
|
private transient Boolean overdueState;
|
||||||
private String[] targetTags;
|
private String[] targetTags;
|
||||||
private Long distributionId;
|
private Long distributionId;
|
||||||
private String searchText;
|
private String searchText;
|
||||||
@@ -81,6 +84,7 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
|
|
||||||
if (isNotNullOrEmpty(queryConfig)) {
|
if (isNotNullOrEmpty(queryConfig)) {
|
||||||
status = (Collection<TargetUpdateStatus>) queryConfig.get(SPUIDefinitions.FILTER_BY_STATUS);
|
status = (Collection<TargetUpdateStatus>) queryConfig.get(SPUIDefinitions.FILTER_BY_STATUS);
|
||||||
|
overdueState = (Boolean) queryConfig.get(SPUIDefinitions.FILTER_BY_OVERDUE_STATE);
|
||||||
targetTags = (String[]) queryConfig.get(SPUIDefinitions.FILTER_BY_TAG);
|
targetTags = (String[]) queryConfig.get(SPUIDefinitions.FILTER_BY_TAG);
|
||||||
noTagClicked = (Boolean) queryConfig.get(SPUIDefinitions.FILTER_BY_NO_TAG);
|
noTagClicked = (Boolean) queryConfig.get(SPUIDefinitions.FILTER_BY_NO_TAG);
|
||||||
distributionId = (Long) queryConfig.get(SPUIDefinitions.FILTER_BY_DISTRIBUTION);
|
distributionId = (Long) queryConfig.get(SPUIDefinitions.FILTER_BY_DISTRIBUTION);
|
||||||
@@ -114,17 +118,17 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
if (pinnedDistId != null) {
|
if (pinnedDistId != null) {
|
||||||
targetBeans = getTargetManagement().findTargetsAllOrderByLinkedDistributionSet(
|
targetBeans = getTargetManagement().findTargetsAllOrderByLinkedDistributionSet(
|
||||||
new OffsetBasedPageRequest(startIndex, SPUIDefinitions.PAGE_SIZE, sort), pinnedDistId,
|
new OffsetBasedPageRequest(startIndex, SPUIDefinitions.PAGE_SIZE, sort), pinnedDistId,
|
||||||
distributionId, status, searchText, noTagClicked, targetTags);
|
new FilterParams(distributionId, status, overdueState, searchText, noTagClicked, targetTags));
|
||||||
} else if (null != targetFilterQuery) {
|
} else if (null != targetFilterQuery) {
|
||||||
targetBeans = getTargetManagement().findTargetsAll(targetFilterQuery,
|
targetBeans = getTargetManagement().findTargetsAll(targetFilterQuery,
|
||||||
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort));
|
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort));
|
||||||
} else if (!anyFilterSelected()) {
|
} else if (!isAnyFilterSelected()) {
|
||||||
targetBeans = getTargetManagement().findTargetsAll(
|
targetBeans = getTargetManagement().findTargetsAll(
|
||||||
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort));
|
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort));
|
||||||
} else {
|
} else {
|
||||||
targetBeans = getTargetManagement().findTargetByFilters(
|
targetBeans = getTargetManagement().findTargetByFilters(
|
||||||
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort), status,
|
new PageRequest(startIndex / SPUIDefinitions.PAGE_SIZE, SPUIDefinitions.PAGE_SIZE, sort), status,
|
||||||
searchText, distributionId, noTagClicked, targetTags);
|
overdueState, searchText, distributionId, noTagClicked, targetTags);
|
||||||
}
|
}
|
||||||
for (final Target targ : targetBeans) {
|
for (final Target targ : targetBeans) {
|
||||||
final ProxyTarget prxyTarget = new ProxyTarget();
|
final ProxyTarget prxyTarget = new ProxyTarget();
|
||||||
@@ -170,31 +174,27 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOverdueFilterEnabled() {
|
||||||
|
return Boolean.TRUE.equals(overdueState);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void saveBeans(final List<ProxyTarget> addedTargets, final List<ProxyTarget> modifiedTargets,
|
protected void saveBeans(final List<ProxyTarget> addedTargets, final List<ProxyTarget> modifiedTargets,
|
||||||
final List<ProxyTarget> removedTargets) {
|
final List<ProxyTarget> removedTargets) {
|
||||||
// CRUD operations on Target will be done through repository methods
|
// CRUD operations on Target will be done through repository methods
|
||||||
}
|
}
|
||||||
|
|
||||||
private Boolean anyFilterSelected() {
|
|
||||||
if (CollectionUtils.isEmpty(status) && distributionId == null && Strings.isNullOrEmpty(searchText)
|
|
||||||
&& !isTagSelected()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
final long totSize = getTargetManagement().countTargetsAll();
|
final long totSize = getTargetManagement().countTargetsAll();
|
||||||
long size;
|
long size;
|
||||||
if (null != targetFilterQuery) {
|
if (null != targetFilterQuery) {
|
||||||
size = getTargetManagement().countTargetByTargetFilterQuery(targetFilterQuery);
|
size = getTargetManagement().countTargetByTargetFilterQuery(targetFilterQuery);
|
||||||
} else if (!anyFilterSelected()) {
|
} else if (!isAnyFilterSelected()) {
|
||||||
size = totSize;
|
size = totSize;
|
||||||
} else {
|
} else {
|
||||||
size = getTargetManagement().countTargetByFilters(status, searchText, distributionId, noTagClicked,
|
size = getTargetManagement().countTargetByFilters(status, overdueState, searchText, distributionId,
|
||||||
targetTags);
|
noTagClicked, targetTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ManagementUIState tmpManagementUIState = getManagementUIState();
|
final ManagementUIState tmpManagementUIState = getManagementUIState();
|
||||||
@@ -209,6 +209,11 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
return (int) size;
|
return (int) size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAnyFilterSelected() {
|
||||||
|
final boolean isFilterSelected = isTagSelected() || isOverdueFilterEnabled();
|
||||||
|
return isFilterSelected || CollectionUtils.isNotEmpty(status) || distributionId != null || !isNullOrEmpty(searchText);
|
||||||
|
}
|
||||||
|
|
||||||
private TargetManagement getTargetManagement() {
|
private TargetManagement getTargetManagement() {
|
||||||
if (targetManagement == null) {
|
if (targetManagement == null) {
|
||||||
targetManagement = SpringContextHelper.getBean(TargetManagement.class);
|
targetManagement = SpringContextHelper.getBean(TargetManagement.class);
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.util.stream.Collectors;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.eclipse.hawkbit.repository.FilterParams;
|
||||||
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
|
||||||
@@ -411,6 +412,9 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
|
|||||||
.getClickedStatusTargetTags();
|
.getClickedStatusTargetTags();
|
||||||
queryConfig.put(SPUIDefinitions.FILTER_BY_STATUS, statusList);
|
queryConfig.put(SPUIDefinitions.FILTER_BY_STATUS, statusList);
|
||||||
}
|
}
|
||||||
|
if (managementUIState.getTargetTableFilters().isOverdueFilterEnabled()) {
|
||||||
|
queryConfig.put(SPUIDefinitions.FILTER_BY_OVERDUE_STATE, Boolean.TRUE);
|
||||||
|
}
|
||||||
return queryConfig;
|
return queryConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +465,7 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
|
|||||||
/**
|
/**
|
||||||
* Add listener to pin.
|
* Add listener to pin.
|
||||||
*
|
*
|
||||||
* @param pinBtn
|
* @param event
|
||||||
* as event
|
* as event
|
||||||
*/
|
*/
|
||||||
private void addPinClickListener(final ClickEvent event) {
|
private void addPinClickListener(final ClickEvent event) {
|
||||||
@@ -843,6 +847,7 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
|
|||||||
managementUIState.setTargetsCountAll(totalTargetsCount);
|
managementUIState.setTargetsCountAll(totalTargetsCount);
|
||||||
|
|
||||||
Collection<TargetUpdateStatus> status = null;
|
Collection<TargetUpdateStatus> status = null;
|
||||||
|
Boolean overdueState = null;
|
||||||
String[] targetTags = null;
|
String[] targetTags = null;
|
||||||
Long distributionId = null;
|
Long distributionId = null;
|
||||||
String searchText = null;
|
String searchText = null;
|
||||||
@@ -854,6 +859,9 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
|
|||||||
if (isFilteredByStatus()) {
|
if (isFilteredByStatus()) {
|
||||||
status = managementUIState.getTargetTableFilters().getClickedStatusTargetTags();
|
status = managementUIState.getTargetTableFilters().getClickedStatusTargetTags();
|
||||||
}
|
}
|
||||||
|
if (managementUIState.getTargetTableFilters().isOverdueFilterEnabled()) {
|
||||||
|
overdueState = managementUIState.getTargetTableFilters().isOverdueFilterEnabled();
|
||||||
|
}
|
||||||
if (managementUIState.getTargetTableFilters().getDistributionSet().isPresent()) {
|
if (managementUIState.getTargetTableFilters().getDistributionSet().isPresent()) {
|
||||||
distributionId = managementUIState.getTargetTableFilters().getDistributionSet().get().getId();
|
distributionId = managementUIState.getTargetTableFilters().getDistributionSet().get().getId();
|
||||||
}
|
}
|
||||||
@@ -865,25 +873,29 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
|
|||||||
pinnedDistId = managementUIState.getTargetTableFilters().getPinnedDistId().get();
|
pinnedDistId = managementUIState.getTargetTableFilters().getPinnedDistId().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
final long size = getTargetsCountWithFilter(totalTargetsCount, status, targetTags, distributionId, searchText,
|
final long size = getTargetsCountWithFilter(totalTargetsCount, pinnedDistId,
|
||||||
noTagClicked, pinnedDistId);
|
new FilterParams(distributionId, status, overdueState, searchText, noTagClicked, targetTags));
|
||||||
|
|
||||||
if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) {
|
if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) {
|
||||||
managementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES);
|
managementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getTargetsCountWithFilter(final long totalTargetsCount, final Collection<TargetUpdateStatus> status,
|
private long getTargetsCountWithFilter(final long totalTargetsCount,
|
||||||
final String[] targetTags, final Long distributionId, final String searchText, final Boolean noTagClicked,
|
final Long pinnedDistId, final FilterParams filterParams) {
|
||||||
final Long pinnedDistId) {
|
|
||||||
final long size;
|
final long size;
|
||||||
if (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) {
|
if (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) {
|
||||||
size = targetManagement.countTargetByTargetFilterQuery(
|
size = targetManagement.countTargetByTargetFilterQuery(
|
||||||
managementUIState.getTargetTableFilters().getTargetFilterQuery().get());
|
managementUIState.getTargetTableFilters().getTargetFilterQuery().get());
|
||||||
} else if (noFilterSelected(status, pinnedDistId, noTagClicked, targetTags, searchText)) {
|
} else if (noFilterSelected(filterParams.getFilterByStatus(), pinnedDistId,
|
||||||
|
filterParams.getSelectTargetWithNoTag(), filterParams.getFilterByTagNames(),
|
||||||
|
filterParams.getFilterBySearchText())) {
|
||||||
size = totalTargetsCount;
|
size = totalTargetsCount;
|
||||||
} else {
|
} else {
|
||||||
size = targetManagement.countTargetByFilters(status, searchText, distributionId, noTagClicked, targetTags);
|
size = targetManagement.countTargetByFilters(filterParams.getFilterByStatus(),
|
||||||
|
filterParams.getOverdueState(), filterParams.getFilterBySearchText(),
|
||||||
|
filterParams.getFilterByDistributionId(), filterParams.getSelectTargetWithNoTag(),
|
||||||
|
filterParams.getFilterByTagNames());
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,16 +54,20 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ManagementUIState managementUIState;
|
private ManagementUIState managementUIState;
|
||||||
|
|
||||||
|
private static final String OVERDUE_CAPTION = "overdue";
|
||||||
|
|
||||||
private Button unknown;
|
private Button unknown;
|
||||||
private Button inSync;
|
private Button inSync;
|
||||||
private Button pending;
|
private Button pending;
|
||||||
private Button error;
|
private Button error;
|
||||||
private Button registered;
|
private Button registered;
|
||||||
|
private Button overdue;
|
||||||
private Boolean unknownBtnClicked = false;
|
private Boolean unknownBtnClicked = false;
|
||||||
private Boolean errorBtnClicked = false;
|
private Boolean errorBtnClicked = false;
|
||||||
private Boolean pendingBtnClicked = false;
|
private Boolean pendingBtnClicked = false;
|
||||||
private Boolean inSyncBtnClicked = false;
|
private Boolean inSyncBtnClicked = false;
|
||||||
private Boolean registeredBtnClicked = false;
|
private Boolean registeredBtnClicked = false;
|
||||||
|
private Boolean overdueBtnClicked = false;
|
||||||
private Button buttonClicked;
|
private Button buttonClicked;
|
||||||
private static final String BTN_CLICKED = "btnClicked";
|
private static final String BTN_CLICKED = "btnClicked";
|
||||||
|
|
||||||
@@ -103,7 +107,17 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
buttonLayout.addComponent(registered);
|
buttonLayout.addComponent(registered);
|
||||||
buttonLayout.setComponentAlignment(registered, Alignment.MIDDLE_CENTER);
|
buttonLayout.setComponentAlignment(registered, Alignment.MIDDLE_CENTER);
|
||||||
addComponent(buttonLayout);
|
addComponent(buttonLayout);
|
||||||
setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER);
|
setComponentAlignment(buttonLayout, Alignment.MIDDLE_LEFT);
|
||||||
|
|
||||||
|
final HorizontalLayout overdueLayout = new HorizontalLayout();
|
||||||
|
final Label overdueLabel = new LabelBuilder().name(i18n.get("label.filter.by.overdue")).buildLabel();
|
||||||
|
overdueLayout.setStyleName("overdue-button-layout");
|
||||||
|
overdueLayout.addComponent(overdue);
|
||||||
|
overdueLayout.setComponentAlignment(overdue, Alignment.MIDDLE_LEFT);
|
||||||
|
overdueLayout.addComponent(overdueLabel);
|
||||||
|
overdueLayout.setComponentAlignment(overdueLabel, Alignment.MIDDLE_LEFT);
|
||||||
|
addComponent(overdueLayout);
|
||||||
|
setComponentAlignment(overdueLayout, Alignment.MIDDLE_LEFT);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +143,10 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (managementUIState.getTargetTableFilters().isOverdueFilterEnabled()) {
|
||||||
|
overdue.addStyleName(BTN_CLICKED);
|
||||||
|
overdueBtnClicked = Boolean.TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -150,18 +168,23 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
registered = SPUIComponentProvider.getButton(UIComponentIdProvider.REGISTERED_STATUS_ICON,
|
registered = SPUIComponentProvider.getButton(UIComponentIdProvider.REGISTERED_STATUS_ICON,
|
||||||
TargetUpdateStatus.REGISTERED.toString(), i18n.get("tooltip.status.registered"),
|
TargetUpdateStatus.REGISTERED.toString(), i18n.get("tooltip.status.registered"),
|
||||||
SPUIButtonDefinitions.SP_BUTTON_STATUS_STYLE, false, FontAwesome.SQUARE, SPUIButtonStyleSmall.class);
|
SPUIButtonDefinitions.SP_BUTTON_STATUS_STYLE, false, FontAwesome.SQUARE, SPUIButtonStyleSmall.class);
|
||||||
|
overdue = SPUIComponentProvider.getButton(UIComponentIdProvider.OVERDUE_STATUS_ICON,
|
||||||
|
OVERDUE_CAPTION, i18n.get("tooltip.status.overdue"),
|
||||||
|
SPUIButtonDefinitions.SP_BUTTON_STATUS_STYLE, false, FontAwesome.SQUARE, SPUIButtonStyleSmall.class);
|
||||||
applyStatusBtnStyle();
|
applyStatusBtnStyle();
|
||||||
unknown.setData("filterStatusOne");
|
unknown.setData("filterStatusOne");
|
||||||
inSync.setData("filterStatusTwo");
|
inSync.setData("filterStatusTwo");
|
||||||
pending.setData("filterStatusThree");
|
pending.setData("filterStatusThree");
|
||||||
error.setData("filterStatusFour");
|
error.setData("filterStatusFour");
|
||||||
registered.setData("filterStatusFive");
|
registered.setData("filterStatusFive");
|
||||||
|
overdue.setData("filterStatusSix");
|
||||||
|
|
||||||
unknown.addClickListener(this);
|
unknown.addClickListener(this);
|
||||||
inSync.addClickListener(this);
|
inSync.addClickListener(this);
|
||||||
pending.addClickListener(this);
|
pending.addClickListener(this);
|
||||||
error.addClickListener(this);
|
error.addClickListener(this);
|
||||||
registered.addClickListener(this);
|
registered.addClickListener(this);
|
||||||
|
overdue.addClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,6 +196,7 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
pending.addStyleName("pendingBtn");
|
pending.addStyleName("pendingBtn");
|
||||||
error.addStyleName("errorBtn");
|
error.addStyleName("errorBtn");
|
||||||
registered.addStyleName("registeredBtn");
|
registered.addStyleName("registeredBtn");
|
||||||
|
overdue.addStyleName("overdueBtn");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -188,6 +212,8 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
processErrorFilterStatus();
|
processErrorFilterStatus();
|
||||||
} else if (event.getButton().getCaption().equalsIgnoreCase(TargetUpdateStatus.REGISTERED.toString())) {
|
} else if (event.getButton().getCaption().equalsIgnoreCase(TargetUpdateStatus.REGISTERED.toString())) {
|
||||||
processRegisteredFilterStatus();
|
processRegisteredFilterStatus();
|
||||||
|
} else if (event.getButton().getCaption().equalsIgnoreCase(OVERDUE_CAPTION)) {
|
||||||
|
processOverdueFilterStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,9 +257,26 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
processCommonFilterStatus(TargetUpdateStatus.REGISTERED, registeredBtnClicked);
|
processCommonFilterStatus(TargetUpdateStatus.REGISTERED, registeredBtnClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process - OVERDUE.
|
||||||
|
*/
|
||||||
|
private void processOverdueFilterStatus() {
|
||||||
|
overdueBtnClicked = !overdueBtnClicked;
|
||||||
|
managementUIState.getTargetTableFilters().setOverdueFilterEnabled(overdueBtnClicked);
|
||||||
|
|
||||||
|
if (overdueBtnClicked) {
|
||||||
|
buttonClicked.addStyleName(BTN_CLICKED);
|
||||||
|
eventBus.publish(this, TargetFilterEvent.FILTER_BY_STATUS);
|
||||||
|
} else {
|
||||||
|
buttonClicked.removeStyleName(BTN_CLICKED);
|
||||||
|
eventBus.publish(this, TargetFilterEvent.REMOVE_FILTER_BY_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process - COMMON PROCESS.
|
* Process - COMMON PROCESS.
|
||||||
*
|
*
|
||||||
* @param status
|
* @param status
|
||||||
* as enum
|
* as enum
|
||||||
* @param buttonReset
|
* @param buttonReset
|
||||||
@@ -268,11 +311,12 @@ public class FilterByStatusLayout extends VerticalLayout implements Button.Click
|
|||||||
inSync.removeStyleName(BTN_CLICKED);
|
inSync.removeStyleName(BTN_CLICKED);
|
||||||
error.removeStyleName(BTN_CLICKED);
|
error.removeStyleName(BTN_CLICKED);
|
||||||
pending.removeStyleName(BTN_CLICKED);
|
pending.removeStyleName(BTN_CLICKED);
|
||||||
|
overdue.removeStyleName(BTN_CLICKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if any status button in clicked.
|
* Check if any status button in clicked.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean isStatusFilterApplied() {
|
private boolean isStatusFilterApplied() {
|
||||||
|
|||||||
@@ -205,6 +205,12 @@ public final class SPUIDefinitions {
|
|||||||
* Filter by status key.
|
* Filter by status key.
|
||||||
*/
|
*/
|
||||||
public static final String FILTER_BY_STATUS = "FilterByStatus";
|
public static final String FILTER_BY_STATUS = "FilterByStatus";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by overdue state key.
|
||||||
|
*/
|
||||||
|
public static final String FILTER_BY_OVERDUE_STATE = "FilterByOverdueState";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter by tag key.
|
* Filter by tag key.
|
||||||
*/
|
*/
|
||||||
@@ -505,7 +511,7 @@ public final class SPUIDefinitions {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the locales
|
* Get the locales
|
||||||
*
|
*
|
||||||
* @return the availableLocales
|
* @return the availableLocales
|
||||||
*/
|
*/
|
||||||
public static Set<String> getAvailableLocales() {
|
public static Set<String> getAvailableLocales() {
|
||||||
|
|||||||
@@ -189,6 +189,10 @@ public final class UIComponentIdProvider {
|
|||||||
* REGISTERED_STATUS_ICON ID.
|
* REGISTERED_STATUS_ICON ID.
|
||||||
*/
|
*/
|
||||||
public static final String REGISTERED_STATUS_ICON = "registered.status.icon";
|
public static final String REGISTERED_STATUS_ICON = "registered.status.icon";
|
||||||
|
/**
|
||||||
|
* OVERDUE_STATUS_ICON ID.
|
||||||
|
*/
|
||||||
|
public static final String OVERDUE_STATUS_ICON = "overdue.status.icon";
|
||||||
/**
|
/**
|
||||||
* DROP filter icon id.
|
* DROP filter icon id.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -13,8 +13,11 @@
|
|||||||
$unknown-color: $status-unknown-color;
|
$unknown-color: $status-unknown-color;
|
||||||
$in-sync-color: $signal-green-color;
|
$in-sync-color: $signal-green-color;
|
||||||
$pending-color: $signal-yellow-color;
|
$pending-color: $signal-yellow-color;
|
||||||
$error-color: $signal-red-color;
|
$error-color: $signal-red-color;
|
||||||
$registered-color: $bosch-color-light-blue;
|
$registered-color: $signal-light-blue-color;
|
||||||
|
|
||||||
|
//Overdue filter button color
|
||||||
|
$overdue-color: $signal-dark-blue-color;
|
||||||
|
|
||||||
//Filter by status buttons group alignment
|
//Filter by status buttons group alignment
|
||||||
.target-status-filters {
|
.target-status-filters {
|
||||||
@@ -27,6 +30,10 @@
|
|||||||
.status-button-layout {
|
.status-button-layout {
|
||||||
height: 40px !important;
|
height: 40px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overdue-button-layout {
|
||||||
|
height: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
//Filter Button applied with below styles based on the color
|
//Filter Button applied with below styles based on the color
|
||||||
.unknownBtn {
|
.unknownBtn {
|
||||||
@@ -68,6 +75,16 @@
|
|||||||
.errorBtn:active:after {
|
.errorBtn:active:after {
|
||||||
border-color: $error-color;
|
border-color: $error-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overdueBtn {
|
||||||
|
background: $overdue-color;
|
||||||
|
border: solid 3px $overdue-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overdueBtn:focus:after,
|
||||||
|
.overdueBtn:active:after {
|
||||||
|
border-color: $overdue-color;
|
||||||
|
}
|
||||||
|
|
||||||
.registeredBtn {
|
.registeredBtn {
|
||||||
background: $registered-color;
|
background: $registered-color;
|
||||||
|
|||||||
@@ -101,10 +101,13 @@ $details-tab-caption-font-scale: .8;
|
|||||||
//Generic text style
|
//Generic text style
|
||||||
$generic-text-font-scale: .85;
|
$generic-text-font-scale: .85;
|
||||||
|
|
||||||
$status-unknown-color: #3085cb;
|
$status-unknown-color: #d5d5d5;
|
||||||
$signal-green-color: #6eb553;
|
$signal-green-color: #6eb553;
|
||||||
$signal-yellow-color: #ff0;
|
$signal-yellow-color: #ff0;
|
||||||
|
$signal-light-blue-color: #3085cb;
|
||||||
|
$signal-dark-blue-color: #26547a;
|
||||||
$signal-red-color: #f00;
|
$signal-red-color: #f00;
|
||||||
|
$signal-black-color: #000;
|
||||||
$signal-orange-color: #ffa500;
|
$signal-orange-color: #ffa500;
|
||||||
|
|
||||||
$grey-light: #d5d5d5;
|
$grey-light: #d5d5d5;
|
||||||
|
|||||||
@@ -178,7 +178,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.statusIconLightBlue {
|
.statusIconLightBlue {
|
||||||
color: $bosch-color-light-blue;
|
color: $signal-light-blue-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-button-statusIconLightBlue:after {
|
.v-button-statusIconLightBlue:after {
|
||||||
@@ -219,7 +219,7 @@
|
|||||||
pointer-events: auto !important;
|
pointer-events: auto !important;
|
||||||
}
|
}
|
||||||
.blueSpinner{
|
.blueSpinner{
|
||||||
@include valo-spinner($size: $v-font-size--small,$color: $bosch-color-light-blue);
|
@include valo-spinner($size: $v-font-size--small,$color: $signal-light-blue-color);
|
||||||
pointer-events: auto !important;
|
pointer-events: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@
|
|||||||
@mixin target-filter-query {
|
@mixin target-filter-query {
|
||||||
|
|
||||||
.gwt-MenuBar-autocomplete {
|
.gwt-MenuBar-autocomplete {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gwt-MenuBar-autocomplete .gwt-MenuItem{
|
.gwt-MenuBar-autocomplete .gwt-MenuItem{
|
||||||
border-radius: 3px !important;
|
border-radius: 3px !important;
|
||||||
cursor: pointer !important;
|
cursor: pointer !important;
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
position: relative !important;
|
position: relative !important;
|
||||||
white-space: nowrap !important;
|
white-space: nowrap !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gwt-MenuBar-autocomplete .gwt-MenuItem-selected {
|
.gwt-MenuBar-autocomplete .gwt-MenuItem-selected {
|
||||||
background-color: $hawkbit-primary-color;
|
background-color: $hawkbit-primary-color;
|
||||||
background-image: linear-gradient(to bottom, #1b87e3 2%, #166ed5 98%) !important;
|
background-image: linear-gradient(to bottom, #1b87e3 2%, #166ed5 98%) !important;
|
||||||
|
|||||||
@@ -148,6 +148,7 @@ label.filter.selected = Selected :
|
|||||||
label.filter.shown = Shown :
|
label.filter.shown = Shown :
|
||||||
label.filter.targets = Filtered Targets :
|
label.filter.targets = Filtered Targets :
|
||||||
label.filter.status = Status,
|
label.filter.status = Status,
|
||||||
|
label.filter.overdue = Overdue,
|
||||||
label.filter.tags = Tags,
|
label.filter.tags = Tags,
|
||||||
label.filter.text = Search Text
|
label.filter.text = Search Text
|
||||||
label.filter.dist = Distribution,
|
label.filter.dist = Distribution,
|
||||||
@@ -168,6 +169,7 @@ label.target.id = Controller Id :
|
|||||||
label.target.ip = Controller IP :
|
label.target.ip = Controller IP :
|
||||||
label.target.security.token = Security token :
|
label.target.security.token = Security token :
|
||||||
label.filter.by.status = Filter by Status
|
label.filter.by.status = Filter by Status
|
||||||
|
label.filter.by.overdue = Filter by Overdue
|
||||||
label.target.controller.attrs = <b>Controller attributes</b>
|
label.target.controller.attrs = <b>Controller attributes</b>
|
||||||
label.target.lastpolldate = Last poll :
|
label.target.lastpolldate = Last poll :
|
||||||
label.tag.name = Tag name
|
label.tag.name = Tag name
|
||||||
@@ -203,6 +205,7 @@ tooltip.status.registered = Registered
|
|||||||
tooltip.status.pending = Pending
|
tooltip.status.pending = Pending
|
||||||
tooltip.status.error = Error
|
tooltip.status.error = Error
|
||||||
tooltip.status.insync = In-sync
|
tooltip.status.insync = In-sync
|
||||||
|
tooltip.status.overdue = Overdue
|
||||||
tooltip.delete.module = Select and delete Software Module
|
tooltip.delete.module = Select and delete Software Module
|
||||||
tooltip.forced.item=Forced update action
|
tooltip.forced.item=Forced update action
|
||||||
tooltip.soft.item=Soft update action which interacts with an user as a attempt update action for example
|
tooltip.soft.item=Soft update action which interacts with an user as a attempt update action for example
|
||||||
|
|||||||
14
pom.xml
14
pom.xml
@@ -133,7 +133,7 @@
|
|||||||
<org.easytesting.version>2.0M10</org.easytesting.version>
|
<org.easytesting.version>2.0M10</org.easytesting.version>
|
||||||
<allure.version>1.4.22</allure.version>
|
<allure.version>1.4.22</allure.version>
|
||||||
<eclipselink.version>2.6.2</eclipselink.version>
|
<eclipselink.version>2.6.2</eclipselink.version>
|
||||||
<org.powermock.version>1.5.4</org.powermock.version>
|
<org.powermock.version>1.6.5</org.powermock.version>
|
||||||
<pl.pragmatists.version>1.0.2</pl.pragmatists.version>
|
<pl.pragmatists.version>1.0.2</pl.pragmatists.version>
|
||||||
<guava.version>19.0</guava.version>
|
<guava.version>19.0</guava.version>
|
||||||
<mariadb-java-client.version>1.5.3</mariadb-java-client.version>
|
<mariadb-java-client.version>1.5.3</mariadb-java-client.version>
|
||||||
@@ -675,6 +675,18 @@
|
|||||||
<version>${pl.pragmatists.version}</version>
|
<version>${pl.pragmatists.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-module-junit4</artifactId>
|
||||||
|
<version>${org.powermock.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.powermock</groupId>
|
||||||
|
<artifactId>powermock-api-mockito</artifactId>
|
||||||
|
<version>${org.powermock.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mariadb.jdbc</groupId>
|
<groupId>org.mariadb.jdbc</groupId>
|
||||||
<artifactId>mariadb-java-client</artifactId>
|
<artifactId>mariadb-java-client</artifactId>
|
||||||
|
|||||||
Reference in New Issue
Block a user