Merge branch 'master' into feature_multiunassignment_soft_mod
This commit is contained in:
@@ -25,6 +25,7 @@ import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
|||||||
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configuration for configuring the spring {@link CacheManager} for specific
|
* A configuration for configuring the spring {@link CacheManager} for specific
|
||||||
@@ -33,9 +34,6 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
*
|
*
|
||||||
* This is done by providing a special {@link TenantCacheResolver} which
|
* This is done by providing a special {@link TenantCacheResolver} which
|
||||||
* generates a cache name included the current tenant.
|
* generates a cache name included the current tenant.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
@@ -51,18 +49,27 @@ public class CacheAutoConfiguration extends CachingConfigurerSupport {
|
|||||||
@Override
|
@Override
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
|
@Primary
|
||||||
public TenancyCacheManager cacheManager() {
|
public TenancyCacheManager cacheManager() {
|
||||||
return new TenantAwareCacheManager(new GuavaCacheManager(), tenantAware);
|
return new TenantAwareCacheManager(directCacheManager(), tenantAware);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the direct cache manager to access without tenant aware check,
|
||||||
|
* cause in sometimes it's necessary to access the cache directly
|
||||||
|
* without having the current tenant, e.g. initial creation of
|
||||||
|
* tenant
|
||||||
|
*/
|
||||||
|
@Bean(name = "directCacheManager")
|
||||||
|
@ConditionalOnMissingBean(name = "directCacheManager")
|
||||||
|
public CacheManager directCacheManager() {
|
||||||
|
return new GuavaCacheManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link SimpleCacheResolver} implementation which includes the
|
* A {@link SimpleCacheResolver} implementation which includes the
|
||||||
* {@link TenantAware#getCurrentTenant()} into the cache name before
|
* {@link TenantAware#getCurrentTenant()} into the cache name before
|
||||||
* resolving it.
|
* resolving it.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class TenantCacheResolver extends SimpleCacheResolver {
|
public class TenantCacheResolver extends SimpleCacheResolver {
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||||
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
@@ -50,8 +51,14 @@ public class RedisConfiguration {
|
|||||||
* @return the spring redis cache manager.
|
* @return the spring redis cache manager.
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
|
@Primary
|
||||||
public CacheManager cacheManager() {
|
public CacheManager cacheManager() {
|
||||||
return new TenantAwareCacheManager(new RedisCacheManager(redisTemplate()), tenantAware);
|
return new TenantAwareCacheManager(directCacheManager(), tenantAware);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name = "directCacheManager")
|
||||||
|
public CacheManager directCacheManager() {
|
||||||
|
return new RedisCacheManager(redisTemplate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.Constants;
|
|||||||
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.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTenantMetaData;
|
||||||
@@ -26,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
|||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||||
import org.eclipse.hawkbit.repository.report.model.SystemUsageReport;
|
import org.eclipse.hawkbit.repository.report.model.SystemUsageReport;
|
||||||
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
import org.eclipse.persistence.config.PersistenceUnitProperties;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -33,11 +35,14 @@ import org.springframework.cache.annotation.CacheEvict;
|
|||||||
import org.springframework.cache.annotation.CachePut;
|
import org.springframework.cache.annotation.CachePut;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.TransactionDefinition;
|
||||||
import org.springframework.transaction.annotation.Isolation;
|
import org.springframework.transaction.annotation.Isolation;
|
||||||
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.transaction.support.DefaultTransactionDefinition;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,7 +113,10 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
private SystemManagementCacheKeyGenerator currentTenantCacheKeyGenerator;
|
private SystemManagementCacheKeyGenerator currentTenantCacheKeyGenerator;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApplicationContext applicationContext;
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformTransactionManager txManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SystemUsageReport getSystemUsageStatistics() {
|
public SystemUsageReport getSystemUsageStatistics() {
|
||||||
@@ -159,39 +167,58 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "tenantMetadata", key = "#tenant.toUpperCase()")
|
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Modifying
|
@Modifying
|
||||||
public TenantMetaData getTenantMetadata(final String tenant) {
|
public TenantMetaData getTenantMetadata(final String tenant) {
|
||||||
final TenantMetaData result = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
|
final TenantMetaData result = tenantMetaDataRepository.findByTenantIgnoreCase(tenant);
|
||||||
|
|
||||||
// Create if it does not exist
|
// Create if it does not exist
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
try {
|
try {
|
||||||
currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant);
|
currentTenantCacheKeyGenerator.getCreateInitialTenant().set(tenant);
|
||||||
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
return createInitialTenantMetaData(tenant);
|
||||||
applicationContext.getBean("currentTenantKeyGenerator");
|
|
||||||
return tenantMetaDataRepository.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant));
|
|
||||||
} finally {
|
} finally {
|
||||||
currentTenantCacheKeyGenerator.getCreateInitialTenant().remove();
|
currentTenantCacheKeyGenerator.getCreateInitialTenant().remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creating the initial tenant meta-data in a new transaction. Due the
|
||||||
|
* {@link MultiTenantJpaTransactionManager} is using the current tenant to
|
||||||
|
* set the necessary tenant discriminator to the query. This is not working
|
||||||
|
* if we don't have a current tenant set. Due the
|
||||||
|
* {@link #getTenantMetadata(String)} is maybe called without having a
|
||||||
|
* current tenant we need to re-open a new transaction so the
|
||||||
|
* {@link MultiTenantJpaTransactionManager} is called again and set the
|
||||||
|
* tenant for this transaction.
|
||||||
|
*
|
||||||
|
* @param tenant
|
||||||
|
* the tenant to be created
|
||||||
|
* @return the initial created {@link TenantMetaData}
|
||||||
|
*/
|
||||||
|
private TenantMetaData createInitialTenantMetaData(final String tenant) {
|
||||||
|
final DefaultTransactionDefinition def = new DefaultTransactionDefinition();
|
||||||
|
def.setName("initial-tenant-creation");
|
||||||
|
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
|
||||||
|
return systemSecurityContext.runAsSystemAsTenant(
|
||||||
|
() -> new TransactionTemplate(txManager, def).execute(status -> tenantMetaDataRepository
|
||||||
|
.save(new JpaTenantMetaData(createStandardSoftwareDataSetup(), tenant))),
|
||||||
|
tenant);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> findTenants() {
|
public List<String> findTenants() {
|
||||||
return tenantMetaDataRepository.findAll().stream().map(md -> md.getTenant()).collect(Collectors.toList());
|
return tenantMetaDataRepository.findAll().stream().map(md -> md.getTenant()).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CacheEvict(value = { "tenantMetadata" }, key = "#tenant.toUpperCase()")
|
@CacheEvict(value = { "tenantMetadata" }, key = "#tenant.toUpperCase()", cacheManager = "directCacheManager")
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Modifying
|
@Modifying
|
||||||
public void deleteTenant(final String tenant) {
|
public void deleteTenant(final String tenant) {
|
||||||
cacheManager.evictCaches(tenant);
|
cacheManager.evictCaches(tenant);
|
||||||
cacheManager.getCache("currentTenant").evict(currentTenantKeyGenerator().generate(null, null));
|
|
||||||
tenantAware.runAsTenant(tenant, () -> {
|
tenantAware.runAsTenant(tenant, () -> {
|
||||||
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant.toUpperCase());
|
entityManager.setProperty(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, tenant.toUpperCase());
|
||||||
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
tenantMetaDataRepository.deleteByTenantIgnoreCase(tenant);
|
||||||
@@ -214,7 +241,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "tenantMetadata", keyGenerator = "tenantKeyGenerator")
|
@Cacheable(value = "tenantMetadata", keyGenerator = "tenantKeyGenerator", cacheManager = "directCacheManager")
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Modifying
|
@Modifying
|
||||||
public TenantMetaData getTenantMetadata() {
|
public TenantMetaData getTenantMetadata() {
|
||||||
@@ -226,7 +253,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator")
|
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator", cacheManager = "directCacheManager")
|
||||||
// set transaction to not supported, due we call this in
|
// set transaction to not supported, due we call this in
|
||||||
// BaseEntity#prePersist methods
|
// BaseEntity#prePersist methods
|
||||||
// and it seems that JPA committing the transaction when executing this
|
// and it seems that JPA committing the transaction when executing this
|
||||||
@@ -249,7 +276,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@CachePut(value = "tenantMetadata", key = "#metaData.tenant.toUpperCase()")
|
@CachePut(value = "tenantMetadata", key = "#metaData.tenant.toUpperCase()", cacheManager = "directCacheManager")
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
@Modifying
|
@Modifying
|
||||||
public TenantMetaData updateTenantMetadata(final TenantMetaData metaData) {
|
public TenantMetaData updateTenantMetadata(final TenantMetaData metaData) {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import java.util.Random;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
||||||
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
|
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -29,6 +30,15 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
@Stories("System Management")
|
@Stories("System Management")
|
||||||
public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
|
public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Ensures that you can create a tenant without setting the necessary security context which holds a current tenant")
|
||||||
|
public void createInitialTenantWithoutSecurityContext() {
|
||||||
|
securityRule.clear();
|
||||||
|
final String tenantToBeCreated = "newTenantToCreate";
|
||||||
|
final TenantMetaData tenantMetadata = systemManagement.getTenantMetadata(tenantToBeCreated);
|
||||||
|
assertThat(tenantMetadata).isNotNull();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in")
|
@Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in")
|
||||||
public void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() throws Exception {
|
public void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() throws Exception {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class WithSpringAuthorityRule implements TestRule {
|
|||||||
}
|
}
|
||||||
return oldContext;
|
return oldContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param annotation
|
* @param annotation
|
||||||
*/
|
*/
|
||||||
@@ -129,6 +129,14 @@ public class WithSpringAuthorityRule implements TestRule {
|
|||||||
private void after(final SecurityContext oldContext) {
|
private void after(final SecurityContext oldContext) {
|
||||||
SecurityContextHolder.setContext(oldContext);
|
SecurityContextHolder.setContext(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the current security context.
|
||||||
|
*/
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callable
|
* @param callable
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
@@ -80,32 +81,37 @@ public class SecurityContextTenantAware implements TenantAware {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object another) {
|
public boolean equals(final Object another) {
|
||||||
return delegate.equals(another);
|
if (delegate != null) {
|
||||||
|
return delegate.equals(another);
|
||||||
|
} else if (another == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return delegate.toString();
|
return (delegate != null) ? delegate.toString() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return delegate.hashCode();
|
return (delegate != null) ? delegate.hashCode() : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return delegate.getName();
|
return (delegate != null) ? delegate.getName() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
return delegate.getAuthorities();
|
return (delegate != null) ? delegate.getAuthorities() : Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getCredentials() {
|
public Object getCredentials() {
|
||||||
return delegate.getCredentials();
|
return (delegate != null) ? delegate.getCredentials() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -115,16 +121,19 @@ public class SecurityContextTenantAware implements TenantAware {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getPrincipal() {
|
public Object getPrincipal() {
|
||||||
return delegate.getPrincipal();
|
return (delegate != null) ? delegate.getPrincipal() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAuthenticated() {
|
public boolean isAuthenticated() {
|
||||||
return delegate.isAuthenticated();
|
return (delegate != null) ? delegate.isAuthenticated() : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
|
public void setAuthenticated(final boolean isAuthenticated) {
|
||||||
|
if (delegate == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
delegate.setAuthenticated(isAuthenticated);
|
delegate.setAuthenticated(isAuthenticated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ public class SystemSecurityContext {
|
|||||||
* The security context will be switched to the system code and back after
|
* The security context will be switched to the system code and back after
|
||||||
* the callable is called.
|
* the callable is called.
|
||||||
*
|
*
|
||||||
|
* The system code is executed for a current tenant by using the
|
||||||
|
* {@link TenantAware#getCurrentTenant()}.
|
||||||
|
*
|
||||||
* @param callable
|
* @param callable
|
||||||
* the callable to call within the system security context
|
* the callable to call within the system security context
|
||||||
* @return the return value of the {@link Callable#call()} method.
|
* @return the return value of the {@link Callable#call()} method.
|
||||||
@@ -67,12 +70,36 @@ public class SystemSecurityContext {
|
|||||||
// Exception squid:S2221 - Callable declares Exception
|
// Exception squid:S2221 - Callable declares Exception
|
||||||
@SuppressWarnings("squid:S2221")
|
@SuppressWarnings("squid:S2221")
|
||||||
public <T> T runAsSystem(final Callable<T> callable) {
|
public <T> T runAsSystem(final Callable<T> callable) {
|
||||||
|
return runAsSystemAsTenant(callable, tenantAware.getCurrentTenant());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a given {@link Callable} within a system security context, which is
|
||||||
|
* permitted to call secured system code. Often the system needs to call
|
||||||
|
* secured methods by it's own without relying on the current security
|
||||||
|
* context e.g. if the current security context does not contain the
|
||||||
|
* necessary permission it's necessary to execute code as system code to
|
||||||
|
* execute necessary methods and functionality.
|
||||||
|
*
|
||||||
|
* The security context will be switched to the system code and back after
|
||||||
|
* the callable is called.
|
||||||
|
*
|
||||||
|
* The system code is executed for a specific given tenant by using the
|
||||||
|
* {@link TenantAware}.
|
||||||
|
*
|
||||||
|
* @param callable
|
||||||
|
* the callable to call within the system security context
|
||||||
|
* @param tenant
|
||||||
|
* the tenant to act as system code
|
||||||
|
* @return the return value of the {@link Callable#call()} method.
|
||||||
|
*/
|
||||||
|
public <T> T runAsSystemAsTenant(final Callable<T> callable, final String tenant) {
|
||||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||||
try {
|
try {
|
||||||
logger.debug("entering system code execution");
|
logger.debug("entering system code execution");
|
||||||
return tenantAware.runAsTenant(tenantAware.getCurrentTenant(), () -> {
|
return tenantAware.runAsTenant(tenant, () -> {
|
||||||
try {
|
try {
|
||||||
setSystemContext(oldContext);
|
setSystemContext(SecurityContextHolder.getContext());
|
||||||
return callable.call();
|
return callable.call();
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
throw Throwables.propagate(e);
|
throw Throwables.propagate(e);
|
||||||
@@ -100,6 +127,13 @@ public class SystemSecurityContext {
|
|||||||
SecurityContextHolder.setContext(securityContextImpl);
|
SecurityContextHolder.setContext(securityContextImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the Spring's {@link Authentication} object which is
|
||||||
|
* used within a system security code block and wraps the original
|
||||||
|
* authentication object. The wrapped object contains the necessary
|
||||||
|
* {@link SpringEvalExpressions#SYSTEM_ROLE} which is allowed to execute all
|
||||||
|
* secured methods.
|
||||||
|
*/
|
||||||
public static class SystemCodeAuthentication implements Authentication {
|
public static class SystemCodeAuthentication implements Authentication {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.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.SPUIButtonStyleBorderWithIcon;
|
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
|
||||||
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
|
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
|
||||||
import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout;
|
import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout;
|
||||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
@@ -378,11 +378,10 @@ public class CommonDialogWindow extends Window implements Serializable {
|
|||||||
buttonsLayout = new HorizontalLayout();
|
buttonsLayout = new HorizontalLayout();
|
||||||
buttonsLayout.setSizeFull();
|
buttonsLayout.setSizeFull();
|
||||||
buttonsLayout.setSpacing(true);
|
buttonsLayout.setSpacing(true);
|
||||||
|
buttonsLayout.addStyleName("actionButtonsMargin");
|
||||||
|
|
||||||
createSaveButton();
|
createSaveButton();
|
||||||
|
|
||||||
createCancelButton();
|
createCancelButton();
|
||||||
buttonsLayout.addStyleName("actionButtonsMargin");
|
|
||||||
|
|
||||||
addHelpLink();
|
addHelpLink();
|
||||||
|
|
||||||
@@ -411,9 +410,8 @@ public class CommonDialogWindow extends Window implements Serializable {
|
|||||||
|
|
||||||
private void createCancelButton() {
|
private void createCancelButton() {
|
||||||
cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true,
|
cancelButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.CANCEL_BUTTON, "Cancel", "", "", true,
|
||||||
FontAwesome.TIMES, SPUIButtonStyleBorderWithIcon.class);
|
FontAwesome.TIMES, SPUIButtonStyleNoBorderWithIcon.class);
|
||||||
cancelButton.setSizeUndefined();
|
cancelButton.setSizeUndefined();
|
||||||
cancelButton.addStyleName("default-color");
|
|
||||||
if (cancelButtonClickListener != null) {
|
if (cancelButtonClickListener != null) {
|
||||||
cancelButton.addClickListener(cancelButtonClickListener);
|
cancelButton.addClickListener(cancelButtonClickListener);
|
||||||
}
|
}
|
||||||
@@ -425,9 +423,8 @@ public class CommonDialogWindow extends Window implements Serializable {
|
|||||||
|
|
||||||
private void createSaveButton() {
|
private void createSaveButton() {
|
||||||
saveButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.SAVE_BUTTON, "Save", "", "", true,
|
saveButton = SPUIComponentProvider.getButton(SPUIComponentIdProvider.SAVE_BUTTON, "Save", "", "", true,
|
||||||
FontAwesome.SAVE, SPUIButtonStyleBorderWithIcon.class);
|
FontAwesome.SAVE, SPUIButtonStyleNoBorderWithIcon.class);
|
||||||
saveButton.setSizeUndefined();
|
saveButton.setSizeUndefined();
|
||||||
saveButton.addStyleName("default-color");
|
|
||||||
saveButton.addClickListener(saveButtonClickListener);
|
saveButton.addClickListener(saveButtonClickListener);
|
||||||
saveButton.setEnabled(false);
|
saveButton.setEnabled(false);
|
||||||
buttonsLayout.addComponent(saveButton);
|
buttonsLayout.addComponent(saveButton);
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public class ConfirmationDialog implements Button.ClickListener {
|
|||||||
final Button cancelButton = SPUIComponentProvider.getButton(null, cancelLabel, "", null, false, null,
|
final Button cancelButton = SPUIComponentProvider.getButton(null, cancelLabel, "", null, false, null,
|
||||||
SPUIButtonStyleTiny.class);
|
SPUIButtonStyleTiny.class);
|
||||||
cancelButton.addClickListener(this);
|
cancelButton.addClickListener(this);
|
||||||
|
cancelButton.setId(SPUIComponentIdProvider.CANCEL_BUTTON);
|
||||||
window.setModal(true);
|
window.setModal(true);
|
||||||
window.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_WINDOW_SYLE);
|
window.addStyleName(SPUIStyleDefinitions.CONFIRMBOX_WINDOW_SYLE);
|
||||||
if (this.callback == null) {
|
if (this.callback == null) {
|
||||||
|
|||||||
@@ -8,39 +8,60 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.customrenderers.client.renderers;
|
package org.eclipse.hawkbit.ui.customrenderers.client.renderers;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
|
|
||||||
import com.google.gwt.user.client.ui.Button;
|
import com.google.gwt.user.client.ui.Button;
|
||||||
import com.vaadin.client.renderers.ButtonRenderer;
|
import com.vaadin.client.renderers.ButtonRenderer;
|
||||||
import com.vaadin.client.ui.VButton;
|
import com.vaadin.client.ui.VButton;
|
||||||
import com.vaadin.client.widget.grid.RendererCellReference;
|
import com.vaadin.client.widget.grid.RendererCellReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Renders button with provided HTML content. Used to display button with icons.
|
||||||
* Renders button with provided HTML content.
|
|
||||||
* Used to display button with icons.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class HtmlButtonRenderer extends ButtonRenderer {
|
public class HtmlButtonRenderer extends ButtonRenderer {
|
||||||
|
|
||||||
|
public static final String DISABLE_VALUE = "_Disabled_";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(RendererCellReference cell, String text, Button button) {
|
public void render(final RendererCellReference cell, final String text, final Button button) {
|
||||||
|
final boolean buttonEnable = isButtonEnable(cell.getElement().getClassName());
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
button.setHTML(text);
|
button.setHTML(text);
|
||||||
}
|
}
|
||||||
applystyles(button);
|
applystyles(button, buttonEnable);
|
||||||
// this is to allow the button to disappear, if the text is null
|
// this is to allow the button to disappear, if the text is null
|
||||||
button.setVisible(text != null);
|
button.setVisible(text != null);
|
||||||
button.getElement().setId("rollout.action.button.id");
|
button.getElement().setId(SPUIComponentIdProvider.ROLLOUT_ACTION_ID + "." + cell.getColumnIndex());
|
||||||
|
button.setEnabled(buttonEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applystyles(Button button) {
|
/**
|
||||||
|
* see here https://vaadin.com/forum#!/thread/9418390/9765924
|
||||||
|
*
|
||||||
|
* @param text
|
||||||
|
* the button text
|
||||||
|
* @return is button enable.
|
||||||
|
*/
|
||||||
|
private static boolean isButtonEnable(final String text) {
|
||||||
|
return !text.contains(DISABLE_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applystyles(final Button button, final boolean buttonEnable) {
|
||||||
|
|
||||||
button.setStyleName(VButton.CLASSNAME);
|
button.setStyleName(VButton.CLASSNAME);
|
||||||
button.addStyleName(getStyle("tiny"));
|
button.addStyleName(getStyle("tiny"));
|
||||||
button.addStyleName(getStyle("borderless"));
|
button.addStyleName(getStyle("borderless-colored"));
|
||||||
button.addStyleName(getStyle("icon-only"));
|
|
||||||
button.addStyleName(getStyle("button-no-border"));
|
button.addStyleName(getStyle("button-no-border"));
|
||||||
|
button.addStyleName(getStyle("action-type-padding"));
|
||||||
|
|
||||||
|
if (buttonEnable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
button.addStyleName("v-disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getStyle(final String style) {
|
private String getStyle(final String style) {
|
||||||
return new StringBuilder(style).append(" ").append(VButton.CLASSNAME).append("-").append(style).toString();
|
return new StringBuilder(style).append(" ").append(VButton.CLASSNAME).append("-").append(style).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class HtmlButtonRenderer extends ButtonRenderer {
|
|||||||
* @param listener
|
* @param listener
|
||||||
* RendererClickListener
|
* RendererClickListener
|
||||||
*/
|
*/
|
||||||
public HtmlButtonRenderer(RendererClickListener listener) {
|
public HtmlButtonRenderer(final RendererClickListener listener) {
|
||||||
super(listener);
|
super(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.decorators;
|
package org.eclipse.hawkbit.ui.decorators;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.vaadin.server.Resource;
|
import com.vaadin.server.Resource;
|
||||||
import com.vaadin.ui.Button;
|
import com.vaadin.ui.Button;
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Button with icon decorator.
|
* Decorator class for a borderless Button with an icon.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class SPUIButtonStyleBorderWithIcon implements SPUIButtonDecorator {
|
public class SPUIButtonStyleNoBorderWithIcon implements SPUIButtonDecorator {
|
||||||
|
|
||||||
private Button button;
|
private Button button;
|
||||||
|
|
||||||
@@ -24,23 +25,25 @@ public class SPUIButtonStyleBorderWithIcon implements SPUIButtonDecorator {
|
|||||||
public Button decorate(final Button button, final String style, final boolean setStyle, final Resource icon) {
|
public Button decorate(final Button button, final String style, final boolean setStyle, final Resource icon) {
|
||||||
|
|
||||||
this.button = button;
|
this.button = button;
|
||||||
|
button.setSizeFull();
|
||||||
setButtonStyle(style, setStyle);
|
|
||||||
setButtonIcon(icon);
|
|
||||||
|
|
||||||
button.addStyleName(ValoTheme.LABEL_SMALL);
|
button.addStyleName(ValoTheme.LABEL_SMALL);
|
||||||
button.setSizeFull();
|
button.addStyleName(ValoTheme.BUTTON_BORDERLESS_COLORED);
|
||||||
|
setOrAddButtonStyle(style, setStyle);
|
||||||
|
|
||||||
|
setButtonIcon(icon);
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setButtonStyle(final String style, final boolean setStyle) {
|
private void setOrAddButtonStyle(final String style, final boolean setStyle) {
|
||||||
|
|
||||||
if (style == null) {
|
if (StringUtils.isEmpty(style)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setStyle) {
|
if (setStyle) {
|
||||||
|
// overwrite all other styles
|
||||||
button.setStyleName(style);
|
button.setStyleName(style);
|
||||||
} else {
|
} else {
|
||||||
button.addStyleName(style);
|
button.addStyleName(style);
|
||||||
@@ -87,7 +87,7 @@ public class TargetFilterTable extends Table {
|
|||||||
setStyleName("sp-table");
|
setStyleName("sp-table");
|
||||||
setSizeFull();
|
setSizeFull();
|
||||||
setImmediate(true);
|
setImmediate(true);
|
||||||
setHeight(100.0f, Unit.PERCENTAGE);
|
setHeight(100.0F, Unit.PERCENTAGE);
|
||||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||||
addStyleName(ValoTheme.TABLE_SMALL);
|
addStyleName(ValoTheme.TABLE_SMALL);
|
||||||
addCustomGeneratedColumns();
|
addCustomGeneratedColumns();
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
|
import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
|
||||||
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
|
||||||
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
|
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
|
||||||
import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
|
import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
|
||||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
||||||
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
|
||||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
@@ -50,15 +50,14 @@ import org.vaadin.spring.events.EventBus;
|
|||||||
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;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.vaadin.data.Container;
|
import com.vaadin.data.Container;
|
||||||
import com.vaadin.data.Item;
|
import com.vaadin.data.Item;
|
||||||
import com.vaadin.data.util.HierarchicalContainer;
|
import com.vaadin.data.util.HierarchicalContainer;
|
||||||
import com.vaadin.event.Action.Handler;
|
|
||||||
import com.vaadin.server.FontAwesome;
|
import com.vaadin.server.FontAwesome;
|
||||||
import com.vaadin.shared.ui.label.ContentMode;
|
import com.vaadin.shared.ui.label.ContentMode;
|
||||||
import com.vaadin.spring.annotation.SpringComponent;
|
import com.vaadin.spring.annotation.SpringComponent;
|
||||||
import com.vaadin.spring.annotation.ViewScope;
|
import com.vaadin.spring.annotation.ViewScope;
|
||||||
|
import com.vaadin.ui.Button;
|
||||||
import com.vaadin.ui.Component;
|
import com.vaadin.ui.Component;
|
||||||
import com.vaadin.ui.HorizontalLayout;
|
import com.vaadin.ui.HorizontalLayout;
|
||||||
import com.vaadin.ui.Label;
|
import com.vaadin.ui.Label;
|
||||||
@@ -74,11 +73,13 @@ import com.vaadin.ui.themes.ValoTheme;
|
|||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
public class ActionHistoryTable extends TreeTable implements Handler {
|
public class ActionHistoryTable extends TreeTable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -1631514704696786653L;
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(ActionHistoryTable.class);
|
||||||
private static final String BUTTON_CANCEL = "button.cancel";
|
private static final String BUTTON_CANCEL = "button.cancel";
|
||||||
private static final String BUTTON_OK = "button.ok";
|
private static final String BUTTON_OK = "button.ok";
|
||||||
private static final long serialVersionUID = -1631514704696786653L;
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private I18N i18n;
|
private I18N i18n;
|
||||||
|
|
||||||
@@ -95,14 +96,10 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
private ManagementUIState managementUIState;
|
private ManagementUIState managementUIState;
|
||||||
|
|
||||||
private Container hierarchicalContainer;
|
private Container hierarchicalContainer;
|
||||||
private boolean alreadyHasMessages = false;
|
private boolean alreadyHasMessages;
|
||||||
|
|
||||||
private Target target;
|
private Target target;
|
||||||
|
|
||||||
com.vaadin.event.Action actionCancel;
|
|
||||||
com.vaadin.event.Action actionForce;
|
|
||||||
com.vaadin.event.Action actionForceQuit;
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ActionHistoryTable.class);
|
|
||||||
private static final String STATUS_ICON_GREEN = "statusIconGreen";
|
private static final String STATUS_ICON_GREEN = "statusIconGreen";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,10 +107,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
actionCancel = new com.vaadin.event.Action(i18n.get("message.cancel.action"));
|
|
||||||
actionForceQuit = new com.vaadin.event.Action(i18n.get("message.forcequit.action"));
|
|
||||||
actionForceQuit.setIcon(FontAwesome.WARNING);
|
|
||||||
actionForce = new com.vaadin.event.Action(i18n.get("message.force.action"));
|
|
||||||
initializeTableSettings();
|
initializeTableSettings();
|
||||||
buildComponent();
|
buildComponent();
|
||||||
restorePreviousState();
|
restorePreviousState();
|
||||||
@@ -150,11 +143,12 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setColumnExpandRatioForMinimisedTable() {
|
private void setColumnExpandRatioForMinimisedTable() {
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.3f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.3F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.15f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.15F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.3f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.3F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.15f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.15F);
|
||||||
|
setColumnExpandRatio(SPUIDefinitions.ACTIONS_COLUMN, 0.2F);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeTableSettings() {
|
private void initializeTableSettings() {
|
||||||
@@ -164,14 +158,15 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
setMultiSelect(false);
|
setMultiSelect(false);
|
||||||
setSortEnabled(true);
|
setSortEnabled(true);
|
||||||
setColumnReorderingAllowed(true);
|
setColumnReorderingAllowed(true);
|
||||||
setHeight(100.0f, Unit.PERCENTAGE);
|
setHeight(100.0F, Unit.PERCENTAGE);
|
||||||
setWidth(100.0f, Unit.PERCENTAGE);
|
setWidth(100.0F, Unit.PERCENTAGE);
|
||||||
setImmediate(true);
|
setImmediate(true);
|
||||||
setStyleName("sp-table");
|
setStyleName("sp-table");
|
||||||
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||||
addStyleName(ValoTheme.TABLE_SMALL);
|
addStyleName(ValoTheme.TABLE_SMALL);
|
||||||
setColumnAlignment(SPUIDefinitions.ACTION_HIS_TBL_FORCED, Align.CENTER);
|
setColumnAlignment(SPUIDefinitions.ACTION_HIS_TBL_FORCED, Align.CENTER);
|
||||||
setColumnAlignment(SPUIDefinitions.ACTION_HIS_TBL_STATUS, Align.CENTER);
|
setColumnAlignment(SPUIDefinitions.ACTION_HIS_TBL_STATUS, Align.CENTER);
|
||||||
|
setColumnAlignment(SPUIDefinitions.ACTIONS_COLUMN, Align.CENTER);
|
||||||
// listeners for child
|
// listeners for child
|
||||||
addExpandListener(event -> {
|
addExpandListener(event -> {
|
||||||
expandParentActionRow(event.getItemId());
|
expandParentActionRow(event.getItemId());
|
||||||
@@ -181,11 +176,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
collapseParentActionRow(event.getItemId());
|
collapseParentActionRow(event.getItemId());
|
||||||
managementUIState.getExpandParentActionRowId().remove(event.getItemId());
|
managementUIState.getExpandParentActionRowId().remove(event.getItemId());
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
* Add the cancel action handler for active actions. To be used to
|
|
||||||
* cancel the action.
|
|
||||||
*/
|
|
||||||
addActionHandler(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,6 +194,7 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
null);
|
null);
|
||||||
hierarchicalContainer.addContainerProperty(SPUIDefinitions.ACTION_HIS_TBL_MSGS_HIDDEN, List.class, null);
|
hierarchicalContainer.addContainerProperty(SPUIDefinitions.ACTION_HIS_TBL_MSGS_HIDDEN, List.class, null);
|
||||||
hierarchicalContainer.addContainerProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, String.class, null);
|
hierarchicalContainer.addContainerProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, String.class, null);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Object> getVisbleColumns() {
|
private List<Object> getVisbleColumns() {
|
||||||
@@ -213,6 +204,8 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_DATETIME);
|
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_DATETIME);
|
||||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_STATUS);
|
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_STATUS);
|
||||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_FORCED);
|
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_FORCED);
|
||||||
|
visibleColumnIds.add(SPUIDefinitions.ACTIONS_COLUMN);
|
||||||
|
|
||||||
if (managementUIState.isActionHistoryMaximized()) {
|
if (managementUIState.isActionHistoryMaximized()) {
|
||||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME);
|
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME);
|
||||||
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_MSGS);
|
visibleColumnIds.add(SPUIDefinitions.ACTION_HIS_TBL_MSGS);
|
||||||
@@ -242,12 +235,12 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
|
|
||||||
private void getcontainerData() {
|
private void getcontainerData() {
|
||||||
hierarchicalContainer.removeAllItems();
|
hierarchicalContainer.removeAllItems();
|
||||||
|
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
/* service method to create action history for target */
|
/* service method to create action history for target */
|
||||||
final List<ActionWithStatusCount> actionHistory = deploymentManagement
|
final List<ActionWithStatusCount> actionHistory = deploymentManagement
|
||||||
.findActionsWithStatusCountByTargetOrderByIdDesc(target);
|
.findActionsWithStatusCountByTargetOrderByIdDesc(target);
|
||||||
|
|
||||||
addDetailsToContainer(actionHistory);
|
addDetailsToContainer(actionHistory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,23 +293,22 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
* add distribution name to the item which will be displayed in the
|
* add distribution name to the item which will be displayed in the
|
||||||
* table. The name should not exceed certain limit.
|
* table. The name should not exceed certain limit.
|
||||||
*/
|
*/
|
||||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(actionWithStatusCount.getDsName() + ":" +
|
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST)
|
||||||
actionWithStatusCount.getDsVersion());
|
.setValue(actionWithStatusCount.getDsName() + ":" + actionWithStatusCount.getDsVersion());
|
||||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).setValue(action);
|
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).setValue(action);
|
||||||
|
|
||||||
/* Default no child */
|
/* Default no child */
|
||||||
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(), false);
|
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(), false);
|
||||||
|
|
||||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
|
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
|
||||||
.setValue(SPDateTimeUtil.getFormattedDate((actionWithStatusCount.getAction().getLastModifiedAt() != null)
|
.setValue(SPDateTimeUtil.getFormattedDate(actionWithStatusCount.getAction().getLastModifiedAt()));
|
||||||
? actionWithStatusCount.getAction().getLastModifiedAt()
|
|
||||||
: actionWithStatusCount.getAction().getLastModifiedAt()));
|
|
||||||
|
|
||||||
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME)
|
item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME)
|
||||||
.setValue(actionWithStatusCount.getRolloutName());
|
.setValue(actionWithStatusCount.getRolloutName());
|
||||||
|
|
||||||
if (actionWithStatusCount.getActionStatusCount() > 0) {
|
if (actionWithStatusCount.getActionStatusCount() > 0) {
|
||||||
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(), true);
|
((Hierarchical) hierarchicalContainer).setChildrenAllowed(actionWithStatusCount.getAction().getId(),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -350,12 +342,18 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
return getForcedColumn(itemId);
|
return getForcedColumn(itemId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addGeneratedColumn(SPUIDefinitions.ACTIONS_COLUMN, new Table.ColumnGenerator() {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Component generateCell(final Table source, final Object itemId, final Object columnId) {
|
||||||
|
return createActionBarColumn(itemId);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Component getForcedColumn(final Object itemId) {
|
private Component getForcedColumn(final Object itemId) {
|
||||||
final Action actionWithActiveStatus = (Action) hierarchicalContainer.getItem(itemId)
|
final Action actionWithActiveStatus = (Action) hierarchicalContainer.getItem(itemId)
|
||||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).getValue();
|
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).getValue();
|
||||||
@@ -372,10 +370,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
return actionLabel;
|
return actionLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param itemId
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private Component getActiveColumn(final Object itemId) {
|
private Component getActiveColumn(final Object itemId) {
|
||||||
final Action.Status status = (Action.Status) hierarchicalContainer.getItem(itemId)
|
final Action.Status status = (Action.Status) hierarchicalContainer.getItem(itemId)
|
||||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue();
|
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue();
|
||||||
@@ -397,10 +391,44 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
return activeStatusIcon;
|
return activeStatusIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private HorizontalLayout createActionBarColumn(final Object itemId) {
|
||||||
* @param itemId
|
final HorizontalLayout actionBar = new HorizontalLayout();
|
||||||
* @return
|
final Item item = hierarchicalContainer.getItem(itemId);
|
||||||
*/
|
final Long actionId = (Long) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID_HIDDEN).getValue();
|
||||||
|
final String activeValue = (String) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN)
|
||||||
|
.getValue();
|
||||||
|
final Action actionWithActiveStatus = (Action) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED)
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
if (actionWithActiveStatus == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final boolean isActionActive = target != null && SPUIDefinitions.ACTIVE.equals(activeValue);
|
||||||
|
|
||||||
|
final Button actionCancel = SPUIComponentProvider.getButton(
|
||||||
|
SPUIComponentIdProvider.ACTION_HISTORY_TABLE_CANCEL_ID, "", i18n.get("message.cancel.action"),
|
||||||
|
ValoTheme.BUTTON_TINY, true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||||
|
actionCancel.setEnabled(isActionActive && !actionWithActiveStatus.isCancelingOrCanceled());
|
||||||
|
actionCancel.addClickListener(event -> confirmAndCancelAction(actionId));
|
||||||
|
|
||||||
|
final Button actionForce = SPUIComponentProvider.getButton(
|
||||||
|
SPUIComponentIdProvider.ACTION_HISTORY_TABLE_FORCE_ID, "", i18n.get("message.force.action"),
|
||||||
|
ValoTheme.BUTTON_TINY, true, FontAwesome.BOLT, SPUIButtonStyleSmallNoBorder.class);
|
||||||
|
actionForce.setEnabled(
|
||||||
|
isActionActive && !actionWithActiveStatus.isForce() && !actionWithActiveStatus.isCancelingOrCanceled());
|
||||||
|
actionForce.addClickListener(event -> confirmAndForceAction(actionId));
|
||||||
|
|
||||||
|
final Button actionForceQuit = SPUIComponentProvider.getButton(
|
||||||
|
SPUIComponentIdProvider.ACTION_HISTORY_TABLE_FORCE_QUIT_ID, "", i18n.get("message.forcequit.action"),
|
||||||
|
ValoTheme.BUTTON_TINY + " redicon", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
|
||||||
|
actionForceQuit.setEnabled(isActionActive && actionWithActiveStatus.isCancelingOrCanceled());
|
||||||
|
actionForceQuit.addClickListener(event -> confirmAndForceQuitAction(actionId));
|
||||||
|
|
||||||
|
actionBar.addComponents(actionCancel, actionForce, actionForceQuit);
|
||||||
|
|
||||||
|
return actionBar;
|
||||||
|
}
|
||||||
|
|
||||||
private Component getStatusColumn(final Object itemId) {
|
private Component getStatusColumn(final Object itemId) {
|
||||||
final Action.Status status = (Action.Status) hierarchicalContainer.getItem(itemId)
|
final Action.Status status = (Action.Status) hierarchicalContainer.getItem(itemId)
|
||||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue();
|
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_STATUS_HIDDEN).getValue();
|
||||||
@@ -427,11 +455,11 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
final Pageable pageReq = new PageRequest(0, 1000,
|
final Pageable pageReq = new PageRequest(0, 1000,
|
||||||
new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName()));
|
new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName()));
|
||||||
final Page<ActionStatus> actionStatusList;
|
final Page<ActionStatus> actionStatusList;
|
||||||
if (managementUIState.isActionHistoryMaximized()) {
|
if (managementUIState.isActionHistoryMaximized()) {
|
||||||
actionStatusList = deploymentManagement.findActionStatusByActionWithMessages(pageReq, action);
|
actionStatusList = deploymentManagement.findActionStatusByActionWithMessages(pageReq, action);
|
||||||
} else {
|
} else {
|
||||||
actionStatusList = deploymentManagement.findActionStatusByAction(pageReq, action);
|
actionStatusList = deploymentManagement.findActionStatusByAction(pageReq, action);
|
||||||
}
|
}
|
||||||
final List<ActionStatus> content = actionStatusList.getContent();
|
final List<ActionStatus> content = actionStatusList.getContent();
|
||||||
/*
|
/*
|
||||||
* Since the recent action status and messages are already
|
* Since the recent action status and messages are already
|
||||||
@@ -449,9 +477,8 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
*/
|
*/
|
||||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN).setValue("");
|
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN).setValue("");
|
||||||
|
|
||||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST)
|
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DIST).setValue(
|
||||||
.setValue(action.getDistributionSet().getName() + ":"
|
action.getDistributionSet().getName() + ":" + action.getDistributionSet().getVersion());
|
||||||
+ action.getDistributionSet().getVersion());
|
|
||||||
|
|
||||||
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
|
childItem.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_DATETIME)
|
||||||
.setValue(SPDateTimeUtil.getFormattedDate(actionStatus.getCreatedAt()));
|
.setValue(SPDateTimeUtil.getFormattedDate(actionStatus.getCreatedAt()));
|
||||||
@@ -637,14 +664,15 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
|
|
||||||
private void setColumnExpantRatioOnTableMaximize() {
|
private void setColumnExpantRatioOnTableMaximize() {
|
||||||
/* set messages column can expand the rest of the available space */
|
/* set messages column can expand the rest of the available space */
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE, 0.1f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE, 0.1F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID, 0.1F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.1f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_STATUS, 0.1F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.2f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DIST, 0.2F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.1f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_FORCED, 0.1F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, 0.1f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_ROLLOUT_NAME, 0.1F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_MSGS, 0.35f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_MSGS, 0.35F);
|
||||||
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.15f);
|
setColumnExpandRatio(SPUIDefinitions.ACTION_HIS_TBL_DATETIME, 0.15F);
|
||||||
|
setColumnExpandRatio(SPUIDefinitions.ACTIONS_COLUMN, 0.2F);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -706,46 +734,6 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
setColumnExpandRatioForMinimisedTable();
|
setColumnExpandRatioForMinimisedTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleAction(final com.vaadin.event.Action action, final Object sender, final Object target) {
|
|
||||||
/* Get the actionId details of the cancel item or row */
|
|
||||||
final Item item = hierarchicalContainer.getItem(target);
|
|
||||||
final Long actionId = (Long) item.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTION_ID_HIDDEN).getValue();
|
|
||||||
if (action.equals(actionCancel)) {
|
|
||||||
if (actionId != null) {
|
|
||||||
confirmAndCancelAction(actionId);
|
|
||||||
}
|
|
||||||
} else if (action.equals(actionForce)) {
|
|
||||||
confirmAndForceAction(actionId);
|
|
||||||
} else if (action.equals(actionForceQuit)) {
|
|
||||||
confirmAndForceQuitAction(actionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public com.vaadin.event.Action[] getActions(final Object target, final Object sender) {
|
|
||||||
final List<com.vaadin.event.Action> actions = Lists.newArrayList();
|
|
||||||
if (target != null) {
|
|
||||||
/* Check if the row or item belongs to active action */
|
|
||||||
final String activeValue = (String) hierarchicalContainer.getItem(target)
|
|
||||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_ACTIVE_HIDDEN).getValue();
|
|
||||||
if (SPUIDefinitions.ACTIVE.equals(activeValue)) {
|
|
||||||
final Action actionWithActiveStatus = (Action) hierarchicalContainer.getItem(target)
|
|
||||||
.getItemProperty(SPUIDefinitions.ACTION_HIS_TBL_FORCED).getValue();
|
|
||||||
if (!actionWithActiveStatus.isForce()) {
|
|
||||||
actions.add(actionForce);
|
|
||||||
}
|
|
||||||
if (!actionWithActiveStatus.isCancelingOrCanceled()) {
|
|
||||||
actions.add(actionCancel);
|
|
||||||
} else {
|
|
||||||
actions.add(actionForceQuit);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return actions.toArray(new com.vaadin.event.Action[actions.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show confirmation window and if ok then only, force the action.
|
* Show confirmation window and if ok then only, force the action.
|
||||||
*
|
*
|
||||||
@@ -756,21 +744,15 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
/* Display the confirmation */
|
/* Display the confirmation */
|
||||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.force.action.confirmbox"),
|
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.force.action.confirmbox"),
|
||||||
i18n.get("message.force.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
i18n.get("message.force.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
||||||
if (ok) {
|
if (!ok) {
|
||||||
/* cancel the action */
|
return;
|
||||||
deploymentManagement.forceTargetAction(actionId);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Refresh the action history table to show latest
|
|
||||||
* change of the action cancellation and update the
|
|
||||||
* Target Details
|
|
||||||
*/
|
|
||||||
|
|
||||||
populateAndupdateTargetDetails(target);
|
|
||||||
notification.displaySuccess(i18n.get("message.force.action.success"));
|
|
||||||
}
|
}
|
||||||
|
deploymentManagement.forceTargetAction(actionId);
|
||||||
|
populateAndupdateTargetDetails(target);
|
||||||
|
notification.displaySuccess(i18n.get("message.force.action.success"));
|
||||||
});
|
});
|
||||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||||
|
|
||||||
confirmDialog.getWindow().bringToFront();
|
confirmDialog.getWindow().bringToFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,22 +760,19 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
/* Display the confirmation */
|
/* Display the confirmation */
|
||||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.forcequit.action.confirmbox"),
|
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.forcequit.action.confirmbox"),
|
||||||
i18n.get("message.forcequit.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
i18n.get("message.forcequit.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
||||||
if (ok) {
|
if (!ok) {
|
||||||
final boolean cancelResult = forceQuitActiveAction(actionId);
|
return;
|
||||||
if (cancelResult) {
|
|
||||||
/*
|
|
||||||
* Refresh the action history table to show latest
|
|
||||||
* change of the action cancellation and update the
|
|
||||||
* Target Details
|
|
||||||
*/
|
|
||||||
populateAndupdateTargetDetails(target);
|
|
||||||
notification.displaySuccess(i18n.get("message.forcequit.action.success"));
|
|
||||||
} else {
|
|
||||||
notification.displayValidationError(i18n.get("message.forcequit.action.failed"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} , FontAwesome.WARNING);
|
final boolean cancelResult = forceQuitActiveAction(actionId);
|
||||||
|
if (cancelResult) {
|
||||||
|
populateAndupdateTargetDetails(target);
|
||||||
|
notification.displaySuccess(i18n.get("message.forcequit.action.success"));
|
||||||
|
} else {
|
||||||
|
notification.displayValidationError(i18n.get("message.forcequit.action.failed"));
|
||||||
|
}
|
||||||
|
}, FontAwesome.WARNING);
|
||||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||||
|
|
||||||
confirmDialog.getWindow().bringToFront();
|
confirmDialog.getWindow().bringToFront();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,21 +783,21 @@ public class ActionHistoryTable extends TreeTable implements Handler {
|
|||||||
* as Id if the action needs to be cancelled.
|
* as Id if the action needs to be cancelled.
|
||||||
*/
|
*/
|
||||||
private void confirmAndCancelAction(final Long actionId) {
|
private void confirmAndCancelAction(final Long actionId) {
|
||||||
|
if (actionId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.cancel.action.confirmbox"),
|
final ConfirmationDialog confirmDialog = new ConfirmationDialog(i18n.get("caption.cancel.action.confirmbox"),
|
||||||
i18n.get("message.cancel.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
i18n.get("message.cancel.action.confirm"), i18n.get(BUTTON_OK), i18n.get(BUTTON_CANCEL), ok -> {
|
||||||
if (ok) {
|
if (!ok) {
|
||||||
final boolean cancelResult = cancelActiveAction(actionId);
|
return;
|
||||||
if (cancelResult) {
|
}
|
||||||
/*
|
final boolean cancelResult = cancelActiveAction(actionId);
|
||||||
* Refresh the action history table to show latest
|
if (cancelResult) {
|
||||||
* change of the action cancellation and update the
|
populateAndupdateTargetDetails(target);
|
||||||
* Target Details
|
notification.displaySuccess(i18n.get("message.cancel.action.success"));
|
||||||
*/
|
} else {
|
||||||
populateAndupdateTargetDetails(target);
|
notification.displayValidationError(i18n.get("message.cancel.action.failed"));
|
||||||
notification.displaySuccess(i18n.get("message.cancel.action.success"));
|
|
||||||
} else {
|
|
||||||
notification.displayValidationError(i18n.get("message.cancel.action.failed"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
UI.getCurrent().addWindow(confirmDialog.getWindow());
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout {
|
|||||||
|
|
||||||
private void createOptionGroup() {
|
private void createOptionGroup() {
|
||||||
actionTypeOptionGroup = new FlexibleOptionGroup();
|
actionTypeOptionGroup = new FlexibleOptionGroup();
|
||||||
actionTypeOptionGroup.setId(SPUIComponentIdProvider.ROLLOUT_ACTION_BUTTON_ID);
|
|
||||||
actionTypeOptionGroup.addItem(ActionTypeOption.SOFT);
|
actionTypeOptionGroup.addItem(ActionTypeOption.SOFT);
|
||||||
actionTypeOptionGroup.addItem(ActionTypeOption.FORCED);
|
actionTypeOptionGroup.addItem(ActionTypeOption.FORCED);
|
||||||
actionTypeOptionGroup.addItem(ActionTypeOption.AUTO_FORCED);
|
actionTypeOptionGroup.addItem(ActionTypeOption.AUTO_FORCED);
|
||||||
@@ -100,6 +99,7 @@ public class ActionTypeOptionGroupLayout extends HorizontalLayout {
|
|||||||
addComponent(forceLabel);
|
addComponent(forceLabel);
|
||||||
|
|
||||||
final FlexibleOptionGroupItemComponent softItem = actionTypeOptionGroup.getItemComponent(ActionTypeOption.SOFT);
|
final FlexibleOptionGroupItemComponent softItem = actionTypeOptionGroup.getItemComponent(ActionTypeOption.SOFT);
|
||||||
|
softItem.setId(SPUIComponentIdProvider.ACTION_DETAILS_SOFT_ID);
|
||||||
softItem.setStyleName(STYLE_DIST_WINDOW_ACTIONTYPE);
|
softItem.setStyleName(STYLE_DIST_WINDOW_ACTIONTYPE);
|
||||||
addComponent(softItem);
|
addComponent(softItem);
|
||||||
final Label softLabel = new Label();
|
final Label softLabel = new Label();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_UL_OPEN_TAG;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -48,17 +49,12 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
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.addons.lazyquerycontainer.LazyQueryDefinition;
|
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
||||||
import org.vaadin.peter.contextmenu.ContextMenu;
|
|
||||||
import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItem;
|
|
||||||
import org.vaadin.peter.contextmenu.ContextMenu.ContextMenuItemClickEvent;
|
|
||||||
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;
|
||||||
|
|
||||||
import com.vaadin.data.Container;
|
import com.vaadin.data.Container;
|
||||||
import com.vaadin.data.Item;
|
import com.vaadin.data.Item;
|
||||||
import com.vaadin.data.util.PropertyValueGenerator;
|
|
||||||
import com.vaadin.data.util.converter.Converter;
|
import com.vaadin.data.util.converter.Converter;
|
||||||
import com.vaadin.server.AbstractClientConnector;
|
|
||||||
import com.vaadin.server.FontAwesome;
|
import com.vaadin.server.FontAwesome;
|
||||||
import com.vaadin.spring.annotation.SpringComponent;
|
import com.vaadin.spring.annotation.SpringComponent;
|
||||||
import com.vaadin.spring.annotation.ViewScope;
|
import com.vaadin.spring.annotation.ViewScope;
|
||||||
@@ -77,11 +73,9 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
private static final String UPDATE_OPTION = "Update";
|
private static final String UPDATE_OPTION = "Update";
|
||||||
|
|
||||||
private static final String RESUME_OPTION = "Resume";
|
|
||||||
|
|
||||||
private static final String PAUSE_OPTION = "Pause";
|
private static final String PAUSE_OPTION = "Pause";
|
||||||
|
|
||||||
private static final String START_OPTION = "Start";
|
private static final String RUN_OPTION = "Run";
|
||||||
|
|
||||||
private static final String DS_TYPE = "type";
|
private static final String DS_TYPE = "type";
|
||||||
|
|
||||||
@@ -143,7 +137,7 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
final LazyQueryContainer rolloutContainer = (LazyQueryContainer) getContainerDataSource();
|
final LazyQueryContainer rolloutContainer = (LazyQueryContainer) getContainerDataSource();
|
||||||
final Item item = rolloutContainer.getItem(rolloutChangeEvent.getRolloutId());
|
final Item item = rolloutContainer.getItem(rolloutChangeEvent.getRolloutId());
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
refreshGrid();
|
refreshGrid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
||||||
@@ -196,8 +190,15 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS,
|
||||||
TotalTargetCountStatus.class, null, false, false);
|
TotalTargetCountStatus.class, null, false, false);
|
||||||
|
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.ACTION, String.class,
|
rolloutGridContainer.addContainerProperty(RUN_OPTION, String.class, FontAwesome.PLAY.getHtml(), false, false);
|
||||||
FontAwesome.CIRCLE_O.getHtml(), false, false);
|
|
||||||
|
rolloutGridContainer.addContainerProperty(PAUSE_OPTION, String.class, FontAwesome.PAUSE.getHtml(), false,
|
||||||
|
false);
|
||||||
|
|
||||||
|
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||||
|
rolloutGridContainer.addContainerProperty(UPDATE_OPTION, String.class, FontAwesome.EDIT.getHtml(), false,
|
||||||
|
false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -218,8 +219,16 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setMinimumWidth(40);
|
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setMinimumWidth(40);
|
||||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setMaximumWidth(100);
|
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setMaximumWidth(100);
|
||||||
|
|
||||||
getColumn(SPUILabelDefinitions.ACTION).setMinimumWidth(75);
|
getColumn(RUN_OPTION).setMinimumWidth(25);
|
||||||
getColumn(SPUILabelDefinitions.ACTION).setMaximumWidth(75);
|
getColumn(RUN_OPTION).setMaximumWidth(25);
|
||||||
|
|
||||||
|
getColumn(PAUSE_OPTION).setMinimumWidth(25);
|
||||||
|
getColumn(PAUSE_OPTION).setMaximumWidth(25);
|
||||||
|
|
||||||
|
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||||
|
getColumn(UPDATE_OPTION).setMinimumWidth(25);
|
||||||
|
getColumn(UPDATE_OPTION).setMaximumWidth(25);
|
||||||
|
}
|
||||||
|
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setMinimumWidth(280);
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setMinimumWidth(280);
|
||||||
|
|
||||||
@@ -229,9 +238,9 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
@Override
|
@Override
|
||||||
protected void setColumnHeaderNames() {
|
protected void setColumnHeaderNames() {
|
||||||
getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.get("header.name"));
|
getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.get("header.name"));
|
||||||
getColumn(DS_TYPE).setHeaderCaption("Type");
|
getColumn(DS_TYPE).setHeaderCaption(i18n.get("header.type"));
|
||||||
getColumn(SW_MODULES).setHeaderCaption("swModules");
|
getColumn(SW_MODULES).setHeaderCaption(i18n.get("header.swmodules"));
|
||||||
getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption("IsRequiredMigrationStep");
|
getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption(i18n.get("header.migrations.step"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setHeaderCaption(i18n.get("header.distributionset"));
|
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setHeaderCaption(i18n.get("header.distributionset"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setHeaderCaption(i18n.get("header.numberofgroups"));
|
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setHeaderCaption(i18n.get("header.numberofgroups"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setHeaderCaption(i18n.get("header.total.targets"));
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setHeaderCaption(i18n.get("header.total.targets"));
|
||||||
@@ -243,7 +252,16 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
||||||
.setHeaderCaption(i18n.get("header.detail.status"));
|
.setHeaderCaption(i18n.get("header.detail.status"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_STATUS).setHeaderCaption(i18n.get("header.status"));
|
getColumn(SPUILabelDefinitions.VAR_STATUS).setHeaderCaption(i18n.get("header.status"));
|
||||||
getColumn(SPUILabelDefinitions.ACTION).setHeaderCaption(i18n.get("upload.action"));
|
|
||||||
|
getColumn(RUN_OPTION).setHeaderCaption(i18n.get("header.action.run"));
|
||||||
|
getColumn(PAUSE_OPTION).setHeaderCaption(i18n.get("header.action.pause"));
|
||||||
|
|
||||||
|
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||||
|
getColumn(UPDATE_OPTION).setHeaderCaption(i18n.get("header.action.update"));
|
||||||
|
}
|
||||||
|
|
||||||
|
final HeaderCell join = getDefaultHeaderRow().join(RUN_OPTION, PAUSE_OPTION, UPDATE_OPTION);
|
||||||
|
join.setText(i18n.get("header.action"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -263,7 +281,13 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS);
|
columnList.add(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS);
|
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS);
|
||||||
columnList.add(SPUILabelDefinitions.ACTION);
|
|
||||||
|
columnList.add(RUN_OPTION);
|
||||||
|
columnList.add(PAUSE_OPTION);
|
||||||
|
|
||||||
|
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||||
|
columnList.add(UPDATE_OPTION);
|
||||||
|
}
|
||||||
|
|
||||||
columnList.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
columnList.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
columnList.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
||||||
@@ -306,11 +330,21 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
createRolloutStatusToFontMap();
|
createRolloutStatusToFontMap();
|
||||||
getColumn(SPUILabelDefinitions.VAR_STATUS).setRenderer(new HtmlLabelRenderer(), new RolloutStatusConverter());
|
getColumn(SPUILabelDefinitions.VAR_STATUS).setRenderer(new HtmlLabelRenderer(), new RolloutStatusConverter());
|
||||||
|
|
||||||
getColumn(SPUILabelDefinitions.ACTION).setRenderer(new HtmlButtonRenderer(this::onClickOfActionBtn));
|
|
||||||
|
|
||||||
final RolloutRenderer customObjectRenderer = new RolloutRenderer(RolloutRendererData.class);
|
final RolloutRenderer customObjectRenderer = new RolloutRenderer(RolloutRendererData.class);
|
||||||
customObjectRenderer.addClickListener(this::onClickOfRolloutName);
|
customObjectRenderer.addClickListener(this::onClickOfRolloutName);
|
||||||
getColumn(ROLLOUT_RENDERER_DATA).setRenderer(customObjectRenderer);
|
getColumn(ROLLOUT_RENDERER_DATA).setRenderer(customObjectRenderer);
|
||||||
|
|
||||||
|
getColumn(RUN_OPTION)
|
||||||
|
.setRenderer(new HtmlButtonRenderer(clickEvent -> startOrResumeRollout((Long) clickEvent.getItemId())));
|
||||||
|
|
||||||
|
getColumn(PAUSE_OPTION)
|
||||||
|
.setRenderer(new HtmlButtonRenderer(clickEvent -> pauseRollout((Long) clickEvent.getItemId())));
|
||||||
|
|
||||||
|
if (permissionChecker.hasRolloutUpdatePermission()) {
|
||||||
|
getColumn(UPDATE_OPTION)
|
||||||
|
.setRenderer(new HtmlButtonRenderer(clickEvent -> updateRollout((Long) clickEvent.getItemId())));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRolloutStatusToFontMap() {
|
private void createRolloutStatusToFontMap() {
|
||||||
@@ -332,18 +366,7 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void alignColumns() {
|
private void alignColumns() {
|
||||||
setCellStyleGenerator(new CellStyleGenerator() {
|
setCellStyleGenerator(new RollouStatusCellStyleGenerator(getContainerDataSource()));
|
||||||
private static final long serialVersionUID = 5573570647129792429L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getStyle(final CellReference cellReference) {
|
|
||||||
final String[] coulmnNames = { SPUILabelDefinitions.VAR_STATUS, SPUILabelDefinitions.ACTION };
|
|
||||||
if (Arrays.asList(coulmnNames).contains(cellReference.getPropertyId())) {
|
|
||||||
return "centeralign";
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onClickOfRolloutName(final RendererClickEvent event) {
|
private void onClickOfRolloutName(final RendererClickEvent event) {
|
||||||
@@ -357,82 +380,44 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUPS);
|
eventBus.publish(this, RolloutEvent.SHOW_ROLLOUT_GROUPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onClickOfActionBtn(final RendererClickEvent event) {
|
private void pauseRollout(final Long rolloutId) {
|
||||||
final ContextMenu contextMenu = createContextMenu((Long) event.getItemId());
|
|
||||||
contextMenu.setAsContextMenuOf((AbstractClientConnector) event.getComponent());
|
|
||||||
contextMenu.open(event.getClientX(), event.getClientY());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ContextMenu createContextMenu(final Long rolloutId) {
|
|
||||||
final ContextMenu context = new ContextMenu();
|
|
||||||
context.addItemClickListener(this::menuItemClicked);
|
|
||||||
final Item row = getContainerDataSource().getItem(rolloutId);
|
final Item row = getContainerDataSource().getItem(rolloutId);
|
||||||
|
|
||||||
final RolloutStatus rolloutStatus = (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS)
|
final RolloutStatus rolloutStatus = (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS)
|
||||||
.getValue();
|
.getValue();
|
||||||
|
|
||||||
switch (rolloutStatus) {
|
if (!RolloutStatus.RUNNING.equals(rolloutStatus)) {
|
||||||
case READY:
|
|
||||||
final ContextMenuItem startItem = context.addItem(START_OPTION);
|
|
||||||
startItem.setData(new ContextMenuData(rolloutId, ACTION.START));
|
|
||||||
break;
|
|
||||||
case RUNNING:
|
|
||||||
final ContextMenuItem pauseItem = context.addItem(PAUSE_OPTION);
|
|
||||||
pauseItem.setData(new ContextMenuData(rolloutId, ACTION.PAUSE));
|
|
||||||
break;
|
|
||||||
case PAUSED:
|
|
||||||
final ContextMenuItem resumeItem = context.addItem(RESUME_OPTION);
|
|
||||||
resumeItem.setData(new ContextMenuData(rolloutId, ACTION.RESUME));
|
|
||||||
break;
|
|
||||||
case STARTING:
|
|
||||||
case CREATING:
|
|
||||||
case ERROR_CREATING:
|
|
||||||
case ERROR_STARTING:
|
|
||||||
// do not provide any action on these statuses
|
|
||||||
return context;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
getUpdateMenuItem(context, rolloutId);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getUpdateMenuItem(final ContextMenu context, final Long rolloutId) {
|
|
||||||
// Add 'Update' option only if user has update permission
|
|
||||||
if (!permissionChecker.hasRolloutUpdatePermission()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ContextMenuItem cancelItem = context.addItem(UPDATE_OPTION);
|
|
||||||
cancelItem.setData(new ContextMenuData(rolloutId, ACTION.UPDATE));
|
final String rolloutName = (String) row.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
|
||||||
|
|
||||||
|
rolloutManagement.pauseRollout(rolloutManagement.findRolloutById(rolloutId));
|
||||||
|
uiNotification.displaySuccess(i18n.get("message.rollout.paused", rolloutName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuItemClicked(final ContextMenuItemClickEvent event) {
|
private void startOrResumeRollout(final Long rolloutId) {
|
||||||
final ContextMenuItem item = (ContextMenuItem) event.getSource();
|
final Item row = getContainerDataSource().getItem(rolloutId);
|
||||||
final ContextMenuData contextMenuData = (ContextMenuData) item.getData();
|
|
||||||
final Item row = getContainerDataSource().getItem(contextMenuData.getRolloutId());
|
final RolloutStatus rolloutStatus = (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS)
|
||||||
|
.getValue();
|
||||||
final String rolloutName = (String) row.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
|
final String rolloutName = (String) row.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue();
|
||||||
switch (contextMenuData.getAction()) {
|
|
||||||
case PAUSE:
|
if (RolloutStatus.READY.equals(rolloutStatus)) {
|
||||||
rolloutManagement.pauseRollout(rolloutManagement.findRolloutById(contextMenuData.getRolloutId()));
|
|
||||||
uiNotification.displaySuccess(i18n.get("message.rollout.paused", rolloutName));
|
|
||||||
break;
|
|
||||||
case RESUME:
|
|
||||||
rolloutManagement.resumeRollout(rolloutManagement.findRolloutById(contextMenuData.getRolloutId()));
|
|
||||||
uiNotification.displaySuccess(i18n.get("message.rollout.resumed", rolloutName));
|
|
||||||
break;
|
|
||||||
case START:
|
|
||||||
rolloutManagement.startRolloutAsync(rolloutManagement.findRolloutByName(rolloutName));
|
rolloutManagement.startRolloutAsync(rolloutManagement.findRolloutByName(rolloutName));
|
||||||
uiNotification.displaySuccess(i18n.get("message.rollout.started", rolloutName));
|
uiNotification.displaySuccess(i18n.get("message.rollout.started", rolloutName));
|
||||||
break;
|
return;
|
||||||
case UPDATE:
|
}
|
||||||
onUpdate(contextMenuData);
|
|
||||||
break;
|
if (RolloutStatus.PAUSED.equals(rolloutStatus)) {
|
||||||
default:
|
rolloutManagement.resumeRollout(rolloutManagement.findRolloutById(rolloutId));
|
||||||
break;
|
uiNotification.displaySuccess(i18n.get("message.rollout.resumed", rolloutName));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onUpdate(final ContextMenuData contextMenuData) {
|
private void updateRollout(final Long rolloutId) {
|
||||||
final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(contextMenuData.getRolloutId());
|
final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(rolloutId);
|
||||||
addTargetWindow.setCaption(i18n.get("caption.update.rollout"));
|
addTargetWindow.setCaption(i18n.get("caption.update.rollout"));
|
||||||
UI.getCurrent().addWindow(addTargetWindow);
|
UI.getCurrent().addWindow(addTargetWindow);
|
||||||
addTargetWindow.setVisible(Boolean.TRUE);
|
addTargetWindow.setVisible(Boolean.TRUE);
|
||||||
@@ -442,29 +427,6 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
((LazyQueryContainer) getContainerDataSource()).refresh();
|
((LazyQueryContainer) getContainerDataSource()).refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generator to generate fontIcon by String.
|
|
||||||
*/
|
|
||||||
public final class FontIconGenerator extends PropertyValueGenerator<String> {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 2544026030795375748L;
|
|
||||||
private final FontAwesome fontIcon;
|
|
||||||
|
|
||||||
public FontIconGenerator(final FontAwesome icon) {
|
|
||||||
this.fontIcon = icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getValue(final Item item, final Object itemId, final Object propertyId) {
|
|
||||||
return fontIcon.getHtml();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<String> getType() {
|
|
||||||
return String.class;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getDescription(final CellReference cell) {
|
private String getDescription(final CellReference cell) {
|
||||||
if (SPUILabelDefinitions.VAR_STATUS.equals(cell.getPropertyId())) {
|
if (SPUILabelDefinitions.VAR_STATUS.equals(cell.getPropertyId())) {
|
||||||
return cell.getProperty().getValue().toString().toLowerCase();
|
return cell.getProperty().getValue().toString().toLowerCase();
|
||||||
@@ -518,61 +480,70 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
return stringBuilder.toString();
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ACTION {
|
private static class RollouStatusCellStyleGenerator implements CellStyleGenerator {
|
||||||
PAUSE, RESUME, START, UPDATE
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private static final long serialVersionUID = 1L;
|
||||||
* Represents data of context menu item.
|
/**
|
||||||
*
|
* Contains all expected rollout status per column to enable or disable
|
||||||
*/
|
* the button.
|
||||||
public static class ContextMenuData {
|
*/
|
||||||
|
private static final Map<String, RolloutStatus> EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON = new HashMap<>();
|
||||||
|
private final Container.Indexed containerDataSource;
|
||||||
|
|
||||||
private Long rolloutId;
|
static {
|
||||||
|
EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON.put(RUN_OPTION, RolloutStatus.READY);
|
||||||
private ACTION action;
|
EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON.put(PAUSE_OPTION, RolloutStatus.RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set rollout if and action.
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param rolloutId
|
* @param containerDataSource
|
||||||
* id of rollout
|
* the container
|
||||||
* @param action
|
|
||||||
* user action {@link ACTION}
|
|
||||||
*/
|
*/
|
||||||
public ContextMenuData(final Long rolloutId, final ACTION action) {
|
public RollouStatusCellStyleGenerator(final Container.Indexed containerDataSource) {
|
||||||
this.action = action;
|
this.containerDataSource = containerDataSource;
|
||||||
this.rolloutId = rolloutId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* @return the rolloutId
|
public String getStyle(final CellReference cellReference) {
|
||||||
*/
|
if (SPUILabelDefinitions.VAR_STATUS.equals(cellReference.getPropertyId())) {
|
||||||
public Long getRolloutId() {
|
return "centeralign";
|
||||||
return rolloutId;
|
}
|
||||||
|
return convertRolloutStatusToString(cellReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String convertRolloutStatusToString(final CellReference cellReference) {
|
||||||
* @param rolloutId
|
final Object propertyId = cellReference.getPropertyId();
|
||||||
* the rolloutId to set
|
final RolloutStatus expectedRolloutStatus = EXPECTED_ROLLOUT_STATUS_ENABLE_BUTTON.get(propertyId);
|
||||||
*/
|
if (expectedRolloutStatus == null) {
|
||||||
public void setRolloutId(final Long rolloutId) {
|
return null;
|
||||||
this.rolloutId = rolloutId;
|
}
|
||||||
|
|
||||||
|
if (RUN_OPTION.equals(cellReference.getPropertyId())) {
|
||||||
|
return getStatus(cellReference, RolloutStatus.READY, RolloutStatus.PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PAUSE_OPTION.equals(cellReference.getPropertyId())) {
|
||||||
|
return getStatus(cellReference, RolloutStatus.RUNNING);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private String getStatus(final CellReference cellReference, final RolloutStatus... expectedRolloutStatus) {
|
||||||
* @return the action
|
final RolloutStatus currentRolloutStatus = getRolloutStatus(cellReference.getItemId());
|
||||||
*/
|
|
||||||
public ACTION getAction() {
|
if (Arrays.asList(expectedRolloutStatus).contains(currentRolloutStatus)) {
|
||||||
return action;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return org.eclipse.hawkbit.ui.customrenderers.client.renderers.HtmlButtonRenderer.DISABLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private RolloutStatus getRolloutStatus(final Object itemId) {
|
||||||
* @param action
|
final Item row = containerDataSource.getItem(itemId);
|
||||||
* the action to set
|
return (RolloutStatus) row.getItemProperty(SPUILabelDefinitions.VAR_STATUS).getValue();
|
||||||
*/
|
|
||||||
public void setAction(final ACTION action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,6 +246,11 @@ public final class SPUIComponentIdProvider {
|
|||||||
*/
|
*/
|
||||||
public static final String DISCARD_SW_MODULE_TYPE = "save.actions.popup.discard.sw.module.type";
|
public static final String DISCARD_SW_MODULE_TYPE = "save.actions.popup.discard.sw.module.type";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action history table cancel Id.
|
||||||
|
*/
|
||||||
|
public static final String ACTION_DETAILS_SOFT_ID = "action.details.soft.group";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID - Label.
|
* ID - Label.
|
||||||
*/
|
*/
|
||||||
@@ -293,6 +298,21 @@ public final class SPUIComponentIdProvider {
|
|||||||
*/
|
*/
|
||||||
public static final String ACTION_HISTORY_TABLE_ID = "action.history.tableId";
|
public static final String ACTION_HISTORY_TABLE_ID = "action.history.tableId";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action history table cancel Id.
|
||||||
|
*/
|
||||||
|
public static final String ACTION_HISTORY_TABLE_CANCEL_ID = "action.history.table.action.cancel";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action history table force Id.
|
||||||
|
*/
|
||||||
|
public static final String ACTION_HISTORY_TABLE_FORCE_ID = "action.history.table.action.force";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action history table force quit Id.
|
||||||
|
*/
|
||||||
|
public static final String ACTION_HISTORY_TABLE_FORCE_QUIT_ID = "action.history.table.action.force.quit";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Target filter wrapper id.
|
* Target filter wrapper id.
|
||||||
*/
|
*/
|
||||||
@@ -837,19 +857,26 @@ public final class SPUIComponentIdProvider {
|
|||||||
* Rollout target filter query combo id.
|
* Rollout target filter query combo id.
|
||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_TARGET_FILTER_COMBO_ID = "rollout.target.filter.combo.id";
|
public static final String ROLLOUT_TARGET_FILTER_COMBO_ID = "rollout.target.filter.combo.id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rollout action button id.
|
* Rollout action button id.
|
||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_ACTION_BUTTON_ID = "rollout.action.button.id";
|
public static final String ROLLOUT_ACTION_ID = "rollout.action.button.id";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollout start button id.
|
||||||
|
*/
|
||||||
|
public static final String ROLLOUT_RUN_BUTTON_ID = ROLLOUT_ACTION_ID + ".9";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rollout pause button id.
|
* Rollout pause button id.
|
||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_PAUSE_BUTTON_ID = "rollout.pause.button.id";
|
public static final String ROLLOUT_PAUSE_BUTTON_ID = ROLLOUT_ACTION_ID + ".10";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rollout resume button id.
|
* Rollout resume button id.
|
||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_RESUME_BUTTON_ID = "rollout.resume.button.id";
|
public static final String ROLLOUT_UPDATE_BUTTON_ID = ROLLOUT_ACTION_ID + ".11";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rollout save or start option group id.
|
* Rollout save or start option group id.
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ public final class SPUIDefinitions {
|
|||||||
*/
|
*/
|
||||||
public static final String ACTION_HIS_TBL_STATUS = "Status";
|
public static final String ACTION_HIS_TBL_STATUS = "Status";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions column.
|
||||||
|
*/
|
||||||
|
public static final String ACTIONS_COLUMN = "Actions";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action history messages of particular action update.
|
* Action history messages of particular action update.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -293,8 +293,4 @@
|
|||||||
padding-bottom: 12px !important;
|
padding-bottom: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-button-default-color {
|
|
||||||
color: #551f62;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,4 +56,5 @@
|
|||||||
.marginTop {
|
.marginTop {
|
||||||
margin-top: 20px !important;
|
margin-top: 20px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,5 +164,6 @@
|
|||||||
|
|
||||||
.actionButtonsMargin {
|
.actionButtonsMargin {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,10 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.action-type-padding{
|
||||||
|
padding: 0 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.rollout-caption-links{
|
.rollout-caption-links{
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
height: 25px ;
|
height: 25px ;
|
||||||
|
|||||||
@@ -438,6 +438,14 @@ header.distributionset = Distribution set
|
|||||||
header.numberofgroups = No. of groups
|
header.numberofgroups = No. of groups
|
||||||
header.detail.status = Detail status
|
header.detail.status = Detail status
|
||||||
header.total.targets = Total targets
|
header.total.targets = Total targets
|
||||||
|
header.type = Type
|
||||||
|
header.swmodules = SwModules
|
||||||
|
header.migrations.step=IsRequiredMigrationStep
|
||||||
|
|
||||||
|
header.action=Actions
|
||||||
|
header.action.run=Run
|
||||||
|
header.action.pause=Pause
|
||||||
|
header.action.update=Edit
|
||||||
|
|
||||||
distribution.details.header = Distribution set
|
distribution.details.header = Distribution set
|
||||||
target.details.header = Target
|
target.details.header = Target
|
||||||
|
|||||||
@@ -422,6 +422,14 @@ header.distributionset = Distribution set
|
|||||||
header.numberofgroups = No. of groups
|
header.numberofgroups = No. of groups
|
||||||
header.detail.status = Detail status
|
header.detail.status = Detail status
|
||||||
header.total.targets = Total targets
|
header.total.targets = Total targets
|
||||||
|
header.type = Type
|
||||||
|
header.swmodules = SwModules
|
||||||
|
header.migrations.step=IsRequiredMigrationStep
|
||||||
|
|
||||||
|
header.action=Actions
|
||||||
|
header.action.run=Run
|
||||||
|
header.action.pause=Pause
|
||||||
|
header.action.update=Edit
|
||||||
|
|
||||||
header.rolloutgroup.installed.percentage = % Finished
|
header.rolloutgroup.installed.percentage = % Finished
|
||||||
header.rolloutgroup.threshold.error = Error threshold
|
header.rolloutgroup.threshold.error = Error threshold
|
||||||
|
|||||||
@@ -419,11 +419,21 @@ header.distributionset = Distribution Set
|
|||||||
header.numberofgroups = No. of groups
|
header.numberofgroups = No. of groups
|
||||||
header.detail.status = Detail status
|
header.detail.status = Detail status
|
||||||
header.total.targets = Total targets
|
header.total.targets = Total targets
|
||||||
|
header.type = Type
|
||||||
|
header.swmodules = SwModules
|
||||||
|
header.migrations.step=IsRequiredMigrationStep
|
||||||
|
|
||||||
|
header.action=Actions
|
||||||
|
header.action.run=Run
|
||||||
|
header.action.pause=Pause
|
||||||
|
header.action.update=Edit
|
||||||
|
|
||||||
header.rolloutgroup.installed.percentage = % Finished
|
header.rolloutgroup.installed.percentage = % Finished
|
||||||
header.rolloutgroup.threshold.error = Error threshold
|
header.rolloutgroup.threshold.error = Error threshold
|
||||||
header.rolloutgroup.threshold = Trigger threshold
|
header.rolloutgroup.threshold = Trigger threshold
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
header.rolloutgroup.target.date = Date and time
|
header.rolloutgroup.target.date = Date and time
|
||||||
header.rolloutgroup.target.message = Messages
|
header.rolloutgroup.target.message = Messages
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user