Fix rollouts status cache eviction and NPE in UI (#530)
* Fix nullpointer in UI and rollout cache invalidation prob. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Sonar issue and util usage. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Evict cache on tenant delete. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -44,6 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.io.BaseEncoding;
|
import com.google.common.io.BaseEncoding;
|
||||||
@@ -105,7 +106,7 @@ public class DeviceSimulatorUpdater {
|
|||||||
|
|
||||||
device.setProgress(0.0);
|
device.setProgress(0.0);
|
||||||
|
|
||||||
if (modules == null || modules.isEmpty()) {
|
if (CollectionUtils.isEmpty(modules)) {
|
||||||
device.setSwversion(swVersion);
|
device.setSwversion(swVersion);
|
||||||
} else {
|
} else {
|
||||||
device.setSwversion(
|
device.setSwversion(
|
||||||
|
|||||||
@@ -32,6 +32,10 @@
|
|||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ben-manes.caffeine</groupId>
|
||||||
|
<artifactId>caffeine</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context-support</artifactId>
|
<artifactId>spring-context-support</artifactId>
|
||||||
|
|||||||
@@ -24,10 +24,10 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
|||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountActionStatus;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.guava.GuavaCacheManager;
|
import org.springframework.cache.caffeine.CaffeineCacheManager;
|
||||||
import org.springframework.context.event.EventListener;
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal cache for Rollout status.
|
* Internal cache for Rollout status.
|
||||||
@@ -49,11 +49,11 @@ public class RolloutStatusCache {
|
|||||||
public RolloutStatusCache(final TenantAware tenantAware, final long size) {
|
public RolloutStatusCache(final TenantAware tenantAware, final long size) {
|
||||||
this.tenantAware = tenantAware;
|
this.tenantAware = tenantAware;
|
||||||
|
|
||||||
final CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.newBuilder().maximumSize(size);
|
final Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder().maximumSize(size);
|
||||||
final GuavaCacheManager guavaCacheManager = new GuavaCacheManager();
|
final CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
|
||||||
guavaCacheManager.setCacheBuilder(cacheBuilder);
|
caffeineCacheManager.setCaffeine(cacheBuilder);
|
||||||
|
|
||||||
this.cacheManager = new TenantAwareCacheManager(guavaCacheManager, tenantAware);
|
this.cacheManager = new TenantAwareCacheManager(caffeineCacheManager, tenantAware);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -174,8 +174,8 @@ public class RolloutStatusCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Map<Long, List<TotalTargetCountActionStatus>> retrieveFromCache(final List<Long> ids, final Cache cache) {
|
private Map<Long, List<TotalTargetCountActionStatus>> retrieveFromCache(final List<Long> ids, final Cache cache) {
|
||||||
return ids.stream().map(rolloutId -> cache.get(rolloutId, CachedTotalTargetCountActionStatus.class))
|
return ids.stream().map(id -> cache.get(id, CachedTotalTargetCountActionStatus.class)).filter(Objects::nonNull)
|
||||||
.filter(Objects::nonNull).collect(Collectors.toMap(CachedTotalTargetCountActionStatus::getRolloutId,
|
.collect(Collectors.toMap(CachedTotalTargetCountActionStatus::getId,
|
||||||
CachedTotalTargetCountActionStatus::getStatus));
|
CachedTotalTargetCountActionStatus::getStatus));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,9 +189,8 @@ public class RolloutStatusCache {
|
|||||||
return cacheItem.getStatus();
|
return cacheItem.getStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putIntoCache(final Long rolloutId, final List<TotalTargetCountActionStatus> status,
|
private void putIntoCache(final Long id, final List<TotalTargetCountActionStatus> status, final Cache cache) {
|
||||||
final Cache cache) {
|
cache.put(id, new CachedTotalTargetCountActionStatus(id, status));
|
||||||
cache.put(rolloutId, new CachedTotalTargetCountActionStatus(rolloutId, status));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putIntoCache(final Map<Long, List<TotalTargetCountActionStatus>> put, final Cache cache) {
|
private void putIntoCache(final Map<Long, List<TotalTargetCountActionStatus>> put, final Cache cache) {
|
||||||
@@ -201,20 +200,16 @@ public class RolloutStatusCache {
|
|||||||
|
|
||||||
@EventListener(classes = AbstractActionEvent.class)
|
@EventListener(classes = AbstractActionEvent.class)
|
||||||
void invalidateCachedTotalTargetCountActionStatus(final AbstractActionEvent event) {
|
void invalidateCachedTotalTargetCountActionStatus(final AbstractActionEvent event) {
|
||||||
if (event.getRolloutId() == null) {
|
if (event.getRolloutId() != null) {
|
||||||
return;
|
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
||||||
}
|
|
||||||
|
|
||||||
Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_RO_NAME));
|
|
||||||
cache.evict(event.getRolloutId());
|
cache.evict(event.getRolloutId());
|
||||||
|
|
||||||
if (event.getRolloutGroupId() == null) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_GR_NAME));
|
if (event.getRolloutGroupId() != null) {
|
||||||
|
final Cache cache = tenantAware.runAsTenant(event.getTenant(), () -> cacheManager.getCache(CACHE_GR_NAME));
|
||||||
cache.evict(event.getRolloutGroupId());
|
cache.evict(event.getRolloutGroupId());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventListener(classes = RolloutDeletedEvent.class)
|
@EventListener(classes = RolloutDeletedEvent.class)
|
||||||
void invalidateCachedTotalTargetCountOnRolloutDelete(final RolloutDeletedEvent event) {
|
void invalidateCachedTotalTargetCountOnRolloutDelete(final RolloutDeletedEvent event) {
|
||||||
@@ -228,18 +223,28 @@ public class RolloutStatusCache {
|
|||||||
cache.evict(event.getEntityId());
|
cache.evict(event.getEntityId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evicts all caches for a given tenant. All caches under a certain tenant
|
||||||
|
* gets evicted.
|
||||||
|
*
|
||||||
|
* @param tenant
|
||||||
|
* the tenant to evict caches
|
||||||
|
*/
|
||||||
|
public void evictCaches(final String tenant) {
|
||||||
|
cacheManager.evictCaches(tenant);
|
||||||
|
}
|
||||||
|
|
||||||
private static final class CachedTotalTargetCountActionStatus {
|
private static final class CachedTotalTargetCountActionStatus {
|
||||||
private final long rolloutId;
|
private final long id;
|
||||||
private final List<TotalTargetCountActionStatus> status;
|
private final List<TotalTargetCountActionStatus> status;
|
||||||
|
|
||||||
private CachedTotalTargetCountActionStatus(final long rolloutId,
|
private CachedTotalTargetCountActionStatus(final long id, final List<TotalTargetCountActionStatus> status) {
|
||||||
final List<TotalTargetCountActionStatus> status) {
|
this.id = id;
|
||||||
this.rolloutId = rolloutId;
|
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getRolloutId() {
|
public long getId() {
|
||||||
return rolloutId;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TotalTargetCountActionStatus> getStatus() {
|
public List<TotalTargetCountActionStatus> getStatus() {
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
final DistributionSetFilter distributionSetFilter) {
|
final DistributionSetFilter distributionSetFilter) {
|
||||||
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
|
final List<Specification<JpaDistributionSet>> specList = buildDistributionSetSpecifications(
|
||||||
distributionSetFilter);
|
distributionSetFilter);
|
||||||
if (specList == null || specList.isEmpty()) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return distributionSetRepository.findOne(SpecificationsBuilder.combineWithAnd(specList));
|
return distributionSetRepository.findOne(SpecificationsBuilder.combineWithAnd(specList));
|
||||||
@@ -667,7 +667,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
private Page<JpaDistributionSet> findByCriteriaAPI(final Pageable pageable,
|
private Page<JpaDistributionSet> findByCriteriaAPI(final Pageable pageable,
|
||||||
final List<Specification<JpaDistributionSet>> specList) {
|
final List<Specification<JpaDistributionSet>> specList) {
|
||||||
|
|
||||||
if (specList == null || specList.isEmpty()) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return distributionSetRepository.findAll(pageable);
|
return distributionSetRepository.findAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ import org.springframework.data.domain.PageImpl;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,7 +167,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
|
|||||||
List<TotalTargetCountActionStatus> rolloutStatusCountItems = rolloutStatusCache
|
List<TotalTargetCountActionStatus> rolloutStatusCountItems = rolloutStatusCache
|
||||||
.getRolloutGroupStatus(rolloutGroupId);
|
.getRolloutGroupStatus(rolloutGroupId);
|
||||||
|
|
||||||
if (rolloutStatusCountItems.isEmpty()) {
|
if (CollectionUtils.isEmpty(rolloutStatusCountItems)) {
|
||||||
rolloutStatusCountItems = actionRepository.getStatusCountByRolloutGroupId(rolloutGroupId);
|
rolloutStatusCountItems = actionRepository.getStatusCountByRolloutGroupId(rolloutGroupId);
|
||||||
rolloutStatusCache.putRolloutGroupStatus(rolloutGroupId, rolloutStatusCountItems);
|
rolloutStatusCache.putRolloutGroupStatus(rolloutGroupId, rolloutStatusCountItems);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||||||
import org.springframework.transaction.TransactionException;
|
import org.springframework.transaction.TransactionException;
|
||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.util.concurrent.ListenableFuture;
|
import org.springframework.util.concurrent.ListenableFuture;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -177,7 +178,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
|
|||||||
*/
|
*/
|
||||||
private Page<JpaRollout> findByCriteriaAPI(final Pageable pageable,
|
private Page<JpaRollout> findByCriteriaAPI(final Pageable pageable,
|
||||||
final List<Specification<JpaRollout>> specList) {
|
final List<Specification<JpaRollout>> specList) {
|
||||||
if (specList == null || specList.isEmpty()) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return rolloutRepository.findAll(pageable);
|
return rolloutRepository.findAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -992,7 +993,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement {
|
|||||||
|
|
||||||
List<TotalTargetCountActionStatus> rolloutStatusCountItems = rolloutStatusCache.getRolloutStatus(rolloutId);
|
List<TotalTargetCountActionStatus> rolloutStatusCountItems = rolloutStatusCache.getRolloutStatus(rolloutId);
|
||||||
|
|
||||||
if (rolloutStatusCountItems.isEmpty()) {
|
if (CollectionUtils.isEmpty(rolloutStatusCountItems)) {
|
||||||
rolloutStatusCountItems = actionRepository.getStatusCountByRolloutId(rolloutId);
|
rolloutStatusCountItems = actionRepository.getStatusCountByRolloutId(rolloutId);
|
||||||
rolloutStatusCache.putRolloutStatus(rolloutId, rolloutStatusCountItems);
|
rolloutStatusCache.putRolloutStatus(rolloutId, rolloutStatusCountItems);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import java.util.stream.Collectors;
|
|||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
import org.eclipse.hawkbit.cache.TenancyCacheManager;
|
||||||
|
import org.eclipse.hawkbit.repository.RolloutStatusCache;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
||||||
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
import org.eclipse.hawkbit.repository.jpa.configuration.Constants;
|
||||||
@@ -112,6 +113,9 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PlatformTransactionManager txManager;
|
private PlatformTransactionManager txManager;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RolloutStatusCache rolloutStatusCache;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SystemUsageReport getSystemUsageStatistics() {
|
public SystemUsageReport getSystemUsageStatistics() {
|
||||||
|
|
||||||
@@ -219,6 +223,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
public void deleteTenant(final String t) {
|
public void deleteTenant(final String t) {
|
||||||
final String tenant = t.toUpperCase();
|
final String tenant = t.toUpperCase();
|
||||||
cacheManager.evictCaches(tenant);
|
cacheManager.evictCaches(tenant);
|
||||||
|
rolloutStatusCache.evictCaches(tenant);
|
||||||
tenantAware.runAsTenant(tenant, () -> {
|
tenantAware.runAsTenant(tenant, () -> {
|
||||||
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant);
|
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant);
|
||||||
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import org.springframework.data.jpa.domain.Specifications;
|
|||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
@@ -157,7 +158,7 @@ public class JpaTargetFilterQueryManagement implements TargetFilterQueryManageme
|
|||||||
|
|
||||||
private Page<JpaTargetFilterQuery> findTargetFilterQueryByCriteriaAPI(final Pageable pageable,
|
private Page<JpaTargetFilterQuery> findTargetFilterQueryByCriteriaAPI(final Pageable pageable,
|
||||||
final List<Specification<JpaTargetFilterQuery>> specList) {
|
final List<Specification<JpaTargetFilterQuery>> specList) {
|
||||||
if (specList == null || specList.isEmpty()) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return targetFilterQueryRepository.findAll(pageable);
|
return targetFilterQueryRepository.findAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ import org.springframework.data.jpa.domain.Specification;
|
|||||||
import org.springframework.retry.annotation.Backoff;
|
import org.springframework.retry.annotation.Backoff;
|
||||||
import org.springframework.retry.annotation.Retryable;
|
import org.springframework.retry.annotation.Retryable;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
@@ -317,7 +318,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 (CollectionUtils.isEmpty(specList)) {
|
||||||
return convertPage(criteriaNoCountDao.findAll(pageable, JpaTarget.class), pageable);
|
return convertPage(criteriaNoCountDao.findAll(pageable, JpaTarget.class), pageable);
|
||||||
}
|
}
|
||||||
return convertPage(
|
return convertPage(
|
||||||
@@ -326,7 +327,7 @@ public class JpaTargetManagement implements TargetManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Long countByCriteriaAPI(final List<Specification<JpaTarget>> specList) {
|
private Long countByCriteriaAPI(final List<Specification<JpaTarget>> specList) {
|
||||||
if (specList == null || specList.isEmpty()) {
|
if (CollectionUtils.isEmpty(specList)) {
|
||||||
return targetRepository.count();
|
return targetRepository.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.SimpleTypeConverter;
|
import org.springframework.beans.SimpleTypeConverter;
|
||||||
import org.springframework.beans.TypeMismatchException;
|
import org.springframework.beans.TypeMismatchException;
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import cz.jirutka.rsql.parser.RSQLParser;
|
import cz.jirutka.rsql.parser.RSQLParser;
|
||||||
import cz.jirutka.rsql.parser.RSQLParserException;
|
import cz.jirutka.rsql.parser.RSQLParserException;
|
||||||
@@ -169,7 +170,7 @@ public final class RSQLUtility {
|
|||||||
virtualPropertyReplacer);
|
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 (!CollectionUtils.isEmpty(accept)) {
|
||||||
return cb.and(accept.toArray(new Predicate[accept.size()]));
|
return cb.and(accept.toArray(new Predicate[accept.size()]));
|
||||||
}
|
}
|
||||||
return cb.conjunction();
|
return cb.conjunction();
|
||||||
@@ -652,7 +653,7 @@ public final class RSQLUtility {
|
|||||||
final List<Predicate> childs = new ArrayList<>();
|
final List<Predicate> childs = new ArrayList<>();
|
||||||
for (final Node node2 : children) {
|
for (final Node node2 : children) {
|
||||||
final List<Predicate> accept = node2.accept(this);
|
final List<Predicate> accept = node2.accept(this);
|
||||||
if (accept != null && !accept.isEmpty()) {
|
if (!CollectionUtils.isEmpty(accept)) {
|
||||||
childs.addAll(accept);
|
childs.addAll(accept);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.debug("visit logical node children but could not parse it, ignoring {}", node2);
|
LOGGER.debug("visit logical node children but could not parse it, ignoring {}", node2);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
@@ -149,7 +150,7 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
|||||||
final int currentTokenEndColumn, final int[] is) {
|
final int currentTokenEndColumn, final int[] is) {
|
||||||
for (final int i : is) {
|
for (final int i : is) {
|
||||||
final Collection<String> tokenImage = TokenDescription.getTokenImage(i);
|
final Collection<String> tokenImage = TokenDescription.getTokenImage(i);
|
||||||
if (tokenImage != null && !tokenImage.isEmpty()) {
|
if (!CollectionUtils.isEmpty(tokenImage)) {
|
||||||
tokenImage.forEach(image -> listTokens.add(new SuggestToken(currentTokenEndColumn + 1,
|
tokenImage.forEach(image -> listTokens.add(new SuggestToken(currentTokenEndColumn + 1,
|
||||||
nextTokenBeginColumn + image.length(), null, image)));
|
nextTokenBeginColumn + image.length(), null, image)));
|
||||||
}
|
}
|
||||||
@@ -164,8 +165,8 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
|||||||
.of(FieldNameDescription.toTopSuggestToken(nextTokenBeginColumn - currentTokenImageName.length(),
|
.of(FieldNameDescription.toTopSuggestToken(nextTokenBeginColumn - currentTokenImageName.length(),
|
||||||
nextTokenBeginColumn + currentTokenImageName.length(), currentTokenImageName));
|
nextTokenBeginColumn + currentTokenImageName.length(), currentTokenImageName));
|
||||||
} else if (shouldSuggestDotToken(currentTokenImageName, containsDot)) {
|
} else if (shouldSuggestDotToken(currentTokenImageName, containsDot)) {
|
||||||
return Optional.of(
|
return Optional
|
||||||
Arrays.asList(new SuggestToken(currentTokenEndColumn, nextTokenBeginColumn + 1, null, ".")));
|
.of(Arrays.asList(new SuggestToken(currentTokenEndColumn, nextTokenBeginColumn + 1, null, ".")));
|
||||||
} else if (shouldSuggestSubTokenFieldNames(currentTokenImageName, containsDot)) {
|
} else if (shouldSuggestSubTokenFieldNames(currentTokenImageName, containsDot)) {
|
||||||
return handleSubtokenSuggestion(currentTokenImageName, nextTokenBeginColumn);
|
return handleSubtokenSuggestion(currentTokenImageName, nextTokenBeginColumn);
|
||||||
}
|
}
|
||||||
@@ -222,7 +223,7 @@ public class RsqlParserValidationOracle implements RsqlValidationOracle {
|
|||||||
builder = builder.substring(0, builder.lastIndexOf("Was expecting"));
|
builder = builder.substring(0, builder.lastIndexOf("Was expecting"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedTokens != null && !expectedTokens.isEmpty()) {
|
if (!CollectionUtils.isEmpty(expectedTokens)) {
|
||||||
final StringBuilder tokens = new StringBuilder();
|
final StringBuilder tokens = new StringBuilder();
|
||||||
expectedTokens.stream().forEach(value -> tokens.append(value.getSuggestion() + ","));
|
expectedTokens.stream().forEach(value -> tokens.append(value.getSuggestion() + ","));
|
||||||
builder = builder.concat("Was expecting :" + tokens.toString().substring(0, tokens.length() - 1));
|
builder = builder.concat("Was expecting :" + tokens.toString().substring(0, tokens.length() - 1));
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
|
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
|
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
|
||||||
@@ -28,6 +27,8 @@ import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout
|
|||||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
@@ -359,7 +360,7 @@ public class CommonDialogWindow extends Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Object emptyToNull(final Collection<?> c) {
|
private static Object emptyToNull(final Collection<?> c) {
|
||||||
return (c == null || c.isEmpty()) ? null : c;
|
return CollectionUtils.isEmpty(c) ? null : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNullValidator(final Component component) {
|
private boolean hasNullValidator(final Component component) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.eclipse.hawkbit.ui.utils.UINotification;
|
|||||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.vaadin.spring.events.EventBus;
|
import org.vaadin.spring.events.EventBus;
|
||||||
|
|
||||||
import com.vaadin.data.Item;
|
import com.vaadin.data.Item;
|
||||||
@@ -156,10 +157,10 @@ public class SoftwareModuleDetailsTable extends Table {
|
|||||||
final Set<SoftwareModuleType> swModuleMandatoryTypes = distributionSet.getType().getMandatoryModuleTypes();
|
final Set<SoftwareModuleType> swModuleMandatoryTypes = distributionSet.getType().getMandatoryModuleTypes();
|
||||||
final Set<SoftwareModuleType> swModuleOptionalTypes = distributionSet.getType().getOptionalModuleTypes();
|
final Set<SoftwareModuleType> swModuleOptionalTypes = distributionSet.getType().getOptionalModuleTypes();
|
||||||
|
|
||||||
if (swModuleMandatoryTypes != null && !swModuleMandatoryTypes.isEmpty()) {
|
if (!CollectionUtils.isEmpty(swModuleMandatoryTypes)) {
|
||||||
swModuleMandatoryTypes.forEach(swModule -> setSwModuleProperties(swModule, true, distributionSet));
|
swModuleMandatoryTypes.forEach(swModule -> setSwModuleProperties(swModule, true, distributionSet));
|
||||||
}
|
}
|
||||||
if (swModuleOptionalTypes != null && !swModuleOptionalTypes.isEmpty()) {
|
if (!CollectionUtils.isEmpty(swModuleOptionalTypes)) {
|
||||||
swModuleOptionalTypes.forEach(swModule -> setSwModuleProperties(swModule, false, distributionSet));
|
swModuleOptionalTypes.forEach(swModule -> setSwModuleProperties(swModule, false, distributionSet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
|||||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import com.vaadin.data.Item;
|
import com.vaadin.data.Item;
|
||||||
import com.vaadin.data.util.IndexedContainer;
|
import com.vaadin.data.util.IndexedContainer;
|
||||||
@@ -99,7 +100,7 @@ public class SoftwareModuleMetadatadetailslayout extends Table {
|
|||||||
.findSoftwareModuleMetadataBySoftwareModuleId(selectedSWModuleId,
|
.findSoftwareModuleMetadataBySoftwareModuleId(selectedSWModuleId,
|
||||||
new PageRequest(0, MAX_METADATA_QUERY))
|
new PageRequest(0, MAX_METADATA_QUERY))
|
||||||
.getContent();
|
.getContent();
|
||||||
if (null != swMetadataList && !swMetadataList.isEmpty()) {
|
if (!CollectionUtils.isEmpty(swMetadataList)) {
|
||||||
swMetadataList.forEach(this::setSWMetadataProperties);
|
swMetadataList.forEach(this::setSWMetadataProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -606,11 +606,14 @@ public abstract class AbstractGrid<T extends Indexed> extends Grid implements Re
|
|||||||
@Override
|
@Override
|
||||||
public String getStyle(final CellReference cellReference) {
|
public String getStyle(final CellReference cellReference) {
|
||||||
|
|
||||||
if (Arrays.stream(center).anyMatch(o -> Objects.equals(o, cellReference.getPropertyId()))) {
|
if (center != null
|
||||||
|
&& Arrays.stream(center).anyMatch(o -> Objects.equals(o, cellReference.getPropertyId()))) {
|
||||||
return "centeralign";
|
return "centeralign";
|
||||||
} else if (Arrays.stream(right).anyMatch(o -> Objects.equals(o, cellReference.getPropertyId()))) {
|
} else if (right != null
|
||||||
|
&& Arrays.stream(right).anyMatch(o -> Objects.equals(o, cellReference.getPropertyId()))) {
|
||||||
return "rightalign";
|
return "rightalign";
|
||||||
} else if (Arrays.stream(left).anyMatch(o -> Objects.equals(o, cellReference.getPropertyId()))) {
|
} else if (left != null
|
||||||
|
&& Arrays.stream(left).anyMatch(o -> Objects.equals(o, cellReference.getPropertyId()))) {
|
||||||
return "leftalign";
|
return "leftalign";
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
|||||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
||||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
||||||
import org.vaadin.spring.events.EventBus.UIEventBus;
|
import org.vaadin.spring.events.EventBus.UIEventBus;
|
||||||
@@ -388,7 +389,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout<Distri
|
|||||||
final String typeKeyValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeKey.getValue());
|
final String typeKeyValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeKey.getValue());
|
||||||
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
||||||
final List<Long> itemIds = (List<Long>) selectedTable.getItemIds();
|
final List<Long> itemIds = (List<Long>) selectedTable.getItemIds();
|
||||||
if (null != typeNameValue && null != typeKeyValue && null != itemIds && !itemIds.isEmpty()) {
|
if (null != typeNameValue && null != typeKeyValue && !CollectionUtils.isEmpty(itemIds)) {
|
||||||
|
|
||||||
final List<Long> mandatory = itemIds.stream()
|
final List<Long> mandatory = itemIds.stream()
|
||||||
.filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId)))
|
.filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId)))
|
||||||
@@ -429,8 +430,8 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout<Distri
|
|||||||
final DistributionSetTypeUpdate update = entityFactory.distributionSetType().update(existingType.getId())
|
final DistributionSetTypeUpdate update = entityFactory.distributionSetType().update(existingType.getId())
|
||||||
.description(tagDesc.getValue())
|
.description(tagDesc.getValue())
|
||||||
.colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()));
|
.colour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()));
|
||||||
if (distributionSetTypeManagement.countDistributionSetsByType(existingType.getId()) <= 0 && null != itemIds
|
if (distributionSetTypeManagement.countDistributionSetsByType(existingType.getId()) <= 0
|
||||||
&& !itemIds.isEmpty()) {
|
&& !CollectionUtils.isEmpty(itemIds)) {
|
||||||
|
|
||||||
update.mandatory(itemIds.stream().filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId)))
|
update.mandatory(itemIds.stream().filter(itemId -> isMandatoryModuleType(selectedTable.getItem(itemId)))
|
||||||
.collect(Collectors.toList()))
|
.collect(Collectors.toList()))
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
|||||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
import org.eclipse.hawkbit.ui.utils.VaadinMessageSource;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.vaadin.spring.events.EventBus.UIEventBus;
|
import org.vaadin.spring.events.EventBus.UIEventBus;
|
||||||
import org.vaadin.spring.events.EventScope;
|
import org.vaadin.spring.events.EventScope;
|
||||||
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
|
||||||
@@ -324,8 +325,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
|
|||||||
|
|
||||||
private void discardSoftwareTypeDelete(final String discardSWModuleType, final Object itemId,
|
private void discardSoftwareTypeDelete(final String discardSWModuleType, final Object itemId,
|
||||||
final ConfirmationTab tab) {
|
final ConfirmationTab tab) {
|
||||||
if (null != manageDistUIState.getSelectedDeleteSWModuleTypes()
|
if (!CollectionUtils.isEmpty(manageDistUIState.getSelectedDeleteSWModuleTypes())
|
||||||
&& !manageDistUIState.getSelectedDeleteSWModuleTypes().isEmpty()
|
|
||||||
&& manageDistUIState.getSelectedDeleteSWModuleTypes().contains(discardSWModuleType)) {
|
&& manageDistUIState.getSelectedDeleteSWModuleTypes().contains(discardSWModuleType)) {
|
||||||
manageDistUIState.getSelectedDeleteSWModuleTypes().remove(discardSWModuleType);
|
manageDistUIState.getSelectedDeleteSWModuleTypes().remove(discardSWModuleType);
|
||||||
}
|
}
|
||||||
@@ -420,8 +420,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
|
|||||||
private void discardDistDelete(final Button.ClickEvent event, final Object itemId, final ConfirmationTab tab) {
|
private void discardDistDelete(final Button.ClickEvent event, final Object itemId, final ConfirmationTab tab) {
|
||||||
|
|
||||||
final DistributionSetIdName distId = (DistributionSetIdName) ((Button) event.getComponent()).getData();
|
final DistributionSetIdName distId = (DistributionSetIdName) ((Button) event.getComponent()).getData();
|
||||||
if (null != manageDistUIState.getDeletedDistributionList()
|
if (!CollectionUtils.isEmpty(manageDistUIState.getDeletedDistributionList())
|
||||||
&& !manageDistUIState.getDeletedDistributionList().isEmpty()
|
|
||||||
&& manageDistUIState.getDeletedDistributionList().contains(distId)) {
|
&& manageDistUIState.getDeletedDistributionList().contains(distId)) {
|
||||||
manageDistUIState.getDeletedDistributionList().remove(distId);
|
manageDistUIState.getDeletedDistributionList().remove(distId);
|
||||||
}
|
}
|
||||||
@@ -509,8 +508,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
|
|||||||
|
|
||||||
private void discardDistTypeDelete(final String discardDSType, final Object itemId, final ConfirmationTab tab) {
|
private void discardDistTypeDelete(final String discardDSType, final Object itemId, final ConfirmationTab tab) {
|
||||||
|
|
||||||
if (null != manageDistUIState.getSelectedDeleteDistSetTypes()
|
if (!CollectionUtils.isEmpty(manageDistUIState.getSelectedDeleteDistSetTypes())
|
||||||
&& !manageDistUIState.getSelectedDeleteDistSetTypes().isEmpty()
|
|
||||||
&& manageDistUIState.getSelectedDeleteDistSetTypes().contains(discardDSType)) {
|
&& manageDistUIState.getSelectedDeleteDistSetTypes().contains(discardDSType)) {
|
||||||
manageDistUIState.getSelectedDeleteDistSetTypes().remove(discardDSType);
|
manageDistUIState.getSelectedDeleteDistSetTypes().remove(discardDSType);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user