Merge branch 'master' into feature_enable_push_in_deployment_view
Conflicts: hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java
This commit is contained in:
@@ -10,8 +10,6 @@ package org.eclipse.hawkbit.simulator;
|
|||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.DigestOutputStream;
|
import java.security.DigestOutputStream;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
@@ -34,6 +32,7 @@ import org.apache.http.conn.ssl.SSLContextBuilder;
|
|||||||
import org.apache.http.impl.client.CloseableHttpClient;
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
import org.apache.http.impl.client.HttpClients;
|
import org.apache.http.impl.client.HttpClients;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.Artifact.UrlProtocol;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.SoftwareModule;
|
import org.eclipse.hawkbit.dmf.json.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
||||||
import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus;
|
import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus;
|
||||||
@@ -59,7 +58,7 @@ import com.google.common.io.ByteStreams;
|
|||||||
public class DeviceSimulatorUpdater {
|
public class DeviceSimulatorUpdater {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class);
|
||||||
|
|
||||||
private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4);
|
private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(8);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SpSenderService spSenderService;
|
private SpSenderService spSenderService;
|
||||||
@@ -198,18 +197,14 @@ public class DeviceSimulatorUpdater {
|
|||||||
|
|
||||||
private static void handleArtifacts(final String targetToken, final List<UpdateStatus> status,
|
private static void handleArtifacts(final String targetToken, final List<UpdateStatus> status,
|
||||||
final Artifact artifact) {
|
final Artifact artifact) {
|
||||||
artifact.getUrls().entrySet().forEach(entry -> {
|
|
||||||
switch (entry.getKey()) {
|
if (artifact.getUrls().containsKey(UrlProtocol.HTTPS)) {
|
||||||
case HTTP:
|
status.add(downloadUrl(artifact.getUrls().get(UrlProtocol.HTTPS), targetToken,
|
||||||
case HTTPS:
|
artifact.getHashes().getSha1(), artifact.getSize()));
|
||||||
status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1(),
|
} else if (artifact.getUrls().containsKey(UrlProtocol.HTTP)) {
|
||||||
artifact.getSize()));
|
status.add(downloadUrl(artifact.getUrls().get(UrlProtocol.HTTP), targetToken,
|
||||||
break;
|
artifact.getHashes().getSha1(), artifact.getSize()));
|
||||||
default:
|
|
||||||
// not supported yet
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash,
|
private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash,
|
||||||
@@ -236,24 +231,17 @@ public class DeviceSimulatorUpdater {
|
|||||||
return new UpdateStatus(ResponseStatus.ERROR, message);
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
final File tempFile = File.createTempFile("uploadFile", null);
|
|
||||||
|
|
||||||
// Exception squid:S2070 - not used for hashing sensitive
|
// Exception squid:S2070 - not used for hashing sensitive
|
||||||
// data
|
// data
|
||||||
@SuppressWarnings("squid:S2070")
|
@SuppressWarnings("squid:S2070")
|
||||||
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||||
|
|
||||||
try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) {
|
try (final BufferedOutputStream bdos = new BufferedOutputStream(
|
||||||
try (final BufferedOutputStream bdos = new BufferedOutputStream(dos)) {
|
new DigestOutputStream(ByteStreams.nullOutputStream(), md))) {
|
||||||
try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) {
|
try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) {
|
||||||
overallread = ByteStreams.copy(bis, bdos);
|
overallread = ByteStreams.copy(bis, bdos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
if (tempFile != null && !tempFile.delete()) {
|
|
||||||
LOGGER.error("Could not delete temporary file: {}", tempFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overallread != size) {
|
if (overallread != size) {
|
||||||
final String message = incompleteRead(url, size, overallread);
|
final String message = incompleteRead(url, size, overallread);
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class DownloadIdCacheAutoConfiguration {
|
|||||||
private CacheManager cacheManager;
|
private CacheManager cacheManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bean for the downlod id cache.
|
* Bean for the download id cache.
|
||||||
*
|
*
|
||||||
* @return the cache
|
* @return the cache
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -45,6 +45,12 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- Test -->
|
<!-- Test -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
|
<artifactId>hawkbit-repository-api</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ import static org.mockito.Mockito.verify;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
|
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
|
||||||
|
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -56,7 +56,7 @@ public class EventDistributorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void distributeDistributedEventSendsToRedis() {
|
public void distributeDistributedEventSendsToRedis() {
|
||||||
|
|
||||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||||
underTest.distribute(event);
|
underTest.distribute(event);
|
||||||
|
|
||||||
// origin node ID should be set by distributing the event
|
// origin node ID should be set by distributing the event
|
||||||
@@ -67,7 +67,7 @@ public class EventDistributorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void dontDistributeDistributedEventIfSameNode() {
|
public void dontDistributeDistributedEventIfSameNode() {
|
||||||
final String knownNodeId = EventDistributor.getNodeId();
|
final String knownNodeId = EventDistributor.getNodeId();
|
||||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||||
event.setNodeId(knownNodeId);
|
event.setNodeId(knownNodeId);
|
||||||
|
|
||||||
// test
|
// test
|
||||||
@@ -79,7 +79,7 @@ public class EventDistributorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleDistributedMessageFromRedis() {
|
public void handleDistributedMessageFromRedis() {
|
||||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||||
final String knownChannel = "someChannel";
|
final String knownChannel = "someChannel";
|
||||||
|
|
||||||
underTest.handleMessage(event, knownChannel);
|
underTest.handleMessage(event, knownChannel);
|
||||||
@@ -90,7 +90,7 @@ public class EventDistributorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleDistributedMessageFilteredIfSameNodeId() {
|
public void handleDistributedMessageFilteredIfSameNodeId() {
|
||||||
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 10);
|
final DownloadProgressEvent event = new DownloadProgressEvent("tenant", 123L, 500L, 100L, 200L);
|
||||||
final String knownChannel = "someChannel";
|
final String knownChannel = "someChannel";
|
||||||
event.setOriginNodeId(EventDistributor.getNodeId());
|
event.setOriginNodeId(EventDistributor.getNodeId());
|
||||||
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.eventbus.event;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Event that contains an updated download progress for a given Action.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class DownloadProgressEvent extends AbstractDistributedEvent {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private final Long statusId;
|
|
||||||
private final int progressPercent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param tenant
|
|
||||||
* the tenant for this event
|
|
||||||
* @param statusId
|
|
||||||
* of {@link UpdateActionStatus}
|
|
||||||
* @param progressPercent
|
|
||||||
* number (1-100)
|
|
||||||
*/
|
|
||||||
public DownloadProgressEvent(final String tenant, final Long statusId, final int progressPercent) {
|
|
||||||
// the revision of the DownloadProgressEvent is just equal the
|
|
||||||
// progressPercentage due the
|
|
||||||
// percentage is going from 0 to 100.
|
|
||||||
super(statusId, tenant);
|
|
||||||
this.statusId = statusId;
|
|
||||||
this.progressPercent = progressPercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the statusId
|
|
||||||
*/
|
|
||||||
public Long getStatusId() {
|
|
||||||
return statusId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the progressPercent
|
|
||||||
*/
|
|
||||||
public int getProgressPercent() {
|
|
||||||
return progressPercent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -93,12 +93,12 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
|||||||
// we set a download status only if we are aware of the
|
// we set a download status only if we are aware of the
|
||||||
// targetid, i.e. authenticated and not anonymous
|
// targetid, i.e. authenticated and not anonymous
|
||||||
if (targetid != null && !"anonymous".equals(targetid)) {
|
if (targetid != null && !"anonymous".equals(targetid)) {
|
||||||
final Action action = checkAndReportDownloadByTarget(
|
final ActionStatus actionStatus = checkAndReportDownloadByTarget(
|
||||||
requestResponseContextHolder.getHttpServletRequest(), targetid, artifact);
|
requestResponseContextHolder.getHttpServletRequest(), targetid, artifact);
|
||||||
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
||||||
requestResponseContextHolder.getHttpServletResponse(),
|
requestResponseContextHolder.getHttpServletResponse(),
|
||||||
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
|
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
|
||||||
action.getId());
|
actionStatus.getId());
|
||||||
} else {
|
} else {
|
||||||
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
||||||
requestResponseContextHolder.getHttpServletResponse(),
|
requestResponseContextHolder.getHttpServletResponse(),
|
||||||
@@ -131,7 +131,7 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
|||||||
return new ResponseEntity<>(HttpStatus.OK);
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
|
private ActionStatus checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
|
||||||
final LocalArtifact artifact) {
|
final LocalArtifact artifact) {
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, securityProperties));
|
IpUtil.getClientIpFromRequest(request, securityProperties));
|
||||||
@@ -152,8 +152,8 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
|||||||
actionStatus.addMessage(
|
actionStatus.addMessage(
|
||||||
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI());
|
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI());
|
||||||
}
|
}
|
||||||
controllerManagement.addInformationalActionStatus(actionStatus);
|
|
||||||
return action;
|
return controllerManagement.addInformationalActionStatus(actionStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,8 +156,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
|
if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) {
|
||||||
result = new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
|
result = new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED);
|
||||||
} else {
|
} else {
|
||||||
final Action action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(), target,
|
final ActionStatus action = checkAndLogDownload(requestResponseContextHolder.getHttpServletRequest(),
|
||||||
module);
|
target, module);
|
||||||
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
result = RestResourceConversionHelper.writeFileResponse(artifact,
|
||||||
requestResponseContextHolder.getHttpServletResponse(),
|
requestResponseContextHolder.getHttpServletResponse(),
|
||||||
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
|
requestResponseContextHolder.getHttpServletRequest(), file, controllerManagement,
|
||||||
@@ -167,7 +167,7 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action checkAndLogDownload(final HttpServletRequest request, final Target target,
|
private ActionStatus checkAndLogDownload(final HttpServletRequest request, final Target target,
|
||||||
final SoftwareModule module) {
|
final SoftwareModule module) {
|
||||||
final Action action = controllerManagement
|
final Action action = controllerManagement
|
||||||
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module);
|
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), module);
|
||||||
@@ -185,8 +185,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
statusMessage.addMessage(
|
statusMessage.addMessage(
|
||||||
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI());
|
RepositoryConstants.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI());
|
||||||
}
|
}
|
||||||
controllerManagement.addInformationalActionStatus(statusMessage);
|
|
||||||
return action;
|
return controllerManagement.addInformationalActionStatus(statusMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkModule(final String fileName, final SoftwareModule module) {
|
private static boolean checkModule(final String fileName, final SoftwareModule module) {
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.RandomUtils;
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Artifact;
|
import org.eclipse.hawkbit.repository.model.Artifact;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
|
import org.eclipse.hawkbit.rest.AbstractRestIntegrationTestWithMongoDB;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -59,11 +59,15 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
@Stories("Artifact Download Resource")
|
@Stories("Artifact Download Resource")
|
||||||
public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMongoDB {
|
public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
private static final int ARTIFACT_SIZE = 5 * 1024 * 1024;
|
||||||
|
|
||||||
public DdiArtifactDownloadTest() {
|
public DdiArtifactDownloadTest() {
|
||||||
LOG = LoggerFactory.getLogger(DdiArtifactDownloadTest.class);
|
LOG = LoggerFactory.getLogger(DdiArtifactDownloadTest.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private volatile int downLoadProgress = 0;
|
private volatile int downLoadProgress = 0;
|
||||||
|
private volatile long shippedBytes = 0;
|
||||||
|
private volatile long shippedBytesTotal = 0;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EventBus eventBus;
|
private EventBus eventBus;
|
||||||
@@ -236,6 +240,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
@Description("Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.")
|
@Description("Tests valid downloads through the artifact resource by identifying the artifact not by ID but file name.")
|
||||||
public void downloadArtifactThroughFileName() throws Exception {
|
public void downloadArtifactThroughFileName() throws Exception {
|
||||||
downLoadProgress = 1;
|
downLoadProgress = 1;
|
||||||
|
shippedBytes = 0;
|
||||||
|
shippedBytesTotal = 0;
|
||||||
eventBus.register(this);
|
eventBus.register(this);
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||||
|
|
||||||
@@ -249,7 +255,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
// create artifact
|
// create artifact
|
||||||
final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024);
|
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
|
||||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||||
|
|
||||||
@@ -276,6 +282,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
|
|
||||||
// download complete
|
// download complete
|
||||||
assertThat(downLoadProgress).isEqualTo(10);
|
assertThat(downLoadProgress).isEqualTo(10);
|
||||||
|
assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -313,35 +320,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
+ "anonymous as authorization is notpossible, e.g. chekc if the controller has the artifact assigned.")
|
+ "anonymous as authorization is notpossible, e.g. chekc if the controller has the artifact assigned.")
|
||||||
public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception {
|
public void downloadArtifactByNameFailsIfNotAuthenticated() throws Exception {
|
||||||
downLoadProgress = 1;
|
downLoadProgress = 1;
|
||||||
eventBus.register(this);
|
shippedBytes = 0;
|
||||||
|
shippedBytesTotal = 0;
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
|
|
||||||
// create target
|
|
||||||
Target target = entityFactory.generateTarget("4712");
|
|
||||||
target = targetManagement.createTarget(target);
|
|
||||||
final List<Target> targets = new ArrayList();
|
|
||||||
targets.add(target);
|
|
||||||
|
|
||||||
// create ds
|
|
||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
|
||||||
|
|
||||||
// create artifact
|
|
||||||
final byte random[] = RandomUtils.nextBytes(5 * 1024);
|
|
||||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
|
||||||
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
|
||||||
|
|
||||||
// download fails as artifact is not yet assigned to target
|
|
||||||
deploymentManagement.assignDistributionSet(ds, targets);
|
|
||||||
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2"))
|
|
||||||
.andExpect(status().isNotFound());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
|
||||||
@Description("Ensures that an authenticated and named controller is permitted to download.")
|
|
||||||
public void downloadArtifactByNameByNamedController() throws Exception {
|
|
||||||
downLoadProgress = 1;
|
|
||||||
eventBus.register(this);
|
eventBus.register(this);
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||||
@@ -356,7 +336,41 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
// create artifact
|
// create artifact
|
||||||
final byte random[] = RandomUtils.nextBytes(5 * 1024 * 1024);
|
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
|
||||||
|
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||||
|
ds.findFirstModuleByType(osType).getId(), "file1.tar.bz2", false);
|
||||||
|
|
||||||
|
// download fails as artifact is not yet assigned to target
|
||||||
|
deploymentManagement.assignDistributionSet(ds, targets);
|
||||||
|
mvc.perform(get("/controller/artifacts/v1/filename/{filename}", "file1.tar.bz2"))
|
||||||
|
.andExpect(status().isNotFound());
|
||||||
|
|
||||||
|
assertThat(downLoadProgress).isEqualTo(1);
|
||||||
|
assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(0L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithUser(principal = "4712", authorities = "ROLE_CONTROLLER", allSpPermissions = true)
|
||||||
|
@Description("Ensures that an authenticated and named controller is permitted to download.")
|
||||||
|
public void downloadArtifactByNameByNamedController() throws Exception {
|
||||||
|
downLoadProgress = 1;
|
||||||
|
shippedBytes = 0;
|
||||||
|
shippedBytesTotal = 0;
|
||||||
|
eventBus.register(this);
|
||||||
|
|
||||||
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||||
|
|
||||||
|
// create target
|
||||||
|
Target target = entityFactory.generateTarget("4712");
|
||||||
|
target = targetManagement.createTarget(target);
|
||||||
|
final List<Target> targets = new ArrayList<>();
|
||||||
|
targets.add(target);
|
||||||
|
|
||||||
|
// create ds
|
||||||
|
final DistributionSet ds = testdataFactory.createDistributionSet("");
|
||||||
|
|
||||||
|
// create artifact
|
||||||
|
final byte random[] = RandomUtils.nextBytes(ARTIFACT_SIZE);
|
||||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||||
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
ds.findFirstModuleByType(osType).getId(), "file1", false);
|
||||||
|
|
||||||
@@ -389,6 +403,7 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
|
|
||||||
// download complete
|
// download complete
|
||||||
assertThat(downLoadProgress).isEqualTo(10);
|
assertThat(downLoadProgress).isEqualTo(10);
|
||||||
|
assertThat(shippedBytes).isEqualTo(shippedBytesTotal).isEqualTo(ARTIFACT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -550,5 +565,8 @@ public class DdiArtifactDownloadTest extends AbstractRestIntegrationTestWithMong
|
|||||||
@Subscribe
|
@Subscribe
|
||||||
public void listen(final DownloadProgressEvent event) {
|
public void listen(final DownloadProgressEvent event) {
|
||||||
downLoadProgress++;
|
downLoadProgress++;
|
||||||
|
shippedBytes += event.getShippedBytesSinceLast();
|
||||||
|
shippedBytesTotal = event.getShippedBytesOverall();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ import org.springframework.amqp.core.BindingBuilder;
|
|||||||
import org.springframework.amqp.core.FanoutExchange;
|
import org.springframework.amqp.core.FanoutExchange;
|
||||||
import org.springframework.amqp.core.Queue;
|
import org.springframework.amqp.core.Queue;
|
||||||
import org.springframework.amqp.core.QueueBuilder;
|
import org.springframework.amqp.core.QueueBuilder;
|
||||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
|
||||||
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -268,15 +268,8 @@ public class AmqpConfiguration {
|
|||||||
* AMQP messages
|
* AMQP messages
|
||||||
*/
|
*/
|
||||||
@Bean(name = { "listenerContainerFactory" })
|
@Bean(name = { "listenerContainerFactory" })
|
||||||
public SimpleRabbitListenerContainerFactory listenerContainerFactory() {
|
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory() {
|
||||||
final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory();
|
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory);
|
||||||
containerFactory.setDefaultRequeueRejected(true);
|
|
||||||
containerFactory.setConnectionFactory(rabbitConnectionFactory);
|
|
||||||
containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
|
||||||
containerFactory.setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers());
|
|
||||||
containerFactory.setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers());
|
|
||||||
containerFactory.setPrefetchCount(amqpProperties.getPrefetchCount());
|
|
||||||
return containerFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
||||||
|
|||||||
@@ -138,9 +138,18 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory")
|
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory")
|
||||||
public Message onAuthenticationRequest(final Message message,
|
public Message onAuthenticationRequest(final Message message) {
|
||||||
@Header(MessageHeaderKey.TENANT) final String tenant) {
|
checkContentTypeJson(message);
|
||||||
return onAuthenticationRequest(message);
|
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||||
|
try {
|
||||||
|
return handleAuthentifiactionMessage(message);
|
||||||
|
} catch (final IllegalArgumentException ex) {
|
||||||
|
throw new AmqpRejectAndDontRequeueException("Invalid message!", ex);
|
||||||
|
} catch (final TenantNotExistException teex) {
|
||||||
|
throw new AmqpRejectAndDontRequeueException(teex);
|
||||||
|
} finally {
|
||||||
|
SecurityContextHolder.setContext(oldContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) {
|
public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) {
|
||||||
@@ -159,7 +168,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
final EventTopic eventTopic = EventTopic.valueOf(topicValue);
|
final EventTopic eventTopic = EventTopic.valueOf(topicValue);
|
||||||
handleIncomingEvent(message, eventTopic);
|
handleIncomingEvent(message, eventTopic);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logAndThrowMessageError(message, "No handle method was found for the given message type.");
|
logAndThrowMessageError(message, "No handle method was found for the given message type.");
|
||||||
}
|
}
|
||||||
@@ -173,20 +181,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message onAuthenticationRequest(final Message message) {
|
|
||||||
checkContentTypeJson(message);
|
|
||||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
|
||||||
try {
|
|
||||||
return handleAuthentifiactionMessage(message);
|
|
||||||
} catch (final IllegalArgumentException ex) {
|
|
||||||
throw new AmqpRejectAndDontRequeueException("Invalid message!", ex);
|
|
||||||
} catch (final TenantNotExistException teex) {
|
|
||||||
throw new AmqpRejectAndDontRequeueException(teex);
|
|
||||||
} finally {
|
|
||||||
SecurityContextHolder.setContext(oldContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Message handleAuthentifiactionMessage(final Message message) {
|
private Message handleAuthentifiactionMessage(final Message message) {
|
||||||
final DownloadResponse authentificationResponse = new DownloadResponse();
|
final DownloadResponse authentificationResponse = new DownloadResponse();
|
||||||
final MessageProperties messageProperties = message.getMessageProperties();
|
final MessageProperties messageProperties = message.getMessageProperties();
|
||||||
@@ -414,7 +408,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
|
|
||||||
if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) {
|
if (ArrayUtils.isNotEmpty(message.getMessageProperties().getCorrelationId())) {
|
||||||
actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id "
|
actionStatus.addMessage(RepositoryConstants.SERVER_MESSAGE_PREFIX + "DMF message correlation-id "
|
||||||
+ message.getMessageProperties().getCorrelationId());
|
+ convertCorrelationId(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
actionStatus.setAction(action);
|
actionStatus.setAction(action);
|
||||||
@@ -422,6 +416,10 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
return actionStatus;
|
return actionStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String convertCorrelationId(final Message message) {
|
||||||
|
return new String(message.getMessageProperties().getCorrelationId());
|
||||||
|
}
|
||||||
|
|
||||||
private Action getUpdateActionStatus(final ActionStatus actionStatus) {
|
private Action getUpdateActionStatus(final ActionStatus actionStatus) {
|
||||||
if (actionStatus.getStatus().equals(Status.CANCELED)) {
|
if (actionStatus.getStatus().equals(Status.CANCELED)) {
|
||||||
return controllerManagement.addCancelActionStatus(actionStatus);
|
return controllerManagement.addCancelActionStatus(actionStatus);
|
||||||
@@ -466,7 +464,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) {
|
if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException("Content-Type is not JSON compatible");
|
throw new AmqpRejectAndDontRequeueException("Content-Type is not JSON compatible");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setControllerManagement(final ControllerManagement controllerManagement) {
|
void setControllerManagement(final ControllerManagement controllerManagement) {
|
||||||
|
|||||||
@@ -68,6 +68,29 @@ public class AmqpProperties {
|
|||||||
*/
|
*/
|
||||||
private int initialConcurrentConsumers = 3;
|
private int initialConcurrentConsumers = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of retry attempts when passive queue declaration fails.
|
||||||
|
* Passive queue declaration occurs when the consumer starts or, when
|
||||||
|
* consuming from multiple queues, when not all queues were available during
|
||||||
|
* initialization.
|
||||||
|
*/
|
||||||
|
private int declarationRetries = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the declarationRetries
|
||||||
|
*/
|
||||||
|
public int getDeclarationRetries() {
|
||||||
|
return declarationRetries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param declarationRetries
|
||||||
|
* the declarationRetries to set
|
||||||
|
*/
|
||||||
|
public void setDeclarationRetries(final int declarationRetries) {
|
||||||
|
this.declarationRetries = declarationRetries;
|
||||||
|
}
|
||||||
|
|
||||||
public String getAuthenticationReceiverQueue() {
|
public String getAuthenticationReceiverQueue() {
|
||||||
return authenticationReceiverQueue;
|
return authenticationReceiverQueue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||||
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
|
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||||
|
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link RabbitListenerContainerFactory} that can be configured through
|
||||||
|
* hawkBit's {@link AmqpProperties}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitListenerContainerFactory {
|
||||||
|
private final AmqpProperties amqpProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param rabbitConnectionFactory
|
||||||
|
* for the container factory
|
||||||
|
* @param amqpProperties
|
||||||
|
* to configure the container factory
|
||||||
|
*/
|
||||||
|
public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties,
|
||||||
|
final ConnectionFactory rabbitConnectionFactory) {
|
||||||
|
this.amqpProperties = amqpProperties;
|
||||||
|
setDefaultRequeueRejected(true);
|
||||||
|
setConnectionFactory(rabbitConnectionFactory);
|
||||||
|
setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
||||||
|
setConcurrentConsumers(amqpProperties.getInitialConcurrentConsumers());
|
||||||
|
setMaxConcurrentConsumers(amqpProperties.getMaxConcurrentConsumers());
|
||||||
|
setPrefetchCount(amqpProperties.getPrefetchCount());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
// Exception squid:UnusedProtectedMethod - called by
|
||||||
|
// AbstractRabbitListenerContainerFactory
|
||||||
|
@SuppressWarnings("squid:UnusedProtectedMethod")
|
||||||
|
protected void initializeContainer(final SimpleMessageListenerContainer instance) {
|
||||||
|
super.initializeContainer(instance);
|
||||||
|
instance.setDeclarationRetries(amqpProperties.getDeclarationRetries());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -140,8 +140,8 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final Message message = new Message(new byte[0], messageProperties);
|
final Message message = new Message(new byte[0], messageProperties);
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted due to worng content type");
|
fail("AmqpRejectAndDontRequeueException was excepeted due to worng content type");
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final AmqpRejectAndDontRequeueException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no replyTo header was set");
|
fail("AmqpRejectAndDontRequeueException was excepeted since no replyTo header was set");
|
||||||
} catch (final AmqpRejectAndDontRequeueException exception) {
|
} catch (final AmqpRejectAndDontRequeueException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no thingID was set");
|
fail("AmqpRejectAndDontRequeueException was excepeted since no thingID was set");
|
||||||
} catch (final AmqpRejectAndDontRequeueException exception) {
|
} catch (final AmqpRejectAndDontRequeueException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
}
|
}
|
||||||
@@ -205,7 +205,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, type, TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, type, TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted due to unknown message type");
|
fail("AmqpRejectAndDontRequeueException was excepeted due to unknown message type");
|
||||||
} catch (final AmqpRejectAndDontRequeueException exception) {
|
} catch (final AmqpRejectAndDontRequeueException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
}
|
}
|
||||||
@@ -218,21 +218,21 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final Message message = new Message(new byte[0], messageProperties);
|
final Message message = new Message(new byte[0], messageProperties);
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted due to unknown message type");
|
fail("AmqpRejectAndDontRequeueException was excepeted due to unknown message type");
|
||||||
} catch (final AmqpRejectAndDontRequeueException e) {
|
} catch (final AmqpRejectAndDontRequeueException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
|
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted due to unknown topic");
|
fail("AmqpRejectAndDontRequeueException was excepeted due to unknown topic");
|
||||||
} catch (final AmqpRejectAndDontRequeueException e) {
|
} catch (final AmqpRejectAndDontRequeueException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
|
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted because there was no event topic");
|
fail("AmqpRejectAndDontRequeueException was excepeted because there was no event topic");
|
||||||
} catch (final AmqpRejectAndDontRequeueException exception) {
|
} catch (final AmqpRejectAndDontRequeueException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no action id was set");
|
fail("AmqpRejectAndDontRequeueException was excepeted since no action id was set");
|
||||||
} catch (final AmqpRejectAndDontRequeueException exception) {
|
} catch (final AmqpRejectAndDontRequeueException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no action id was set");
|
fail("AmqpRejectAndDontRequeueException was excepeted since no action id was set");
|
||||||
} catch (final AmqpRejectAndDontRequeueException exception) {
|
} catch (final AmqpRejectAndDontRequeueException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ public class MgmtSystemTenantServiceUsage {
|
|||||||
* @param tenantName
|
* @param tenantName
|
||||||
*/
|
*/
|
||||||
public MgmtSystemTenantServiceUsage(final String tenantName) {
|
public MgmtSystemTenantServiceUsage(final String tenantName) {
|
||||||
super();
|
|
||||||
this.tenantName = tenantName;
|
this.tenantName = tenantName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,17 @@ public class MgmtTargetRequestBody {
|
|||||||
@JsonProperty
|
@JsonProperty
|
||||||
private String address;
|
private String address;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private String securityToken;
|
||||||
|
|
||||||
|
public String getSecurityToken() {
|
||||||
|
return securityToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecurityToken(final String securityToken) {
|
||||||
|
this.securityToken = securityToken;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the name
|
* @return the name
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -182,10 +182,11 @@ public final class MgmtTargetMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Target fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) {
|
static Target fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) {
|
||||||
final Target target = entityFactory.generateTarget(targetRest.getControllerId());
|
final Target target = entityFactory.generateTarget(targetRest.getControllerId(), targetRest.getSecurityToken());
|
||||||
target.setDescription(targetRest.getDescription());
|
target.setDescription(targetRest.getDescription());
|
||||||
target.setName(targetRest.getName());
|
target.setName(targetRest.getName());
|
||||||
target.getTargetInfo().setAddress(targetRest.getAddress());
|
target.getTargetInfo().setAddress(targetRest.getAddress());
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,6 +125,13 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
|
|||||||
if (targetRest.getName() != null) {
|
if (targetRest.getName() != null) {
|
||||||
existingTarget.setName(targetRest.getName());
|
existingTarget.setName(targetRest.getName());
|
||||||
}
|
}
|
||||||
|
if (targetRest.getAddress() != null) {
|
||||||
|
existingTarget.getTargetInfo().setAddress(targetRest.getAddress());
|
||||||
|
}
|
||||||
|
if (targetRest.getSecurityToken() != null) {
|
||||||
|
existingTarget.setSecurityToken(targetRest.getSecurityToken());
|
||||||
|
}
|
||||||
|
|
||||||
final Target updateTarget = this.targetManagement.updateTarget(existingTarget);
|
final Target updateTarget = this.targetManagement.updateTarget(existingTarget);
|
||||||
|
|
||||||
return new ResponseEntity<>(MgmtTargetMapper.toResponse(updateTarget), HttpStatus.OK);
|
return new ResponseEntity<>(MgmtTargetMapper.toResponse(updateTarget), HttpStatus.OK);
|
||||||
|
|||||||
@@ -355,6 +355,54 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Ensures that target update request is reflected by repository.")
|
||||||
|
public void updateTargetSecurityToken() throws Exception {
|
||||||
|
final String knownControllerId = "123";
|
||||||
|
final String knownNewToken = "6567576565";
|
||||||
|
final String knownNameNotModiy = "nameNotModiy";
|
||||||
|
final String body = new JSONObject().put("securityToken", knownNewToken).toString();
|
||||||
|
|
||||||
|
// prepare
|
||||||
|
final Target t = entityFactory.generateTarget(knownControllerId);
|
||||||
|
t.setName(knownNameNotModiy);
|
||||||
|
targetManagement.createTarget(t);
|
||||||
|
|
||||||
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
||||||
|
.andExpect(jsonPath("$.securityToken", equalTo(knownNewToken)))
|
||||||
|
.andExpect(jsonPath("$.name", equalTo(knownNameNotModiy)));
|
||||||
|
|
||||||
|
final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownControllerId);
|
||||||
|
assertThat(findTargetByControllerID.getSecurityToken()).isEqualTo(knownNewToken);
|
||||||
|
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Description("Ensures that target update request is reflected by repository.")
|
||||||
|
public void updateTargetAddress() throws Exception {
|
||||||
|
final String knownControllerId = "123";
|
||||||
|
final String knownNewAddress = "amqp://test123/foobar";
|
||||||
|
final String knownNameNotModiy = "nameNotModiy";
|
||||||
|
final String body = new JSONObject().put("address", knownNewAddress).toString();
|
||||||
|
|
||||||
|
// prepare
|
||||||
|
final Target t = entityFactory.generateTarget(knownControllerId);
|
||||||
|
t.setName(knownNameNotModiy);
|
||||||
|
targetManagement.createTarget(t);
|
||||||
|
|
||||||
|
mvc.perform(put(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownControllerId).content(body)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.controllerId", equalTo(knownControllerId)))
|
||||||
|
.andExpect(jsonPath("$.address", equalTo(knownNewAddress)))
|
||||||
|
.andExpect(jsonPath("$.name", equalTo(knownNameNotModiy)));
|
||||||
|
|
||||||
|
final Target findTargetByControllerID = targetManagement.findTargetByControllerID(knownControllerId);
|
||||||
|
assertThat(findTargetByControllerID.getTargetInfo().getAddress().toString()).isEqualTo(knownNewAddress);
|
||||||
|
assertThat(findTargetByControllerID.getName()).isEqualTo(knownNameNotModiy);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that target query returns list of targets in defined format.")
|
@Description("Ensures that target query returns list of targets in defined format.")
|
||||||
public void getTargetWithoutAddtionalRequestParameters() throws Exception {
|
public void getTargetWithoutAddtionalRequestParameters() throws Exception {
|
||||||
@@ -679,7 +727,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void createTargetsListReturnsSuccessful() throws Exception {
|
public void createTargetsListReturnsSuccessful() throws Exception {
|
||||||
final Target test1 = entityFactory.generateTarget("id1");
|
final Target test1 = entityFactory.generateTarget("id1", "token");
|
||||||
test1.setDescription("testid1");
|
test1.setDescription("testid1");
|
||||||
test1.setName("testname1");
|
test1.setName("testname1");
|
||||||
test1.getTargetInfo().setAddress("amqp://test123/foobar");
|
test1.getTargetInfo().setAddress("amqp://test123/foobar");
|
||||||
@@ -696,7 +744,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
targets.add(test3);
|
targets.add(test3);
|
||||||
|
|
||||||
final MvcResult mvcResult = mvc
|
final MvcResult mvcResult = mvc
|
||||||
.perform(post("/rest/v1/targets/").content(JsonBuilder.targets(targets))
|
.perform(post("/rest/v1/targets/").content(JsonBuilder.targets(targets, true))
|
||||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
@@ -705,6 +753,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
.andExpect(jsonPath("[0].description", equalTo("testid1")))
|
.andExpect(jsonPath("[0].description", equalTo("testid1")))
|
||||||
.andExpect(jsonPath("[0].createdAt", not(equalTo(0))))
|
.andExpect(jsonPath("[0].createdAt", not(equalTo(0))))
|
||||||
.andExpect(jsonPath("[0].createdBy", equalTo("bumlux")))
|
.andExpect(jsonPath("[0].createdBy", equalTo("bumlux")))
|
||||||
|
.andExpect(jsonPath("[0].securityToken", equalTo("token")))
|
||||||
.andExpect(jsonPath("[0].address", equalTo("amqp://test123/foobar")))
|
.andExpect(jsonPath("[0].address", equalTo("amqp://test123/foobar")))
|
||||||
.andExpect(jsonPath("[1].name", equalTo("testname2")))
|
.andExpect(jsonPath("[1].name", equalTo("testname2")))
|
||||||
.andExpect(jsonPath("[1].createdBy", equalTo("bumlux")))
|
.andExpect(jsonPath("[1].createdBy", equalTo("bumlux")))
|
||||||
@@ -731,6 +780,9 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
|
|||||||
assertThat(targetManagement.findTargetByControllerID("id1")).isNotNull();
|
assertThat(targetManagement.findTargetByControllerID("id1")).isNotNull();
|
||||||
assertThat(targetManagement.findTargetByControllerID("id1").getName()).isEqualTo("testname1");
|
assertThat(targetManagement.findTargetByControllerID("id1").getName()).isEqualTo("testname1");
|
||||||
assertThat(targetManagement.findTargetByControllerID("id1").getDescription()).isEqualTo("testid1");
|
assertThat(targetManagement.findTargetByControllerID("id1").getDescription()).isEqualTo("testid1");
|
||||||
|
assertThat(targetManagement.findTargetByControllerID("id1").getSecurityToken()).isEqualTo("token");
|
||||||
|
assertThat(targetManagement.findTargetByControllerID("id1").getTargetInfo().getAddress().toString())
|
||||||
|
.isEqualTo("amqp://test123/foobar");
|
||||||
assertThat(targetManagement.findTargetByControllerID("id2")).isNotNull();
|
assertThat(targetManagement.findTargetByControllerID("id2")).isNotNull();
|
||||||
assertThat(targetManagement.findTargetByControllerID("id2").getName()).isEqualTo("testname2");
|
assertThat(targetManagement.findTargetByControllerID("id2").getName()).isEqualTo("testname2");
|
||||||
assertThat(targetManagement.findTargetByControllerID("id2").getDescription()).isEqualTo("testid2");
|
assertThat(targetManagement.findTargetByControllerID("id2").getDescription()).isEqualTo("testid2");
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import java.util.Map;
|
|||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
|
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
|
||||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||||
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
|
import org.eclipse.hawkbit.repository.exception.ToManyAttributeEntriesException;
|
||||||
@@ -58,16 +58,20 @@ public interface ControllerManagement {
|
|||||||
Action addCancelActionStatus(@NotNull ActionStatus actionStatus);
|
Action addCancelActionStatus(@NotNull ActionStatus actionStatus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the download progress in percentage and notifies the
|
* Sends the download progress and notifies the {@link EventBus} with a
|
||||||
* {@link EventBus} with a {@link DownloadProgressEvent}.
|
* {@link DownloadProgressEvent}.
|
||||||
*
|
*
|
||||||
* @param statusId
|
* @param statusId
|
||||||
* the ID of the {@link ActionStatus}
|
* the ID of the {@link ActionStatus}
|
||||||
* @param progressPercent
|
* @param requestedBytes
|
||||||
* the progress in percentage which must be between 0-100
|
* requested bytes of the request
|
||||||
|
* @param shippedBytesSinceLast
|
||||||
|
* since the last report
|
||||||
|
* @param shippedBytesOverall
|
||||||
|
* for the {@link ActionStatus}
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||||
void downloadProgressPercent(long statusId, int progressPercent);
|
void downloadProgress(Long statusId, Long requestedBytes, Long shippedBytesSinceLast, Long shippedBytesOverall);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple addition of a new {@link ActionStatus} entry to the {@link Action}
|
* Simple addition of a new {@link ActionStatus} entry to the {@link Action}
|
||||||
@@ -75,9 +79,11 @@ public interface ControllerManagement {
|
|||||||
*
|
*
|
||||||
* @param statusMessage
|
* @param statusMessage
|
||||||
* to add to the action
|
* to add to the action
|
||||||
|
*
|
||||||
|
* @return create {@link ActionStatus} entity
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER)
|
||||||
void addInformationalActionStatus(@NotNull ActionStatus statusMessage);
|
ActionStatus addInformationalActionStatus(@NotNull ActionStatus statusMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an {@link ActionStatus} entry for an update {@link Action} including
|
* Adds an {@link ActionStatus} entry for an update {@link Action} including
|
||||||
|
|||||||
@@ -269,8 +269,7 @@ public interface DeploymentManagement {
|
|||||||
* @return the actions referring a specific rollout and a specific parent
|
* @return the actions referring a specific rollout and a specific parent
|
||||||
* rollout group in a specific status
|
* rollout group in a specific status
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
List<Action> findActionsByRolloutGroupParentAndStatus(@NotNull Rollout rollout,
|
List<Action> findActionsByRolloutGroupParentAndStatus(@NotNull Rollout rollout,
|
||||||
@NotNull RolloutGroup rolloutGroupParent, @NotNull Action.Status actionStatus);
|
@NotNull RolloutGroup rolloutGroupParent, @NotNull Action.Status actionStatus);
|
||||||
|
|
||||||
@@ -496,8 +495,7 @@ public interface DeploymentManagement {
|
|||||||
* the action to start now.
|
* the action to start now.
|
||||||
* @return the action which has been started
|
* @return the action which has been started
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
Action startScheduledAction(@NotNull Action action);
|
Action startScheduledAction(@NotNull Action action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -287,6 +287,7 @@ public interface EntityFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an empty {@link Target} without persisting it.
|
* Generates an empty {@link Target} without persisting it.
|
||||||
|
* {@link Target#getSecurityToken()} is generated.
|
||||||
*
|
*
|
||||||
* @param controllerID
|
* @param controllerID
|
||||||
* of the {@link Target}
|
* of the {@link Target}
|
||||||
@@ -295,6 +296,19 @@ public interface EntityFactory {
|
|||||||
*/
|
*/
|
||||||
Target generateTarget(@NotEmpty String controllerID);
|
Target generateTarget(@NotEmpty String controllerID);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an empty {@link Target} without persisting it.
|
||||||
|
*
|
||||||
|
* @param controllerID
|
||||||
|
* of the {@link Target}
|
||||||
|
* @param securityToken
|
||||||
|
* of the {@link Target} for authentication if enabled on tenant.
|
||||||
|
* Generates one if empty or <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return {@link Target} object
|
||||||
|
*/
|
||||||
|
Target generateTarget(@NotEmpty String controllerID, @NotEmpty String securityToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an empty {@link TargetFilterQuery} without persisting it.
|
* Generates an empty {@link TargetFilterQuery} without persisting it.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ public interface RolloutManagement {
|
|||||||
* this check. This check is only applied if the last check is
|
* this check. This check is only applied if the last check is
|
||||||
* less than (lastcheck-delay).
|
* less than (lastcheck-delay).
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
void checkRunningRollouts(long delayBetweenChecks);
|
void checkRunningRollouts(long delayBetweenChecks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -266,8 +265,7 @@ public interface RolloutManagement {
|
|||||||
* if given rollout is not in {@link RolloutStatus#RUNNING}.
|
* if given rollout is not in {@link RolloutStatus#RUNNING}.
|
||||||
* Only running rollouts can be paused.
|
* Only running rollouts can be paused.
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
void pauseRollout(@NotNull Rollout rollout);
|
void pauseRollout(@NotNull Rollout rollout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -281,8 +279,7 @@ public interface RolloutManagement {
|
|||||||
* if given rollout is not in {@link RolloutStatus#PAUSED}. Only
|
* if given rollout is not in {@link RolloutStatus#PAUSED}. Only
|
||||||
* paused rollouts can be resumed.
|
* paused rollouts can be resumed.
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
void resumeRollout(@NotNull Rollout rollout);
|
void resumeRollout(@NotNull Rollout rollout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -303,8 +300,7 @@ public interface RolloutManagement {
|
|||||||
* if given rollout is not in {@link RolloutStatus#READY}. Only
|
* if given rollout is not in {@link RolloutStatus#READY}. Only
|
||||||
* ready rollouts can be started.
|
* ready rollouts can be started.
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
Rollout startRollout(@NotNull Rollout rollout);
|
Rollout startRollout(@NotNull Rollout rollout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -326,8 +322,7 @@ public interface RolloutManagement {
|
|||||||
* if given rollout is not in {@link RolloutStatus#READY}. Only
|
* if given rollout is not in {@link RolloutStatus#READY}. Only
|
||||||
* ready rollouts can be started.
|
* ready rollouts can be started.
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
Rollout startRolloutAsync(@NotNull Rollout rollout);
|
Rollout startRolloutAsync(@NotNull Rollout rollout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,16 +39,14 @@ public interface SystemManagement {
|
|||||||
* @param tenant
|
* @param tenant
|
||||||
* to delete
|
* to delete
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
void deleteTenant(@NotNull String tenant);
|
void deleteTenant(@NotNull String tenant);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @return list of all tenant names in the system.
|
* @return list of all tenant names in the system.
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
List<String> findTenants();
|
List<String> findTenants();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,8 +66,8 @@ public interface SystemManagement {
|
|||||||
/**
|
/**
|
||||||
* Returns {@link TenantMetaData} of given and current tenant. Creates for
|
* Returns {@link TenantMetaData} of given and current tenant. Creates for
|
||||||
* new tenants also two {@link SoftwareModuleType} (os and app) and
|
* new tenants also two {@link SoftwareModuleType} (os and app) and
|
||||||
* {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT} {@link DistributionSetType}s
|
* {@link RepositoryConstants#DEFAULT_DS_TYPES_IN_TENANT}
|
||||||
* (os and os_app).
|
* {@link DistributionSetType}s (os and os_app).
|
||||||
*
|
*
|
||||||
* DISCLAIMER: this variant is used during initial login (where the tenant
|
* DISCLAIMER: this variant is used during initial login (where the tenant
|
||||||
* is not yet in the session). Please user {@link #getTenantMetadata()} for
|
* is not yet in the session). Please user {@link #getTenantMetadata()} for
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ public interface TenantConfigurationManagement {
|
|||||||
* @return <null> if no default value is set and no database value available
|
* @return <null> if no default value is set and no database value available
|
||||||
* or returns the tenant configuration value
|
* or returns the tenant configuration value
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
<T> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(TenantConfigurationKey configurationKey,
|
<T> TenantConfigurationValue<T> buildTenantConfigurationValueByKey(TenantConfigurationKey configurationKey,
|
||||||
Class<T> propertyType, TenantConfiguration tenantConfiguration);
|
Class<T> propertyType, TenantConfiguration tenantConfiguration);
|
||||||
|
|
||||||
@@ -87,8 +86,7 @@ public interface TenantConfigurationManagement {
|
|||||||
* if the property cannot be converted to the given
|
* if the property cannot be converted to the given
|
||||||
* {@code propertyType}
|
* {@code propertyType}
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey);
|
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,8 +112,7 @@ public interface TenantConfigurationManagement {
|
|||||||
* if the property cannot be converted to the given
|
* if the property cannot be converted to the given
|
||||||
* {@code propertyType}
|
* {@code propertyType}
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey,
|
<T> TenantConfigurationValue<T> getConfigurationValue(TenantConfigurationKey configurationKey,
|
||||||
Class<T> propertyType);
|
Class<T> propertyType);
|
||||||
|
|
||||||
@@ -139,7 +136,6 @@ public interface TenantConfigurationManagement {
|
|||||||
* if the property cannot be converted to the given
|
* if the property cannot be converted to the given
|
||||||
* {@code propertyType}
|
* {@code propertyType}
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(value = SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||||
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
|
||||||
<T> T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class<T> propertyType);
|
<T> T getGlobalConfigurationValue(TenantConfigurationKey configurationKey, Class<T> propertyType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,14 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
public interface TenantStatsManagement {
|
public interface TenantStatsManagement {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for stats of a single tenant. Opens a new transaction and as a
|
* Service for stats of the current tenant.
|
||||||
* result can an be used for multiple tenants, i.e. to allow in one session
|
|
||||||
* to collect data of all tenants in the system.
|
|
||||||
*
|
*
|
||||||
* @param tenant
|
|
||||||
* to collect for
|
|
||||||
* @return collected statistics
|
* @return collected statistics
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_SYSTEM_ADMIN)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
TenantUsage getStatsOfTenant(String tenant);
|
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
|
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
|
+ SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||||
|
TenantUsage getStatsOfTenant();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event that contains an updated download progress for a given ActionStatus
|
||||||
|
* that was written for a download request.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DownloadProgressEvent extends AbstractDistributedEvent {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final Long statusId;
|
||||||
|
private final long requestedBytes;
|
||||||
|
private final long shippedBytesSinceLast;
|
||||||
|
private final long shippedBytesOverall;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param tenant
|
||||||
|
* the tenant for this event
|
||||||
|
* @param statusId
|
||||||
|
* of ActionStatus that was written for the download request
|
||||||
|
* @param requestedBytes
|
||||||
|
* bytes requested
|
||||||
|
* @param shippedBytesSinceLast
|
||||||
|
* bytes since last event
|
||||||
|
* @param shippedBytesOverall
|
||||||
|
* on the download request
|
||||||
|
*/
|
||||||
|
public DownloadProgressEvent(final String tenant, final Long statusId, final Long requestedBytes,
|
||||||
|
final Long shippedBytesSinceLast, final Long shippedBytesOverall) {
|
||||||
|
// the revision of the DownloadProgressEvent is just equal the
|
||||||
|
// shippedBytesOverall as this is a growing number.
|
||||||
|
super(shippedBytesOverall, tenant);
|
||||||
|
this.statusId = statusId;
|
||||||
|
this.requestedBytes = requestedBytes;
|
||||||
|
this.shippedBytesSinceLast = shippedBytesSinceLast;
|
||||||
|
this.shippedBytesOverall = shippedBytesOverall;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getStatusId() {
|
||||||
|
return statusId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRequestedBytes() {
|
||||||
|
return requestedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getShippedBytesSinceLast() {
|
||||||
|
return shippedBytesSinceLast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getShippedBytesOverall() {
|
||||||
|
return shippedBytesOverall;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,12 +39,6 @@ public interface Action extends TenantAwareBaseEntity {
|
|||||||
return Status.CANCELING.equals(getStatus()) || Status.CANCELED.equals(getStatus());
|
return Status.CANCELING.equals(getStatus()) || Status.CANCELED.equals(getStatus());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return current {@link Status#DOWNLOAD} progress if known by the update
|
|
||||||
* server.
|
|
||||||
*/
|
|
||||||
int getDownloadProgressPercent();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return current {@link Status} of the {@link Action}.
|
* @return current {@link Status} of the {@link Action}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ public interface ActionStatus extends TenantAwareBaseEntity {
|
|||||||
*/
|
*/
|
||||||
void addMessage(String message);
|
void addMessage(String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return current {@link Status#DOWNLOAD} progress if known by the update
|
||||||
|
* server.
|
||||||
|
*/
|
||||||
|
int getDownloadProgressPercent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of message entries that can be added to the
|
* @return list of message entries that can be added to the
|
||||||
* {@link ActionStatus}.
|
* {@link ActionStatus}.
|
||||||
|
|||||||
@@ -58,4 +58,10 @@ public interface Target extends NamedEntity {
|
|||||||
*/
|
*/
|
||||||
String getSecurityToken();
|
String getSecurityToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param token
|
||||||
|
* new securityToken
|
||||||
|
*/
|
||||||
|
void setSecurityToken(String token);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class TenantUsage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() { // NOSONAR - as this is generated code
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
result = prime * result + (int) (actions ^ (actions >>> 32));
|
result = prime * result + (int) (actions ^ (actions >>> 32));
|
||||||
@@ -118,15 +118,14 @@ public class TenantUsage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) { // NOSONAR - as this is generated
|
public boolean equals(final Object obj) {
|
||||||
// code
|
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getClass() != obj.getClass()) {
|
if (!(obj instanceof TenantUsage)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final TenantUsage other = (TenantUsage) obj;
|
final TenantUsage other = (TenantUsage) obj;
|
||||||
@@ -154,7 +153,7 @@ public class TenantUsage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SystemUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts
|
return "TenantUsage [tenantName=" + tenantName + ", targets=" + targets + ", artifacts=" + artifacts
|
||||||
+ ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]";
|
+ ", actions=" + actions + ", overallArtifactVolumeInBytes=" + overallArtifactVolumeInBytes + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManage
|
|||||||
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
|
||||||
@@ -71,6 +72,8 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General configuration for hawkBit's Repository.
|
* General configuration for hawkBit's Repository.
|
||||||
*
|
*
|
||||||
@@ -85,6 +88,9 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess
|
|||||||
@EnableConfigurationProperties(RepositoryProperties.class)
|
@EnableConfigurationProperties(RepositoryProperties.class)
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
||||||
|
@Autowired
|
||||||
|
private EventBus eventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the {@link SystemSecurityContext} singleton bean which make it
|
* @return the {@link SystemSecurityContext} singleton bean which make it
|
||||||
* accessible in beans which cannot access the service directly,
|
* accessible in beans which cannot access the service directly,
|
||||||
@@ -249,7 +255,9 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public TenantStatsManagement tenantStatsManagement() {
|
public TenantStatsManagement tenantStatsManagement() {
|
||||||
return new JpaTenantStatsManagement();
|
final TenantStatsManagement mgmt = new JpaTenantStatsManagement();
|
||||||
|
eventBus.register(mgmt);
|
||||||
|
return mgmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -451,8 +451,8 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
@Override
|
@Override
|
||||||
@Modifying
|
@Modifying
|
||||||
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
|
||||||
public void addInformationalActionStatus(final ActionStatus statusMessage) {
|
public ActionStatus addInformationalActionStatus(final ActionStatus statusMessage) {
|
||||||
actionStatusRepository.save((JpaActionStatus) statusMessage);
|
return actionStatusRepository.save((JpaActionStatus) statusMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -469,8 +469,9 @@ public class JpaControllerManagement implements ControllerManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void downloadProgressPercent(final long statusId, final int progressPercent) {
|
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
|
||||||
cacheWriteNotify.downloadProgressPercent(statusId, progressPercent);
|
final Long shippedBytesOverall) {
|
||||||
|
cacheWriteNotify.downloadProgress(statusId, requestedBytes, shippedBytesSinceLast, shippedBytesOverall);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus;
|
||||||
@@ -87,6 +88,14 @@ public class JpaEntityFactory implements EntityFactory {
|
|||||||
return new JpaTarget(controllerId);
|
return new JpaTarget(controllerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Target generateTarget(final String controllerId, final String securityToken) {
|
||||||
|
if (StringUtils.isEmpty(securityToken)) {
|
||||||
|
return new JpaTarget(controllerId);
|
||||||
|
}
|
||||||
|
return new JpaTarget(controllerId, securityToken);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TargetTag generateTargetTag() {
|
public TargetTag generateTargetTag() {
|
||||||
return new JpaTargetTag();
|
return new JpaTargetTag();
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
|
|||||||
final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId());
|
final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId());
|
||||||
|
|
||||||
boolean updated = false;
|
boolean updated = false;
|
||||||
if (sm.getDescription() != null && !sm.getDescription().equals(type.getDescription())) {
|
if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) {
|
||||||
type.setDescription(sm.getDescription());
|
type.setDescription(sm.getDescription());
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
||||||
@@ -147,7 +155,7 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
final List<String> tenants = findTenants();
|
final List<String> tenants = findTenants();
|
||||||
|
|
||||||
tenants.forEach(tenant -> tenantAware.runAsTenant(tenant, () -> {
|
tenants.forEach(tenant -> tenantAware.runAsTenant(tenant, () -> {
|
||||||
report.addTenantData(systemStatsManagement.getStatsOfTenant(tenant));
|
report.addTenantData(systemStatsManagement.getStatsOfTenant());
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -159,27 +167,48 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Cacheable(value = "tenantMetadata", key = "#tenant.toUpperCase()")
|
@Cacheable(value = "tenantMetadata", key = "#tenant.toUpperCase()", cacheManager = "directCacheManager")
|
||||||
@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());
|
||||||
@@ -191,7 +220,6 @@ public class JpaSystemManagement implements CurrentTenantCacheKeyGenerator, Syst
|
|||||||
@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);
|
||||||
@@ -226,7 +254,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
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
import org.eclipse.hawkbit.repository.TenantStatsManagement;
|
||||||
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
|
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
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;
|
||||||
@@ -35,9 +35,14 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ActionRepository actionRepository;
|
private ActionRepository actionRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
|
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_UNCOMMITTED)
|
||||||
public TenantUsage getStatsOfTenant(final String tenant) {
|
public TenantUsage getStatsOfTenant() {
|
||||||
|
final String tenant = tenantAware.getCurrentTenant();
|
||||||
|
|
||||||
final TenantUsage result = new TenantUsage(tenant);
|
final TenantUsage result = new TenantUsage(tenant);
|
||||||
|
|
||||||
result.setTargets(targetRepository.count());
|
result.setTargets(targetRepository.count());
|
||||||
|
|||||||
@@ -8,9 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.jpa.cache;
|
package org.eclipse.hawkbit.repository.jpa.cache;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
import java.math.RoundingMode;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||||
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
|
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupCreatedEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
|
||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
@@ -20,6 +21,7 @@ import org.springframework.cache.CacheManager;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
import com.google.common.math.DoubleMath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An service which combines the functionality for functional use cases to write
|
* An service which combines the functionality for functional use cases to write
|
||||||
@@ -30,10 +32,6 @@ import com.google.common.eventbus.EventBus;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class CacheWriteNotify {
|
public class CacheWriteNotify {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final int DOWNLOAD_PROGRESS_MAX = 100;
|
private static final int DOWNLOAD_PROGRESS_MAX = 100;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -46,20 +44,29 @@ public class CacheWriteNotify {
|
|||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* writes the download progress in percentage into the cache
|
* writes the download progress into the cache
|
||||||
* {@link CacheKeys#DOWNLOAD_PROGRESS_PERCENT} and notifies the
|
* {@link CacheKeys#DOWNLOAD_PROGRESS_PERCENT} and notifies the
|
||||||
* {@link EventBus} with a {@link DownloadProgressEvent}.
|
* {@link EventBus} with a {@link DownloadProgressEvent}.
|
||||||
*
|
*
|
||||||
* @param statusId
|
* @param statusId
|
||||||
* the ID of the {@link ActionStatus}
|
* the ID of the {@link ActionStatus}
|
||||||
* @param progressPercent
|
* @param requestedBytes
|
||||||
* the progress in percentage which must be between 0-100
|
* requested bytes of the request
|
||||||
|
* @param shippedBytesSinceLast
|
||||||
|
* since last event
|
||||||
|
* @param shippedBytesOverall
|
||||||
|
* for the download request
|
||||||
*/
|
*/
|
||||||
public void downloadProgressPercent(final long statusId, final int progressPercent) {
|
public void downloadProgress(final Long statusId, final Long requestedBytes, final Long shippedBytesSinceLast,
|
||||||
|
final Long shippedBytesOverall) {
|
||||||
|
|
||||||
final Cache cache = cacheManager.getCache(Action.class.getName());
|
final Cache cache = cacheManager.getCache(ActionStatus.class.getName());
|
||||||
final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId),
|
final String cacheKey = CacheKeys.entitySpecificCacheKey(String.valueOf(statusId),
|
||||||
CacheKeys.DOWNLOAD_PROGRESS_PERCENT);
|
CacheKeys.DOWNLOAD_PROGRESS_PERCENT);
|
||||||
|
|
||||||
|
final int progressPercent = DoubleMath.roundToInt(shippedBytesOverall * 100.0 / requestedBytes,
|
||||||
|
RoundingMode.DOWN);
|
||||||
|
|
||||||
if (progressPercent < DOWNLOAD_PROGRESS_MAX) {
|
if (progressPercent < DOWNLOAD_PROGRESS_MAX) {
|
||||||
cache.put(cacheKey, progressPercent);
|
cache.put(cacheKey, progressPercent);
|
||||||
} else {
|
} else {
|
||||||
@@ -69,7 +76,8 @@ public class CacheWriteNotify {
|
|||||||
cache.evict(cacheKey);
|
cache.evict(cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, progressPercent));
|
eventBus.post(new DownloadProgressEvent(tenantAware.getCurrentTenant(), statusId, requestedBytes,
|
||||||
|
shippedBytesSinceLast, shippedBytesOverall));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ import javax.persistence.NamedEntityGraphs;
|
|||||||
import javax.persistence.NamedSubgraph;
|
import javax.persistence.NamedSubgraph;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Transient;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
|
||||||
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -89,13 +86,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
|||||||
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
|
@JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout"))
|
||||||
private JpaRollout rollout;
|
private JpaRollout rollout;
|
||||||
|
|
||||||
/**
|
|
||||||
* Note: filled only in {@link Status#DOWNLOAD}.
|
|
||||||
*/
|
|
||||||
@Transient
|
|
||||||
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
|
|
||||||
private int downloadProgressPercent;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DistributionSet getDistributionSet() {
|
public DistributionSet getDistributionSet() {
|
||||||
return distributionSet;
|
return distributionSet;
|
||||||
@@ -120,15 +110,6 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
|
|||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getDownloadProgressPercent() {
|
|
||||||
return downloadProgressPercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDownloadProgressPercent(final int downloadProgressPercent) {
|
|
||||||
this.downloadProgressPercent = downloadProgressPercent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return active;
|
return active;
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import javax.persistence.ManyToOne;
|
|||||||
import javax.persistence.NamedAttributeNode;
|
import javax.persistence.NamedAttributeNode;
|
||||||
import javax.persistence.NamedEntityGraph;
|
import javax.persistence.NamedEntityGraph;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Transient;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.cache.CacheField;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
@@ -63,6 +66,13 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
|
|||||||
@Column(name = "detail_message", length = 512)
|
@Column(name = "detail_message", length = 512)
|
||||||
private final List<String> messages = new ArrayList<>();
|
private final List<String> messages = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: filled only in {@link Status#DOWNLOAD}.
|
||||||
|
*/
|
||||||
|
@Transient
|
||||||
|
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
|
||||||
|
private int downloadProgressPercent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link ActionStatus} object.
|
* Creates a new {@link ActionStatus} object.
|
||||||
*
|
*
|
||||||
@@ -105,6 +115,11 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
|
|||||||
// JPA default constructor.
|
// JPA default constructor.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDownloadProgressPercent() {
|
||||||
|
return downloadProgressPercent;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getOccurredAt() {
|
public Long getOccurredAt() {
|
||||||
return occurredAt;
|
return occurredAt;
|
||||||
|
|||||||
@@ -115,9 +115,21 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
|
|||||||
* controller ID of the {@link Target}
|
* controller ID of the {@link Target}
|
||||||
*/
|
*/
|
||||||
public JpaTarget(final String controllerId) {
|
public JpaTarget(final String controllerId) {
|
||||||
|
this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param controllerId
|
||||||
|
* controller ID of the {@link Target}
|
||||||
|
* @param securityToken
|
||||||
|
* for target authentication if enabled
|
||||||
|
*/
|
||||||
|
public JpaTarget(final String controllerId, final String securityToken) {
|
||||||
this.controllerId = controllerId;
|
this.controllerId = controllerId;
|
||||||
setName(controllerId);
|
setName(controllerId);
|
||||||
securityToken = SecurityTokenGeneratorHolder.getInstance().generateToken();
|
this.securityToken = securityToken;
|
||||||
targetInfo = new JpaTargetInfo(this);
|
targetInfo = new JpaTargetInfo(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTargetTag;
|
||||||
import org.eclipse.hawkbit.repository.model.Action.Status;
|
import org.eclipse.hawkbit.repository.model.Action.Status;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Tag;
|
import org.eclipse.hawkbit.repository.model.Tag;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetIdName;
|
import org.eclipse.hawkbit.repository.model.TargetIdName;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetTag;
|
import org.eclipse.hawkbit.repository.model.TargetTag;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Ensures that retrieving the target security is only permitted with the necessary permissions.")
|
@Description("Ensures that retrieving the target security is only permitted with the necessary permissions.")
|
||||||
public void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
|
public void getTargetSecurityTokenOnlyWithCorrectPermission() throws Exception {
|
||||||
final Target createdTarget = targetManagement.createTarget(new JpaTarget("targetWithSecurityToken"));
|
final Target createdTarget = targetManagement.createTarget(new JpaTarget("targetWithSecurityToken", "token"));
|
||||||
|
|
||||||
// retrieve security token only with READ_TARGET_SEC_TOKEN permission
|
// retrieve security token only with READ_TARGET_SEC_TOKEN permission
|
||||||
final String securityTokenWithReadPermission = securityRule.runAs(WithSpringAuthorityRule
|
final String securityTokenWithReadPermission = securityRule.runAs(WithSpringAuthorityRule
|
||||||
@@ -80,7 +80,7 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
return createdTarget.getSecurityToken();
|
return createdTarget.getSecurityToken();
|
||||||
});
|
});
|
||||||
|
|
||||||
assertThat(createdTarget.getSecurityToken()).isNotNull();
|
assertThat(createdTarget.getSecurityToken()).isEqualTo("token");
|
||||||
assertThat(securityTokenWithReadPermission).isNotNull();
|
assertThat(securityTokenWithReadPermission).isNotNull();
|
||||||
assertThat(securityTokenAsSystemCode).isNotNull();
|
assertThat(securityTokenAsSystemCode).isNotNull();
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import static org.mockito.Matchers.eq;
|
|||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.DownloadProgressEvent;
|
import org.eclipse.hawkbit.repository.eventbus.event.DownloadProgressEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -59,15 +59,14 @@ public class CacheWriteNotifyTest {
|
|||||||
@Test
|
@Test
|
||||||
public void downloadgProgressIsCachedAndEventSent() {
|
public void downloadgProgressIsCachedAndEventSent() {
|
||||||
final long knownStatusId = 1;
|
final long knownStatusId = 1;
|
||||||
final int knownPercentage = 23;
|
|
||||||
|
|
||||||
when(cacheManagerMock.getCache(Action.class.getName())).thenReturn(cacheMock);
|
when(cacheManagerMock.getCache(ActionStatus.class.getName())).thenReturn(cacheMock);
|
||||||
when(tenantAwareMock.getCurrentTenant()).thenReturn("default");
|
when(tenantAwareMock.getCurrentTenant()).thenReturn("default");
|
||||||
|
|
||||||
underTest.downloadProgressPercent(knownStatusId, knownPercentage);
|
underTest.downloadProgress(knownStatusId, 500L, 100L, 100L);
|
||||||
|
|
||||||
verify(cacheManagerMock).getCache(eq(Action.class.getName()));
|
verify(cacheManagerMock).getCache(eq(ActionStatus.class.getName()));
|
||||||
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, knownPercentage);
|
verify(cacheMock).put(knownStatusId + "." + CacheKeys.DOWNLOAD_PROGRESS_PERCENT, 20);
|
||||||
verify(eventBusMock).post(any(DownloadProgressEvent.class));
|
verify(eventBusMock).post(any(DownloadProgressEvent.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,14 @@ public class WithSpringAuthorityRule implements TestRule {
|
|||||||
SecurityContextHolder.setContext(oldContext);
|
SecurityContextHolder.setContext(oldContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the current security context.
|
||||||
|
*/
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param callable
|
* @param callable
|
||||||
* @return
|
* @return
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
package org.eclipse.hawkbit.rest.exception;
|
package org.eclipse.hawkbit.rest.exception;
|
||||||
|
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.tomcat.util.http.fileupload.FileUploadException;
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.SpServerRtException;
|
||||||
import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException;
|
import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException;
|
||||||
@@ -27,6 +28,8 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
|
|||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.multipart.MultipartException;
|
import org.springframework.web.multipart.MultipartException;
|
||||||
|
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General controller advice for exception handling.
|
* General controller advice for exception handling.
|
||||||
*/
|
*/
|
||||||
@@ -135,13 +138,8 @@ public class ResponseExceptionHandler {
|
|||||||
|
|
||||||
logRequest(request, ex);
|
logRequest(request, ex);
|
||||||
|
|
||||||
Throwable responseCause = ex;
|
final List<Throwable> throwables = ExceptionUtils.getThrowableList(ex);
|
||||||
|
final Throwable responseCause = Iterables.getLast(throwables);
|
||||||
final Throwable searchForCause = searchForCause(ex, FileUploadException.class);
|
|
||||||
if (searchForCause != null) {
|
|
||||||
responseCause = searchForCause;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ExceptionInfo response = createExceptionInfo(new MultiPartFileUploadException(responseCause));
|
final ExceptionInfo response = createExceptionInfo(new MultiPartFileUploadException(responseCause));
|
||||||
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
@@ -150,19 +148,6 @@ public class ResponseExceptionHandler {
|
|||||||
LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL());
|
LOG.debug("Handling exception {} of request {}", ex.getClass().getName(), request.getRequestURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Throwable searchForCause(final Throwable t, final Class<?> lookFor) {
|
|
||||||
if (t == null || t.getCause() == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Throwable cause = t.getCause();
|
|
||||||
|
|
||||||
if (cause.getClass().equals(lookFor)) {
|
|
||||||
return cause;
|
|
||||||
}
|
|
||||||
return searchForCause(cause, lookFor);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ExceptionInfo createExceptionInfo(final Exception ex) {
|
private ExceptionInfo createExceptionInfo(final Exception ex) {
|
||||||
final ExceptionInfo response = new ExceptionInfo();
|
final ExceptionInfo response = new ExceptionInfo();
|
||||||
response.setMessage(ex.getMessage());
|
response.setMessage(ex.getMessage());
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -87,7 +88,7 @@ public final class RestResourceConversionHelper {
|
|||||||
* @param controllerManagement
|
* @param controllerManagement
|
||||||
* to write progress updates to
|
* to write progress updates to
|
||||||
* @param statusId
|
* @param statusId
|
||||||
* of the UpdateActionStatus
|
* of the {@link ActionStatus}
|
||||||
*
|
*
|
||||||
* @return http code
|
* @return http code
|
||||||
*
|
*
|
||||||
@@ -293,6 +294,7 @@ public final class RestResourceConversionHelper {
|
|||||||
|
|
||||||
long toRead = length;
|
long toRead = length;
|
||||||
boolean toContinue = true;
|
boolean toContinue = true;
|
||||||
|
long shippedSinceLastEvent = 0;
|
||||||
|
|
||||||
while (toContinue) {
|
while (toContinue) {
|
||||||
final int r = from.read(buf);
|
final int r = from.read(buf);
|
||||||
@@ -304,9 +306,11 @@ public final class RestResourceConversionHelper {
|
|||||||
if (toRead > 0) {
|
if (toRead > 0) {
|
||||||
to.write(buf, 0, r);
|
to.write(buf, 0, r);
|
||||||
total += r;
|
total += r;
|
||||||
|
shippedSinceLastEvent += r;
|
||||||
} else {
|
} else {
|
||||||
to.write(buf, 0, (int) toRead + r);
|
to.write(buf, 0, (int) toRead + r);
|
||||||
total += toRead + r;
|
total += toRead + r;
|
||||||
|
shippedSinceLastEvent += toRead + r;
|
||||||
toContinue = false;
|
toContinue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +320,8 @@ public final class RestResourceConversionHelper {
|
|||||||
// every 10 percent an event
|
// every 10 percent an event
|
||||||
if (newPercent == 100 || newPercent > progressPercent + 10) {
|
if (newPercent == 100 || newPercent > progressPercent + 10) {
|
||||||
progressPercent = newPercent;
|
progressPercent = newPercent;
|
||||||
controllerManagement.downloadProgressPercent(statusId, progressPercent);
|
controllerManagement.downloadProgress(statusId, length, shippedSinceLastEvent, total);
|
||||||
|
shippedSinceLastEvent = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -367,11 +367,7 @@ public abstract class JsonBuilder {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public static String targets(final List<Target> targets, final boolean withToken) {
|
||||||
* @param targets
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static String targets(final List<Target> targets) {
|
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
builder.append("[");
|
builder.append("[");
|
||||||
@@ -381,10 +377,12 @@ public abstract class JsonBuilder {
|
|||||||
final String address = target.getTargetInfo().getAddress() != null
|
final String address = target.getTargetInfo().getAddress() != null
|
||||||
? target.getTargetInfo().getAddress().toString() : null;
|
? target.getTargetInfo().getAddress().toString() : null;
|
||||||
|
|
||||||
|
final String token = withToken ? target.getSecurityToken() : null;
|
||||||
|
|
||||||
builder.append(new JSONObject().put("controllerId", target.getControllerId())
|
builder.append(new JSONObject().put("controllerId", target.getControllerId())
|
||||||
.put("description", target.getDescription()).put("name", target.getName()).put("createdAt", "0")
|
.put("description", target.getDescription()).put("name", target.getName()).put("createdAt", "0")
|
||||||
.put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh")
|
.put("updatedAt", "0").put("createdBy", "fghdfkjghdfkjh").put("updatedBy", "fghdfkjghdfkjh")
|
||||||
.put("address", address).toString());
|
.put("address", address).put("securityToken", token).toString());
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -224,8 +224,10 @@ public final class SpPermission {
|
|||||||
/*
|
/*
|
||||||
* Spring security eval expressions.
|
* Spring security eval expressions.
|
||||||
*/
|
*/
|
||||||
private static final String HAS_AUTH_PREFIX = "hasAuthority('";
|
private static final String BRACKET_OPEN = "(";
|
||||||
private static final String HAS_AUTH_SUFFIX = "')";
|
private static final String BRACKET_CLOSE = ")";
|
||||||
|
private static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'";
|
||||||
|
private static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE;
|
||||||
private static final String HAS_AUTH_AND = " and ";
|
private static final String HAS_AUTH_AND = " and ";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -257,99 +259,6 @@ public final class SpPermission {
|
|||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_OR = " or ";
|
public static final String HAS_AUTH_OR = " or ";
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#UPDATE_TARGET}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#SYSTEM_ADMIN}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#READ_TARGET}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#CREATE_TARGET}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#DELETE_TARGET}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#READ_REPOSITORY} and
|
|
||||||
* {@link SpPermission#UPDATE_TARGET}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY
|
|
||||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#CREATE_REPOSITORY}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#DELETE_REPOSITORY}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#READ_REPOSITORY}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#UPDATE_REPOSITORY}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#READ_REPOSITORY} and
|
|
||||||
* {@link SpPermission#READ_TARGET}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = HAS_AUTH_PREFIX + READ_REPOSITORY
|
|
||||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
|
||||||
* context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT
|
|
||||||
+ HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAnyRole expression to check if the spring
|
|
||||||
* context contains the anoynmous role or the controller specific role
|
|
||||||
* {@link SpPermission#CONTROLLER_ROLE}.
|
|
||||||
*/
|
|
||||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
|
||||||
+ "')";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spring security eval hasAuthority expression to check if the spring
|
|
||||||
* context contains the role to allow controllers to download specific
|
|
||||||
* role {@link SpPermission#CONTROLLER_DOWNLOAD_ROLE}.
|
|
||||||
*/
|
|
||||||
public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE
|
|
||||||
+ HAS_AUTH_SUFFIX;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAnyRole expression to check if the spring
|
* Spring security eval hasAnyRole expression to check if the spring
|
||||||
* context contains system code role
|
* context contains system code role
|
||||||
@@ -359,48 +268,168 @@ public final class SpPermission {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#CREATE_REPOSITORY} and
|
* context contains {@link SpPermission#UPDATE_TARGET} or
|
||||||
* {@link SpPermission#CREATE_TARGET}.
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_REPOSITORY
|
public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX
|
||||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX;
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT}
|
* context contains {@link SpPermission#SYSTEM_ADMIN} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#READ_TARGET} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR
|
||||||
|
+ IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#CREATE_TARGET} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#DELETE_TARGET} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#READ_REPOSITORY} and
|
||||||
|
* {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||||
|
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX
|
||||||
|
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#CREATE_REPOSITORY} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#DELETE_REPOSITORY} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#READ_REPOSITORY} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#UPDATE_REPOSITORY} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#READ_REPOSITORY} and
|
||||||
|
* {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||||
|
+ READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX
|
||||||
|
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT
|
||||||
|
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAnyRole expression to check if the spring
|
||||||
|
* context contains the anoynmous role or the controller specific role
|
||||||
|
* {@link SpringEvalExpressions#CONTROLLER_ROLE}.
|
||||||
|
*/
|
||||||
|
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
||||||
|
+ "')";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if the spring
|
||||||
|
* context contains the role to allow controllers to download specific
|
||||||
|
* role {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE}
|
||||||
|
*/
|
||||||
|
public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE
|
||||||
|
+ HAS_AUTH_SUFFIX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#CREATE_REPOSITORY} and
|
||||||
|
* {@link SpPermission#CREATE_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||||
|
+ CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX
|
||||||
|
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
|
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
||||||
+ HAS_AUTH_SUFFIX;
|
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
||||||
* {@link SpPermission#READ_TARGET}
|
* {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = HAS_AUTH_PREFIX
|
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||||
+ ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET
|
+ ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX
|
||||||
+ HAS_AUTH_SUFFIX;;
|
+ BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
||||||
* {@link SpPermission#UPDATE_TARGET}.
|
* {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}.
|
||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = BRACKET_OPEN + HAS_AUTH_PREFIX
|
||||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
+ ROLLOUT_MANAGEMENT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET
|
||||||
|
+ HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#TENANT_CONFIGURATION}
|
* context contains {@link SpPermission#TENANT_CONFIGURATION} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION
|
public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION
|
||||||
+ HAS_AUTH_SUFFIX;
|
+ HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAuthority expression to check if spring
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#SYSTEM_MONITOR}
|
* context contains {@link SpPermission#SYSTEM_MONITOR} or
|
||||||
|
* {@link #IS_SYSTEM_CODE}.
|
||||||
*/
|
*/
|
||||||
public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX;
|
public static final String HAS_AUTH_SYSTEM_MONITOR = HAS_AUTH_PREFIX + SYSTEM_MONITOR + HAS_AUTH_SUFFIX
|
||||||
|
+ HAS_AUTH_OR + IS_SYSTEM_CODE;
|
||||||
|
|
||||||
private SpringEvalExpressions() {
|
private SpringEvalExpressions() {
|
||||||
// utility class
|
// utility class
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
if (delegate != null) {
|
||||||
return delegate.equals(another);
|
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() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@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;
|
||||||
|
|||||||
@@ -200,6 +200,10 @@
|
|||||||
<groupId>org.springframework.security</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
<artifactId>spring-security-web</artifactId>
|
<artifactId>spring-security-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.vaadin</groupId>
|
<groupId>com.vaadin</groupId>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.artifacts.smtable;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
@@ -18,18 +20,17 @@ import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
|||||||
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
|
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
|
||||||
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.SPUIWindowDecorator;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
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.SPUIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
|
||||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
||||||
import org.vaadin.spring.events.EventBus;
|
import org.vaadin.spring.events.EventBus;
|
||||||
|
|
||||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
|
||||||
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.ComboBox;
|
import com.vaadin.ui.ComboBox;
|
||||||
@@ -38,8 +39,6 @@ import com.vaadin.ui.FormLayout;
|
|||||||
import com.vaadin.ui.Label;
|
import com.vaadin.ui.Label;
|
||||||
import com.vaadin.ui.TextArea;
|
import com.vaadin.ui.TextArea;
|
||||||
import com.vaadin.ui.TextField;
|
import com.vaadin.ui.TextField;
|
||||||
import com.vaadin.ui.UI;
|
|
||||||
import com.vaadin.ui.Window;
|
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,8 +65,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
@Autowired
|
@Autowired
|
||||||
private transient EntityFactory entityFactory;
|
private transient EntityFactory entityFactory;
|
||||||
|
|
||||||
private Label mandatoryLabel;
|
|
||||||
|
|
||||||
private TextField nameTextField;
|
private TextField nameTextField;
|
||||||
|
|
||||||
private TextField versionTextField;
|
private TextField versionTextField;
|
||||||
@@ -80,14 +77,20 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
|
|
||||||
private CommonDialogWindow window;
|
private CommonDialogWindow window;
|
||||||
|
|
||||||
private String oldDescriptionValue;
|
|
||||||
|
|
||||||
private String oldVendorValue;
|
|
||||||
|
|
||||||
private Boolean editSwModule = Boolean.FALSE;
|
private Boolean editSwModule = Boolean.FALSE;
|
||||||
|
|
||||||
private Long baseSwModuleId;
|
private Long baseSwModuleId;
|
||||||
|
|
||||||
|
private FormLayout formLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Distribution Add and Edit Window.
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
void init() {
|
||||||
|
createRequiredComponents();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create window for new software module.
|
* Create window for new software module.
|
||||||
*
|
*
|
||||||
@@ -95,11 +98,7 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
* module.
|
* module.
|
||||||
*/
|
*/
|
||||||
public CommonDialogWindow createAddSoftwareModuleWindow() {
|
public CommonDialogWindow createAddSoftwareModuleWindow() {
|
||||||
|
return createUpdateSoftwareModuleWindow(null);
|
||||||
editSwModule = Boolean.FALSE;
|
|
||||||
createRequiredComponents();
|
|
||||||
createWindow();
|
|
||||||
return window;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,17 +109,11 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
* @return reference of {@link com.vaadin.ui.Window} to update software
|
* @return reference of {@link com.vaadin.ui.Window} to update software
|
||||||
* module.
|
* module.
|
||||||
*/
|
*/
|
||||||
public Window createUpdateSoftwareModuleWindow(final Long baseSwModuleId) {
|
public CommonDialogWindow createUpdateSoftwareModuleWindow(final Long baseSwModuleId) {
|
||||||
|
|
||||||
editSwModule = Boolean.TRUE;
|
|
||||||
this.baseSwModuleId = baseSwModuleId;
|
this.baseSwModuleId = baseSwModuleId;
|
||||||
createRequiredComponents();
|
resetComponents();
|
||||||
createWindow();
|
|
||||||
/* populate selected target values to edit. */
|
|
||||||
populateValuesOfSwModule();
|
populateValuesOfSwModule();
|
||||||
nameTextField.setEnabled(false);
|
createWindow();
|
||||||
versionTextField.setEnabled(false);
|
|
||||||
typeComboBox.setEnabled(false);
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,13 +138,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"),
|
ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"),
|
||||||
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||||
descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION);
|
descTextArea.setId(SPUIComponentIdProvider.ADD_SW_MODULE_DESCRIPTION);
|
||||||
addDescriptionTextChangeListener();
|
|
||||||
addVendorTextChangeListener();
|
|
||||||
|
|
||||||
/* Label for mandatory symbol */
|
|
||||||
mandatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
|
||||||
mandatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
|
||||||
mandatoryLabel.addStyleName(ValoTheme.LABEL_SMALL);
|
|
||||||
|
|
||||||
typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true,
|
typeComboBox = SPUIComponentProvider.getComboBox(i18n.get("upload.swmodule.type"), "", "", null, null, true,
|
||||||
null, i18n.get("upload.swmodule.type"));
|
null, i18n.get("upload.swmodule.type"));
|
||||||
@@ -159,46 +145,34 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY);
|
typeComboBox.setStyleName(SPUIDefinitions.COMBO_BOX_SPECIFIC_STYLE + " " + ValoTheme.COMBOBOX_TINY);
|
||||||
typeComboBox.setNewItemsAllowed(Boolean.FALSE);
|
typeComboBox.setNewItemsAllowed(Boolean.FALSE);
|
||||||
typeComboBox.setImmediate(Boolean.TRUE);
|
typeComboBox.setImmediate(Boolean.TRUE);
|
||||||
|
|
||||||
populateTypeNameCombo();
|
populateTypeNameCombo();
|
||||||
|
|
||||||
resetOldValues();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private void populateTypeNameCombo() {
|
private void populateTypeNameCombo() {
|
||||||
typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer(
|
typeComboBox.setContainerDataSource(HawkbitCommonUtil.createLazyQueryContainer(
|
||||||
new BeanQueryFactory<SoftwareModuleTypeBeanQuery>(SoftwareModuleTypeBeanQuery.class)));
|
new BeanQueryFactory<SoftwareModuleTypeBeanQuery>(SoftwareModuleTypeBeanQuery.class)));
|
||||||
typeComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
typeComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetOldValues() {
|
private void resetComponents() {
|
||||||
oldDescriptionValue = null;
|
|
||||||
oldVendorValue = null;
|
vendorTextField.clear();
|
||||||
|
nameTextField.clear();
|
||||||
|
versionTextField.clear();
|
||||||
|
descTextArea.clear();
|
||||||
|
typeComboBox.clear();
|
||||||
|
editSwModule = Boolean.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Build the window content and get an instance of customDialogWindow
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private void createWindow() {
|
private void createWindow() {
|
||||||
|
|
||||||
final Label madatoryStarLabel = new Label("*");
|
final Label madatoryStarLabel = new Label("*");
|
||||||
madatoryStarLabel.setStyleName("v-caption v-required-field-indicator");
|
madatoryStarLabel.setStyleName("v-caption v-required-field-indicator");
|
||||||
madatoryStarLabel.setWidth(null);
|
madatoryStarLabel.setWidth(null);
|
||||||
|
|
||||||
/*
|
|
||||||
* The main layout of the window contains mandatory info, textboxes
|
|
||||||
* (controller Id, name & description) and action buttons layout
|
|
||||||
*/
|
|
||||||
addStyleName("lay-color");
|
addStyleName("lay-color");
|
||||||
setSizeUndefined();
|
setSizeUndefined();
|
||||||
|
|
||||||
final FormLayout formLayout = new FormLayout();
|
formLayout = new FormLayout();
|
||||||
formLayout.addComponent(mandatoryLabel);
|
formLayout.setCaption(null);
|
||||||
formLayout.addComponent(typeComboBox);
|
formLayout.addComponent(typeComboBox);
|
||||||
formLayout.addComponent(nameTextField);
|
formLayout.addComponent(nameTextField);
|
||||||
formLayout.addComponent(versionTextField);
|
formLayout.addComponent(versionTextField);
|
||||||
@@ -207,24 +181,17 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
|
|
||||||
setCompositionRoot(formLayout);
|
setCompositionRoot(formLayout);
|
||||||
|
|
||||||
/* add main layout to the window */
|
window = SPUIWindowDecorator.getWindow(i18n.get("upload.caption.add.new.swmodule"), null,
|
||||||
window = SPUIComponentProvider.getWindow(i18n.get("upload.caption.add.new.swmodule"), null,
|
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), null, null, formLayout, i18n);
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveOrUpdate(), event -> closeThisWindow(), null);
|
|
||||||
window.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
window.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
||||||
nameTextField.focus();
|
|
||||||
|
nameTextField.setEnabled(!editSwModule);
|
||||||
|
versionTextField.setEnabled(!editSwModule);
|
||||||
|
typeComboBox.setEnabled(!editSwModule);
|
||||||
|
|
||||||
|
typeComboBox.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDescriptionTextChangeListener() {
|
|
||||||
descTextArea.addTextChangeListener(event -> window.setSaveButtonEnabled(hasDescriptionChanged(event)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addVendorTextChangeListener() {
|
|
||||||
vendorTextField.addTextChangeListener(event -> window.setSaveButtonEnabled(hasVendorChanged(event)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add new SW module.
|
|
||||||
*/
|
|
||||||
private void addNewBaseSoftware() {
|
private void addNewBaseSoftware() {
|
||||||
final String name = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue());
|
final String name = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue());
|
||||||
final String version = HawkbitCommonUtil.trimAndNullIfEmpty(versionTextField.getValue());
|
final String version = HawkbitCommonUtil.trimAndNullIfEmpty(versionTextField.getValue());
|
||||||
@@ -232,10 +199,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
final String description = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
final String description = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||||
final String type = typeComboBox.getValue() != null ? typeComboBox.getValue().toString() : null;
|
final String type = typeComboBox.getValue() != null ? typeComboBox.getValue().toString() : null;
|
||||||
|
|
||||||
if (!mandatoryCheck(name, version, type)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (HawkbitCommonUtil.isDuplicate(name, version, type)) {
|
if (HawkbitCommonUtil.isDuplicate(name, version, type)) {
|
||||||
uiNotifcation.displayValidationError(
|
uiNotifcation.displayValidationError(
|
||||||
i18n.get("message.duplicate.softwaremodule", new Object[] { name, version }));
|
i18n.get("message.duplicate.softwaremodule", new Object[] { name, version }));
|
||||||
@@ -248,8 +211,6 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
new Object[] { newBaseSoftwareModule.getName() + ":" + newBaseSoftwareModule.getVersion() }));
|
new Object[] { newBaseSoftwareModule.getName() + ":" + newBaseSoftwareModule.getVersion() }));
|
||||||
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.NEW_ENTITY, newBaseSoftwareModule));
|
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.NEW_ENTITY, newBaseSoftwareModule));
|
||||||
}
|
}
|
||||||
// close the window
|
|
||||||
closeThisWindow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,13 +230,16 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
|
|
||||||
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.UPDATED_ENTITY, newSWModule));
|
eventBus.publish(this, new SoftwareModuleEvent(BaseEntityEventType.UPDATED_ENTITY, newSWModule));
|
||||||
}
|
}
|
||||||
closeThisWindow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fill the data of a softwareModule in the content of the window
|
* fill the data of a softwareModule in the content of the window
|
||||||
*/
|
*/
|
||||||
private void populateValuesOfSwModule() {
|
private void populateValuesOfSwModule() {
|
||||||
|
if (baseSwModuleId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
editSwModule = Boolean.TRUE;
|
||||||
final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId);
|
final SoftwareModule swModle = softwareManagement.findSoftwareModuleById(baseSwModuleId);
|
||||||
nameTextField.setValue(swModle.getName());
|
nameTextField.setValue(swModle.getName());
|
||||||
versionTextField.setValue(swModle.getVersion());
|
versionTextField.setValue(swModle.getVersion());
|
||||||
@@ -283,49 +247,10 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
: HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getVendor()));
|
: HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getVendor()));
|
||||||
descTextArea.setValue(swModle.getDescription() == null ? HawkbitCommonUtil.SP_STRING_EMPTY
|
descTextArea.setValue(swModle.getDescription() == null ? HawkbitCommonUtil.SP_STRING_EMPTY
|
||||||
: HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getDescription()));
|
: HawkbitCommonUtil.trimAndNullIfEmpty(swModle.getDescription()));
|
||||||
oldDescriptionValue = descTextArea.getValue();
|
|
||||||
oldVendorValue = vendorTextField.getValue();
|
|
||||||
if (swModle.getType().isDeleted()) {
|
if (swModle.getType().isDeleted()) {
|
||||||
typeComboBox.addItem(swModle.getType().getName());
|
typeComboBox.addItem(swModle.getType().getName());
|
||||||
}
|
}
|
||||||
typeComboBox.setValue(swModle.getType().getName());
|
typeComboBox.setValue(swModle.getType().getName());
|
||||||
window.setSaveButtonEnabled(Boolean.FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to close window.
|
|
||||||
*/
|
|
||||||
private void closeThisWindow() {
|
|
||||||
window.close();
|
|
||||||
UI.getCurrent().removeWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validation check - Mandatory.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* as String
|
|
||||||
* @param version
|
|
||||||
* as version
|
|
||||||
* @return boolena as flag
|
|
||||||
*/
|
|
||||||
private boolean mandatoryCheck(final String name, final String version, final String type) {
|
|
||||||
boolean isValid = true;
|
|
||||||
if (name == null || version == null || type == null) {
|
|
||||||
if (name == null) {
|
|
||||||
nameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
|
||||||
}
|
|
||||||
if (version == null) {
|
|
||||||
versionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
|
||||||
}
|
|
||||||
if (type == null) {
|
|
||||||
typeComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
uiNotifcation.displayValidationError(i18n.get("message.mandatory.check"));
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
return isValid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveOrUpdate() {
|
private void saveOrUpdate() {
|
||||||
@@ -336,12 +261,8 @@ public class SoftwareModuleAddUpdateWindow extends CustomComponent implements Se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasDescriptionChanged(final TextChangeEvent event) {
|
public FormLayout getFormLayout() {
|
||||||
return !(event.getText().equals(oldDescriptionValue) && vendorTextField.getValue().equals(oldVendorValue));
|
return formLayout;
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasVendorChanged(final TextChangeEvent event) {
|
|
||||||
return !(event.getText().equals(oldVendorValue) && descTextArea.getValue().equals(oldDescriptionValue));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ import com.vaadin.ui.UI;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Header of Software module table.
|
* Header of Software module table.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
|
|||||||
@@ -11,13 +11,11 @@ package org.eclipse.hawkbit.ui.artifacts.smtype;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.eclipse.hawkbit.repository.EntityFactory;
|
import org.eclipse.hawkbit.repository.EntityFactory;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent;
|
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent;
|
||||||
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum;
|
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum;
|
||||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants;
|
|
||||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
||||||
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
|
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
@@ -34,12 +32,10 @@ import com.vaadin.data.Property.ValueChangeEvent;
|
|||||||
import com.vaadin.shared.ui.colorpicker.Color;
|
import com.vaadin.shared.ui.colorpicker.Color;
|
||||||
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.Alignment;
|
|
||||||
import com.vaadin.ui.Button.ClickEvent;
|
import com.vaadin.ui.Button.ClickEvent;
|
||||||
import com.vaadin.ui.Label;
|
import com.vaadin.ui.Label;
|
||||||
import com.vaadin.ui.OptionGroup;
|
import com.vaadin.ui.OptionGroup;
|
||||||
import com.vaadin.ui.components.colorpicker.ColorChangeListener;
|
import com.vaadin.ui.components.colorpicker.ColorChangeListener;
|
||||||
import com.vaadin.ui.components.colorpicker.ColorSelector;
|
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,8 +44,7 @@ import com.vaadin.ui.themes.ValoTheme;
|
|||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout {
|
||||||
implements ColorChangeListener, ColorSelector {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -5169398523815919367L;
|
private static final long serialVersionUID = -5169398523815919367L;
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateSoftwareTypeLayout.class);
|
private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateSoftwareTypeLayout.class);
|
||||||
@@ -69,7 +64,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
@Override
|
@Override
|
||||||
protected void addListeners() {
|
protected void addListeners() {
|
||||||
super.addListeners();
|
super.addListeners();
|
||||||
optiongroup.addValueChangeListener(this::createOptionValueChanged);
|
optiongroup.addValueChangeListener(this::optionValueChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -95,7 +90,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
||||||
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "",
|
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TYPE_DESC, false, "",
|
||||||
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||||
|
|
||||||
tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC);
|
tagDesc.setId(SPUIDefinitions.NEW_SOFTWARE_TYPE_DESC);
|
||||||
tagDesc.setImmediate(true);
|
tagDesc.setImmediate(true);
|
||||||
tagDesc.setNullRepresentation("");
|
tagDesc.setNullRepresentation("");
|
||||||
@@ -113,10 +107,8 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createWindow() {
|
protected String getWindowCaption() {
|
||||||
reset();
|
return i18n.get("caption.add.type");
|
||||||
window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null,
|
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,15 +118,16 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
* ValueChangeEvent
|
* ValueChangeEvent
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void createOptionValueChanged(final ValueChangeEvent event) {
|
protected void optionValueChanged(final ValueChangeEvent event) {
|
||||||
|
|
||||||
super.createOptionValueChanged(event);
|
super.optionValueChanged(event);
|
||||||
|
|
||||||
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
||||||
assignOptiongroup.setEnabled(false);
|
assignOptiongroup.setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
assignOptiongroup.setEnabled(true);
|
assignOptiongroup.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
assignOptiongroup.select(singleAssignStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -171,12 +164,11 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
if (null != selectedTypeTag) {
|
if (null != selectedTypeTag) {
|
||||||
tagDesc.setValue(selectedTypeTag.getDescription());
|
tagDesc.setValue(selectedTypeTag.getDescription());
|
||||||
typeKey.setValue(selectedTypeTag.getKey());
|
typeKey.setValue(selectedTypeTag.getKey());
|
||||||
if (selectedTypeTag.getMaxAssignments() == Integer.MAX_VALUE) {
|
if (selectedTypeTag.getMaxAssignments() == 1) {
|
||||||
assignOptiongroup.setValue(multiAssignStr);
|
|
||||||
} else {
|
|
||||||
assignOptiongroup.setValue(singleAssignStr);
|
assignOptiongroup.setValue(singleAssignStr);
|
||||||
|
} else {
|
||||||
|
assignOptiongroup.setValue(multiAssignStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
setColorPickerComponentsColor(selectedTypeTag.getColour());
|
setColorPickerComponentsColor(selectedTypeTag.getColour());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,10 +190,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void save(final ClickEvent event) {
|
protected void save(final ClickEvent event) {
|
||||||
if (!mandatoryValuesPresent()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final SoftwareModuleType existingSMTypeByKey = swTypeManagementService
|
final SoftwareModuleType existingSMTypeByKey = swTypeManagementService
|
||||||
.findSoftwareModuleTypeByKey(typeKey.getValue());
|
.findSoftwareModuleTypeByKey(typeKey.getValue());
|
||||||
final SoftwareModuleType existingSMTypeByName = swTypeManagementService
|
final SoftwareModuleType existingSMTypeByName = swTypeManagementService
|
||||||
@@ -211,7 +199,6 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
createNewSWModuleType();
|
createNewSWModuleType();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
updateSWModuleType(existingSMTypeByName);
|
updateSWModuleType(existingSMTypeByName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,22 +220,14 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
SoftwareModuleType newSWType = entityFactory.generateSoftwareModuleType(typeKeyValue, typeNameValue,
|
SoftwareModuleType newSWType = entityFactory.generateSoftwareModuleType(typeKeyValue, typeNameValue,
|
||||||
typeDescValue, assignNumber);
|
typeDescValue, assignNumber);
|
||||||
newSWType.setColour(colorPicked);
|
newSWType.setColour(colorPicked);
|
||||||
|
|
||||||
if (null != typeDescValue) {
|
|
||||||
newSWType.setDescription(typeDescValue);
|
newSWType.setDescription(typeDescValue);
|
||||||
}
|
|
||||||
|
|
||||||
newSWType.setColour(colorPicked);
|
newSWType.setColour(colorPicked);
|
||||||
|
|
||||||
newSWType = swTypeManagementService.createSoftwareModuleType(newSWType);
|
newSWType = swTypeManagementService.createSoftwareModuleType(newSWType);
|
||||||
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() }));
|
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newSWType.getName() }));
|
||||||
closeWindow();
|
|
||||||
eventBus.publish(this,
|
eventBus.publish(this,
|
||||||
new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType));
|
new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE, newSWType));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey"));
|
uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey"));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,51 +237,15 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout
|
|||||||
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
||||||
if (null != typeNameValue) {
|
if (null != typeNameValue) {
|
||||||
existingType.setName(typeNameValue);
|
existingType.setName(typeNameValue);
|
||||||
|
existingType.setDescription(typeDescValue);
|
||||||
existingType.setDescription(null != typeDescValue ? typeDescValue : null);
|
|
||||||
|
|
||||||
existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()));
|
existingType.setColour(ColorPickerHelper.getColorPickedString(getColorPickerLayout().getSelPreview()));
|
||||||
swTypeManagementService.updateSoftwareModuleType(existingType);
|
swTypeManagementService.updateSoftwareModuleType(existingType);
|
||||||
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() }));
|
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { existingType.getName() }));
|
||||||
closeWindow();
|
|
||||||
eventBus.publish(this,
|
eventBus.publish(this,
|
||||||
new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType));
|
new SoftwareModuleTypeEvent(SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE, existingType));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open color picker on click of preview button. Auto select the color based
|
|
||||||
* on target tag if already selected.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void previewButtonClicked() {
|
|
||||||
if (!tagPreviewBtnClicked) {
|
|
||||||
final String selectedOption = (String) optiongroup.getValue();
|
|
||||||
if (StringUtils.isNotEmpty(selectedOption) && selectedOption.equalsIgnoreCase(updateTypeStr)) {
|
|
||||||
if (null != tagNameComboBox.getValue()) {
|
|
||||||
final SoftwareModuleType typeSelected = swTypeManagementService
|
|
||||||
.findSoftwareModuleTypeByName(tagNameComboBox.getValue().toString());
|
|
||||||
if (null != typeSelected) {
|
|
||||||
getColorPickerLayout().setSelectedColor(typeSelected.getColour() != null
|
|
||||||
? ColorPickerHelper.rgbToColorConverter(typeSelected.getColour())
|
|
||||||
: ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getColorPickerLayout().setSelectedColor(
|
|
||||||
ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor());
|
|
||||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
|
||||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
|
||||||
} else {
|
|
||||||
mainLayout.removeComponent(colorPickerLayout);
|
|
||||||
}
|
|
||||||
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.ui.common.CoordinatesToColor;
|
import org.eclipse.hawkbit.ui.common.CoordinatesToColor;
|
||||||
import org.eclipse.hawkbit.ui.management.tag.SpColorPickerPreview;
|
import org.eclipse.hawkbit.ui.management.tag.SpColorPickerPreview;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
|
|
||||||
import com.vaadin.shared.ui.colorpicker.Color;
|
import com.vaadin.shared.ui.colorpicker.Color;
|
||||||
import com.vaadin.ui.AbstractColorPicker.Coordinates2Color;
|
import com.vaadin.ui.AbstractColorPicker.Coordinates2Color;
|
||||||
@@ -47,6 +48,7 @@ public class ColorPickerLayout extends GridLayout {
|
|||||||
|
|
||||||
setColumns(2);
|
setColumns(2);
|
||||||
setRows(4);
|
setRows(4);
|
||||||
|
setId(SPUIComponentIdProvider.COLOR_PICKER_LAYOUT);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
@@ -71,6 +73,7 @@ public class ColorPickerLayout extends GridLayout {
|
|||||||
colorSelect.setWidth("220px");
|
colorSelect.setWidth("220px");
|
||||||
|
|
||||||
redSlider = createRGBSlider("", "red");
|
redSlider = createRGBSlider("", "red");
|
||||||
|
redSlider.setId(SPUIComponentIdProvider.COLOR_PICKER_RED_SLIDER);
|
||||||
greenSlider = createRGBSlider("", "green");
|
greenSlider = createRGBSlider("", "green");
|
||||||
blueSlider = createRGBSlider("", "blue");
|
blueSlider = createRGBSlider("", "blue");
|
||||||
|
|
||||||
|
|||||||
@@ -10,32 +10,69 @@ package org.eclipse.hawkbit.ui.common;
|
|||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import java.io.Serializable;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import java.util.ArrayList;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleBorderWithIcon;
|
import java.util.Collection;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
|
||||||
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
|
||||||
|
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
|
||||||
|
import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||||
|
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
||||||
|
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.vaadin.data.Container.ItemSetChangeEvent;
|
||||||
|
import com.vaadin.data.Container.ItemSetChangeListener;
|
||||||
|
import com.vaadin.data.Property.ValueChangeEvent;
|
||||||
import com.vaadin.data.Property.ValueChangeListener;
|
import com.vaadin.data.Property.ValueChangeListener;
|
||||||
|
import com.vaadin.data.Validator;
|
||||||
|
import com.vaadin.data.validator.NullValidator;
|
||||||
|
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
||||||
|
import com.vaadin.event.FieldEvents.TextChangeListener;
|
||||||
|
import com.vaadin.event.FieldEvents.TextChangeNotifier;
|
||||||
import com.vaadin.server.FontAwesome;
|
import com.vaadin.server.FontAwesome;
|
||||||
|
import com.vaadin.ui.AbstractComponent;
|
||||||
|
import com.vaadin.ui.AbstractField;
|
||||||
|
import com.vaadin.ui.AbstractLayout;
|
||||||
import com.vaadin.ui.AbstractOrderedLayout;
|
import com.vaadin.ui.AbstractOrderedLayout;
|
||||||
import com.vaadin.ui.Alignment;
|
import com.vaadin.ui.Alignment;
|
||||||
import com.vaadin.ui.Button;
|
import com.vaadin.ui.Button;
|
||||||
import com.vaadin.ui.Button.ClickListener;
|
import com.vaadin.ui.Button.ClickListener;
|
||||||
|
import com.vaadin.ui.CheckBox;
|
||||||
import com.vaadin.ui.Component;
|
import com.vaadin.ui.Component;
|
||||||
|
import com.vaadin.ui.Field;
|
||||||
|
import com.vaadin.ui.GridLayout;
|
||||||
import com.vaadin.ui.HorizontalLayout;
|
import com.vaadin.ui.HorizontalLayout;
|
||||||
|
import com.vaadin.ui.Label;
|
||||||
import com.vaadin.ui.Link;
|
import com.vaadin.ui.Link;
|
||||||
|
import com.vaadin.ui.Table;
|
||||||
import com.vaadin.ui.VerticalLayout;
|
import com.vaadin.ui.VerticalLayout;
|
||||||
import com.vaadin.ui.Window;
|
import com.vaadin.ui.Window;
|
||||||
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Superclass for pop-up-windows including a minimize and close icon in the
|
* Table pop-up-windows including a minimize and close icon in the upper right
|
||||||
* upper right corner and a save and cancel button at the bottom.
|
* corner and a save and cancel button at the bottom. Is not intended to reuse.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CommonDialogWindow extends Window {
|
public class CommonDialogWindow extends Window implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = -1321949234316858703L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final VerticalLayout mainLayout = new VerticalLayout();
|
private final VerticalLayout mainLayout = new VerticalLayout();
|
||||||
|
|
||||||
@@ -57,6 +94,14 @@ public class CommonDialogWindow extends Window {
|
|||||||
|
|
||||||
private final ClickListener cancelButtonClickListener;
|
private final ClickListener cancelButtonClickListener;
|
||||||
|
|
||||||
|
private final ClickListener close = event -> close();
|
||||||
|
|
||||||
|
private final transient Map<Component, Object> orginalValues;
|
||||||
|
|
||||||
|
private final List<AbstractField<?>> allComponents;
|
||||||
|
|
||||||
|
private final I18N i18n;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -72,28 +117,83 @@ public class CommonDialogWindow extends Window {
|
|||||||
* the cancelButtonClickListener
|
* the cancelButtonClickListener
|
||||||
*/
|
*/
|
||||||
public CommonDialogWindow(final String caption, final Component content, final String helpLink,
|
public CommonDialogWindow(final String caption, final Component content, final String helpLink,
|
||||||
final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener) {
|
final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener,
|
||||||
|
final AbstractLayout layout, final I18N i18n) {
|
||||||
checkNotNull(saveButtonClickListener);
|
checkNotNull(saveButtonClickListener);
|
||||||
checkNotNull(cancelButtonClickListener);
|
|
||||||
this.caption = caption;
|
this.caption = caption;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
this.helpLink = helpLink;
|
this.helpLink = helpLink;
|
||||||
this.saveButtonClickListener = saveButtonClickListener;
|
this.saveButtonClickListener = saveButtonClickListener;
|
||||||
this.cancelButtonClickListener = cancelButtonClickListener;
|
this.cancelButtonClickListener = cancelButtonClickListener;
|
||||||
|
this.orginalValues = new HashMap<>();
|
||||||
|
this.allComponents = getAllComponents(layout);
|
||||||
|
this.i18n = i18n;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
super.close();
|
||||||
|
orginalValues.clear();
|
||||||
|
removeListeners();
|
||||||
|
allComponents.clear();
|
||||||
|
this.saveButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeListeners() {
|
||||||
|
for (final AbstractField<?> field : allComponents) {
|
||||||
|
removeTextListener(field);
|
||||||
|
removeValueChangeListener(field);
|
||||||
|
removeItemSetChangeistener(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeItemSetChangeistener(final AbstractField<?> field) {
|
||||||
|
if (!(field instanceof Table)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (final Object listener : field.getListeners(ItemSetChangeEvent.class)) {
|
||||||
|
if (listener instanceof ChangeListener) {
|
||||||
|
((Table) field).removeItemSetChangeListener((ChangeListener) listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTextListener(final AbstractField<?> field) {
|
||||||
|
if (!(field instanceof TextChangeNotifier)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (final Object listener : field.getListeners(TextChangeEvent.class)) {
|
||||||
|
if (listener instanceof ChangeListener) {
|
||||||
|
((TextChangeNotifier) field).removeTextChangeListener((ChangeListener) listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeValueChangeListener(final AbstractField<?> field) {
|
||||||
|
for (final Object listener : field.getListeners(ValueChangeEvent.class)) {
|
||||||
|
if (listener instanceof ChangeListener) {
|
||||||
|
field.removeValueChangeListener((ChangeListener) listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final void init() {
|
private final void init() {
|
||||||
|
|
||||||
if (content instanceof AbstractOrderedLayout) {
|
if (content instanceof AbstractOrderedLayout) {
|
||||||
((AbstractOrderedLayout) content).setSpacing(true);
|
((AbstractOrderedLayout) content).setSpacing(true);
|
||||||
((AbstractOrderedLayout) content).setMargin(true);
|
((AbstractOrderedLayout) content).setMargin(true);
|
||||||
}
|
}
|
||||||
|
if (content instanceof GridLayout) {
|
||||||
|
addStyleName("marginTop");
|
||||||
|
}
|
||||||
|
|
||||||
if (null != content) {
|
if (null != content) {
|
||||||
mainLayout.addComponent(content);
|
mainLayout.addComponent(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createMandatoryLabel();
|
||||||
|
|
||||||
final HorizontalLayout buttonLayout = createActionButtonsLayout();
|
final HorizontalLayout buttonLayout = createActionButtonsLayout();
|
||||||
mainLayout.addComponent(buttonLayout);
|
mainLayout.addComponent(buttonLayout);
|
||||||
mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER);
|
mainLayout.setComponentAlignment(buttonLayout, Alignment.TOP_CENTER);
|
||||||
@@ -104,6 +204,173 @@ public class CommonDialogWindow extends Window {
|
|||||||
center();
|
center();
|
||||||
setModal(true);
|
setModal(true);
|
||||||
addStyleName("fontsize");
|
addStyleName("fontsize");
|
||||||
|
setOrginaleValues();
|
||||||
|
addListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* saves the original values in a Map so we can use them for detecting
|
||||||
|
* changes
|
||||||
|
*/
|
||||||
|
public final void setOrginaleValues() {
|
||||||
|
for (final AbstractField<?> field : allComponents) {
|
||||||
|
Object value = field.getValue();
|
||||||
|
|
||||||
|
if (field instanceof Table) {
|
||||||
|
value = Sets.newHashSet(((Table) field).getContainerDataSource().getItemIds());
|
||||||
|
}
|
||||||
|
orginalValues.put(field, value);
|
||||||
|
}
|
||||||
|
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(null, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void addListeners() {
|
||||||
|
for (final AbstractField<?> field : allComponents) {
|
||||||
|
if (field instanceof TextChangeNotifier) {
|
||||||
|
((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field instanceof Table) {
|
||||||
|
((Table) field).addItemSetChangeListener(new ChangeListener(field));
|
||||||
|
} else {
|
||||||
|
field.addValueChangeListener(new ChangeListener(field));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saveButton.addClickListener(close);
|
||||||
|
cancelButton.addClickListener(close);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSaveButtonEnabledAfterValueChange(final Component currentChangedComponent,
|
||||||
|
final Object newValue) {
|
||||||
|
return isMandatoryFieldNotEmptyAndValid(currentChangedComponent, newValue)
|
||||||
|
&& isValuesChanged(currentChangedComponent, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValuesChanged(final Component currentChangedComponent, final Object newValue) {
|
||||||
|
for (final AbstractField<?> field : allComponents) {
|
||||||
|
Object originalValue = orginalValues.get(field);
|
||||||
|
if (field instanceof CheckBox && originalValue == null) {
|
||||||
|
originalValue = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field);
|
||||||
|
|
||||||
|
if (!isValueEquals(field, originalValue, currentValue)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValueEquals(final AbstractField<?> field, final Object orginalValue, final Object currentValue) {
|
||||||
|
if (Set.class.equals(field.getType())) {
|
||||||
|
return CollectionUtils.isEqualCollection(CollectionUtils.emptyIfNull((Collection<?>) orginalValue),
|
||||||
|
CollectionUtils.emptyIfNull((Collection<?>) currentValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (String.class.equals(field.getType())) {
|
||||||
|
return Objects.equals(Strings.emptyToNull((String) orginalValue),
|
||||||
|
Strings.emptyToNull((String) currentValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Objects.equals(orginalValue, currentValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getCurrentVaue(final Component currentChangedComponent, final Object newValue,
|
||||||
|
final AbstractField<?> field) {
|
||||||
|
Object currentValue = field.getValue();
|
||||||
|
if (field instanceof Table) {
|
||||||
|
currentValue = ((Table) field).getContainerDataSource().getItemIds();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field.equals(currentChangedComponent)) {
|
||||||
|
currentValue = newValue;
|
||||||
|
}
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldMandatoryLabelShown() {
|
||||||
|
for (final AbstractField<?> field : allComponents) {
|
||||||
|
if (field.isRequired()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMandatoryFieldNotEmptyAndValid(final Component currentChangedComponent, final Object newValue) {
|
||||||
|
|
||||||
|
boolean valid = true;
|
||||||
|
final List<AbstractField<?>> requiredComponents = allComponents.stream().filter(field -> field.isRequired())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
requiredComponents.addAll(allComponents.stream().filter(this::hasNullValidator).collect(Collectors.toList()));
|
||||||
|
|
||||||
|
for (final AbstractField field : requiredComponents) {
|
||||||
|
Object value = getCurrentVaue(currentChangedComponent, newValue, field);
|
||||||
|
|
||||||
|
if (String.class.equals(field.getType())) {
|
||||||
|
value = Strings.emptyToNull((String) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Set.class.equals(field.getType())) {
|
||||||
|
value = emptyToNull((Collection<?>) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to loop through the entire loop for validity testing.
|
||||||
|
// Otherwise the UI will only mark the
|
||||||
|
// first field with errors and then stop. If there are several
|
||||||
|
// fields with errors, this is bad.
|
||||||
|
field.setValue(value);
|
||||||
|
if (!field.isValid()) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object emptyToNull(final Collection<?> c) {
|
||||||
|
return (c == null || c.isEmpty()) ? null : c;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasNullValidator(final Component component) {
|
||||||
|
|
||||||
|
if (component instanceof AbstractField<?>) {
|
||||||
|
final AbstractField<?> fieldComponent = (AbstractField<?>) component;
|
||||||
|
for (final Validator validator : fieldComponent.getValidators()) {
|
||||||
|
if (validator instanceof NullValidator) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AbstractField<?>> getAllComponents(final AbstractLayout abstractLayout) {
|
||||||
|
final List<AbstractField<?>> components = new ArrayList<>();
|
||||||
|
|
||||||
|
final Iterator<Component> iterate = abstractLayout.iterator();
|
||||||
|
while (iterate.hasNext()) {
|
||||||
|
final Component c = iterate.next();
|
||||||
|
if (c instanceof AbstractLayout) {
|
||||||
|
components.addAll(getAllComponents((AbstractLayout) c));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c instanceof AbstractField) {
|
||||||
|
components.add((AbstractField<?>) c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c instanceof FlexibleOptionGroupItemComponent) {
|
||||||
|
components.add(((FlexibleOptionGroupItemComponent) c).getOwner());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HorizontalLayout createActionButtonsLayout() {
|
private HorizontalLayout createActionButtonsLayout() {
|
||||||
@@ -111,23 +378,43 @@ public class CommonDialogWindow extends Window {
|
|||||||
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();
|
||||||
|
|
||||||
return buttonsLayout;
|
return buttonsLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createMandatoryLabel() {
|
||||||
|
|
||||||
|
if (!shouldMandatoryLabelShown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Label mandatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
||||||
|
mandatoryLabel.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_TINY);
|
||||||
|
|
||||||
|
if (content instanceof TargetAddUpdateWindowLayout) {
|
||||||
|
((TargetAddUpdateWindowLayout) content).getFormLayout().addComponent(mandatoryLabel);
|
||||||
|
} else if (content instanceof SoftwareModuleAddUpdateWindow) {
|
||||||
|
((SoftwareModuleAddUpdateWindow) content).getFormLayout().addComponent(mandatoryLabel);
|
||||||
|
} else if (content instanceof AbstractCreateUpdateTagLayout) {
|
||||||
|
((AbstractCreateUpdateTagLayout) content).getMainLayout().addComponent(mandatoryLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
mainLayout.addComponent(mandatoryLabel);
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
cancelButton.addClickListener(cancelButtonClickListener);
|
cancelButton.addClickListener(cancelButtonClickListener);
|
||||||
|
}
|
||||||
|
|
||||||
buttonsLayout.addComponent(cancelButton);
|
buttonsLayout.addComponent(cancelButton);
|
||||||
buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT);
|
buttonsLayout.setComponentAlignment(cancelButton, Alignment.MIDDLE_LEFT);
|
||||||
@@ -136,10 +423,10 @@ public class CommonDialogWindow extends Window {
|
|||||||
|
|
||||||
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);
|
||||||
buttonsLayout.addComponent(saveButton);
|
buttonsLayout.addComponent(saveButton);
|
||||||
buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT);
|
buttonsLayout.setComponentAlignment(saveButton, Alignment.MIDDLE_RIGHT);
|
||||||
buttonsLayout.setExpandRatio(saveButton, 1.0F);
|
buttonsLayout.setExpandRatio(saveButton, 1.0F);
|
||||||
@@ -155,16 +442,52 @@ public class CommonDialogWindow extends Window {
|
|||||||
buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT);
|
buttonsLayout.setComponentAlignment(helpLinkComponent, Alignment.MIDDLE_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSaveButtonEnabled(final boolean enabled) {
|
public AbstractComponent getButtonsLayout() {
|
||||||
saveButton.setEnabled(enabled);
|
return this.buttonsLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCancelButtonEnabled(final boolean enabled) {
|
private class ChangeListener implements ValueChangeListener, TextChangeListener, ItemSetChangeListener {
|
||||||
cancelButton.setEnabled(enabled);
|
|
||||||
|
private final Field<?> field;
|
||||||
|
|
||||||
|
public ChangeListener(final Field<?> field) {
|
||||||
|
super();
|
||||||
|
this.field = field;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HorizontalLayout getButtonsLayout() {
|
@Override
|
||||||
return buttonsLayout;
|
public void textChange(final TextChangeEvent event) {
|
||||||
|
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, event.getText()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChange(final ValueChangeEvent event) {
|
||||||
|
saveButton.setEnabled(isSaveButtonEnabledAfterValueChange(field, field.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void containerItemSetChange(final ItemSetChangeEvent event) {
|
||||||
|
if (!(field instanceof Table)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Table table = (Table) field;
|
||||||
|
saveButton.setEnabled(
|
||||||
|
isSaveButtonEnabledAfterValueChange(table, table.getContainerDataSource().getItemIds()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the component manually to the allComponents-List and adds a
|
||||||
|
* ValueChangeListener to it. Necessary in Update Distribution Type as the
|
||||||
|
* CheckBox concerned is an ItemProperty...
|
||||||
|
*
|
||||||
|
* @param component
|
||||||
|
* AbstractField
|
||||||
|
*/
|
||||||
|
public void updateAllComponents(final AbstractField component) {
|
||||||
|
|
||||||
|
allComponents.add(component);
|
||||||
|
component.addValueChangeListener(new ChangeListener(component));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import com.vaadin.ui.Button.ClickEvent;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractFilterMultiButtonClick extends AbstractFilterButtonClickBehaviour {
|
public abstract class AbstractFilterMultiButtonClick extends AbstractFilterButtonClickBehaviour {
|
||||||
|
|
||||||
protected final Set<Button> alreadyClickedButtons = new HashSet<>();
|
private static final long serialVersionUID = 1L;
|
||||||
|
protected final transient Set<Button> alreadyClickedButtons = new HashSet<>();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
|
|||||||
@@ -95,9 +95,6 @@ public abstract class AbstractTable<E extends NamedEntity, I> extends Table {
|
|||||||
if (values == null) {
|
if (values == null) {
|
||||||
values = Collections.emptySet();
|
values = Collections.emptySet();
|
||||||
}
|
}
|
||||||
if (values.contains(null)) {
|
|
||||||
LOG.warn("Null values in table content. How could this happen?");
|
|
||||||
}
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ import com.vaadin.ui.themes.ValoTheme;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class for target/ds tag token layout.
|
* Abstract class for target/ds tag token layout.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractTagToken<T extends BaseEntity> implements Serializable {
|
public abstract class AbstractTagToken<T extends BaseEntity> implements Serializable {
|
||||||
|
|
||||||
@@ -58,9 +54,9 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
|
|||||||
|
|
||||||
protected IndexedContainer container;
|
protected IndexedContainer container;
|
||||||
|
|
||||||
protected final Map<Long, TagData> tagDetails = new HashMap<>();
|
protected final transient Map<Long, TagData> tagDetails = new HashMap<>();
|
||||||
|
|
||||||
protected final Map<Long, TagData> tokensAdded = new HashMap<>();
|
protected final transient Map<Long, TagData> tokensAdded = new HashMap<>();
|
||||||
|
|
||||||
protected CssLayout tokenLayout = new CssLayout();
|
protected CssLayout tokenLayout = new CssLayout();
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import java.util.Map;
|
|||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
|
||||||
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator;
|
import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator;
|
import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator;
|
||||||
@@ -33,10 +32,8 @@ import com.vaadin.server.FontAwesome;
|
|||||||
import com.vaadin.server.Resource;
|
import com.vaadin.server.Resource;
|
||||||
import com.vaadin.shared.ui.label.ContentMode;
|
import com.vaadin.shared.ui.label.ContentMode;
|
||||||
import com.vaadin.ui.Button;
|
import com.vaadin.ui.Button;
|
||||||
import com.vaadin.ui.Button.ClickListener;
|
|
||||||
import com.vaadin.ui.CheckBox;
|
import com.vaadin.ui.CheckBox;
|
||||||
import com.vaadin.ui.ComboBox;
|
import com.vaadin.ui.ComboBox;
|
||||||
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;
|
||||||
import com.vaadin.ui.Link;
|
import com.vaadin.ui.Link;
|
||||||
@@ -140,24 +137,6 @@ public final class SPUIComponentProvider {
|
|||||||
return SPUILabelDecorator.getDeocratedLabel(name, type);
|
return SPUILabelDecorator.getDeocratedLabel(name, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get window component.
|
|
||||||
*
|
|
||||||
* @param caption
|
|
||||||
* window caption
|
|
||||||
* @param id
|
|
||||||
* window id
|
|
||||||
* @param type
|
|
||||||
* type of window
|
|
||||||
* @return Window
|
|
||||||
*/
|
|
||||||
public static CommonDialogWindow getWindow(final String caption, final String id, final String type,
|
|
||||||
final Component content, final ClickListener saveButtonClickListener,
|
|
||||||
final ClickListener cancelButtonClickListener, final String helpLink) {
|
|
||||||
return SPUIWindowDecorator.getDeocratedWindow(caption, id, type, content, saveButtonClickListener,
|
|
||||||
cancelButtonClickListener, helpLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get window component.
|
* Get window component.
|
||||||
*
|
*
|
||||||
@@ -204,6 +183,8 @@ public final class SPUIComponentProvider {
|
|||||||
/**
|
/**
|
||||||
* Get Label UI component. *
|
* Get Label UI component. *
|
||||||
*
|
*
|
||||||
|
* @param caption
|
||||||
|
* set the caption of the textArea
|
||||||
* @param style
|
* @param style
|
||||||
* set style
|
* set style
|
||||||
* @param styleName
|
* @param styleName
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -9,9 +9,11 @@
|
|||||||
package org.eclipse.hawkbit.ui.decorators;
|
package org.eclipse.hawkbit.ui.decorators;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
||||||
|
|
||||||
|
import com.vaadin.ui.AbstractLayout;
|
||||||
import com.vaadin.ui.Button.ClickListener;
|
import com.vaadin.ui.Button.ClickListener;
|
||||||
import com.vaadin.ui.Component;
|
import com.vaadin.ui.Component;
|
||||||
import com.vaadin.ui.Window;
|
import com.vaadin.ui.Window;
|
||||||
@@ -42,12 +44,13 @@ public final class SPUIWindowDecorator {
|
|||||||
* window type
|
* window type
|
||||||
* @return Window
|
* @return Window
|
||||||
*/
|
*/
|
||||||
public static CommonDialogWindow getDeocratedWindow(final String caption, final String id, final String type,
|
public static CommonDialogWindow getWindow(final String caption, final String id, final String type,
|
||||||
final Component content, final ClickListener saveButtonClickListener,
|
final Component content, final ClickListener saveButtonClickListener,
|
||||||
final ClickListener cancelButtonClickListener, final String helpLink) {
|
final ClickListener cancelButtonClickListener, final String helpLink, final AbstractLayout layout,
|
||||||
|
final I18N i18n) {
|
||||||
|
|
||||||
final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener,
|
final CommonDialogWindow window = new CommonDialogWindow(caption, content, helpLink, saveButtonClickListener,
|
||||||
cancelButtonClickListener);
|
cancelButtonClickListener, layout, i18n);
|
||||||
if (null != id) {
|
if (null != id) {
|
||||||
window.setId(id);
|
window.setId(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.ui.distributions.disttype;
|
package org.eclipse.hawkbit.ui.distributions.disttype;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||||
@@ -16,7 +17,6 @@ import org.eclipse.hawkbit.repository.EntityFactory;
|
|||||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
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.ui.colorpicker.ColorPickerConstants;
|
|
||||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
||||||
import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery;
|
import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
@@ -49,8 +49,6 @@ import com.vaadin.ui.Component;
|
|||||||
import com.vaadin.ui.HorizontalLayout;
|
import com.vaadin.ui.HorizontalLayout;
|
||||||
import com.vaadin.ui.Table;
|
import com.vaadin.ui.Table;
|
||||||
import com.vaadin.ui.VerticalLayout;
|
import com.vaadin.ui.VerticalLayout;
|
||||||
import com.vaadin.ui.components.colorpicker.ColorChangeListener;
|
|
||||||
import com.vaadin.ui.components.colorpicker.ColorSelector;
|
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,8 +56,7 @@ import com.vaadin.ui.themes.ValoTheme;
|
|||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout {
|
||||||
implements ColorChangeListener, ColorSelector {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -5169398523815877767L;
|
private static final long serialVersionUID = -5169398523815877767L;
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateDistSetTypeLayout.class);
|
private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateDistSetTypeLayout.class);
|
||||||
@@ -82,8 +79,12 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
private Table sourceTable;
|
private Table sourceTable;
|
||||||
private Table selectedTable;
|
private Table selectedTable;
|
||||||
|
|
||||||
private IndexedContainer selectedTablecontainer;
|
private IndexedContainer selectedTableContainer;
|
||||||
private IndexedContainer sourceTablecontainer;
|
private IndexedContainer sourceTableContainer;
|
||||||
|
|
||||||
|
private IndexedContainer originalSelectedTableContainer;
|
||||||
|
|
||||||
|
private Map<CheckBox, Boolean> mandatoryCheckboxMap;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void createRequiredComponents() {
|
protected void createRequiredComponents() {
|
||||||
@@ -103,7 +104,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
||||||
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "",
|
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.DIST_SET_TYPE_DESC, false, "",
|
||||||
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||||
|
|
||||||
tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC);
|
tagDesc.setId(SPUIDefinitions.NEW_DISTRIBUTION_TYPE_DESC);
|
||||||
tagDesc.setImmediate(true);
|
tagDesc.setImmediate(true);
|
||||||
tagDesc.setNullRepresentation("");
|
tagDesc.setNullRepresentation("");
|
||||||
@@ -159,9 +159,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
return twinColumnLayout;
|
return twinColumnLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private void buildSelectedTable() {
|
private void buildSelectedTable() {
|
||||||
|
|
||||||
selectedTable = new Table();
|
selectedTable = new Table();
|
||||||
@@ -176,13 +173,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
selectedTable.addStyleName("dist_type_twin-table");
|
selectedTable.addStyleName("dist_type_twin-table");
|
||||||
selectedTable.setSizeFull();
|
selectedTable.setSizeFull();
|
||||||
createSelectedTableContainer();
|
createSelectedTableContainer();
|
||||||
selectedTable.setContainerDataSource(selectedTablecontainer);
|
selectedTable.setContainerDataSource(selectedTableContainer);
|
||||||
addTooltTipToSelectedTable();
|
addTooltTipToSelectedTable();
|
||||||
selectedTable.setImmediate(true);
|
selectedTable.setImmediate(true);
|
||||||
selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY);
|
selectedTable.setVisibleColumns(DIST_TYPE_NAME, DIST_TYPE_MANDATORY);
|
||||||
selectedTable.setColumnHeaders(i18n.get("header.dist.twintable.selected"), STAR);
|
selectedTable.setColumnHeaders(i18n.get("header.dist.twintable.selected"), STAR);
|
||||||
selectedTable.setColumnExpandRatio(DIST_TYPE_NAME, 0.75f);
|
selectedTable.setColumnExpandRatio(DIST_TYPE_NAME, 0.75F);
|
||||||
selectedTable.setColumnExpandRatio(DIST_TYPE_MANDATORY, 0.25f);
|
selectedTable.setColumnExpandRatio(DIST_TYPE_MANDATORY, 0.25F);
|
||||||
|
selectedTable.setRequired(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTooltTipToSelectedTable() {
|
private void addTooltTipToSelectedTable() {
|
||||||
@@ -218,14 +216,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
sourceTable.addStyleName(ValoTheme.TABLE_NO_VERTICAL_LINES);
|
||||||
sourceTable.addStyleName(ValoTheme.TABLE_SMALL);
|
sourceTable.addStyleName(ValoTheme.TABLE_SMALL);
|
||||||
sourceTable.setImmediate(true);
|
sourceTable.setImmediate(true);
|
||||||
// sourceTable
|
|
||||||
sourceTable.setSizeFull();
|
sourceTable.setSizeFull();
|
||||||
sourceTable.addStyleName("dist_type_twin-table");
|
sourceTable.addStyleName("dist_type_twin-table");
|
||||||
sourceTable.setSortEnabled(false);
|
sourceTable.setSortEnabled(false);
|
||||||
sourceTablecontainer = new IndexedContainer();
|
sourceTableContainer = new IndexedContainer();
|
||||||
sourceTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
sourceTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||||
sourceTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
sourceTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||||
sourceTable.setContainerDataSource(sourceTablecontainer);
|
sourceTable.setContainerDataSource(sourceTableContainer);
|
||||||
|
|
||||||
sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME });
|
sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME });
|
||||||
sourceTable.setColumnHeaders(i18n.get("header.dist.twintable.available"));
|
sourceTable.setColumnHeaders(i18n.get("header.dist.twintable.available"));
|
||||||
@@ -237,44 +234,54 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
|
|
||||||
private void createSelectedTableContainer() {
|
private void createSelectedTableContainer() {
|
||||||
|
|
||||||
selectedTablecontainer = new IndexedContainer();
|
selectedTableContainer = new IndexedContainer();
|
||||||
selectedTablecontainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
selectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||||
selectedTablecontainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
selectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||||
selectedTablecontainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null);
|
selectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createOriginalSelectedTableContainer() {
|
||||||
|
|
||||||
|
originalSelectedTableContainer = new IndexedContainer();
|
||||||
|
originalSelectedTableContainer.addContainerProperty(DIST_TYPE_NAME, String.class, "");
|
||||||
|
originalSelectedTableContainer.addContainerProperty(DIST_TYPE_DESCRIPTION, String.class, "");
|
||||||
|
originalSelectedTableContainer.addContainerProperty(DIST_TYPE_MANDATORY, CheckBox.class, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void addSMType() {
|
private void addSMType() {
|
||||||
|
|
||||||
final Set<Long> selectedIds = (Set<Long>) sourceTable.getValue();
|
final Set<Long> selectedIds = (Set<Long>) sourceTable.getValue();
|
||||||
if (null != selectedIds && !selectedIds.isEmpty()) {
|
if (selectedIds == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (final Long id : selectedIds) {
|
for (final Long id : selectedIds) {
|
||||||
addTargetTableData(id);
|
addTargetTableData(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void removeSMType() {
|
private void removeSMType() {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
final Set<Long> selectedIds = (Set<Long>) selectedTable.getValue();
|
final Set<Long> selectedIds = (Set<Long>) selectedTable.getValue();
|
||||||
if (null != selectedIds && !selectedIds.isEmpty()) {
|
if (selectedIds == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (final Long id : selectedIds) {
|
for (final Long id : selectedIds) {
|
||||||
addSourceTableData(id);
|
addSourceTableData(id);
|
||||||
selectedTable.removeItem(id);
|
selectedTable.removeItem(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void getSourceTableData() {
|
private void getSourceTableData() {
|
||||||
|
|
||||||
sourceTablecontainer.removeAllItems();
|
sourceTableContainer.removeAllItems();
|
||||||
final Iterable<SoftwareModuleType> moduleTypeBeans = softwareManagement
|
final Iterable<SoftwareModuleType> moduleTypeBeans = softwareManagement
|
||||||
.findSoftwareModuleTypesAll(new PageRequest(0, 1_000));
|
.findSoftwareModuleTypesAll(new PageRequest(0, 1_000));
|
||||||
Item saveTblitem;
|
Item saveTblitem;
|
||||||
for (final SoftwareModuleType swTypeTag : moduleTypeBeans) {
|
for (final SoftwareModuleType swTypeTag : moduleTypeBeans) {
|
||||||
saveTblitem = sourceTablecontainer.addItem(swTypeTag.getId());
|
saveTblitem = sourceTableContainer.addItem(swTypeTag.getId());
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName());
|
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swTypeTag.getName());
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription());
|
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(swTypeTag.getDescription());
|
||||||
}
|
}
|
||||||
@@ -307,11 +314,13 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
private void getSelectedTableItemData(final Long id) {
|
private void getSelectedTableItemData(final Long id) {
|
||||||
|
|
||||||
Item saveTblitem;
|
Item saveTblitem;
|
||||||
if (null != selectedTablecontainer) {
|
if (selectedTableContainer != null) {
|
||||||
saveTblitem = selectedTablecontainer.addItem(id);
|
saveTblitem = selectedTableContainer.addItem(id);
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(
|
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(
|
||||||
sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue());
|
sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_NAME).getValue());
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox());
|
final CheckBox mandatoryCheckBox = new CheckBox();
|
||||||
|
window.updateAllComponents(mandatoryCheckBox);
|
||||||
|
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckBox);
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(
|
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(
|
||||||
sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue());
|
sourceTable.getContainerDataSource().getItem(id).getItemProperty(DIST_TYPE_DESCRIPTION).getValue());
|
||||||
}
|
}
|
||||||
@@ -320,10 +329,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void addSourceTableData(final Long selectedId) {
|
private void addSourceTableData(final Long selectedId) {
|
||||||
|
|
||||||
if (null != sourceTablecontainer) {
|
if (sourceTableContainer != null) {
|
||||||
Item saveTblitem;
|
Item saveTblitem;
|
||||||
saveTblitem = sourceTablecontainer.addItem(selectedId);
|
saveTblitem = sourceTableContainer.addItem(selectedId);
|
||||||
selectedTable.getContainerDataSource().getItem(selectedId).getItemProperty(DIST_TYPE_NAME);
|
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource()
|
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(selectedTable.getContainerDataSource()
|
||||||
.getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue());
|
.getItem(selectedId).getItemProperty(DIST_TYPE_NAME).getValue());
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource()
|
saveTblitem.getItemProperty(DIST_TYPE_DESCRIPTION).setValue(selectedTable.getContainerDataSource()
|
||||||
@@ -353,20 +361,14 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
final SoftwareModuleType swModuleType = softwareManagement.findSoftwareModuleTypeByName(distTypeName);
|
final SoftwareModuleType swModuleType = softwareManagement.findSoftwareModuleTypeByName(distTypeName);
|
||||||
checkMandatoryAndAddMandatoryModuleType(newDistType, isMandatory, swModuleType);
|
checkMandatoryAndAddMandatoryModuleType(newDistType, isMandatory, swModuleType);
|
||||||
}
|
}
|
||||||
if (null != typeDescValue) {
|
|
||||||
newDistType.setDescription(typeDescValue);
|
newDistType.setDescription(typeDescValue);
|
||||||
}
|
|
||||||
|
|
||||||
newDistType.setColour(colorPicked);
|
newDistType.setColour(colorPicked);
|
||||||
newDistType = distributionSetManagement.createDistributionSetType(newDistType);
|
newDistType = distributionSetManagement.createDistributionSetType(newDistType);
|
||||||
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() }));
|
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { newDistType.getName() }));
|
||||||
closeWindow();
|
|
||||||
eventBus.publish(this,
|
eventBus.publish(this,
|
||||||
new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType));
|
new DistributionSetTypeEvent(DistributionSetTypeEnum.ADD_DIST_SET_TYPE, newDistType));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey"));
|
uiNotification.displayValidationError(i18n.get("message.error.missing.typenameorkey"));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,7 +388,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
if (null != typeNameValue) {
|
if (null != typeNameValue) {
|
||||||
updateDistSetType.setName(typeNameValue);
|
updateDistSetType.setName(typeNameValue);
|
||||||
updateDistSetType.setKey(typeKeyValue);
|
updateDistSetType.setKey(typeKeyValue);
|
||||||
updateDistSetType.setDescription(null != typeDescValue ? typeDescValue : null);
|
updateDistSetType.setDescription(typeDescValue);
|
||||||
|
|
||||||
if (distributionSetManagement.countDistributionSetsByType(existingType) <= 0 && null != itemIds
|
if (distributionSetManagement.countDistributionSetsByType(existingType) <= 0 && null != itemIds
|
||||||
&& !itemIds.isEmpty()) {
|
&& !itemIds.isEmpty()) {
|
||||||
@@ -404,21 +406,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
distributionSetManagement.updateDistributionSetType(updateDistSetType);
|
distributionSetManagement.updateDistributionSetType(updateDistSetType);
|
||||||
uiNotification
|
uiNotification
|
||||||
.displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() }));
|
.displaySuccess(i18n.get("message.update.success", new Object[] { updateDistSetType.getName() }));
|
||||||
closeWindow();
|
|
||||||
eventBus.publish(this,
|
eventBus.publish(this,
|
||||||
new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType));
|
new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType,
|
private void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType,
|
||||||
final Boolean isMandatory, final SoftwareModuleType swModuleType) {
|
final Boolean isMandatory, final SoftwareModuleType swModuleType) {
|
||||||
if (isMandatory) {
|
if (isMandatory) {
|
||||||
updateDistSetType.addMandatoryModuleType(swModuleType);
|
updateDistSetType.addMandatoryModuleType(swModuleType);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
updateDistSetType.addOptionalModuleType(swModuleType);
|
updateDistSetType.addOptionalModuleType(swModuleType);
|
||||||
}
|
}
|
||||||
@@ -440,32 +438,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
return distSetType;
|
return distSetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see com.vaadin.ui.components.colorpicker.HasColorChangeListener#
|
|
||||||
* addColorChangeListener(com.vaadin
|
|
||||||
* .ui.components.colorpicker.ColorChangeListener)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void addColorChangeListener(final ColorChangeListener listener) {
|
|
||||||
|
|
||||||
LOG.info("in side addColorChangeListener() ");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see com.vaadin.ui.components.colorpicker.HasColorChangeListener#
|
|
||||||
* removeColorChangeListener(com.
|
|
||||||
* vaadin.ui.components.colorpicker.ColorChangeListener)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void removeColorChangeListener(final ColorChangeListener listener) {
|
|
||||||
|
|
||||||
LOG.info("in side removeColorChangeListener() ");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reset the components.
|
* reset the components.
|
||||||
*/
|
*/
|
||||||
@@ -484,9 +456,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
* ValueChangeEvent
|
* ValueChangeEvent
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void createOptionValueChanged(final ValueChangeEvent event) {
|
protected void optionValueChanged(final ValueChangeEvent event) {
|
||||||
|
|
||||||
super.createOptionValueChanged(event);
|
super.optionValueChanged(event);
|
||||||
|
|
||||||
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
||||||
selectedTable.getContainerDataSource().removeAllItems();
|
selectedTable.getContainerDataSource().removeAllItems();
|
||||||
@@ -552,18 +524,17 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
if (null != selectedTypeTag) {
|
if (null != selectedTypeTag) {
|
||||||
tagDesc.setValue(selectedTypeTag.getDescription());
|
tagDesc.setValue(selectedTypeTag.getDescription());
|
||||||
typeKey.setValue(selectedTypeTag.getKey());
|
typeKey.setValue(selectedTypeTag.getKey());
|
||||||
|
|
||||||
if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) {
|
if (distributionSetManagement.countDistributionSetsByType(selectedTypeTag) <= 0) {
|
||||||
distTypeSelectLayout.setEnabled(true);
|
distTypeSelectLayout.setEnabled(true);
|
||||||
selectedTable.setEnabled(true);
|
selectedTable.setEnabled(true);
|
||||||
window.setSaveButtonEnabled(true);
|
|
||||||
} else {
|
} else {
|
||||||
uiNotification.displayValidationError(
|
uiNotification.displayValidationError(
|
||||||
selectedTypeTag.getName() + " " + i18n.get("message.error.dist.set.type.update"));
|
selectedTypeTag.getName() + " " + i18n.get("message.error.dist.set.type.update"));
|
||||||
distTypeSelectLayout.setEnabled(false);
|
distTypeSelectLayout.setEnabled(false);
|
||||||
selectedTable.setEnabled(false);
|
selectedTable.setEnabled(false);
|
||||||
window.setSaveButtonEnabled(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createOriginalSelectedTableContainer();
|
||||||
for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) {
|
for (final SoftwareModuleType swModuleType : selectedTypeTag.getOptionalModuleTypes()) {
|
||||||
addTargetTableforUpdate(swModuleType, false);
|
addTargetTableforUpdate(swModuleType, false);
|
||||||
}
|
}
|
||||||
@@ -583,19 +554,25 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) {
|
private void addTargetTableforUpdate(final SoftwareModuleType swModuleType, final boolean mandatory) {
|
||||||
|
|
||||||
Item saveTblitem;
|
if (selectedTableContainer == null) {
|
||||||
if (null != selectedTablecontainer) {
|
return;
|
||||||
saveTblitem = selectedTablecontainer.addItem(swModuleType.getId());
|
}
|
||||||
|
final Item saveTblitem = selectedTableContainer.addItem(swModuleType.getId());
|
||||||
sourceTable.removeItem(swModuleType.getId());
|
sourceTable.removeItem(swModuleType.getId());
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName());
|
saveTblitem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName());
|
||||||
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(new CheckBox("", mandatory));
|
final CheckBox mandatoryCheckbox = new CheckBox("", mandatory);
|
||||||
}
|
mandatoryCheckbox.setId(swModuleType.getName());
|
||||||
|
saveTblitem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox);
|
||||||
|
|
||||||
|
final Item originalItem = originalSelectedTableContainer.addItem(swModuleType.getId());
|
||||||
|
originalItem.getItemProperty(DIST_TYPE_NAME).setValue(swModuleType.getName());
|
||||||
|
originalItem.getItemProperty(DIST_TYPE_MANDATORY).setValue(mandatoryCheckbox);
|
||||||
|
|
||||||
|
window.updateAllComponents(mandatoryCheckbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void save(final ClickEvent event) {
|
protected void save(final ClickEvent event) {
|
||||||
|
|
||||||
if (mandatoryValuesPresent()) {
|
|
||||||
final DistributionSetType existingDistTypeByKey = distributionSetManagement
|
final DistributionSetType existingDistTypeByKey = distributionSetManagement
|
||||||
.findDistributionSetTypeByKey(typeKey.getValue());
|
.findDistributionSetTypeByKey(typeKey.getValue());
|
||||||
final DistributionSetType existingDistTypeByName = distributionSetManagement
|
final DistributionSetType existingDistTypeByName = distributionSetManagement
|
||||||
@@ -608,40 +585,10 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout
|
|||||||
updateDistributionSetType(existingDistTypeByKey);
|
updateDistributionSetType(existingDistTypeByKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createWindow() {
|
protected String getWindowCaption() {
|
||||||
reset();
|
return i18n.get("caption.add.type");
|
||||||
window = SPUIComponentProvider.getWindow(i18n.get("caption.add.type"), null,
|
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void previewButtonClicked() {
|
|
||||||
if (!tagPreviewBtnClicked) {
|
|
||||||
final String selectedOption = (String) optiongroup.getValue();
|
|
||||||
if (null != selectedOption && selectedOption.equalsIgnoreCase(updateTypeStr)
|
|
||||||
&& null != tagNameComboBox.getValue()) {
|
|
||||||
|
|
||||||
final DistributionSetType existedDistType = distributionSetManagement
|
|
||||||
.findDistributionSetTypeByKey(tagNameComboBox.getValue().toString());
|
|
||||||
if (null != existedDistType) {
|
|
||||||
getColorPickerLayout().setSelectedColor(existedDistType.getColour() != null
|
|
||||||
? ColorPickerHelper.rgbToColorConverter(existedDistType.getColour())
|
|
||||||
: ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
|
||||||
} else {
|
|
||||||
getColorPickerLayout().setSelectedColor(
|
|
||||||
ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
getColorPickerLayout().getSelPreview().setColor(getColorPickerLayout().getSelectedColor());
|
|
||||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
|
||||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
|
||||||
} else {
|
|
||||||
mainLayout.removeComponent(colorPickerLayout);
|
|
||||||
}
|
|
||||||
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
|||||||
|
|
||||||
private VerticalLayout tagsLayout;
|
private VerticalLayout tagsLayout;
|
||||||
|
|
||||||
Map<String, StringBuilder> assignedSWModule = new HashMap<>();
|
private final Map<String, StringBuilder> assignedSWModule = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* softwareLayout Initialize the component.
|
* softwareLayout Initialize the component.
|
||||||
@@ -259,8 +259,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onEdit(final ClickEvent event) {
|
protected void onEdit(final ClickEvent event) {
|
||||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow();
|
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId());
|
||||||
distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId());
|
|
||||||
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
||||||
UI.getCurrent().addWindow(newDistWindow);
|
UI.getCurrent().addWindow(newDistWindow);
|
||||||
newDistWindow.setVisible(Boolean.TRUE);
|
newDistWindow.setVisible(Boolean.TRUE);
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class DistributionSetTableHeader extends AbstractTableHeader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addNewItem(final ClickEvent event) {
|
protected void addNewItem(final ClickEvent event) {
|
||||||
final Window newDistWindow = addUpdateWindowLayout.getWindow();
|
final Window newDistWindow = addUpdateWindowLayout.getWindow(null);
|
||||||
newDistWindow.setCaption(i18n.get("caption.add.new.dist"));
|
newDistWindow.setCaption(i18n.get("caption.add.new.dist"));
|
||||||
UI.getCurrent().addWindow(newDistWindow);
|
UI.getCurrent().addWindow(newDistWindow);
|
||||||
newDistWindow.setVisible(Boolean.TRUE);
|
newDistWindow.setVisible(Boolean.TRUE);
|
||||||
|
|||||||
@@ -20,17 +20,16 @@ import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
|
|||||||
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout;
|
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerLayout;
|
||||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
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.SPUIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
|
|
||||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.vaadin.spring.events.EventBus;
|
import org.vaadin.spring.events.EventBus;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.vaadin.data.Property.ValueChangeEvent;
|
import com.vaadin.data.Property.ValueChangeEvent;
|
||||||
import com.vaadin.data.Property.ValueChangeListener;
|
import com.vaadin.data.Property.ValueChangeListener;
|
||||||
import com.vaadin.server.Page;
|
import com.vaadin.server.Page;
|
||||||
@@ -87,7 +86,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
protected CommonDialogWindow window;
|
protected CommonDialogWindow window;
|
||||||
|
|
||||||
protected Label colorLabel;
|
protected Label colorLabel;
|
||||||
protected Label madatoryLabel;
|
|
||||||
protected TextField tagName;
|
protected TextField tagName;
|
||||||
protected TextArea tagDesc;
|
protected TextArea tagDesc;
|
||||||
protected Button tagColorPreviewBtn;
|
protected Button tagColorPreviewBtn;
|
||||||
@@ -99,17 +97,13 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
protected GridLayout mainLayout;
|
protected GridLayout mainLayout;
|
||||||
protected VerticalLayout contentLayout;
|
protected VerticalLayout contentLayout;
|
||||||
|
|
||||||
protected boolean tagPreviewBtnClicked = false;
|
protected boolean tagPreviewBtnClicked;
|
||||||
|
|
||||||
private String colorPicked;
|
private String colorPicked;
|
||||||
protected String tagNameValue;
|
protected String tagNameValue;
|
||||||
protected String tagDescValue;
|
protected String tagDescValue;
|
||||||
|
|
||||||
protected void createWindow() {
|
protected abstract String getWindowCaption();
|
||||||
reset();
|
|
||||||
setWindow(SPUIComponentProvider.getWindow(i18n.get("caption.add.tag"), null,
|
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, this::save, this::discard, null));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save new tag / update new tag.
|
* Save new tag / update new tag.
|
||||||
@@ -142,7 +136,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
setSizeUndefined();
|
setSizeUndefined();
|
||||||
createRequiredComponents();
|
createRequiredComponents();
|
||||||
buildLayout();
|
buildLayout();
|
||||||
createWindow();
|
|
||||||
addListeners();
|
addListeners();
|
||||||
eventBus.subscribe(this);
|
eventBus.subscribe(this);
|
||||||
}
|
}
|
||||||
@@ -157,7 +150,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
createTagStr = i18n.get("label.create.tag");
|
createTagStr = i18n.get("label.create.tag");
|
||||||
updateTagStr = i18n.get("label.update.tag");
|
updateTagStr = i18n.get("label.update.tag");
|
||||||
comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null);
|
comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag"), null);
|
||||||
madatoryLabel = getMandatoryLabel();
|
|
||||||
colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null);
|
colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.tag.color"), null);
|
||||||
colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE);
|
colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE);
|
||||||
|
|
||||||
@@ -169,7 +161,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
tagDesc = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "",
|
||||||
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"),
|
ValoTheme.TEXTFIELD_TINY + " " + SPUIDefinitions.TAG_DESC, false, "", i18n.get("textfield.description"),
|
||||||
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||||
|
|
||||||
tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC);
|
tagDesc.setId(SPUIDefinitions.NEW_TARGET_TAG_DESC);
|
||||||
tagDesc.setImmediate(true);
|
tagDesc.setImmediate(true);
|
||||||
tagDesc.setNullRepresentation("");
|
tagDesc.setNullRepresentation("");
|
||||||
@@ -178,6 +169,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
i18n.get("label.combobox.tag"));
|
i18n.get("label.combobox.tag"));
|
||||||
tagNameComboBox.addStyleName(SPUIDefinitions.FILTER_TYPE_COMBO_STYLE);
|
tagNameComboBox.addStyleName(SPUIDefinitions.FILTER_TYPE_COMBO_STYLE);
|
||||||
tagNameComboBox.setImmediate(true);
|
tagNameComboBox.setImmediate(true);
|
||||||
|
tagNameComboBox.setId(SPUIComponentIdProvider.DIST_TAG_COMBO);
|
||||||
|
|
||||||
tagColorPreviewBtn = new Button();
|
tagColorPreviewBtn = new Button();
|
||||||
tagColorPreviewBtn.setId(SPUIComponentIdProvider.TAG_COLOR_PREVIEW_ID);
|
tagColorPreviewBtn.setId(SPUIComponentIdProvider.TAG_COLOR_PREVIEW_ID);
|
||||||
@@ -200,7 +192,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
|
|
||||||
formLayout.addComponent(optiongroup);
|
formLayout.addComponent(optiongroup);
|
||||||
formLayout.addComponent(comboLayout);
|
formLayout.addComponent(comboLayout);
|
||||||
formLayout.addComponent(madatoryLabel);
|
|
||||||
formLayout.addComponent(tagName);
|
formLayout.addComponent(tagName);
|
||||||
formLayout.addComponent(tagDesc);
|
formLayout.addComponent(tagDesc);
|
||||||
formLayout.addStyleName("form-lastrow");
|
formLayout.addStyleName("form-lastrow");
|
||||||
@@ -215,6 +206,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
mainLayout.setSizeFull();
|
mainLayout.setSizeFull();
|
||||||
mainLayout.addComponent(contentLayout, 0, 0);
|
mainLayout.addComponent(contentLayout, 0, 0);
|
||||||
|
|
||||||
|
colorPickerLayout.setVisible(false);
|
||||||
|
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
||||||
|
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
||||||
|
|
||||||
setCompositionRoot(mainLayout);
|
setCompositionRoot(mainLayout);
|
||||||
tagName.focus();
|
tagName.focus();
|
||||||
}
|
}
|
||||||
@@ -234,13 +229,10 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
protected void previewButtonClicked() {
|
protected void previewButtonClicked() {
|
||||||
if (!tagPreviewBtnClicked) {
|
if (!tagPreviewBtnClicked) {
|
||||||
setColor();
|
setColor();
|
||||||
mainLayout.getComponent(1, 0);
|
|
||||||
mainLayout.addComponent(colorPickerLayout, 1, 0);
|
|
||||||
mainLayout.setComponentAlignment(colorPickerLayout, Alignment.MIDDLE_CENTER);
|
|
||||||
} else {
|
|
||||||
mainLayout.removeComponent(colorPickerLayout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
tagPreviewBtnClicked = !tagPreviewBtnClicked;
|
||||||
|
colorPickerLayout.setVisible(tagPreviewBtnClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setColor() {
|
private void setColor() {
|
||||||
@@ -270,12 +262,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Label getMandatoryLabel() {
|
|
||||||
final Label label = new Label(i18n.get("label.mandatory.field"));
|
|
||||||
label.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tagNameChosen(final ValueChangeEvent event) {
|
private void tagNameChosen(final ValueChangeEvent event) {
|
||||||
final String tagSelected = (String) event.getProperty().getValue();
|
final String tagSelected = (String) event.getProperty().getValue();
|
||||||
if (null != tagSelected) {
|
if (null != tagSelected) {
|
||||||
@@ -283,6 +269,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
} else {
|
} else {
|
||||||
resetTagNameField();
|
resetTagNameField();
|
||||||
}
|
}
|
||||||
|
window.setOrginaleValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resetTagNameField() {
|
protected void resetTagNameField() {
|
||||||
@@ -290,7 +277,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
tagName.clear();
|
tagName.clear();
|
||||||
tagDesc.clear();
|
tagDesc.clear();
|
||||||
restoreComponentStyles();
|
restoreComponentStyles();
|
||||||
mainLayout.removeComponent(colorPickerLayout);
|
|
||||||
colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor());
|
colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor());
|
||||||
colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor());
|
colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor());
|
||||||
tagPreviewBtnClicked = false;
|
tagPreviewBtnClicked = false;
|
||||||
@@ -327,7 +313,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR);
|
getPreviewButtonColor(ColorPickerConstants.DEFAULT_COLOR);
|
||||||
colorPickerLayout.getSelPreview()
|
colorPickerLayout.getSelPreview()
|
||||||
.setColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
.setColor(ColorPickerHelper.rgbToColorConverter(ColorPickerConstants.DEFAULT_COLOR));
|
||||||
mainLayout.removeComponent(colorPickerLayout);
|
window.setOrginaleValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,9 +328,9 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
// hide target name combo
|
// hide target name combo
|
||||||
comboLayout.removeComponent(comboLabel);
|
comboLayout.removeComponent(comboLabel);
|
||||||
comboLayout.removeComponent(tagNameComboBox);
|
comboLayout.removeComponent(tagNameComboBox);
|
||||||
mainLayout.removeComponent(colorPickerLayout);
|
|
||||||
|
|
||||||
// Default green color
|
// Default green color
|
||||||
|
colorPickerLayout.setVisible(false);
|
||||||
colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor());
|
colorPickerLayout.setSelectedColor(colorPickerLayout.getDefaultColor());
|
||||||
colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor());
|
colorPickerLayout.getSelPreview().setColor(colorPickerLayout.getSelectedColor());
|
||||||
tagPreviewBtnClicked = false;
|
tagPreviewBtnClicked = false;
|
||||||
@@ -389,6 +375,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
*/
|
*/
|
||||||
protected void createDynamicStyleForComponents(final TextField tagName, final TextArea tagDesc,
|
protected void createDynamicStyleForComponents(final TextField tagName, final TextArea tagDesc,
|
||||||
final String taregtTagColor) {
|
final String taregtTagColor) {
|
||||||
|
|
||||||
tagName.removeStyleName(SPUIDefinitions.TAG_NAME);
|
tagName.removeStyleName(SPUIDefinitions.TAG_NAME);
|
||||||
tagDesc.removeStyleName(SPUIDefinitions.TAG_DESC);
|
tagDesc.removeStyleName(SPUIDefinitions.TAG_DESC);
|
||||||
getTargetDynamicStyles(taregtTagColor);
|
getTargetDynamicStyles(taregtTagColor);
|
||||||
@@ -435,11 +422,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview);
|
createDynamicStyleForComponents(tagName, tagDesc, colorPickedPreview);
|
||||||
colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor());
|
colorPickerLayout.getColorSelect().setColor(colorPickerLayout.getSelPreview().getColor());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected void closeWindow() {
|
|
||||||
window.close();
|
|
||||||
UI.getCurrent().removeWindow(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -448,6 +431,7 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) {
|
protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) {
|
||||||
|
|
||||||
optiongroup = new OptionGroup("Select Action");
|
optiongroup = new OptionGroup("Select Action");
|
||||||
|
optiongroup.setId(SPUIComponentIdProvider.OPTION_GROUP);
|
||||||
optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
||||||
optiongroup.addStyleName("custom-option-group");
|
optiongroup.addStyleName("custom-option-group");
|
||||||
optiongroup.setNullSelectionAllowed(false);
|
optiongroup.setNullSelectionAllowed(false);
|
||||||
@@ -472,27 +456,17 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addColorChangeListener(final ColorChangeListener listener) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeColorChangeListener(final ColorChangeListener listener) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ColorPickerLayout getColorPickerLayout() {
|
public ColorPickerLayout getColorPickerLayout() {
|
||||||
return colorPickerLayout;
|
return colorPickerLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommonDialogWindow getWindow() {
|
public CommonDialogWindow getWindow() {
|
||||||
reset();
|
reset();
|
||||||
|
window = SPUIWindowDecorator.getWindow(getWindowCaption(), null, SPUIDefinitions.CREATE_UPDATE_WINDOW, this,
|
||||||
|
this::save, this::discard, null, mainLayout, i18n);
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWindow(final CommonDialogWindow window) {
|
|
||||||
this.window = window;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value change listeners implementations of sliders.
|
* Value change listeners implementations of sliders.
|
||||||
*/
|
*/
|
||||||
@@ -565,7 +539,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
tagManagement.updateDistributionSetTag((DistributionSetTag) targetObj);
|
tagManagement.updateDistributionSetTag((DistributionSetTag) targetObj);
|
||||||
}
|
}
|
||||||
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() }));
|
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() }));
|
||||||
closeWindow();
|
|
||||||
} else {
|
} else {
|
||||||
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
|
||||||
}
|
}
|
||||||
@@ -587,27 +560,6 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
getPreviewButtonColor(previewColor);
|
getPreviewButtonColor(previewColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected Boolean mandatoryValuesPresent() {
|
|
||||||
if (Strings.isNullOrEmpty(tagName.getValue())) {
|
|
||||||
if (optiongroup.getValue().equals(createTagStr)) {
|
|
||||||
displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME);
|
|
||||||
}
|
|
||||||
if (optiongroup.getValue().equals(updateTagStr)) {
|
|
||||||
if (null == tagNameComboBox.getValue()) {
|
|
||||||
displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME));
|
|
||||||
} else {
|
|
||||||
displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Boolean checkIsDuplicate(final Tag existingTag) {
|
protected Boolean checkIsDuplicate(final Tag existingTag) {
|
||||||
if (existingTag != null) {
|
if (existingTag != null) {
|
||||||
displayValidationError(i18n.get("message.tag.duplicate.check", new Object[] { existingTag.getName() }));
|
displayValidationError(i18n.get("message.tag.duplicate.check", new Object[] { existingTag.getName() }));
|
||||||
@@ -644,4 +596,16 @@ public abstract class AbstractCreateUpdateTagLayout extends CustomComponent
|
|||||||
return formLayout;
|
return formLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GridLayout getMainLayout() {
|
||||||
|
return mainLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addColorChangeListener(final ColorChangeListener listener) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeColorChangeListener(final ColorChangeListener listener) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
|||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.vaadin.data.Property.ValueChangeEvent;
|
import com.vaadin.data.Property.ValueChangeEvent;
|
||||||
import com.vaadin.server.Page;
|
import com.vaadin.server.Page;
|
||||||
import com.vaadin.shared.ui.colorpicker.Color;
|
import com.vaadin.shared.ui.colorpicker.Color;
|
||||||
@@ -33,12 +31,10 @@ import com.vaadin.ui.components.colorpicker.ColorSelector;
|
|||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Superclass defining common properties and methods for creating/updating
|
* Superclass defining common properties and methods for creating/updating
|
||||||
* types.
|
* types.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
public abstract class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
||||||
|
|
||||||
private static final long serialVersionUID = 5732904956185988397L;
|
private static final long serialVersionUID = 5732904956185988397L;
|
||||||
|
|
||||||
@@ -52,7 +48,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
|||||||
@Override
|
@Override
|
||||||
protected void addListeners() {
|
protected void addListeners() {
|
||||||
super.addListeners();
|
super.addListeners();
|
||||||
optiongroup.addValueChangeListener(this::createOptionValueChanged);
|
optiongroup.addValueChangeListener(this::optionValueChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -61,7 +57,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
|||||||
createTypeStr = i18n.get("label.create.type");
|
createTypeStr = i18n.get("label.create.type");
|
||||||
updateTypeStr = i18n.get("label.update.type");
|
updateTypeStr = i18n.get("label.update.type");
|
||||||
comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null);
|
comboLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type"), null);
|
||||||
madatoryLabel = getMandatoryLabel();
|
|
||||||
colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null);
|
colorLabel = SPUIComponentProvider.getLabel(i18n.get("label.choose.type.color"), null);
|
||||||
colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE);
|
colorLabel.addStyleName(SPUIDefinitions.COLOR_LABEL_STYLE);
|
||||||
|
|
||||||
@@ -137,7 +132,8 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
|||||||
* @param event
|
* @param event
|
||||||
* ValueChangeEvent
|
* ValueChangeEvent
|
||||||
*/
|
*/
|
||||||
protected void createOptionValueChanged(final ValueChangeEvent event) {
|
@Override
|
||||||
|
protected void optionValueChanged(final ValueChangeEvent event) {
|
||||||
|
|
||||||
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
if (updateTypeStr.equals(event.getProperty().getValue())) {
|
||||||
tagName.clear();
|
tagName.clear();
|
||||||
@@ -151,7 +147,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
|||||||
} else {
|
} else {
|
||||||
typeKey.setEnabled(true);
|
typeKey.setEnabled(true);
|
||||||
tagName.setEnabled(true);
|
tagName.setEnabled(true);
|
||||||
window.setSaveButtonEnabled(true);
|
|
||||||
tagName.clear();
|
tagName.clear();
|
||||||
tagDesc.clear();
|
tagDesc.clear();
|
||||||
typeKey.clear();
|
typeKey.clear();
|
||||||
@@ -203,6 +198,7 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
|||||||
protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) {
|
protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) {
|
||||||
|
|
||||||
optiongroup = new OptionGroup("Select Action");
|
optiongroup = new OptionGroup("Select Action");
|
||||||
|
optiongroup.setId(SPUIComponentIdProvider.OPTION_GROUP);
|
||||||
optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
optiongroup.addStyleName(ValoTheme.OPTIONGROUP_SMALL);
|
||||||
optiongroup.addStyleName("custom-option-group");
|
optiongroup.addStyleName("custom-option-group");
|
||||||
optiongroup.setNullSelectionAllowed(false);
|
optiongroup.setNullSelectionAllowed(false);
|
||||||
@@ -285,24 +281,6 @@ public class CreateUpdateTypeLayout extends AbstractCreateUpdateTagLayout {
|
|||||||
return Boolean.FALSE;
|
return Boolean.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean mandatoryValuesPresent() {
|
|
||||||
if (Strings.isNullOrEmpty(tagName.getValue()) || Strings.isNullOrEmpty(typeKey.getValue())) {
|
|
||||||
if (optiongroup.getValue().equals(createTypeStr)) {
|
|
||||||
displayValidationError(SPUILabelDefinitions.MISSING_TYPE_NAME_KEY);
|
|
||||||
}
|
|
||||||
if (optiongroup.getValue().equals(updateTypeStr)) {
|
|
||||||
if (null == tagNameComboBox.getValue()) {
|
|
||||||
displayValidationError(i18n.get("message.error.missing.tagName"));
|
|
||||||
} else {
|
|
||||||
displayValidationError(SPUILabelDefinitions.MISSING_TAG_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Boolean.FALSE;
|
|
||||||
}
|
|
||||||
return Boolean.TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void save(final ClickEvent event) {
|
protected void save(final ClickEvent event) {
|
||||||
// is implemented in the inherited class
|
// is implemented in the inherited class
|
||||||
|
|||||||
@@ -8,10 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.management.dstable;
|
package org.eclipse.hawkbit.ui.management.dstable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -27,8 +25,11 @@ import org.eclipse.hawkbit.repository.model.TenantMetaData;
|
|||||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||||
import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery;
|
import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery;
|
||||||
|
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.SPUIWindowDecorator;
|
||||||
import org.eclipse.hawkbit.ui.distributions.dstable.DistributionSetTable;
|
import org.eclipse.hawkbit.ui.distributions.dstable.DistributionSetTable;
|
||||||
|
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
|
||||||
import org.eclipse.hawkbit.ui.management.event.DragEvent;
|
import org.eclipse.hawkbit.ui.management.event.DragEvent;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
@@ -45,26 +46,18 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
|||||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
||||||
import org.vaadin.spring.events.EventBus;
|
import org.vaadin.spring.events.EventBus;
|
||||||
|
|
||||||
import com.vaadin.data.Property.ValueChangeEvent;
|
|
||||||
import com.vaadin.data.Property.ValueChangeListener;
|
|
||||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
|
||||||
import com.vaadin.event.FieldEvents.TextChangeListener;
|
|
||||||
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.CheckBox;
|
import com.vaadin.ui.CheckBox;
|
||||||
import com.vaadin.ui.ComboBox;
|
import com.vaadin.ui.ComboBox;
|
||||||
import com.vaadin.ui.Component;
|
|
||||||
import com.vaadin.ui.CustomComponent;
|
import com.vaadin.ui.CustomComponent;
|
||||||
import com.vaadin.ui.FormLayout;
|
import com.vaadin.ui.FormLayout;
|
||||||
import com.vaadin.ui.Label;
|
|
||||||
import com.vaadin.ui.TextArea;
|
import com.vaadin.ui.TextArea;
|
||||||
import com.vaadin.ui.TextField;
|
import com.vaadin.ui.TextField;
|
||||||
import com.vaadin.ui.UI;
|
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* WindowContent for adding/editing a Distribution
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
@@ -97,24 +90,12 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
|
|
||||||
private TextField distNameTextField;
|
private TextField distNameTextField;
|
||||||
private TextField distVersionTextField;
|
private TextField distVersionTextField;
|
||||||
private Label madatoryLabel;
|
|
||||||
private TextArea descTextArea;
|
private TextArea descTextArea;
|
||||||
private CheckBox reqMigStepCheckbox;
|
private CheckBox reqMigStepCheckbox;
|
||||||
private ComboBox distsetTypeNameComboBox;
|
private ComboBox distsetTypeNameComboBox;
|
||||||
private boolean editDistribution = Boolean.FALSE;
|
private boolean editDistribution = Boolean.FALSE;
|
||||||
private Long editDistId;
|
private Long editDistId;
|
||||||
private CommonDialogWindow addDistributionWindow;
|
private CommonDialogWindow window;
|
||||||
private String originalDistName;
|
|
||||||
private String originalDistVersion;
|
|
||||||
private String originalDistDescription;
|
|
||||||
private Boolean originalReqMigStep;
|
|
||||||
private String originalDistSetType;
|
|
||||||
private final List<Component> changedComponents = new ArrayList<>();
|
|
||||||
private ValueChangeListener reqMigStepCheckboxListerner;
|
|
||||||
private TextChangeListener descTextAreaListener;
|
|
||||||
private TextChangeListener distNameTextFieldListener;
|
|
||||||
private TextChangeListener distVersionTextFieldListener;
|
|
||||||
private ValueChangeListener distsetTypeNameComboBoxListener;
|
|
||||||
|
|
||||||
private FormLayout formLayout;
|
private FormLayout formLayout;
|
||||||
|
|
||||||
@@ -128,16 +109,10 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void buildLayout() {
|
private void buildLayout() {
|
||||||
|
|
||||||
/*
|
|
||||||
* The main layout of the window contains mandatory info, textboxes
|
|
||||||
* (controller Id, name & description) and action buttons layout
|
|
||||||
*/
|
|
||||||
addStyleName("lay-color");
|
addStyleName("lay-color");
|
||||||
setSizeUndefined();
|
setSizeUndefined();
|
||||||
|
|
||||||
formLayout = new FormLayout();
|
formLayout = new FormLayout();
|
||||||
formLayout.addComponent(madatoryLabel);
|
|
||||||
formLayout.addComponent(distsetTypeNameComboBox);
|
formLayout.addComponent(distsetTypeNameComboBox);
|
||||||
formLayout.addComponent(distNameTextField);
|
formLayout.addComponent(distNameTextField);
|
||||||
formLayout.addComponent(distVersionTextField);
|
formLayout.addComponent(distVersionTextField);
|
||||||
@@ -145,7 +120,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
formLayout.addComponent(reqMigStepCheckbox);
|
formLayout.addComponent(reqMigStepCheckbox);
|
||||||
|
|
||||||
setCompositionRoot(formLayout);
|
setCompositionRoot(formLayout);
|
||||||
|
|
||||||
distNameTextField.focus();
|
distNameTextField.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +143,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
distsetTypeNameComboBox.setImmediate(true);
|
distsetTypeNameComboBox.setImmediate(true);
|
||||||
distsetTypeNameComboBox.setNullSelectionAllowed(false);
|
distsetTypeNameComboBox.setNullSelectionAllowed(false);
|
||||||
distsetTypeNameComboBox.setId(SPUIComponentIdProvider.DIST_ADD_DISTSETTYPE);
|
distsetTypeNameComboBox.setId(SPUIComponentIdProvider.DIST_ADD_DISTSETTYPE);
|
||||||
|
populateDistSetTypeNameCombo();
|
||||||
|
|
||||||
descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style",
|
descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style",
|
||||||
ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"),
|
ValoTheme.TEXTAREA_TINY, false, null, i18n.get("textfield.description"),
|
||||||
@@ -176,10 +151,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC);
|
descTextArea.setId(SPUIComponentIdProvider.DIST_ADD_DESC);
|
||||||
descTextArea.setNullRepresentation("");
|
descTextArea.setNullRepresentation("");
|
||||||
|
|
||||||
/* Label for mandatory symbol */
|
|
||||||
madatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
|
||||||
madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
|
||||||
|
|
||||||
reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"),
|
reqMigStepCheckbox = SPUIComponentProvider.getCheckBox(i18n.get("checkbox.dist.required.migration.step"),
|
||||||
"dist-checkbox-style", null, false, "");
|
"dist-checkbox-style", null, false, "");
|
||||||
reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL);
|
reqMigStepCheckbox.addStyleName(ValoTheme.CHECKBOX_SMALL);
|
||||||
@@ -205,27 +176,17 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
return disttypeContainer;
|
return disttypeContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableSaveButton() {
|
|
||||||
addDistributionWindow.setSaveButtonEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DistributionSetType getDefaultDistributionSetType() {
|
private DistributionSetType getDefaultDistributionSetType() {
|
||||||
final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata();
|
final TenantMetaData tenantMetaData = systemManagement.getTenantMetadata();
|
||||||
return tenantMetaData.getDefaultDsType();
|
return tenantMetaData.getDefaultDsType();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableSaveButton() {
|
|
||||||
addDistributionWindow.setSaveButtonEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveDistribution() {
|
private void saveDistribution() {
|
||||||
/* add new or update target */
|
|
||||||
if (editDistribution) {
|
if (editDistribution) {
|
||||||
updateDistribution();
|
updateDistribution();
|
||||||
} else {
|
} else {
|
||||||
addNewDistribution();
|
addNewDistribution();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -237,7 +198,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
final String distSetTypeName = HawkbitCommonUtil
|
final String distSetTypeName = HawkbitCommonUtil
|
||||||
.trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue());
|
.trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue());
|
||||||
|
|
||||||
if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) {
|
if (duplicateCheck(name, version)) {
|
||||||
final DistributionSet currentDS = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId);
|
final DistributionSet currentDS = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId);
|
||||||
final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||||
final boolean isMigStepReq = reqMigStepCheckbox.getValue();
|
final boolean isMigStepReq = reqMigStepCheckbox.getValue();
|
||||||
@@ -248,28 +209,16 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
distributionSetManagement.updateDistributionSet(currentDS);
|
distributionSetManagement.updateDistributionSet(currentDS);
|
||||||
notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success",
|
notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success",
|
||||||
new Object[] { currentDS.getName(), currentDS.getVersion() }));
|
new Object[] { currentDS.getName(), currentDS.getVersion() }));
|
||||||
|
// update table row+details layout
|
||||||
|
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, currentDS));
|
||||||
} catch (final EntityAlreadyExistsException entityAlreadyExistsException) {
|
} catch (final EntityAlreadyExistsException entityAlreadyExistsException) {
|
||||||
LOG.error("Update distribution failed {}", entityAlreadyExistsException);
|
LOG.error("Update distribution failed {}", entityAlreadyExistsException);
|
||||||
notificationMessage.displayValidationError(
|
notificationMessage.displayValidationError(
|
||||||
i18n.get("message.distribution.no.update", currentDS.getName() + ":" + currentDS.getVersion()));
|
i18n.get("message.distribution.no.update", currentDS.getName() + ":" + currentDS.getVersion()));
|
||||||
}
|
}
|
||||||
closeThisWindow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addListeners() {
|
|
||||||
reqMigStepCheckboxListerner = event -> checkValueChanged(originalReqMigStep, event);
|
|
||||||
descTextAreaListener = event -> checkValueChanged(originalDistDescription, event);
|
|
||||||
distNameTextFieldListener = event -> checkValueChanged(originalDistName, event);
|
|
||||||
distVersionTextFieldListener = event -> checkValueChanged(originalDistVersion, event);
|
|
||||||
distsetTypeNameComboBoxListener = event -> checkValueChanged(originalDistSetType, event);
|
|
||||||
reqMigStepCheckbox.addValueChangeListener(reqMigStepCheckboxListerner);
|
|
||||||
descTextArea.addTextChangeListener(descTextAreaListener);
|
|
||||||
distNameTextField.addTextChangeListener(distNameTextFieldListener);
|
|
||||||
distVersionTextField.addTextChangeListener(distVersionTextFieldListener);
|
|
||||||
distsetTypeNameComboBox.addValueChangeListener(distsetTypeNameComboBoxListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new Distribution set.
|
* Add new Distribution set.
|
||||||
*/
|
*/
|
||||||
@@ -280,7 +229,7 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
final String distSetTypeName = HawkbitCommonUtil
|
final String distSetTypeName = HawkbitCommonUtil
|
||||||
.trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue());
|
.trimAndNullIfEmpty((String) distsetTypeNameComboBox.getValue());
|
||||||
|
|
||||||
if (mandatoryCheck(name, version, distSetTypeName) && duplicateCheck(name, version)) {
|
if (duplicateCheck(name, version)) {
|
||||||
final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
final String desc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||||
final boolean isMigStepReq = reqMigStepCheckbox.getValue();
|
final boolean isMigStepReq = reqMigStepCheckbox.getValue();
|
||||||
DistributionSet newDist = entityFactory.generateDistributionSet();
|
DistributionSet newDist = entityFactory.generateDistributionSet();
|
||||||
@@ -290,8 +239,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
|
|
||||||
notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success",
|
notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success",
|
||||||
new Object[] { newDist.getName(), newDist.getVersion() }));
|
new Object[] { newDist.getName(), newDist.getVersion() }));
|
||||||
/* close the window */
|
|
||||||
closeThisWindow();
|
|
||||||
|
|
||||||
final Set<DistributionSetIdName> s = new HashSet<>();
|
final Set<DistributionSetIdName> s = new HashSet<>();
|
||||||
s.add(new DistributionSetIdName(newDist.getId(),newDist.getName(),newDist.getVersion()));
|
s.add(new DistributionSetIdName(newDist.getId(),newDist.getName(),newDist.getVersion()));
|
||||||
@@ -299,14 +246,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Close window.
|
|
||||||
*/
|
|
||||||
private void closeThisWindow() {
|
|
||||||
addDistributionWindow.close();
|
|
||||||
UI.getCurrent().removeWindow(addDistributionWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Values for Distribution set.
|
* Set Values for Distribution set.
|
||||||
*
|
*
|
||||||
@@ -350,47 +289,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mandatory Check.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* as String
|
|
||||||
* @param version
|
|
||||||
* as String
|
|
||||||
* @param selectedJVM
|
|
||||||
* as String
|
|
||||||
* @param selectedAgentHub
|
|
||||||
* as String
|
|
||||||
* @param selectedOs
|
|
||||||
* as String
|
|
||||||
* @return boolean as flag
|
|
||||||
*/
|
|
||||||
private boolean mandatoryCheck(final String name, final String version, final String distSetTypeName) {
|
|
||||||
|
|
||||||
if (name == null || version == null || distSetTypeName == null) {
|
|
||||||
if (name == null) {
|
|
||||||
distNameTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
|
||||||
}
|
|
||||||
if (version == null) {
|
|
||||||
distVersionTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
|
||||||
}
|
|
||||||
if (distSetTypeName == null) {
|
|
||||||
distsetTypeNameComboBox.addStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationMessage.displayValidationError(i18n.get("message.mandatory.check"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void discardDistribution() {
|
|
||||||
/* Just close this window */
|
|
||||||
distsetTypeNameComboBox.removeValueChangeListener(distsetTypeNameComboBoxListener);
|
|
||||||
closeThisWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clear all the fields.
|
* clear all the fields.
|
||||||
*/
|
*/
|
||||||
@@ -403,93 +301,22 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
distsetTypeNameComboBox.removeStyleName(SPUIStyleDefinitions.SP_COMBOFIELD_ERROR);
|
||||||
descTextArea.clear();
|
descTextArea.clear();
|
||||||
reqMigStepCheckbox.clear();
|
reqMigStepCheckbox.clear();
|
||||||
if (addDistributionWindow != null) {
|
|
||||||
addDistributionWindow.setSaveButtonEnabled(true);
|
|
||||||
}
|
|
||||||
removeListeners();
|
|
||||||
changedComponents.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateRequiredComponents() {
|
private void populateValuesOfDistribution(final Long editDistId) {
|
||||||
populateDistSetTypeNameCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removeListeners() {
|
|
||||||
reqMigStepCheckbox.removeValueChangeListener(reqMigStepCheckboxListerner);
|
|
||||||
descTextArea.removeTextChangeListener(descTextAreaListener);
|
|
||||||
distNameTextField.removeTextChangeListener(distNameTextFieldListener);
|
|
||||||
distVersionTextField.removeTextChangeListener(distVersionTextFieldListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOriginalDistName(final String originalDistName) {
|
|
||||||
this.originalDistName = originalDistName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOriginalDistVersion(final String originalDistVersion) {
|
|
||||||
this.originalDistVersion = originalDistVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOriginalDistDescription(final String originalDistDescription) {
|
|
||||||
this.originalDistDescription = originalDistDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkValueChanged(final String originalValue, final TextChangeEvent event) {
|
|
||||||
if (editDistribution) {
|
|
||||||
final String newValue = event.getText();
|
|
||||||
if (!originalValue.equalsIgnoreCase(newValue)) {
|
|
||||||
changedComponents.add(event.getComponent());
|
|
||||||
} else {
|
|
||||||
changedComponents.remove(event.getComponent());
|
|
||||||
}
|
|
||||||
enableDisableSaveButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkValueChanged(final Boolean originalValue, final ValueChangeEvent event) {
|
|
||||||
if (editDistribution) {
|
|
||||||
if (!originalValue.equals(event.getProperty().getValue())) {
|
|
||||||
changedComponents.add(reqMigStepCheckbox);
|
|
||||||
} else {
|
|
||||||
changedComponents.remove(reqMigStepCheckbox);
|
|
||||||
}
|
|
||||||
enableDisableSaveButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkValueChanged(final String originalValue, final ValueChangeEvent event) {
|
|
||||||
if (editDistribution) {
|
|
||||||
if (!originalValue.equals(event.getProperty().getValue())) {
|
|
||||||
changedComponents.add(distsetTypeNameComboBox);
|
|
||||||
} else {
|
|
||||||
changedComponents.remove(distsetTypeNameComboBox);
|
|
||||||
}
|
|
||||||
enableDisableSaveButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableDisableSaveButton() {
|
|
||||||
if (changedComponents.isEmpty()) {
|
|
||||||
disableSaveButton();
|
|
||||||
} else {
|
|
||||||
enableSaveButton();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setOriginalReqMigStep(final Boolean originalReqMigStep) {
|
|
||||||
this.originalReqMigStep = originalReqMigStep;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* populate data.
|
|
||||||
*
|
|
||||||
* @param editDistId
|
|
||||||
*/
|
|
||||||
public void populateValuesOfDistribution(final Long editDistId) {
|
|
||||||
this.editDistId = editDistId;
|
this.editDistId = editDistId;
|
||||||
editDistribution = Boolean.TRUE;
|
|
||||||
addDistributionWindow.setSaveButtonEnabled(false);
|
if (editDistId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId);
|
final DistributionSet distSet = distributionSetManagement.findDistributionSetByIdWithDetails(editDistId);
|
||||||
if (distSet != null) {
|
if (distSet == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
editDistribution = Boolean.TRUE;
|
||||||
distNameTextField.setValue(distSet.getName());
|
distNameTextField.setValue(distSet.getName());
|
||||||
distVersionTextField.setValue(distSet.getVersion());
|
distVersionTextField.setValue(distSet.getVersion());
|
||||||
if (distSet.getType().isDeleted()) {
|
if (distSet.getType().isDeleted()) {
|
||||||
@@ -500,42 +327,26 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent {
|
|||||||
if (distSet.getDescription() != null) {
|
if (distSet.getDescription() != null) {
|
||||||
descTextArea.setValue(distSet.getDescription());
|
descTextArea.setValue(distSet.getDescription());
|
||||||
}
|
}
|
||||||
setOriginalDistName(distSet.getName());
|
|
||||||
setOriginalDistVersion(distSet.getVersion());
|
|
||||||
setOriginalDistDescription(distSet.getDescription());
|
|
||||||
setOriginalReqMigStep(distSet.isRequiredMigrationStep());
|
|
||||||
setOriginalDistSetTYpe(distSet.getType().getName());
|
|
||||||
addListeners();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommonDialogWindow getWindow() {
|
public CommonDialogWindow getWindow(final Long editDistId) {
|
||||||
eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
|
eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
|
||||||
populateRequiredComponents();
|
|
||||||
resetComponents();
|
resetComponents();
|
||||||
addDistributionWindow = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.dist"), null,
|
populateDistSetTypeNameCombo();
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), event -> discardDistribution(),
|
populateValuesOfDistribution(editDistId);
|
||||||
null);
|
window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.dist"), null,
|
||||||
addDistributionWindow.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveDistribution(), null, null, formLayout, i18n);
|
||||||
|
window.getButtonsLayout().removeStyleName("actionButtonsMargin");
|
||||||
return addDistributionWindow;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Populate DistributionSet Type name combo.
|
* Populate DistributionSet Type name combo.
|
||||||
*/
|
*/
|
||||||
public void populateDistSetTypeNameCombo() {
|
private void populateDistSetTypeNameCombo() {
|
||||||
distsetTypeNameComboBox.setContainerDataSource(getDistSetTypeLazyQueryContainer());
|
distsetTypeNameComboBox.setContainerDataSource(getDistSetTypeLazyQueryContainer());
|
||||||
distsetTypeNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
distsetTypeNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||||
distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName());
|
distsetTypeNameComboBox.setValue(getDefaultDistributionSetType().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param originalDistSetTYpe
|
|
||||||
* the originalDistSetTYpe to set
|
|
||||||
*/
|
|
||||||
public void setOriginalDistSetTYpe(final String originalDistSetType) {
|
|
||||||
this.originalDistSetType = originalDistSetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,8 +77,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onEdit(final ClickEvent event) {
|
protected void onEdit(final ClickEvent event) {
|
||||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow();
|
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(getSelectedBaseEntityId());
|
||||||
distributionAddUpdateWindowLayout.populateValuesOfDistribution(getSelectedBaseEntityId());
|
|
||||||
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
||||||
UI.getCurrent().addWindow(newDistWindow);
|
UI.getCurrent().addWindow(newDistWindow);
|
||||||
newDistWindow.setVisible(Boolean.TRUE);
|
newDistWindow.setVisible(Boolean.TRUE);
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class DistributionTableHeader extends AbstractTableHeader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addNewItem(final ClickEvent event) {
|
protected void addNewItem(final ClickEvent event) {
|
||||||
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow();
|
final Window newDistWindow = distributionAddUpdateWindowLayout.getWindow(null);
|
||||||
newDistWindow.setCaption(i18n.get("caption.add.new.dist"));
|
newDistWindow.setCaption(i18n.get("caption.add.new.dist"));
|
||||||
UI.getCurrent().addWindow(newDistWindow);
|
UI.getCurrent().addWindow(newDistWindow);
|
||||||
newDistWindow.setVisible(Boolean.TRUE);
|
newDistWindow.setVisible(Boolean.TRUE);
|
||||||
|
|||||||
@@ -32,9 +32,7 @@ import com.vaadin.ui.Button.ClickEvent;
|
|||||||
import com.vaadin.ui.UI;
|
import com.vaadin.ui.UI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Class for Create/Update Tag Layout of distribution set
|
* Class for Create/Update Tag Layout of distribution set
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
@@ -87,18 +85,15 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void save(final ClickEvent event) {
|
public void save(final ClickEvent event) {
|
||||||
if (mandatoryValuesPresent()) {
|
|
||||||
final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue());
|
final DistributionSetTag existingDistTag = tagManagement.findDistributionSetTag(tagName.getValue());
|
||||||
if (optiongroup.getValue().equals(createTagStr)) {
|
if (optiongroup.getValue().equals(createTagStr)) {
|
||||||
if (!checkIsDuplicate(existingDistTag)) {
|
if (!checkIsDuplicate(existingDistTag)) {
|
||||||
createNewTag();
|
createNewTag();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
updateExistingTag(existingDistTag);
|
updateExistingTag(existingDistTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new tag.
|
* Create new tag.
|
||||||
@@ -181,4 +176,9 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat
|
|||||||
setOptionGroupDefaultValue(permChecker.hasCreateDistributionPermission(),
|
setOptionGroupDefaultValue(permChecker.hasCreateDistributionPermission(),
|
||||||
permChecker.hasUpdateDistributionPermission());
|
permChecker.hasUpdateDistributionPermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWindowCaption() {
|
||||||
|
return i18n.get("caption.add.tag");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import javax.annotation.PostConstruct;
|
|||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
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.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroup;
|
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroup;
|
||||||
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
||||||
@@ -78,6 +79,7 @@ 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);
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ package org.eclipse.hawkbit.ui.management.tag;
|
|||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.vaadin.data.Property;
|
import com.vaadin.data.Property;
|
||||||
import com.vaadin.data.Property.ValueChangeEvent;
|
import com.vaadin.data.Property.ValueChangeEvent;
|
||||||
@@ -44,7 +46,7 @@ public final class SpColorPickerPreview extends ColorPickerPreview implements Te
|
|||||||
try {
|
try {
|
||||||
final Field textField = ColorPickerPreview.class.getDeclaredField("field");
|
final Field textField = ColorPickerPreview.class.getDeclaredField("field");
|
||||||
textField.setAccessible(true);
|
textField.setAccessible(true);
|
||||||
((TextField) textField.get(this)).setId("color-preview-field");
|
((TextField) textField.get(this)).setId(SPUIComponentIdProvider.COLOR_PREVIEW_FIELD);
|
||||||
((TextField) textField.get(this)).addTextChangeListener(this);
|
((TextField) textField.get(this)).addTextChangeListener(this);
|
||||||
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
|
} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName;
|
|||||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||||
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.SPUIWindowDecorator;
|
||||||
import org.eclipse.hawkbit.ui.management.event.DragEvent;
|
import org.eclipse.hawkbit.ui.management.event.DragEvent;
|
||||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
@@ -31,24 +32,17 @@ import org.eclipse.hawkbit.ui.utils.UINotification;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.vaadin.spring.events.EventBus;
|
import org.vaadin.spring.events.EventBus;
|
||||||
|
|
||||||
import com.vaadin.event.FieldEvents.TextChangeEvent;
|
|
||||||
import com.vaadin.event.FieldEvents.TextChangeListener;
|
|
||||||
import com.vaadin.spring.annotation.SpringComponent;
|
import com.vaadin.spring.annotation.SpringComponent;
|
||||||
import com.vaadin.spring.annotation.VaadinSessionScope;
|
import com.vaadin.spring.annotation.VaadinSessionScope;
|
||||||
import com.vaadin.ui.CustomComponent;
|
import com.vaadin.ui.CustomComponent;
|
||||||
import com.vaadin.ui.FormLayout;
|
import com.vaadin.ui.FormLayout;
|
||||||
import com.vaadin.ui.Label;
|
|
||||||
import com.vaadin.ui.TextArea;
|
import com.vaadin.ui.TextArea;
|
||||||
import com.vaadin.ui.TextField;
|
import com.vaadin.ui.TextField;
|
||||||
import com.vaadin.ui.UI;
|
|
||||||
import com.vaadin.ui.Window;
|
import com.vaadin.ui.Window;
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add and Update Target.
|
* Add and Update Target.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@VaadinSessionScope
|
@VaadinSessionScope
|
||||||
@@ -73,48 +67,37 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
private TextField controllerIDTextField;
|
private TextField controllerIDTextField;
|
||||||
private TextField nameTextField;
|
private TextField nameTextField;
|
||||||
private TextArea descTextArea;
|
private TextArea descTextArea;
|
||||||
private Label madatoryLabel;
|
|
||||||
private boolean editTarget = Boolean.FALSE;
|
private boolean editTarget = Boolean.FALSE;
|
||||||
private String controllerId;
|
private String controllerId;
|
||||||
private FormLayout formLayout;
|
private FormLayout formLayout;
|
||||||
private CommonDialogWindow window;
|
private CommonDialogWindow window;
|
||||||
|
|
||||||
private String oldTargetName;
|
|
||||||
private String oldTargetDesc;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Add Update Window Component for Target.
|
* Initialize the Add Update Window Component for Target.
|
||||||
*/
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
/* create components */
|
|
||||||
createRequiredComponents();
|
createRequiredComponents();
|
||||||
/* display components in layout */
|
|
||||||
buildLayout();
|
buildLayout();
|
||||||
/* register all listeners related to the Window */
|
|
||||||
addListeners();
|
|
||||||
setCompositionRoot(formLayout);
|
setCompositionRoot(formLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRequiredComponents() {
|
private void createRequiredComponents() {
|
||||||
/* Textfield for controller Id */
|
/* Textfield for controller Id */
|
||||||
controllerIDTextField = SPUIComponentProvider.getTextField( i18n.get("prompt.target.id"), "", ValoTheme.TEXTFIELD_TINY, true, null,
|
controllerIDTextField = SPUIComponentProvider.getTextField(i18n.get("prompt.target.id"), "",
|
||||||
i18n.get("prompt.target.id"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
ValoTheme.TEXTFIELD_TINY, true, null, i18n.get("prompt.target.id"), true,
|
||||||
|
SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||||
controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID);
|
controllerIDTextField.setId(SPUIComponentIdProvider.TARGET_ADD_CONTROLLER_ID);
|
||||||
|
|
||||||
/* Textfield for target name */
|
/* Textfield for target name */
|
||||||
nameTextField = SPUIComponentProvider.getTextField( i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY, false, null,
|
nameTextField = SPUIComponentProvider.getTextField(i18n.get("textfield.name"), "", ValoTheme.TEXTFIELD_TINY,
|
||||||
i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
false, null, i18n.get("textfield.name"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||||
nameTextField.setId(SPUIComponentIdProvider.TARGET_ADD_NAME);
|
nameTextField.setId(SPUIComponentIdProvider.TARGET_ADD_NAME);
|
||||||
|
|
||||||
/* Textarea for target description */
|
/* Textarea for target description */
|
||||||
descTextArea = SPUIComponentProvider.getTextArea( i18n.get("textfield.description"), "text-area-style", ValoTheme.TEXTFIELD_TINY, false, null,
|
descTextArea = SPUIComponentProvider.getTextArea(i18n.get("textfield.description"), "text-area-style",
|
||||||
i18n.get("textfield.description"), SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
ValoTheme.TEXTFIELD_TINY, false, null, i18n.get("textfield.description"),
|
||||||
|
SPUILabelDefinitions.TEXT_AREA_MAX_LENGTH);
|
||||||
descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC);
|
descTextArea.setId(SPUIComponentIdProvider.TARGET_ADD_DESC);
|
||||||
descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY);
|
descTextArea.setNullRepresentation(HawkbitCommonUtil.SP_STRING_EMPTY);
|
||||||
|
|
||||||
/* Label for mandatory symbol */
|
|
||||||
madatoryLabel = new Label(i18n.get("label.mandatory.field"));
|
|
||||||
madatoryLabel.setStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildLayout() {
|
private void buildLayout() {
|
||||||
@@ -125,63 +108,13 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
*/
|
*/
|
||||||
setSizeUndefined();
|
setSizeUndefined();
|
||||||
formLayout = new FormLayout();
|
formLayout = new FormLayout();
|
||||||
formLayout.addComponent(madatoryLabel);
|
|
||||||
formLayout.addComponent(controllerIDTextField);
|
formLayout.addComponent(controllerIDTextField);
|
||||||
formLayout.addComponent(nameTextField);
|
formLayout.addComponent(nameTextField);
|
||||||
formLayout.addComponent(descTextArea);
|
formLayout.addComponent(descTextArea);
|
||||||
|
|
||||||
if (Boolean.TRUE.equals(editTarget)) {
|
|
||||||
madatoryLabel.setVisible(Boolean.FALSE);
|
|
||||||
}
|
|
||||||
controllerIDTextField.focus();
|
controllerIDTextField.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addListeners() {
|
|
||||||
|
|
||||||
addTargetNameChangeListner();
|
|
||||||
addTargetDescChangeListner();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addTargetNameChangeListner() {
|
|
||||||
nameTextField.addTextChangeListener(new TextChangeListener() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1761855781481115921L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void textChange(final TextChangeEvent event) {
|
|
||||||
if (event.getText().equals(oldTargetName) && descTextArea.getValue().equals(oldTargetDesc)) {
|
|
||||||
window.setSaveButtonEnabled(false);
|
|
||||||
} else {
|
|
||||||
window.setSaveButtonEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addTargetDescChangeListner() {
|
|
||||||
descTextArea.addTextChangeListener(new TextChangeListener() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 5770734934988115068L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void textChange(final TextChangeEvent event) {
|
|
||||||
if (event.getText().equals(oldTargetDesc) && nameTextField.getValue().equals(oldTargetName)) {
|
|
||||||
window.setSaveButtonEnabled(false);
|
|
||||||
} else {
|
|
||||||
window.setSaveButtonEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the Target if modified.
|
* Update the Target if modified.
|
||||||
*/
|
*/
|
||||||
@@ -199,10 +132,6 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
uINotification.displaySuccess(i18n.get("message.update.success", new Object[] { latestTarget.getName() }));
|
uINotification.displaySuccess(i18n.get("message.update.success", new Object[] { latestTarget.getName() }));
|
||||||
// publishing through event bus
|
// publishing through event bus
|
||||||
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.UPDATED_ENTITY, latestTarget));
|
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.UPDATED_ENTITY, latestTarget));
|
||||||
|
|
||||||
/* close the window */
|
|
||||||
closeThisWindow();
|
|
||||||
/* update details in table */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveTargetListner() {
|
private void saveTargetListner() {
|
||||||
@@ -213,13 +142,9 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void discardTargetListner() {
|
|
||||||
closeThisWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addNewTarget() {
|
private void addNewTarget() {
|
||||||
final String newControlllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerIDTextField.getValue());
|
final String newControlllerId = HawkbitCommonUtil.trimAndNullIfEmpty(controllerIDTextField.getValue());
|
||||||
if (mandatoryCheck(newControlllerId) && duplicateCheck(newControlllerId)) {
|
if (duplicateCheck(newControlllerId)) {
|
||||||
final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue());
|
final String newName = HawkbitCommonUtil.trimAndNullIfEmpty(nameTextField.getValue());
|
||||||
final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
final String newDesc = HawkbitCommonUtil.trimAndNullIfEmpty(descTextArea.getValue());
|
||||||
|
|
||||||
@@ -236,15 +161,20 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
|
|
||||||
/* display success msg */
|
/* display success msg */
|
||||||
uINotification.displaySuccess(i18n.get("message.save.success", new Object[] { newTarget.getName() }));
|
uINotification.displaySuccess(i18n.get("message.save.success", new Object[] { newTarget.getName() }));
|
||||||
/* close the window */
|
|
||||||
closeThisWindow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Window getWindow() {
|
public Window getWindow() {
|
||||||
eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
|
eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
|
||||||
window = SPUIComponentProvider.getWindow(i18n.get("caption.add.new.target"), null,
|
window = SPUIWindowDecorator.getWindow(i18n.get("caption.add.new.target"), null,
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), event -> discardTargetListner(), null);
|
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> saveTargetListner(), null, null, formLayout, i18n);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Window getWindow(final String entityId) {
|
||||||
|
populateValuesOfTarget(entityId);
|
||||||
|
getWindow();
|
||||||
|
window.addStyleName("target-update-window");
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,39 +184,23 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
public void resetComponents() {
|
public void resetComponents() {
|
||||||
nameTextField.clear();
|
nameTextField.clear();
|
||||||
nameTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
nameTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||||
controllerIDTextField.setEnabled(true);
|
controllerIDTextField.setEnabled(Boolean.TRUE);
|
||||||
controllerIDTextField.setReadOnly(false);
|
|
||||||
controllerIDTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
controllerIDTextField.removeStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
||||||
controllerIDTextField.clear();
|
controllerIDTextField.clear();
|
||||||
descTextArea.clear();
|
descTextArea.clear();
|
||||||
editTarget = Boolean.FALSE;
|
editTarget = Boolean.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeThisWindow() {
|
|
||||||
editTarget = Boolean.FALSE;
|
|
||||||
window.close();
|
|
||||||
UI.getCurrent().removeWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setTargetValues(final Target target, final String name, final String description) {
|
private void setTargetValues(final Target target, final String name, final String description) {
|
||||||
target.setName(name == null ? target.getControllerId() : name);
|
target.setName(name == null ? target.getControllerId() : name);
|
||||||
target.setDescription(description);
|
target.setDescription(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mandatoryCheck(final String newControlllerId) {
|
|
||||||
if (newControlllerId == null) {
|
|
||||||
controllerIDTextField.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR);
|
|
||||||
uINotification.displayValidationError("Mandatory details are missing");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean duplicateCheck(final String newControlllerId) {
|
private boolean duplicateCheck(final String newControlllerId) {
|
||||||
final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim());
|
final Target existingTarget = targetManagement.findTargetByControllerID(newControlllerId.trim());
|
||||||
if (existingTarget != null) {
|
if (existingTarget != null) {
|
||||||
uINotification.displayValidationError(i18n.get("message.target.duplicate.check"));
|
uINotification.displayValidationError(
|
||||||
|
i18n.get("message.target.duplicate.check", new Object[] { newControlllerId }));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
@@ -296,22 +210,21 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
/**
|
/**
|
||||||
* @param controllerId
|
* @param controllerId
|
||||||
*/
|
*/
|
||||||
public void populateValuesOfTarget(final String controllerId) {
|
private void populateValuesOfTarget(final String controllerId) {
|
||||||
resetComponents();
|
resetComponents();
|
||||||
this.controllerId = controllerId;
|
this.controllerId = controllerId;
|
||||||
editTarget = Boolean.TRUE;
|
editTarget = Boolean.TRUE;
|
||||||
final Target target = targetManagement.findTargetByControllerID(controllerId);
|
final Target target = targetManagement.findTargetByControllerID(controllerId);
|
||||||
controllerIDTextField.setValue(target.getControllerId());
|
controllerIDTextField.setValue(target.getControllerId());
|
||||||
controllerIDTextField.setReadOnly(Boolean.TRUE);
|
controllerIDTextField.setEnabled(Boolean.FALSE);
|
||||||
nameTextField.setValue(target.getName());
|
nameTextField.setValue(target.getName());
|
||||||
if (target.getDescription() != null) {
|
if (target.getDescription() != null) {
|
||||||
descTextArea.setValue(target.getDescription());
|
descTextArea.setValue(target.getDescription());
|
||||||
}
|
}
|
||||||
window.setSaveButtonEnabled(Boolean.FALSE);
|
}
|
||||||
|
|
||||||
oldTargetDesc = descTextArea.getValue();
|
public FormLayout getFormLayout() {
|
||||||
oldTargetName = nameTextField.getValue();
|
return formLayout;
|
||||||
window.addStyleName("target-update-window");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import com.google.common.base.Strings;
|
|||||||
public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
||||||
private static final long serialVersionUID = -5645680058303167558L;
|
private static final long serialVersionUID = -5645680058303167558L;
|
||||||
private Sort sort = new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
|
private Sort sort = new Sort(SPUIDefinitions.TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
|
||||||
private Collection<TargetUpdateStatus> status = null;
|
private transient Collection<TargetUpdateStatus> status = null;
|
||||||
private String[] targetTags = null;
|
private String[] targetTags = null;
|
||||||
private Long distributionId = null;
|
private Long distributionId = null;
|
||||||
private String searchText = null;
|
private String searchText = null;
|
||||||
|
|||||||
@@ -106,8 +106,13 @@ public class TargetDetails extends AbstractTableDetailsLayout<Target> {
|
|||||||
if (getSelectedBaseEntity() == null) {
|
if (getSelectedBaseEntity() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
targetAddUpdateWindowLayout.getWindow(getSelectedBaseEntity().getControllerId());
|
||||||
|
// targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId());
|
||||||
|
openWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openWindow() {
|
||||||
final Window newDistWindow = targetAddUpdateWindowLayout.getWindow();
|
final Window newDistWindow = targetAddUpdateWindowLayout.getWindow();
|
||||||
targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId());
|
|
||||||
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
newDistWindow.setCaption(getI18n().get("caption.update.dist"));
|
||||||
UI.getCurrent().addWindow(newDistWindow);
|
UI.getCurrent().addWindow(newDistWindow);
|
||||||
newDistWindow.setVisible(Boolean.TRUE);
|
newDistWindow.setVisible(Boolean.TRUE);
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(final ClickEvent event) {
|
public void save(final ClickEvent event) {
|
||||||
if (mandatoryValuesPresent()) {
|
|
||||||
final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue());
|
final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue());
|
||||||
if (optiongroup.getValue().equals(createTagStr)) {
|
if (optiongroup.getValue().equals(createTagStr)) {
|
||||||
if (!checkIsDuplicate(existingTag)) {
|
if (!checkIsDuplicate(existingTag)) {
|
||||||
@@ -112,7 +111,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
|||||||
updateExistingTag(existingTag);
|
updateExistingTag(existingTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new tag.
|
* Create new tag.
|
||||||
@@ -131,7 +129,6 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
|||||||
}
|
}
|
||||||
newTargetTag = tagManagement.createTargetTag(newTargetTag);
|
newTargetTag = tagManagement.createTargetTag(newTargetTag);
|
||||||
displaySuccess(newTargetTag.getName());
|
displaySuccess(newTargetTag.getName());
|
||||||
closeWindow();
|
|
||||||
} else {
|
} else {
|
||||||
displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME));
|
displayValidationError(i18n.get(MESSAGE_ERROR_MISSING_TAGNAME));
|
||||||
}
|
}
|
||||||
@@ -150,4 +147,9 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
|
|||||||
setOptionGroupDefaultValue(permChecker.hasCreateTargetPermission(), permChecker.hasUpdateTargetPermission());
|
setOptionGroupDefaultValue(permChecker.hasCreateTargetPermission(), permChecker.hasUpdateTargetPermission());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getWindowCaption() {
|
||||||
|
return i18n.get("caption.add.tag");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.eclipse.hawkbit.ui.UiProperties;
|
|||||||
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||||
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
||||||
import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery;
|
import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery;
|
||||||
import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout;
|
import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout;
|
||||||
import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption;
|
import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption;
|
||||||
@@ -56,8 +57,10 @@ import com.vaadin.data.Container;
|
|||||||
import com.vaadin.data.Item;
|
import com.vaadin.data.Item;
|
||||||
import com.vaadin.data.Property.ValueChangeEvent;
|
import com.vaadin.data.Property.ValueChangeEvent;
|
||||||
import com.vaadin.data.Validator;
|
import com.vaadin.data.Validator;
|
||||||
|
import com.vaadin.data.util.converter.StringToIntegerConverter;
|
||||||
import com.vaadin.data.validator.IntegerRangeValidator;
|
import com.vaadin.data.validator.IntegerRangeValidator;
|
||||||
import com.vaadin.data.validator.RegexpValidator;
|
import com.vaadin.data.validator.NullValidator;
|
||||||
|
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.ComboBox;
|
import com.vaadin.ui.ComboBox;
|
||||||
@@ -66,13 +69,10 @@ import com.vaadin.ui.Label;
|
|||||||
import com.vaadin.ui.OptionGroup;
|
import com.vaadin.ui.OptionGroup;
|
||||||
import com.vaadin.ui.TextArea;
|
import com.vaadin.ui.TextArea;
|
||||||
import com.vaadin.ui.TextField;
|
import com.vaadin.ui.TextField;
|
||||||
import com.vaadin.ui.UI;
|
|
||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Rollout add or update popup layout.
|
* Rollout add or update popup layout.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
@@ -86,8 +86,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
private static final String MESSAGE_ENTER_NUMBER = "message.enter.number";
|
private static final String MESSAGE_ENTER_NUMBER = "message.enter.number";
|
||||||
|
|
||||||
private static final String NUMBER_REGEXP = "[-]?[0-9]*\\.?,?[0-9]+";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ActionTypeOptionGroupLayout actionTypeOptionGroupLayout;
|
private ActionTypeOptionGroupLayout actionTypeOptionGroupLayout;
|
||||||
|
|
||||||
@@ -115,8 +113,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private transient EventBus.SessionEventBus eventBus;
|
private transient EventBus.SessionEventBus eventBus;
|
||||||
|
|
||||||
private Label mandatoryLabel;
|
|
||||||
|
|
||||||
private TextField rolloutName;
|
private TextField rolloutName;
|
||||||
|
|
||||||
private ComboBox distributionSet;
|
private ComboBox distributionSet;
|
||||||
@@ -135,7 +131,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
private OptionGroup errorThresholdOptionGroup;
|
private OptionGroup errorThresholdOptionGroup;
|
||||||
|
|
||||||
private CommonDialogWindow addUpdateRolloutWindow;
|
private CommonDialogWindow window;
|
||||||
|
|
||||||
private Boolean editRolloutEnabled;
|
private Boolean editRolloutEnabled;
|
||||||
|
|
||||||
@@ -147,22 +143,28 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
private TextArea targetFilterQuery;
|
private TextArea targetFilterQuery;
|
||||||
|
|
||||||
|
private final NullValidator nullValidator = new NullValidator(null, false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create components and layout.
|
* Create components and layout.
|
||||||
*/
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|
||||||
setSizeUndefined();
|
setSizeUndefined();
|
||||||
createRequiredComponents();
|
createRequiredComponents();
|
||||||
buildLayout();
|
buildLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommonDialogWindow getWindow() {
|
public CommonDialogWindow getWindow(final Long rolloutId) {
|
||||||
|
window = getWindow();
|
||||||
|
populateData(rolloutId);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
addUpdateRolloutWindow = SPUIComponentProvider.getWindow(i18n.get("caption.configure.rollout"), null,
|
public CommonDialogWindow getWindow() {
|
||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), event -> onDiscard(),
|
resetComponents();
|
||||||
uiProperties.getLinks().getDocumentation().getRolloutView());
|
return SPUIWindowDecorator.getWindow(i18n.get("caption.configure.rollout"), null,
|
||||||
return addUpdateRolloutWindow;
|
SPUIDefinitions.CREATE_UPDATE_WINDOW, this, event -> onRolloutSave(), null,
|
||||||
|
uiProperties.getLinks().getDocumentation().getRolloutView(), this, i18n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,10 +181,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
setDefaultSaveStartGroupOption();
|
setDefaultSaveStartGroupOption();
|
||||||
totalTargetsLabel.setVisible(false);
|
totalTargetsLabel.setVisible(false);
|
||||||
groupSizeLabel.setVisible(false);
|
groupSizeLabel.setVisible(false);
|
||||||
removeComponent(targetFilterQuery);
|
removeComponent(1, 2);
|
||||||
if (getComponent(1, 3) == null) {
|
addComponent(targetFilterQueryCombo, 1, 2);
|
||||||
addComponent(targetFilterQueryCombo, 1, 3);
|
|
||||||
}
|
|
||||||
actionTypeOptionGroupLayout.selectDefaultOption();
|
actionTypeOptionGroupLayout.selectDefaultOption();
|
||||||
totalTargetsCount = 0L;
|
totalTargetsCount = 0L;
|
||||||
rolloutForEdit = null;
|
rolloutForEdit = null;
|
||||||
@@ -206,37 +206,60 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
setSizeUndefined();
|
setSizeUndefined();
|
||||||
setRows(9);
|
setRows(9);
|
||||||
setColumns(3);
|
setColumns(3);
|
||||||
|
setStyleName("marginTop");
|
||||||
|
|
||||||
addComponent(mandatoryLabel, 1, 0, 2, 0);
|
addComponent(getMandatoryLabel("textfield.name"), 0, 0);
|
||||||
addComponent(getLabel("textfield.name"), 0, 1);
|
addComponent(rolloutName, 1, 0);
|
||||||
addComponent(rolloutName, 1, 1);
|
rolloutName.addValidator(nullValidator);
|
||||||
addComponent(getLabel("prompt.distribution.set"), 0, 2);
|
|
||||||
addComponent(distributionSet, 1, 2);
|
addComponent(getMandatoryLabel("prompt.distribution.set"), 0, 1);
|
||||||
addComponent(getLabel("prompt.target.filter"), 0, 3);
|
addComponent(distributionSet, 1, 1);
|
||||||
addComponent(targetFilterQueryCombo, 1, 3);
|
distributionSet.addValidator(nullValidator);
|
||||||
addComponent(totalTargetsLabel, 2, 3);
|
|
||||||
addComponent(getLabel("prompt.number.of.groups"), 0, 4);
|
addComponent(getMandatoryLabel("prompt.target.filter"), 0, 2);
|
||||||
addComponent(noOfGroups, 1, 4);
|
addComponent(targetFilterQueryCombo, 1, 2);
|
||||||
addComponent(groupSizeLabel, 2, 4);
|
targetFilterQueryCombo.addValidator(nullValidator);
|
||||||
addComponent(getLabel("prompt.tigger.threshold"), 0, 5);
|
targetFilterQuery.removeValidator(nullValidator);
|
||||||
addComponent(triggerThreshold, 1, 5);
|
|
||||||
addComponent(getPercentHintLabel(), 2, 5);
|
addComponent(totalTargetsLabel, 2, 2);
|
||||||
addComponent(getLabel("prompt.error.threshold"), 0, 6);
|
|
||||||
addComponent(errorThreshold, 1, 6);
|
addComponent(getMandatoryLabel("prompt.number.of.groups"), 0, 3);
|
||||||
addComponent(errorThresholdOptionGroup, 2, 6);
|
addComponent(noOfGroups, 1, 3);
|
||||||
addComponent(getLabel("textfield.description"), 0, 7);
|
noOfGroups.addValidator(nullValidator);
|
||||||
addComponent(description, 1, 7, 2, 7);
|
|
||||||
addComponent(actionTypeOptionGroupLayout, 0, 8, 2, 8);
|
addComponent(groupSizeLabel, 2, 3);
|
||||||
|
|
||||||
|
addComponent(getMandatoryLabel("prompt.tigger.threshold"), 0, 4);
|
||||||
|
addComponent(triggerThreshold, 1, 4);
|
||||||
|
triggerThreshold.addValidator(nullValidator);
|
||||||
|
|
||||||
|
addComponent(getPercentHintLabel(), 2, 4);
|
||||||
|
|
||||||
|
addComponent(getMandatoryLabel("prompt.error.threshold"), 0, 5);
|
||||||
|
addComponent(errorThreshold, 1, 5);
|
||||||
|
errorThreshold.addValidator(nullValidator);
|
||||||
|
addComponent(errorThresholdOptionGroup, 2, 5);
|
||||||
|
|
||||||
|
addComponent(getLabel("textfield.description"), 0, 6);
|
||||||
|
addComponent(description, 1, 6, 2, 6);
|
||||||
|
addComponent(actionTypeOptionGroupLayout, 0, 7, 2, 7);
|
||||||
|
|
||||||
rolloutName.focus();
|
rolloutName.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Label getMandatoryLabel(final String key) {
|
||||||
|
final Label mandatoryLabel = getLabel(i18n.get(key));
|
||||||
|
mandatoryLabel.setContentMode(ContentMode.HTML);
|
||||||
|
mandatoryLabel.setValue(mandatoryLabel.getValue().concat(" <span style='color:#ed473b'>*</span>"));
|
||||||
|
return mandatoryLabel;
|
||||||
|
}
|
||||||
|
|
||||||
private Label getLabel(final String key) {
|
private Label getLabel(final String key) {
|
||||||
return SPUIComponentProvider.getLabel(i18n.get(key), SPUILabelDefinitions.SP_LABEL_SIMPLE);
|
return SPUIComponentProvider.getLabel(i18n.get(key), SPUILabelDefinitions.SP_LABEL_SIMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextField getTextfield(final String key) {
|
private TextField getTextfield(final String key) {
|
||||||
return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, true, null, i18n.get(key), true,
|
return SPUIComponentProvider.getTextField(null, "", ValoTheme.TEXTFIELD_TINY, false, null, i18n.get(key), true,
|
||||||
SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +271,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createRequiredComponents() {
|
private void createRequiredComponents() {
|
||||||
mandatoryLabel = createMandatoryLabel();
|
|
||||||
rolloutName = createRolloutNameField();
|
rolloutName = createRolloutNameField();
|
||||||
distributionSet = createDistributionSetCombo();
|
distributionSet = createDistributionSetCombo();
|
||||||
populateDistributionSet();
|
populateDistributionSet();
|
||||||
@@ -258,7 +280,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
noOfGroups = createNoOfGroupsField();
|
noOfGroups = createNoOfGroupsField();
|
||||||
groupSizeLabel = createGroupSizeLabel();
|
groupSizeLabel = createGroupSizeLabel();
|
||||||
triggerThreshold = createTriggerThresold();
|
triggerThreshold = createTriggerThreshold();
|
||||||
errorThreshold = createErrorThreshold();
|
errorThreshold = createErrorThreshold();
|
||||||
description = createDescription();
|
description = createDescription();
|
||||||
errorThresholdOptionGroup = createErrorThresholdOptionGroup();
|
errorThresholdOptionGroup = createErrorThresholdOptionGroup();
|
||||||
@@ -307,11 +329,11 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
|
errorThresoldOptions.addStyleName(ValoTheme.OPTIONGROUP_HORIZONTAL);
|
||||||
errorThresoldOptions.addStyleName(SPUIStyleDefinitions.ROLLOUT_OPTION_GROUP);
|
errorThresoldOptions.addStyleName(SPUIStyleDefinitions.ROLLOUT_OPTION_GROUP);
|
||||||
errorThresoldOptions.setSizeUndefined();
|
errorThresoldOptions.setSizeUndefined();
|
||||||
errorThresoldOptions.addValueChangeListener(this::onErrorThresoldOptionChange);
|
errorThresoldOptions.addValueChangeListener(this::listenerOnErrorThresoldOptionChange);
|
||||||
return errorThresoldOptions;
|
return errorThresoldOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onErrorThresoldOptionChange(final ValueChangeEvent event) {
|
private void listenerOnErrorThresoldOptionChange(final ValueChangeEvent event) {
|
||||||
errorThreshold.clear();
|
errorThreshold.clear();
|
||||||
errorThreshold.removeAllValidators();
|
errorThreshold.removeAllValidators();
|
||||||
if (event.getProperty().getValue().equals(ERRORTHRESOLDOPTIONS.COUNT.getValue())) {
|
if (event.getProperty().getValue().equals(ERRORTHRESOLDOPTIONS.COUNT.getValue())) {
|
||||||
@@ -324,17 +346,17 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
private ComboBox createTargetFilterQueryCombo() {
|
private ComboBox createTargetFilterQueryCombo() {
|
||||||
final ComboBox targetFilter = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL,
|
final ComboBox targetFilter = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL,
|
||||||
true, "", i18n.get("prompt.target.filter"));
|
false, "", i18n.get("prompt.target.filter"));
|
||||||
targetFilter.setImmediate(true);
|
targetFilter.setImmediate(true);
|
||||||
targetFilter.setPageLength(7);
|
targetFilter.setPageLength(7);
|
||||||
targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
targetFilter.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||||
targetFilter.setId(SPUIComponentIdProvider.ROLLOUT_TARGET_FILTER_COMBO_ID);
|
targetFilter.setId(SPUIComponentIdProvider.ROLLOUT_TARGET_FILTER_COMBO_ID);
|
||||||
targetFilter.setSizeUndefined();
|
targetFilter.setSizeUndefined();
|
||||||
targetFilter.addValueChangeListener(event -> onTargetFilterChange());
|
targetFilter.addValueChangeListener(this::onTargetFilterChange);
|
||||||
return targetFilter;
|
return targetFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onTargetFilterChange() {
|
private void onTargetFilterChange(final ValueChangeEvent event) {
|
||||||
final String filterQueryString = getTargetFilterQuery();
|
final String filterQueryString = getTargetFilterQuery();
|
||||||
if (!Strings.isNullOrEmpty(filterQueryString)) {
|
if (!Strings.isNullOrEmpty(filterQueryString)) {
|
||||||
totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(filterQueryString);
|
totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(filterQueryString);
|
||||||
@@ -344,7 +366,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
totalTargetsCount = 0L;
|
totalTargetsCount = 0L;
|
||||||
totalTargetsLabel.setVisible(false);
|
totalTargetsLabel.setVisible(false);
|
||||||
}
|
}
|
||||||
onGroupNumberChange();
|
onGroupNumberChange(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTotalTargetMessage() {
|
private String getTotalTargetMessage() {
|
||||||
@@ -368,10 +390,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
targetFilterQF);
|
targetFilterQF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDiscard() {
|
|
||||||
closeThisWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onRolloutSave() {
|
private void onRolloutSave() {
|
||||||
if (editRolloutEnabled) {
|
if (editRolloutEnabled) {
|
||||||
editRollout();
|
editRollout();
|
||||||
@@ -381,7 +399,7 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void editRollout() {
|
private void editRollout() {
|
||||||
if (mandatoryCheckForEdit() && validateFields() && duplicateCheckForEdit() && null != rolloutForEdit) {
|
if (duplicateCheckForEdit() && rolloutForEdit != null) {
|
||||||
rolloutForEdit.setName(rolloutName.getValue());
|
rolloutForEdit.setName(rolloutName.getValue());
|
||||||
rolloutForEdit.setDescription(description.getValue());
|
rolloutForEdit.setDescription(description.getValue());
|
||||||
final DistributionSetIdName distributionSetIdName = (DistributionSetIdName) distributionSet.getValue();
|
final DistributionSetIdName distributionSetIdName = (DistributionSetIdName) distributionSet.getValue();
|
||||||
@@ -399,7 +417,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
final Rollout updatedRollout = rolloutManagement.updateRollout(rolloutForEdit);
|
final Rollout updatedRollout = rolloutManagement.updateRollout(rolloutForEdit);
|
||||||
uiNotification
|
uiNotification
|
||||||
.displaySuccess(i18n.get("message.update.success", new Object[] { updatedRollout.getName() }));
|
.displaySuccess(i18n.get("message.update.success", new Object[] { updatedRollout.getName() }));
|
||||||
closeThisWindow();
|
|
||||||
eventBus.publish(this, RolloutEvent.UPDATE_ROLLOUT);
|
eventBus.publish(this, RolloutEvent.UPDATE_ROLLOUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -427,11 +444,10 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createRollout() {
|
private void createRollout() {
|
||||||
if (mandatoryCheck() && validateFields() && duplicateCheck()) {
|
if (duplicateCheck()) {
|
||||||
final Rollout rolloutToCreate = saveRollout();
|
final Rollout rolloutToCreate = saveRollout();
|
||||||
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { rolloutToCreate.getName() }));
|
uiNotification.displaySuccess(i18n.get("message.save.success", new Object[] { rolloutToCreate.getName() }));
|
||||||
eventBus.publish(this, RolloutEvent.CREATE_ROLLOUT);
|
eventBus.publish(this, RolloutEvent.CREATE_ROLLOUT);
|
||||||
closeThisWindow();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,48 +504,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeThisWindow() {
|
|
||||||
addUpdateRolloutWindow.close();
|
|
||||||
UI.getCurrent().removeWindow(addUpdateRolloutWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean mandatoryCheck() {
|
|
||||||
final DistributionSetIdName ds = getDistributionSetSelected();
|
|
||||||
final String targetFilter = (String) targetFilterQueryCombo.getValue();
|
|
||||||
final String triggerThresoldValue = triggerThreshold.getValue();
|
|
||||||
final String errorThresoldValue = errorThreshold.getValue();
|
|
||||||
if (hasNoNameOrTargetFilter(targetFilter) || ds == null
|
|
||||||
|| HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
|
||||||
|| isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) {
|
|
||||||
uiNotification.displayValidationError(i18n.get("message.mandatory.check"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean mandatoryCheckForEdit() {
|
|
||||||
final DistributionSetIdName ds = getDistributionSetSelected();
|
|
||||||
final String targetFilter = targetFilterQuery.getValue();
|
|
||||||
final String triggerThresoldValue = triggerThreshold.getValue();
|
|
||||||
final String errorThresoldValue = errorThreshold.getValue();
|
|
||||||
if (hasNoNameOrTargetFilter(targetFilter) || ds == null
|
|
||||||
|| HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
|
||||||
|| isThresholdValueMissing(triggerThresoldValue, errorThresoldValue)) {
|
|
||||||
uiNotification.displayValidationError(i18n.get("message.mandatory.check"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasNoNameOrTargetFilter(final String targetFilter) {
|
|
||||||
return getRolloutName() == null || targetFilter == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isThresholdValueMissing(final String triggerThresoldValue, final String errorThresoldValue) {
|
|
||||||
return HawkbitCommonUtil.trimAndNullIfEmpty(triggerThresoldValue) == null
|
|
||||||
|| HawkbitCommonUtil.trimAndNullIfEmpty(errorThresoldValue) == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean duplicateCheck() {
|
private boolean duplicateCheck() {
|
||||||
if (rolloutManagement.findRolloutByName(getRolloutName()) != null) {
|
if (rolloutManagement.findRolloutByName(getRolloutName()) != null) {
|
||||||
uiNotification.displayValidationError(
|
uiNotification.displayValidationError(
|
||||||
@@ -555,17 +529,23 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
private TextField createErrorThreshold() {
|
private TextField createErrorThreshold() {
|
||||||
final TextField errorField = getTextfield("prompt.error.threshold");
|
final TextField errorField = getTextfield("prompt.error.threshold");
|
||||||
|
errorField.setNullRepresentation("");
|
||||||
errorField.addValidator(new ThresholdFieldValidator());
|
errorField.addValidator(new ThresholdFieldValidator());
|
||||||
|
errorField.setConverter(new StringToIntegerConverter());
|
||||||
|
errorField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER));
|
||||||
errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID);
|
errorField.setId(SPUIComponentIdProvider.ROLLOUT_ERROR_THRESOLD_ID);
|
||||||
errorField.setMaxLength(7);
|
errorField.setMaxLength(7);
|
||||||
errorField.setSizeUndefined();
|
errorField.setSizeUndefined();
|
||||||
return errorField;
|
return errorField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextField createTriggerThresold() {
|
private TextField createTriggerThreshold() {
|
||||||
final TextField thresholdField = getTextfield("prompt.tigger.threshold");
|
final TextField thresholdField = getTextfield("prompt.tigger.threshold");
|
||||||
thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID);
|
thresholdField.setId(SPUIComponentIdProvider.ROLLOUT_TRIGGER_THRESOLD_ID);
|
||||||
|
thresholdField.setNullRepresentation("");
|
||||||
thresholdField.addValidator(new ThresholdFieldValidator());
|
thresholdField.addValidator(new ThresholdFieldValidator());
|
||||||
|
thresholdField.setConverter(new StringToIntegerConverter());
|
||||||
|
thresholdField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER));
|
||||||
thresholdField.setSizeUndefined();
|
thresholdField.setSizeUndefined();
|
||||||
thresholdField.setMaxLength(3);
|
thresholdField.setMaxLength(3);
|
||||||
return thresholdField;
|
return thresholdField;
|
||||||
@@ -577,12 +557,15 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
noOfGroupsField.addValidator(new GroupNumberValidator());
|
noOfGroupsField.addValidator(new GroupNumberValidator());
|
||||||
noOfGroupsField.setSizeUndefined();
|
noOfGroupsField.setSizeUndefined();
|
||||||
noOfGroupsField.setMaxLength(3);
|
noOfGroupsField.setMaxLength(3);
|
||||||
noOfGroupsField.addValueChangeListener(evevt -> onGroupNumberChange());
|
noOfGroupsField.setConverter(new StringToIntegerConverter());
|
||||||
|
noOfGroupsField.setConversionError(i18n.get(MESSAGE_ENTER_NUMBER));
|
||||||
|
noOfGroupsField.addValueChangeListener(this::onGroupNumberChange);
|
||||||
|
noOfGroupsField.setNullRepresentation("");
|
||||||
return noOfGroupsField;
|
return noOfGroupsField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onGroupNumberChange() {
|
private void onGroupNumberChange(final ValueChangeEvent event) {
|
||||||
if (noOfGroups.isValid() && !Strings.isNullOrEmpty(noOfGroups.getValue())) {
|
if (event.getProperty().getValue() != null && noOfGroups.isValid()) {
|
||||||
groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize())));
|
groupSizeLabel.setValue(getTargetPerGroupMessage(String.valueOf(getGroupSize())));
|
||||||
groupSizeLabel.setVisible(true);
|
groupSizeLabel.setVisible(true);
|
||||||
} else {
|
} else {
|
||||||
@@ -591,8 +574,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ComboBox createDistributionSetCombo() {
|
private ComboBox createDistributionSetCombo() {
|
||||||
final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, true, "",
|
final ComboBox dsSet = SPUIComponentProvider.getComboBox(null, "", "", null, ValoTheme.COMBOBOX_SMALL, false,
|
||||||
i18n.get("prompt.distribution.set"));
|
"", i18n.get("prompt.distribution.set"));
|
||||||
dsSet.setImmediate(true);
|
dsSet.setImmediate(true);
|
||||||
dsSet.setPageLength(7);
|
dsSet.setPageLength(7);
|
||||||
dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
dsSet.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME);
|
||||||
@@ -612,7 +595,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
return new LazyQueryContainer(
|
return new LazyQueryContainer(
|
||||||
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME),
|
new LazyQueryDefinition(true, SPUIDefinitions.PAGE_SIZE, SPUILabelDefinitions.VAR_DIST_ID_NAME),
|
||||||
distributionQF);
|
distributionQF);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextField createRolloutNameField() {
|
private TextField createRolloutNameField() {
|
||||||
@@ -622,44 +604,42 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
return rolloutNameField;
|
return rolloutNameField;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Label createMandatoryLabel() {
|
|
||||||
final Label madatoryLbl = new Label(i18n.get("label.mandatory.field"));
|
|
||||||
madatoryLbl.addStyleName(SPUIStyleDefinitions.SP_TEXTFIELD_ERROR + " " + ValoTheme.LABEL_SMALL);
|
|
||||||
return madatoryLbl;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getRolloutName() {
|
private String getRolloutName() {
|
||||||
return HawkbitCommonUtil.trimAndNullIfEmpty(rolloutName.getValue());
|
return HawkbitCommonUtil.trimAndNullIfEmpty(rolloutName.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private DistributionSetIdName getDistributionSetSelected() {
|
|
||||||
return (DistributionSetIdName) distributionSet.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ErrorThresoldOptionValidator implements Validator {
|
class ErrorThresoldOptionValidator implements Validator {
|
||||||
private static final long serialVersionUID = 9049939751976326550L;
|
private static final long serialVersionUID = 9049939751976326550L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validate(final Object value) {
|
public void validate(final Object value) {
|
||||||
try {
|
try {
|
||||||
if (HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
if (isNoOfGroupsOrTargetFilterEmpty()) {
|
||||||
|| HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null) {
|
|
||||||
uiNotification
|
uiNotification
|
||||||
.displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing"));
|
.displayValidationError(i18n.get("message.rollout.noofgroups.or.targetfilter.missing"));
|
||||||
} else {
|
} else {
|
||||||
new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value);
|
if (value != null) {
|
||||||
final int groupSize = getGroupSize();
|
final int groupSize = getGroupSize();
|
||||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0, groupSize)
|
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, groupSize), 0,
|
||||||
.validate(Integer.valueOf(value.toString()));
|
groupSize).validate(Integer.valueOf(value.toString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// suppress the need of preserve original exception, will blow
|
// suppress the need of preserve original exception, will blow
|
||||||
// up the
|
// up the
|
||||||
// log and not necessary here
|
// log and not necessary here
|
||||||
catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) {
|
catch (final InvalidValueException ex) {
|
||||||
LOG.error(ex.getMessage());
|
// we have to throw the exception here, otherwise the UI won't
|
||||||
|
// show the vaadin validation error!
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isNoOfGroupsOrTargetFilterEmpty() {
|
||||||
|
return HawkbitCommonUtil.trimAndNullIfEmpty(noOfGroups.getValue()) == null
|
||||||
|
|| (HawkbitCommonUtil.trimAndNullIfEmpty((String) targetFilterQueryCombo.getValue()) == null
|
||||||
|
&& targetFilterQuery.getValue() == null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getGroupSize() {
|
private int getGroupSize() {
|
||||||
@@ -672,15 +652,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
@Override
|
@Override
|
||||||
public void validate(final Object value) {
|
public void validate(final Object value) {
|
||||||
try {
|
try {
|
||||||
new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value);
|
if (value != null) {
|
||||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100)
|
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 100), 0, 100)
|
||||||
.validate(Integer.valueOf(value.toString()));
|
.validate(Integer.valueOf(value.toString()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// suppress the need of preserve original exception, will blow
|
// suppress the need of preserve original exception, will blow
|
||||||
// up the
|
// up the
|
||||||
// log and not necessary here
|
// log and not necessary here
|
||||||
catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) {
|
catch (final InvalidValueException ex) {
|
||||||
LOG.error(ex.getMessage());
|
// we have to throw the exception here, otherwise the UI won't
|
||||||
|
// show the vaadin validation error!
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -691,15 +674,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
@Override
|
@Override
|
||||||
public void validate(final Object value) {
|
public void validate(final Object value) {
|
||||||
try {
|
try {
|
||||||
new RegexpValidator(NUMBER_REGEXP, i18n.get(MESSAGE_ENTER_NUMBER)).validate(value);
|
if (value != null) {
|
||||||
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500)
|
new IntegerRangeValidator(i18n.get(MESSAGE_ROLLOUT_FIELD_VALUE_RANGE, 0, 500), 0, 500)
|
||||||
.validate(Integer.valueOf(value.toString()));
|
.validate(Integer.valueOf(value.toString()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// suppress the need of preserve original exception, will blow
|
// suppress the need of preserve original exception, will blow
|
||||||
// up the
|
// up the
|
||||||
// log and not necessary here
|
// log and not necessary here
|
||||||
catch (@SuppressWarnings("squid:S1166") final InvalidValueException ex) {
|
catch (final InvalidValueException ex) {
|
||||||
LOG.error(ex.getMessage());
|
// we have to throw the exception here, otherwise the UI won't
|
||||||
|
// show the vaadin validation error!
|
||||||
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -711,15 +697,18 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
* @param rolloutId
|
* @param rolloutId
|
||||||
* rollout id
|
* rollout id
|
||||||
*/
|
*/
|
||||||
public void populateData(final Long rolloutId) {
|
private void populateData(final Long rolloutId) {
|
||||||
resetComponents();
|
if (rolloutId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
editRolloutEnabled = Boolean.TRUE;
|
editRolloutEnabled = Boolean.TRUE;
|
||||||
rolloutForEdit = rolloutManagement.findRolloutById(rolloutId);
|
rolloutForEdit = rolloutManagement.findRolloutById(rolloutId);
|
||||||
rolloutName.setValue(rolloutForEdit.getName());
|
rolloutName.setValue(rolloutForEdit.getName());
|
||||||
description.setValue(rolloutForEdit.getDescription());
|
description.setValue(rolloutForEdit.getDescription());
|
||||||
distributionSet.setValue(DistributionSetIdName.generate(rolloutForEdit.getDistributionSet()));
|
distributionSet.setValue(DistributionSetIdName.generate(rolloutForEdit.getDistributionSet()));
|
||||||
final List<RolloutGroup> rolloutGroups = rolloutForEdit.getRolloutGroups();
|
final List<RolloutGroup> rolloutGroups = rolloutForEdit.getRolloutGroups();
|
||||||
setThresoldValues(rolloutGroups);
|
setThresholdValues(rolloutGroups);
|
||||||
setActionType(rolloutForEdit);
|
setActionType(rolloutForEdit);
|
||||||
if (rolloutForEdit.getStatus() != RolloutStatus.READY) {
|
if (rolloutForEdit.getStatus() != RolloutStatus.READY) {
|
||||||
disableRequiredFieldsOnEdit();
|
disableRequiredFieldsOnEdit();
|
||||||
@@ -727,12 +716,16 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
|
|
||||||
noOfGroups.setEnabled(false);
|
noOfGroups.setEnabled(false);
|
||||||
targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery());
|
targetFilterQuery.setValue(rolloutForEdit.getTargetFilterQuery());
|
||||||
removeComponent(targetFilterQueryCombo);
|
removeComponent(1, 2);
|
||||||
addComponent(targetFilterQuery, 1, 3);
|
targetFilterQueryCombo.removeValidator(nullValidator);
|
||||||
|
addComponent(targetFilterQuery, 1, 2);
|
||||||
|
targetFilterQuery.addValidator(nullValidator);
|
||||||
|
|
||||||
totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery());
|
totalTargetsCount = targetManagement.countTargetByTargetFilterQuery(rolloutForEdit.getTargetFilterQuery());
|
||||||
totalTargetsLabel.setValue(getTotalTargetMessage());
|
totalTargetsLabel.setValue(getTotalTargetMessage());
|
||||||
totalTargetsLabel.setVisible(true);
|
totalTargetsLabel.setVisible(true);
|
||||||
|
|
||||||
|
window.setOrginaleValues();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disableRequiredFieldsOnEdit() {
|
private void disableRequiredFieldsOnEdit() {
|
||||||
@@ -771,8 +764,8 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
/**
|
/**
|
||||||
* @param rolloutGroups
|
* @param rolloutGroups
|
||||||
*/
|
*/
|
||||||
private void setThresoldValues(final List<RolloutGroup> rolloutGroups) {
|
private void setThresholdValues(final List<RolloutGroup> rolloutGroups) {
|
||||||
if (null != rolloutGroups && !rolloutGroups.isEmpty()) {
|
if (rolloutGroups != null && !rolloutGroups.isEmpty()) {
|
||||||
errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp());
|
errorThreshold.setValue(rolloutGroups.get(0).getErrorConditionExp());
|
||||||
triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp());
|
triggerThreshold.setValue(rolloutGroups.get(0).getSuccessConditionExp());
|
||||||
noOfGroups.setValue(String.valueOf(rolloutGroups.size()));
|
noOfGroups.setValue(String.valueOf(rolloutGroups.size()));
|
||||||
@@ -798,7 +791,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ERRORTHRESOLDOPTIONS {
|
enum ERRORTHRESOLDOPTIONS {
|
||||||
@@ -816,6 +808,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout {
|
|||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.model.Rollout;
|
|||||||
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||||
|
import org.eclipse.hawkbit.ui.common.CommonDialogWindow;
|
||||||
import org.eclipse.hawkbit.ui.common.grid.AbstractGrid;
|
import org.eclipse.hawkbit.ui.common.grid.AbstractGrid;
|
||||||
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer;
|
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer;
|
||||||
@@ -62,14 +63,11 @@ 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;
|
||||||
import com.vaadin.ui.UI;
|
import com.vaadin.ui.UI;
|
||||||
import com.vaadin.ui.Window;
|
|
||||||
import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent;
|
import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent;
|
||||||
import com.vaadin.ui.renderers.HtmlRenderer;
|
import com.vaadin.ui.renderers.HtmlRenderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Rollout list grid component.
|
* Rollout list grid component.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
@@ -145,6 +143,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();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
||||||
@@ -159,7 +158,6 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
}
|
}
|
||||||
item.getItemProperty(ROLLOUT_RENDERER_DATA)
|
item.getItemProperty(ROLLOUT_RENDERER_DATA)
|
||||||
.setValue(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
|
.setValue(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -200,7 +198,6 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.ACTION, String.class,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.ACTION, String.class,
|
||||||
FontAwesome.CIRCLE_O.getHtml(), false, false);
|
FontAwesome.CIRCLE_O.getHtml(), false, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -292,7 +289,6 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
for (final Object propertyId : columnsToBeHidden) {
|
for (final Object propertyId : columnsToBeHidden) {
|
||||||
getColumn(propertyId).setHidden(true);
|
getColumn(propertyId).setHidden(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -315,7 +311,6 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRolloutStatusToFontMap() {
|
private void createRolloutStatusToFontMap() {
|
||||||
@@ -437,8 +432,7 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onUpdate(final ContextMenuData contextMenuData) {
|
private void onUpdate(final ContextMenuData contextMenuData) {
|
||||||
addUpdateRolloutWindow.populateData(contextMenuData.getRolloutId());
|
final CommonDialogWindow addTargetWindow = addUpdateRolloutWindow.getWindow(contextMenuData.getRolloutId());
|
||||||
final Window addTargetWindow = addUpdateRolloutWindow.getWindow();
|
|
||||||
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);
|
||||||
@@ -684,7 +678,6 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
public Class<String> getPresentationType() {
|
public Class<String> getPresentationType() {
|
||||||
return String.class;
|
return String.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ public class RolloutListHeader extends AbstractGridHeader {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addNewItem(final ClickEvent event) {
|
protected void addNewItem(final ClickEvent event) {
|
||||||
addUpdateRolloutWindow.resetComponents();
|
|
||||||
final Window addTargetWindow = addUpdateRolloutWindow.getWindow();
|
final Window addTargetWindow = addUpdateRolloutWindow.getWindow();
|
||||||
UI.getCurrent().addWindow(addTargetWindow);
|
UI.getCurrent().addWindow(addTargetWindow);
|
||||||
addTargetWindow.setVisible(Boolean.TRUE);
|
addTargetWindow.setVisible(Boolean.TRUE);
|
||||||
|
|||||||
@@ -176,6 +176,10 @@ public final class SPUIComponentIdProvider {
|
|||||||
* ID - Dist jvm combo.
|
* ID - Dist jvm combo.
|
||||||
*/
|
*/
|
||||||
public static final String DIST_MODULE_COMBO = "dist.module.combo.";
|
public static final String DIST_MODULE_COMBO = "dist.module.combo.";
|
||||||
|
/**
|
||||||
|
* ID for Distribution Tag ComboBox
|
||||||
|
*/
|
||||||
|
public static final String DIST_TAG_COMBO = "dist.tag.combo";
|
||||||
/**
|
/**
|
||||||
* ID-Dist.PIN.
|
* ID-Dist.PIN.
|
||||||
*/
|
*/
|
||||||
@@ -302,6 +306,22 @@ public final class SPUIComponentIdProvider {
|
|||||||
* tag color preview button id.
|
* tag color preview button id.
|
||||||
*/
|
*/
|
||||||
public static final String TAG_COLOR_PREVIEW_ID = "tag.color.preview";
|
public static final String TAG_COLOR_PREVIEW_ID = "tag.color.preview";
|
||||||
|
/**
|
||||||
|
* Id for ColorPickerLayout
|
||||||
|
*/
|
||||||
|
public static final String COLOR_PICKER_LAYOUT = "color.picker.layout";
|
||||||
|
/**
|
||||||
|
* Id for ColorPickerLayout's red slider
|
||||||
|
*/
|
||||||
|
public static final String COLOR_PICKER_RED_SLIDER = "color.picker.red.slider";
|
||||||
|
/**
|
||||||
|
* Id for Color preview field with the color code
|
||||||
|
*/
|
||||||
|
public static final String COLOR_PREVIEW_FIELD = "color-preview-field";
|
||||||
|
/**
|
||||||
|
* Id for OptionGroup Create/Update tag
|
||||||
|
*/
|
||||||
|
public static final String OPTION_GROUP = "create.update.tag";
|
||||||
/**
|
/**
|
||||||
* Confirmation dialogue OK button id.
|
* Confirmation dialogue OK button id.
|
||||||
*/
|
*/
|
||||||
@@ -915,6 +935,11 @@ public final class SPUIComponentIdProvider {
|
|||||||
*/
|
*/
|
||||||
public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id";
|
public static final String UPLOAD_STATUS_POPUP_ID = "artifact.upload.status.popup.id";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table multiselect for selecting DistType
|
||||||
|
*/
|
||||||
|
public static final String SELECT_DIST_TYPE = "select-dist-type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /* Private Constructor.
|
* /* Private Constructor.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -293,8 +293,4 @@
|
|||||||
padding-bottom: 12px !important;
|
padding-bottom: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-button-default-color {
|
|
||||||
color: #551f62;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,4 +53,8 @@
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.marginTop {
|
||||||
|
margin-top: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,5 +164,6 @@
|
|||||||
|
|
||||||
.actionButtonsMargin {
|
.actionButtonsMargin {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,14 +79,14 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules
|
|||||||
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
||||||
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
||||||
caption.attributes = Attributes
|
caption.attributes = Attributes
|
||||||
caption.panel.dist.installed = Installed distribution set
|
caption.panel.dist.installed = Installed Distribution Set
|
||||||
caption.panel.dist.assigned = Assigned distribution set
|
caption.panel.dist.assigned = Assigned Distribution Set
|
||||||
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
||||||
caption.cancel.action.confirmbox = Confirm action cancel
|
caption.cancel.action.confirmbox = Confirm Action Cancellation
|
||||||
caption.forcequit.action.confirmbox = Confirm force quit action
|
caption.forcequit.action.confirmbox = Confirm force quit action
|
||||||
caption.forced.datefield = Force update at time
|
caption.forced.datefield = Force update at time
|
||||||
caption.force.action.confirmbox = Confirm Force Active Action
|
caption.force.action.confirmbox = Confirm Force Active Action
|
||||||
caption.confirm.abort.action = Confirm abort action
|
caption.confirm.abort.action = Confirm Abort Action
|
||||||
|
|
||||||
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ message.duplicate.softwaremodule = {0} : {1} already exists!
|
|||||||
message.tag.delete = Please unclick the tag {0}, then try to delete
|
message.tag.delete = Please unclick the tag {0}, then try to delete
|
||||||
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
||||||
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
||||||
message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete
|
message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete
|
||||||
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
||||||
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
||||||
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
||||||
@@ -262,10 +262,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre
|
|||||||
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
||||||
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
||||||
message.dist.no.operation = {0} - already assigned/installed, No operation
|
message.dist.no.operation = {0} - already assigned/installed, No operation
|
||||||
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module?
|
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module?
|
||||||
message.error.os.softmodule = Please select the OS to delete
|
message.error.os.softmodule = Please select the OS to delete
|
||||||
message.error.ah.softmodule = Please select the Application to delete
|
message.error.ah.softmodule = Please select the Application to delete
|
||||||
message.error.softmodule.deleted = The selected software module is already deleted
|
message.error.softmodule.deleted = The selected Software Module is already deleted
|
||||||
message.cancel.action = Cancel..
|
message.cancel.action = Cancel..
|
||||||
message.cancel.action.success = Action cancelled successfully !
|
message.cancel.action.success = Action cancelled successfully !
|
||||||
message.cancel.action.failed = Unable to cancel the action !
|
message.cancel.action.failed = Unable to cancel the action !
|
||||||
@@ -284,7 +284,7 @@ message.action.not.allowed = Action not allowed
|
|||||||
message.onlyone.distribution.assigned = Only one distribution set can be assigned
|
message.onlyone.distribution.assigned = Only one distribution set can be assigned
|
||||||
message.onlyone.distribution.dropallowed = Only one distribution set can be dropped
|
message.onlyone.distribution.dropallowed = Only one distribution set can be dropped
|
||||||
message.error.missing.typename = Missing Type Name
|
message.error.missing.typename = Missing Type Name
|
||||||
message.error.missing.typenameorkey = Missing Type Name or Key or software module type
|
message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type
|
||||||
message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0}
|
message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0}
|
||||||
message.no.targets.assiged.fortag = No targets are assigned to tag {0}
|
message.no.targets.assiged.fortag = No targets are assigned to tag {0}
|
||||||
message.error.missing.tagname = Please select tag name
|
message.error.missing.tagname = Please select tag name
|
||||||
@@ -314,12 +314,12 @@ soft.module.os =OS
|
|||||||
#Artifact upload
|
#Artifact upload
|
||||||
message.error.noFileSelected = No file selected for upload
|
message.error.noFileSelected = No file selected for upload
|
||||||
message.error.noProvidedName = Please provide custom file name
|
message.error.noProvidedName = Please provide custom file name
|
||||||
message.error.noSwModuleSelected = Please select a software module
|
message.error.noSwModuleSelected = Please select a Software Module
|
||||||
message.no.duplicateFiles = Duplicate files selected
|
message.no.duplicateFiles = Duplicate files selected
|
||||||
message.no.duplicateFile = Duplicate file selected :
|
message.no.duplicateFile = Duplicate file selected :
|
||||||
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
||||||
message.duplicate.filename = Duplicate file name
|
message.duplicate.filename = Duplicate file name
|
||||||
message.swModule.deleted = {0} Software module(s) deleted
|
message.swModule.deleted = {0} Software Module(s) deleted
|
||||||
message.upload.failed = Streaming Failed
|
message.upload.failed = Streaming Failed
|
||||||
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
||||||
message.uploadedfile.aborted = File upload aborted
|
message.uploadedfile.aborted = File upload aborted
|
||||||
@@ -329,7 +329,7 @@ message.abort.upload = Are you sure that you want to abort the upload?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
upload.swModuleTable.header = Software module
|
upload.swModuleTable.header = Software Module
|
||||||
upload.selectedfile.name = file selected for upload
|
upload.selectedfile.name = file selected for upload
|
||||||
upload.file.name = File name
|
upload.file.name = File name
|
||||||
upload.sha1 = SHA1 checksum
|
upload.sha1 = SHA1 checksum
|
||||||
@@ -347,7 +347,7 @@ upload.reason = Reason
|
|||||||
upload.action = Action
|
upload.action = Action
|
||||||
upload.result.status = Upload status
|
upload.result.status = Upload status
|
||||||
upload.file = Upload File
|
upload.file = Upload File
|
||||||
upload.caption.update.swmodule = Update software module
|
upload.caption.update.swmodule = Update Software Module
|
||||||
caption.tab.details = Details
|
caption.tab.details = Details
|
||||||
caption.tab.description = Description
|
caption.tab.description = Description
|
||||||
|
|
||||||
@@ -363,8 +363,8 @@ label.no.tag.assigned = NO TAG
|
|||||||
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
||||||
message.software.assignment = {0} Software Module(s) Assignment(s) done
|
message.software.assignment = {0} Software Module(s) Assignment(s) done
|
||||||
message.dist.inuse = {0} Distribution is already assigned to target
|
message.dist.inuse = {0} Distribution is already assigned to target
|
||||||
message.software.dist.already.assigned = {0} Distribution already has software module {1}
|
message.software.dist.already.assigned = {0} Distribution already has Software Module {1}
|
||||||
message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1}
|
message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1}
|
||||||
message.target.assigned = {0} is assigned to {1}
|
message.target.assigned = {0} is assigned to {1}
|
||||||
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
||||||
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
||||||
@@ -445,7 +445,7 @@ header.caption.mandatory = Mandatory
|
|||||||
header.caption.typename = SoftwareModuleType
|
header.caption.typename = SoftwareModuleType
|
||||||
header.caption.softwaremodule = SoftwareModule
|
header.caption.softwaremodule = SoftwareModule
|
||||||
header.caption.unassign = Unassign
|
header.caption.unassign = Unassign
|
||||||
message.sw.unassigned = Software module {0} successfully unassigned
|
message.sw.unassigned = Software Module {0} successfully unassigned
|
||||||
header.caption.upload.details = Upload details
|
header.caption.upload.details = Upload details
|
||||||
combo.type.tag.name = Type tag name
|
combo.type.tag.name = Type tag name
|
||||||
|
|
||||||
@@ -468,10 +468,10 @@ rollout.group.label.target.truncated = {0} targets has been truncated in the lis
|
|||||||
prompt.number.of.groups = Number of groups
|
prompt.number.of.groups = Number of groups
|
||||||
prompt.tigger.threshold = Trigger threshold
|
prompt.tigger.threshold = Trigger threshold
|
||||||
prompt.error.threshold = Error threshold
|
prompt.error.threshold = Error threshold
|
||||||
prompt.distribution.set = Distribution set
|
prompt.distribution.set = Distribution Set
|
||||||
caption.configure.rollout = Configure rollout
|
caption.configure.rollout = Configure Rollout
|
||||||
caption.update.rollout = Update rollout
|
caption.update.rollout = Update Rollout
|
||||||
prompt.target.filter = Custom target filter
|
prompt.target.filter = Custom Target Filter
|
||||||
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
||||||
message.rollout.max.group.number = Number of groups must not be greater than 500
|
message.rollout.max.group.number = Number of groups must not be greater than 500
|
||||||
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
||||||
@@ -485,8 +485,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou
|
|||||||
message.rollouts = Rollouts
|
message.rollouts = Rollouts
|
||||||
label.target.per.group = Targets per group :
|
label.target.per.group = Targets per group :
|
||||||
message.dist.already.assigned = Distribution {0} is already assigned to target
|
message.dist.already.assigned = Distribution {0} is already assigned to target
|
||||||
message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator
|
message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator
|
||||||
message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator
|
message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator
|
||||||
#rollout - end
|
#rollout - end
|
||||||
|
|
||||||
#Menu
|
#Menu
|
||||||
|
|||||||
@@ -77,16 +77,16 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules
|
|||||||
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
||||||
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
||||||
caption.attributes = Attributes
|
caption.attributes = Attributes
|
||||||
caption.panel.dist.installed = Installed distribution set
|
caption.panel.dist.installed = Installed Distribution Set
|
||||||
caption.panel.dist.assigned = Assigned distribution set
|
caption.panel.dist.assigned = Assigned Distribution Set
|
||||||
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
||||||
caption.cancel.action.confirmbox = Confirm action cancellation
|
caption.cancel.action.confirmbox = Confirm Action Cancellation
|
||||||
caption.forced.datefield = Force update at time
|
caption.forced.datefield = Force update at time
|
||||||
caption.force.action.confirmbox = Confirm Force Active Action
|
caption.force.action.confirmbox = Confirm Force Active Action
|
||||||
caption.filter.simple = Simple Filter
|
caption.filter.simple = Simple Filter
|
||||||
caption.filter.custom = Custom Filter
|
caption.filter.custom = Custom Filter
|
||||||
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
||||||
caption.confirm.abort.action = Confirm abort action
|
caption.confirm.abort.action = Confirm Abort Action
|
||||||
|
|
||||||
|
|
||||||
# Labels prefix with - label
|
# Labels prefix with - label
|
||||||
@@ -214,13 +214,13 @@ message.target.unassigned.one = {0} is unassigned from {1}
|
|||||||
message.target.unassigned.many = {0} Targets are unassigned from {1}
|
message.target.unassigned.many = {0} Targets are unassigned from {1}
|
||||||
message.target.assigned.pending = Some target(s) are already assigned.Pending for action
|
message.target.assigned.pending = Some target(s) are already assigned.Pending for action
|
||||||
message.cannot.delete = Cannot be deleted
|
message.cannot.delete = Cannot be deleted
|
||||||
message.check.softwaremodule = Please provide both name and verion!
|
message.check.softwaremodule = Please provide both name and version!
|
||||||
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
||||||
message.duplicate.softwaremodule = {0} : {1} already exists!
|
message.duplicate.softwaremodule = {0} : {1} already exists!
|
||||||
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
message.cannot.delete.default.dstype = Default distribution set type cannot be deleted
|
||||||
message.tag.delete = Please unclick the tag {0}, then try to delete
|
message.tag.delete = Please unclick the tag {0}, then try to delete
|
||||||
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
||||||
message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete
|
message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete
|
||||||
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
||||||
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
||||||
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
||||||
@@ -243,7 +243,7 @@ message.accessdenied.view = No access to view: {0}
|
|||||||
message.no.data = No data available
|
message.no.data = No data available
|
||||||
message.target.assignment = {0} Assignment(s) done
|
message.target.assignment = {0} Assignment(s) done
|
||||||
message.target.deleted = {0} Target(s) deleted
|
message.target.deleted = {0} Target(s) deleted
|
||||||
message.dist.deleted = {0} Distribution set(s) deleted
|
message.dist.deleted = {0} Distribution Set(s) deleted
|
||||||
message.tag.update.mandatory = Please select the Tag to update
|
message.tag.update.mandatory = Please select the Tag to update
|
||||||
message.tag.duplicate.check = {0} already exists, please enter another value
|
message.tag.duplicate.check = {0} already exists, please enter another value
|
||||||
message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value
|
message.type.key.duplicate.check = Distribution type with key {0} already exists, please give another value
|
||||||
@@ -262,10 +262,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre
|
|||||||
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
||||||
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
||||||
message.dist.no.operation = {0} - already assigned/installed, No operation
|
message.dist.no.operation = {0} - already assigned/installed, No operation
|
||||||
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module?
|
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module?
|
||||||
message.error.os.softmodule = Please select the OS to delete
|
message.error.os.softmodule = Please select the OS to delete
|
||||||
message.error.ah.softmodule = Please select the Application to delete
|
message.error.ah.softmodule = Please select the Application to delete
|
||||||
message.error.softmodule.deleted = The selected software module is already deleted
|
message.error.softmodule.deleted = The selected Software Module is already deleted
|
||||||
message.cancel.action = Cancel
|
message.cancel.action = Cancel
|
||||||
message.cancel.action.success = Action cancelled successfully !
|
message.cancel.action.success = Action cancelled successfully !
|
||||||
message.cancel.action.failed = Unable to cancel the action !
|
message.cancel.action.failed = Unable to cancel the action !
|
||||||
@@ -307,12 +307,12 @@ soft.module.os =OS
|
|||||||
#Artifact upload
|
#Artifact upload
|
||||||
message.error.noFileSelected = No file selected for upload
|
message.error.noFileSelected = No file selected for upload
|
||||||
message.error.noProvidedName = Please provide custom file name
|
message.error.noProvidedName = Please provide custom file name
|
||||||
message.error.noSwModuleSelected = Please select a software module
|
message.error.noSwModuleSelected = Please select a Software Module
|
||||||
message.no.duplicateFiles = Duplicate files selected
|
message.no.duplicateFiles = Duplicate files selected
|
||||||
message.no.duplicateFile = Duplicate file selected :
|
message.no.duplicateFile = Duplicate file selected :
|
||||||
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
||||||
message.duplicate.filename = Duplicate file name
|
message.duplicate.filename = Duplicate file name
|
||||||
message.swModule.deleted = {0} Software module(s) deleted
|
message.swModule.deleted = {0} Software Module(s) deleted
|
||||||
message.error.missing.tagname = Please select tag name
|
message.error.missing.tagname = Please select tag name
|
||||||
message.upload.failed = Streaming Failed
|
message.upload.failed = Streaming Failed
|
||||||
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
||||||
@@ -323,7 +323,7 @@ message.abort.upload = Are you sure that you want to abort the upload?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
upload.swModuleTable.header = Software module
|
upload.swModuleTable.header = Software Module
|
||||||
upload.selectedfile.name = file selected for upload
|
upload.selectedfile.name = file selected for upload
|
||||||
upload.file.name = File name
|
upload.file.name = File name
|
||||||
upload.sha1 = SHA1 checksum
|
upload.sha1 = SHA1 checksum
|
||||||
@@ -341,7 +341,7 @@ upload.reason = Reason
|
|||||||
upload.action = Action
|
upload.action = Action
|
||||||
upload.result.status = Upload status
|
upload.result.status = Upload status
|
||||||
upload.file = Upload File
|
upload.file = Upload File
|
||||||
upload.caption.update.swmodule = Update software module
|
upload.caption.update.swmodule = Update Software Module
|
||||||
caption.tab.details = Details
|
caption.tab.details = Details
|
||||||
caption.tab.description = Description
|
caption.tab.description = Description
|
||||||
|
|
||||||
@@ -352,8 +352,8 @@ label.drop.dist.delete.area = Drop here<br>to delete
|
|||||||
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
||||||
message.software.assignment = {0} Assignment(s) done
|
message.software.assignment = {0} Assignment(s) done
|
||||||
message.dist.inuse = {0} Distribution is already assigned to target
|
message.dist.inuse = {0} Distribution is already assigned to target
|
||||||
message.software.dist.already.assigned = {0} Distribution already has software module {1}
|
message.software.dist.already.assigned = {0} Distribution already has Software Module {1}
|
||||||
message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1}
|
message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1}
|
||||||
message.target.assigned = {0} is assigned to {1}
|
message.target.assigned = {0} is assigned to {1}
|
||||||
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
||||||
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
||||||
@@ -432,13 +432,13 @@ header.rolloutgroup.target.message = Messages
|
|||||||
|
|
||||||
rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1}
|
rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1}
|
||||||
|
|
||||||
distribution.details.header = Distribution set
|
distribution.details.header = Distribution Set
|
||||||
target.details.header = Target
|
target.details.header = Target
|
||||||
header.caption.mandatory = Mandatory
|
header.caption.mandatory = Mandatory
|
||||||
header.caption.typename = SoftwareModuleType
|
header.caption.typename = SoftwareModuleType
|
||||||
header.caption.softwaremodule = SoftwareModule
|
header.caption.softwaremodule = SoftwareModule
|
||||||
header.caption.unassign = Unassign
|
header.caption.unassign = Unassign
|
||||||
message.sw.unassigned = Software module {0} successfully unassigned
|
message.sw.unassigned = Software Module {0} successfully unassigned
|
||||||
header.caption.upload.details = Upload details
|
header.caption.upload.details = Upload details
|
||||||
combo.type.tag.name = Type tag name
|
combo.type.tag.name = Type tag name
|
||||||
|
|
||||||
@@ -454,10 +454,10 @@ menu.title = Software Provisioning
|
|||||||
prompt.number.of.groups = Number of groups
|
prompt.number.of.groups = Number of groups
|
||||||
prompt.tigger.threshold = Trigger threshold
|
prompt.tigger.threshold = Trigger threshold
|
||||||
prompt.error.threshold = Error threshold
|
prompt.error.threshold = Error threshold
|
||||||
prompt.distribution.set = Distribution set
|
prompt.distribution.set = Distribution Set
|
||||||
caption.configure.rollout = Configure rollout
|
caption.configure.rollout = Configure Rollout
|
||||||
caption.update.rollout = Update rollout
|
caption.update.rollout = Update Rollout
|
||||||
prompt.target.filter = Custom target filter
|
prompt.target.filter = Custom Target Filter
|
||||||
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
||||||
message.rollout.max.group.number = Number of groups must not be greater than 500
|
message.rollout.max.group.number = Number of groups must not be greater than 500
|
||||||
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
||||||
@@ -471,8 +471,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou
|
|||||||
message.rollouts = Rollouts
|
message.rollouts = Rollouts
|
||||||
label.target.per.group = Targets per group :
|
label.target.per.group = Targets per group :
|
||||||
message.dist.already.assigned = Distribution {0} is already assigned to target
|
message.dist.already.assigned = Distribution {0} is already assigned to target
|
||||||
message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator
|
message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator
|
||||||
message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator
|
message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator
|
||||||
|
|
||||||
#Target Filter Management
|
#Target Filter Management
|
||||||
breadcrumb.target.filter.custom.filters = Custom Filters
|
breadcrumb.target.filter.custom.filters = Custom Filters
|
||||||
|
|||||||
@@ -79,14 +79,14 @@ caption.delete.swmodule.accordion.tab = Delete SW Modules
|
|||||||
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
caption.delete.dist.set.type.accordion.tab = Delete Distribution Set Type
|
||||||
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
caption.delete.sw.module.type.accordion.tab = Delete Software Module Type
|
||||||
caption.attributes = Attributes
|
caption.attributes = Attributes
|
||||||
caption.panel.dist.installed = Installed distribution set
|
caption.panel.dist.installed = Installed Distribution Set
|
||||||
caption.panel.dist.assigned = Assigned distribution set
|
caption.panel.dist.assigned = Assigned Distribution Set
|
||||||
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
caption.soft.delete.confirmbox = Confirm Software Module Delete Action
|
||||||
caption.cancel.action.confirmbox = Confirm action cancellation
|
caption.cancel.action.confirmbox = Confirm Action Cancellation
|
||||||
caption.forced.datefield = Force update at time
|
caption.forced.datefield = Force update at time
|
||||||
caption.force.action.confirmbox = Confirm Force Active Action
|
caption.force.action.confirmbox = Confirm Force Active Action
|
||||||
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
caption.filter.delete.confirmbox = Confirm Filter Delete Action
|
||||||
caption.confirm.abort.action = Confirm abort action
|
caption.confirm.abort.action = Confirm Abort Action
|
||||||
|
|
||||||
# Labels prefix with - label
|
# Labels prefix with - label
|
||||||
label.dist.details.type = Type :
|
label.dist.details.type = Type :
|
||||||
@@ -213,11 +213,11 @@ message.target.unassigned.one = {0} is unassigned from {1}
|
|||||||
message.target.unassigned.many = {0} Targets are unassigned from {1}
|
message.target.unassigned.many = {0} Targets are unassigned from {1}
|
||||||
message.target.assigned.pending = Some target(s) are already assigned.Pending for action
|
message.target.assigned.pending = Some target(s) are already assigned.Pending for action
|
||||||
message.cannot.delete = Cannot be deleted
|
message.cannot.delete = Cannot be deleted
|
||||||
message.check.softwaremodule = Please provide both name and verion!
|
message.check.softwaremodule = Please provide both name and version!
|
||||||
message.duplicate.softwaremodule = {0} : {1} already exists!
|
message.duplicate.softwaremodule = {0} : {1} already exists!
|
||||||
message.tag.delete = Please unclick the tag {0}, then try to delete
|
message.tag.delete = Please unclick the tag {0}, then try to delete
|
||||||
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
message.dist.type.check.delete = Please unclick the distribution type {0}, then try to delete
|
||||||
message.swmodule.type.check.delete = Please unclick the software module type {0}, then try to delete
|
message.swmodule.type.check.delete = Please unclick the Software Module type {0}, then try to delete
|
||||||
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
message.targets.already.deleted = Few Target(s) are already deleted.Pending for action
|
||||||
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
message.dists.already.deleted = Few distribution(s) are already deleted.Pending for action
|
||||||
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
message.target.deleted.pending = Target(s) already deleted.Pending for action
|
||||||
@@ -259,10 +259,10 @@ message.dists.assign.tag.alreadyassigned = Few of the DistributionSet's are alre
|
|||||||
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
message.dists.tag.assigned = {0} DistributionSet's assigned to Tag {1}
|
||||||
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
message.dists.tag.unassigned = {0} DistributionSet's un-assigned from Tag {1}
|
||||||
message.dist.no.operation = {0} - already assigned/installed, No operation
|
message.dist.no.operation = {0} - already assigned/installed, No operation
|
||||||
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} software module?
|
message.sm.delete.confirm = Are you sure that you want to delete the selected {0} Software Module?
|
||||||
message.error.os.softmodule = Please select the OS to delete
|
message.error.os.softmodule = Please select the OS to delete
|
||||||
message.error.ah.softmodule = Please select the Application to delete
|
message.error.ah.softmodule = Please select the Application to delete
|
||||||
message.error.softmodule.deleted = The selected software module is already deleted
|
message.error.softmodule.deleted = The selected Software Module is already deleted
|
||||||
message.cancel.action = Cancel
|
message.cancel.action = Cancel
|
||||||
message.cancel.action.success = Action cancelled successfully !
|
message.cancel.action.success = Action cancelled successfully !
|
||||||
message.cancel.action.failed = Unable to cancel the action !
|
message.cancel.action.failed = Unable to cancel the action !
|
||||||
@@ -277,7 +277,7 @@ message.action.not.allowed = Action not allowed
|
|||||||
message.onlyone.distribution.assigned = Only one distribution set can be assigned
|
message.onlyone.distribution.assigned = Only one distribution set can be assigned
|
||||||
message.onlyone.distribution.dropallowed = Only one distribution set can be dropped
|
message.onlyone.distribution.dropallowed = Only one distribution set can be dropped
|
||||||
message.error.missing.typename = Missing Type Name
|
message.error.missing.typename = Missing Type Name
|
||||||
message.error.missing.typenameorkey = Missing Type Name or Key or software module type
|
message.error.missing.typenameorkey = Missing Type Name or Key or Software Module type
|
||||||
message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0}
|
message.tag.cannot.be.assigned = Target/DS cannot be assigned to {0}
|
||||||
message.no.targets.assiged.fortag = No targets are assigned to tag {0}
|
message.no.targets.assiged.fortag = No targets are assigned to tag {0}
|
||||||
message.error.missing.tagname = Please select tag name
|
message.error.missing.tagname = Please select tag name
|
||||||
@@ -305,12 +305,12 @@ soft.module.os =OS
|
|||||||
#Artifact upload
|
#Artifact upload
|
||||||
message.error.noFileSelected = No file selected for upload
|
message.error.noFileSelected = No file selected for upload
|
||||||
message.error.noProvidedName = Please provide custom file name
|
message.error.noProvidedName = Please provide custom file name
|
||||||
message.error.noSwModuleSelected = Please select a software module
|
message.error.noSwModuleSelected = Please select a Software Module
|
||||||
message.no.duplicateFiles = Duplicate files selected
|
message.no.duplicateFiles = Duplicate files selected
|
||||||
message.no.duplicateFile = Duplicate file selected :
|
message.no.duplicateFile = Duplicate file selected :
|
||||||
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
message.delete.artifact = Are you sure that you want to delete artifact {0} ?
|
||||||
message.duplicate.filename = Duplicate file name
|
message.duplicate.filename = Duplicate file name
|
||||||
message.swModule.deleted = {0} Software module(s) deleted
|
message.swModule.deleted = {0} Software Module(s) deleted
|
||||||
message.upload.failed = Streaming Failed
|
message.upload.failed = Streaming Failed
|
||||||
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
message.uploadedfile.size.exceeded = File size exceeded .Allowed size {0} bytes
|
||||||
message.uploadedfile.aborted = File upload aborted
|
message.uploadedfile.aborted = File upload aborted
|
||||||
@@ -318,7 +318,7 @@ message.file.not.found = File not found
|
|||||||
message.abort.upload = Are you sure that you want to abort the upload?
|
message.abort.upload = Are you sure that you want to abort the upload?
|
||||||
|
|
||||||
|
|
||||||
upload.swModuleTable.header = Software module
|
upload.swModuleTable.header = Software Module
|
||||||
upload.selectedfile.name = file selected for upload
|
upload.selectedfile.name = file selected for upload
|
||||||
upload.file.name = File name
|
upload.file.name = File name
|
||||||
upload.sha1 = SHA1 checksum
|
upload.sha1 = SHA1 checksum
|
||||||
@@ -336,7 +336,7 @@ upload.reason = Reason
|
|||||||
upload.action = Action
|
upload.action = Action
|
||||||
upload.result.status = Upload status
|
upload.result.status = Upload status
|
||||||
upload.file = Upload File
|
upload.file = Upload File
|
||||||
upload.caption.update.swmodule = Update software module
|
upload.caption.update.swmodule = Update Software Module
|
||||||
caption.tab.details = Details
|
caption.tab.details = Details
|
||||||
caption.tab.description = Description
|
caption.tab.description = Description
|
||||||
|
|
||||||
@@ -348,8 +348,8 @@ label.drop.dist.delete.area = Drop here<br>to delete
|
|||||||
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
caption.assign.software.dist.accordion.tab = Assign Software Modules
|
||||||
message.software.assignment = {0} Software Module(s) Assignment(s) done
|
message.software.assignment = {0} Software Module(s) Assignment(s) done
|
||||||
message.dist.inuse = {0} Distribution is already assigned to target
|
message.dist.inuse = {0} Distribution is already assigned to target
|
||||||
message.software.dist.already.assigned = {0} Distribution already has software module {1}
|
message.software.dist.already.assigned = {0} Distribution already has Software Module {1}
|
||||||
message.software.dist.type.notallowed = {0} Software module type can not assign to Distribution {1}
|
message.software.dist.type.notallowed = {0} Software Module type can not assign to Distribution {1}
|
||||||
message.target.assigned = {0} is assigned to {1}
|
message.target.assigned = {0} is assigned to {1}
|
||||||
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
message.dist.type.delete = {0} DistributionType(s) Deleted successfully.
|
||||||
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
message.sw.module.type.delete = {0} Software Module Type(s) deleted successfully.
|
||||||
@@ -415,7 +415,7 @@ header.assigned.ds = Assigned DS
|
|||||||
header.installed.ds = Installed DS
|
header.installed.ds = Installed DS
|
||||||
header.status = Status
|
header.status = Status
|
||||||
header.target.tags = Tags
|
header.target.tags = Tags
|
||||||
header.distributionset = Distribution set
|
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
|
||||||
@@ -429,7 +429,7 @@ header.rolloutgroup.target.message = Messages
|
|||||||
|
|
||||||
rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1}
|
rollout.group.label.target.truncated = {0} targets has been truncated in the list due the target size limit of {1}
|
||||||
|
|
||||||
distribution.details.header = Distribution set
|
distribution.details.header = Distribution Set
|
||||||
target.details.header = Target
|
target.details.header = Target
|
||||||
header.caption.mandatory = Mandatory
|
header.caption.mandatory = Mandatory
|
||||||
header.caption.typename = SoftwareModuleType
|
header.caption.typename = SoftwareModuleType
|
||||||
@@ -448,10 +448,10 @@ menu.title = Software Provisioning
|
|||||||
prompt.number.of.groups = Number of groups
|
prompt.number.of.groups = Number of groups
|
||||||
prompt.tigger.threshold = Trigger threshold
|
prompt.tigger.threshold = Trigger threshold
|
||||||
prompt.error.threshold = Error threshold
|
prompt.error.threshold = Error threshold
|
||||||
prompt.distribution.set = Distribution set
|
prompt.distribution.set = Distribution Set
|
||||||
caption.configure.rollout = Configure rollout
|
caption.configure.rollout = Configure Rollout
|
||||||
caption.update.rollout = Update rollout
|
caption.update.rollout = Update Rollout
|
||||||
prompt.target.filter = Custom target filter
|
prompt.target.filter = Custom Target Filter
|
||||||
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
message.rollout.nonzero.group.number = Number of groups must be greater than zero
|
||||||
message.rollout.max.group.number = Number of groups must not be greater than 500
|
message.rollout.max.group.number = Number of groups must not be greater than 500
|
||||||
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
message.rollout.duplicate.check = Rollout [ {0} ] must be unique, entered value already exists.
|
||||||
@@ -465,8 +465,8 @@ message.rollout.noofgroups.or.targetfilter.missing = Please enter number of grou
|
|||||||
message.rollouts = Rollouts
|
message.rollouts = Rollouts
|
||||||
label.target.per.group = Targets per group :
|
label.target.per.group = Targets per group :
|
||||||
message.dist.already.assigned = Distribution {0} is already assigned to target
|
message.dist.already.assigned = Distribution {0} is already assigned to target
|
||||||
message.error.creating.rollout = Server error. Error creating rollout. Please contact the administrator
|
message.error.creating.rollout = Server error. Error creating Rollout. Please contact the administrator
|
||||||
message.error.starting.rollout = Server error. Error starting rollout. Please contact the administrator
|
message.error.starting.rollout = Server error. Error starting Rollout. Please contact the administrator
|
||||||
|
|
||||||
#Target Filter Management
|
#Target Filter Management
|
||||||
breadcrumb.target.filter.custom.filters = Custom Filters
|
breadcrumb.target.filter.custom.filters = Custom Filters
|
||||||
|
|||||||
6
pom.xml
6
pom.xml
@@ -111,6 +111,7 @@
|
|||||||
<jlorem.version>1.1</jlorem.version>
|
<jlorem.version>1.1</jlorem.version>
|
||||||
<json-simple.version>1.1.1</json-simple.version>
|
<json-simple.version>1.1.1</json-simple.version>
|
||||||
<commons-lang3.version>3.4</commons-lang3.version>
|
<commons-lang3.version>3.4</commons-lang3.version>
|
||||||
|
<commons-collections4.version>4.0</commons-collections4.version>
|
||||||
<json.version>20141113</json.version>
|
<json.version>20141113</json.version>
|
||||||
<rsql-parser.version>2.0.0</rsql-parser.version>
|
<rsql-parser.version>2.0.0</rsql-parser.version>
|
||||||
<!-- Misc libraries versions - END -->
|
<!-- Misc libraries versions - END -->
|
||||||
@@ -560,6 +561,11 @@
|
|||||||
<artifactId>commons-lang3</artifactId>
|
<artifactId>commons-lang3</artifactId>
|
||||||
<version>${commons-lang3.version}</version>
|
<version>${commons-lang3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>${commons-collections4.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|||||||
Reference in New Issue
Block a user