Merge branch 'master' into Feature/Add_Rest_Api_with_Java_client
Conflicts: examples/hawkbit-example-app/src/main/java/org/eclipse/hawkbit/app/Start.java examples/hawkbit-mgmt-api-client/pom.xml examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/ArtifactStoreController.java hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/BaseSwModuleBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleAddUpdateWindow.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadHandler.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTableHeader.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/ProxyTarget.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterTable.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterManagementView.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/FilterQueryValidation.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/TargetFilterBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/event/CustomFilterUIEvent.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/login/LoginView.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/CreateUpdateDistributionTagLayoutWindow.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstag/DistributionTagButtons.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/tag/CreateUpdateTagLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetAddUpdateWindowLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/CreateUpdateTargetTagLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettag/TargetTagFilterButtons.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/DistributionBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/ProxyRollout.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/ProxyRolloutGroup.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupListGrid.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgroup/RolloutGroupsListHeader.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/AuthenticationConfigurationView.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPDateTimeUtil.java hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponetIdProvider.java hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/common.scss hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/others.scss hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/rollout.scss hawkbit-ui/src/main/resources/VAADIN/themes/hawkbit/customstyles/target-filter-query.scss hawkbit-ui/src/main/resources/messages.properties hawkbit-ui/src/main/resources/messages_de.properties hawkbit-ui/src/main/resources/messages_en.properties Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>
This commit is contained in:
@@ -22,14 +22,17 @@ import org.springframework.context.annotation.Import;
|
|||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@Import({ RepositoryApplicationConfiguration.class })
|
@Import({ RepositoryApplicationConfiguration.class })
|
||||||
@EnableHawkbitManagedSecurityConfiguration
|
@EnableHawkbitManagedSecurityConfiguration
|
||||||
|
// Exception squid:S1118 - Spring boot standard behavior
|
||||||
|
@SuppressWarnings({ "squid:S1118" })
|
||||||
public class Start {
|
public class Start {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main method to start the spring-boot application.
|
* Main method to start the spring-boot application.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param args
|
||||||
* the VM arguments.
|
* the VM arguments.
|
||||||
*/
|
*/
|
||||||
|
// Exception squid:S2095 - Spring boot standard behavior
|
||||||
|
@SuppressWarnings({ "squid:S2095" })
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
SpringApplication.run(Start.class, args);
|
SpringApplication.run(Start.class, args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
@@ -9,7 +8,8 @@
|
|||||||
http://www.eclipse.org/legal/epl-v10.html
|
http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
@@ -133,13 +133,17 @@
|
|||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.vaadin</groupId>
|
<groupId>com.vaadin</groupId>
|
||||||
<artifactId>vaadin-bom</artifactId>
|
<artifactId>vaadin-bom</artifactId>
|
||||||
<version>7.6.3</version>
|
<version>${vaadin.version}</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator;
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bean of a simulated device which can be stored in the
|
* The bean of a simulated device which can be stored in the
|
||||||
* {@link DeviceSimulatorRepository} or shown in the UI.
|
* {@link DeviceSimulatorRepository} or shown in the UI.
|
||||||
@@ -22,16 +24,15 @@ public abstract class AbstractSimulatedDevice {
|
|||||||
private Status status;
|
private Status status;
|
||||||
private double progress;
|
private double progress;
|
||||||
private String swversion = "unknown";
|
private String swversion = "unknown";
|
||||||
private ResponseStatus responseStatus = ResponseStatus.SUCCESSFUL;
|
private UpdateStatus updateStatus = new UpdateStatus(ResponseStatus.SUCCESSFUL, "Simulation complete!");
|
||||||
private Protocol protocol = Protocol.DMF_AMQP;
|
private Protocol protocol = Protocol.DMF_AMQP;
|
||||||
|
private String targetSecurityToken;
|
||||||
|
|
||||||
private int nextPollCounterSec;
|
private int nextPollCounterSec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum definition of the protocol to be used for the simulated device.
|
* Enum definition of the protocol to be used for the simulated device.
|
||||||
*
|
*
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum Protocol {
|
public enum Protocol {
|
||||||
/**
|
/**
|
||||||
@@ -69,24 +70,6 @@ public abstract class AbstractSimulatedDevice {
|
|||||||
ERROR;
|
ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The status to response to the hawkbit update server if an simulated
|
|
||||||
* update process should be respond with successful or failure update.
|
|
||||||
*
|
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public enum ResponseStatus {
|
|
||||||
/**
|
|
||||||
* updated has been successful and response the successful update.
|
|
||||||
*/
|
|
||||||
SUCCESSFUL,
|
|
||||||
/**
|
|
||||||
* updated has been not successful and response the error update.
|
|
||||||
*/
|
|
||||||
ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* empty constructor.
|
* empty constructor.
|
||||||
*/
|
*/
|
||||||
@@ -158,12 +141,12 @@ public abstract class AbstractSimulatedDevice {
|
|||||||
this.swversion = swversion;
|
this.swversion = swversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResponseStatus getResponseStatus() {
|
public UpdateStatus getUpdateStatus() {
|
||||||
return responseStatus;
|
return updateStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setResponseStatus(final ResponseStatus responseStatus) {
|
public void setUpdateStatus(final UpdateStatus updateStatus) {
|
||||||
this.responseStatus = responseStatus;
|
this.updateStatus = updateStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Protocol getProtocol() {
|
public Protocol getProtocol() {
|
||||||
@@ -177,4 +160,13 @@ public abstract class AbstractSimulatedDevice {
|
|||||||
public void setNextPollCounterSec(final int nextPollDelayInSec) {
|
public void setNextPollCounterSec(final int nextPollDelayInSec) {
|
||||||
this.nextPollCounterSec = nextPollDelayInSec;
|
this.nextPollCounterSec = nextPollDelayInSec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTargetSecurityToken() {
|
||||||
|
return targetSecurityToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetSecurityToken(final String targetSecurityToken) {
|
||||||
|
this.targetSecurityToken = targetSecurityToken;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator;
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.simulator.http.ControllerResource;
|
import org.eclipse.hawkbit.simulator.http.ControllerResource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -18,7 +16,7 @@ import com.jayway.jsonpath.JsonPath;
|
|||||||
import com.jayway.jsonpath.PathNotFoundException;
|
import com.jayway.jsonpath.PathNotFoundException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Hirsch
|
* A simulated device using the DDI API of the hawkBit update server.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DDISimulatedDevice extends AbstractSimulatedDevice {
|
public class DDISimulatedDevice extends AbstractSimulatedDevice {
|
||||||
@@ -26,12 +24,12 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice {
|
|||||||
private static final Logger LOGGER = LoggerFactory.getLogger(DDISimulatedDevice.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(DDISimulatedDevice.class);
|
||||||
|
|
||||||
private final int pollDelaySec;
|
private final int pollDelaySec;
|
||||||
private final ScheduledExecutorService pollthreadpool;
|
|
||||||
private final ControllerResource controllerResource;
|
private final ControllerResource controllerResource;
|
||||||
|
|
||||||
|
private final DeviceSimulatorUpdater deviceUpdater;
|
||||||
|
|
||||||
private volatile boolean removed;
|
private volatile boolean removed;
|
||||||
private volatile Long currentActionId;
|
private volatile Long currentActionId;
|
||||||
private final DeviceSimulatorUpdater deviceUpdater;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
@@ -42,18 +40,14 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice {
|
|||||||
* the delay of the poll interval in sec
|
* the delay of the poll interval in sec
|
||||||
* @param controllerResource
|
* @param controllerResource
|
||||||
* the http controller resource
|
* the http controller resource
|
||||||
* @param pollthreadpool
|
|
||||||
* the threadpool for polling endpoint
|
|
||||||
* @param deviceUpdater
|
* @param deviceUpdater
|
||||||
* the service to update devices
|
* the service to update devices
|
||||||
*/
|
*/
|
||||||
public DDISimulatedDevice(final String id, final String tenant, final int pollDelaySec,
|
public DDISimulatedDevice(final String id, final String tenant, final int pollDelaySec,
|
||||||
final ControllerResource controllerResource, final ScheduledExecutorService pollthreadpool,
|
final ControllerResource controllerResource, final DeviceSimulatorUpdater deviceUpdater) {
|
||||||
final DeviceSimulatorUpdater deviceUpdater) {
|
|
||||||
super(id, tenant, Protocol.DDI_HTTP);
|
super(id, tenant, Protocol.DDI_HTTP);
|
||||||
this.pollDelaySec = pollDelaySec;
|
this.pollDelaySec = pollDelaySec;
|
||||||
this.controllerResource = controllerResource;
|
this.controllerResource = controllerResource;
|
||||||
this.pollthreadpool = pollthreadpool;
|
|
||||||
this.deviceUpdater = deviceUpdater;
|
this.deviceUpdater = deviceUpdater;
|
||||||
setNextPollCounterSec(pollDelaySec);
|
setNextPollCounterSec(pollDelaySec);
|
||||||
}
|
}
|
||||||
@@ -76,27 +70,12 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice {
|
|||||||
final String basePollJson = controllerResource.get(getTenant(), getId());
|
final String basePollJson = controllerResource.get(getTenant(), getId());
|
||||||
try {
|
try {
|
||||||
final String href = JsonPath.parse(basePollJson).read("_links.deploymentBase.href");
|
final String href = JsonPath.parse(basePollJson).read("_links.deploymentBase.href");
|
||||||
final long actionId = Long.parseLong(href.substring(href.lastIndexOf("/") + 1, href.indexOf("?")));
|
final long actionId = Long.parseLong(href.substring(href.lastIndexOf('/') + 1, href.indexOf('?')));
|
||||||
if (currentActionId == null) {
|
if (currentActionId == null) {
|
||||||
final String deploymentJson = controllerResource.getDeployment(getTenant(), getId(), actionId);
|
final String deploymentJson = controllerResource.getDeployment(getTenant(), getId(), actionId);
|
||||||
final String swVersion = JsonPath.parse(deploymentJson).read("deployment.chunks[0].version");
|
final String swVersion = JsonPath.parse(deploymentJson).read("deployment.chunks[0].version");
|
||||||
currentActionId = actionId;
|
currentActionId = actionId;
|
||||||
deviceUpdater.startUpdate(getTenant(), getId(), actionId, swVersion, (device, actionId1) -> {
|
startDdiUpdate(actionId, swVersion);
|
||||||
switch (device.getResponseStatus()) {
|
|
||||||
case SUCCESSFUL:
|
|
||||||
controllerResource.postSuccessFeedback(getTenant(), getId(),
|
|
||||||
actionId1);
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
controllerResource.postErrorFeedback(getTenant(), getId(),
|
|
||||||
actionId1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"simulated device has an unknown response status + " + device.getResponseStatus());
|
|
||||||
}
|
|
||||||
currentActionId = null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (final PathNotFoundException e) {
|
} catch (final PathNotFoundException e) {
|
||||||
// href might not be in the json response, so ignore
|
// href might not be in the json response, so ignore
|
||||||
@@ -106,4 +85,21 @@ public class DDISimulatedDevice extends AbstractSimulatedDevice {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void startDdiUpdate(final long actionId, final String swVersion) {
|
||||||
|
deviceUpdater.startUpdate(getTenant(), getId(), actionId, swVersion, null, null, (device, actionId1) -> {
|
||||||
|
switch (device.getUpdateStatus().getResponseStatus()) {
|
||||||
|
case SUCCESSFUL:
|
||||||
|
controllerResource.postSuccessFeedback(getTenant(), getId(), actionId1);
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
controllerResource.postErrorFeedback(getTenant(), getId(), actionId1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("simulated device has an unknown response status + "
|
||||||
|
+ device.getUpdateStatus().getResponseStatus());
|
||||||
|
}
|
||||||
|
currentActionId = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,10 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.simulator;
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An simulated device using the DMF API of the hawkbit update server.
|
* A simulated device using the DMF API of the hawkBit update server.
|
||||||
*
|
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class DMFSimulatedDevice extends AbstractSimulatedDevice {
|
public class DMFSimulatedDevice extends AbstractSimulatedDevice {
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ import com.vaadin.spring.annotation.EnableVaadin;
|
|||||||
/**
|
/**
|
||||||
* The main-method to start the Spring-Boot application.
|
* The main-method to start the Spring-Boot application.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableVaadin
|
@EnableVaadin
|
||||||
@@ -46,6 +44,8 @@ public class DeviceSimulator {
|
|||||||
* @param args
|
* @param args
|
||||||
* the args
|
* the args
|
||||||
*/
|
*/
|
||||||
|
// Exception squid:S2095 - Spring boot standard behavior
|
||||||
|
@SuppressWarnings({ "squid:S2095" })
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
SpringApplication.run(DeviceSimulator.class, args);
|
SpringApplication.run(DeviceSimulator.class, args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,27 +8,56 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator;
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.DigestOutputStream;
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.SSLContextBuilder;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
||||||
|
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.amqp.SpSenderService;
|
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
||||||
import org.eclipse.hawkbit.simulator.event.InitUpdate;
|
import org.eclipse.hawkbit.simulator.event.InitUpdate;
|
||||||
import org.eclipse.hawkbit.simulator.event.ProgressUpdate;
|
import org.eclipse.hawkbit.simulator.event.ProgressUpdate;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
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.io.BaseEncoding;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Hirsch
|
* Update simulation handler.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class DeviceSimulatorUpdater {
|
public class DeviceSimulatorUpdater {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DeviceSimulatorUpdater.class);
|
||||||
|
|
||||||
private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4);
|
private static final ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4);
|
||||||
|
|
||||||
@@ -54,14 +83,18 @@ public class DeviceSimulatorUpdater {
|
|||||||
* @param actionId
|
* @param actionId
|
||||||
* the actionId from the hawkbit update server to start the
|
* the actionId from the hawkbit update server to start the
|
||||||
* update.
|
* update.
|
||||||
* @param swVersion
|
* @param modules
|
||||||
* the software module version from the hawkbit update server
|
* the software module version from the hawkbit update server
|
||||||
|
* @param swVersion
|
||||||
|
* the software version as static value in case modules is null
|
||||||
|
* @param targetSecurityToken
|
||||||
|
* the target security token for download authentication
|
||||||
* @param callback
|
* @param callback
|
||||||
* the callback which gets called when the simulated update
|
* the callback which gets called when the simulated update
|
||||||
* process has been finished
|
* process has been finished
|
||||||
*/
|
*/
|
||||||
public void startUpdate(final String tenant, final String id, final long actionId, final String swVersion,
|
public void startUpdate(final String tenant, final String id, final long actionId, final String swVersion,
|
||||||
final UpdaterCallback callback) {
|
final List<SoftwareModule> modules, final String targetSecurityToken, final UpdaterCallback callback) {
|
||||||
AbstractSimulatedDevice device = repository.get(tenant, id);
|
AbstractSimulatedDevice device = repository.get(tenant, id);
|
||||||
|
|
||||||
// plug and play - non existing device will be auto created
|
// plug and play - non existing device will be auto created
|
||||||
@@ -70,14 +103,23 @@ public class DeviceSimulatorUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
device.setProgress(0.0);
|
device.setProgress(0.0);
|
||||||
device.setSwversion(swVersion);
|
|
||||||
|
if (modules == null || modules.isEmpty()) {
|
||||||
|
device.setSwversion(swVersion);
|
||||||
|
} else {
|
||||||
|
device.setSwversion(modules.stream().map(sm -> sm.getModuleVersion()).collect(Collectors.joining(", ")));
|
||||||
|
}
|
||||||
|
device.setTargetSecurityToken(targetSecurityToken);
|
||||||
eventbus.post(new InitUpdate(device));
|
eventbus.post(new InitUpdate(device));
|
||||||
|
|
||||||
threadPool.schedule(new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback),
|
threadPool.schedule(
|
||||||
2_000, TimeUnit.MILLISECONDS);
|
new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback, modules), 2_000,
|
||||||
|
TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class DeviceSimulatorUpdateThread implements Runnable {
|
private static final class DeviceSimulatorUpdateThread implements Runnable {
|
||||||
|
private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6;
|
||||||
|
|
||||||
private static final Random rndSleep = new SecureRandom();
|
private static final Random rndSleep = new SecureRandom();
|
||||||
|
|
||||||
private final AbstractSimulatedDevice device;
|
private final AbstractSimulatedDevice device;
|
||||||
@@ -85,38 +127,205 @@ public class DeviceSimulatorUpdater {
|
|||||||
private final long actionId;
|
private final long actionId;
|
||||||
private final EventBus eventbus;
|
private final EventBus eventbus;
|
||||||
private final UpdaterCallback callback;
|
private final UpdaterCallback callback;
|
||||||
|
private final List<SoftwareModule> modules;
|
||||||
|
|
||||||
private DeviceSimulatorUpdateThread(final AbstractSimulatedDevice device, final SpSenderService spSenderService,
|
private DeviceSimulatorUpdateThread(final AbstractSimulatedDevice device, final SpSenderService spSenderService,
|
||||||
final long actionId, final EventBus eventbus, final UpdaterCallback callback) {
|
final long actionId, final EventBus eventbus, final UpdaterCallback callback,
|
||||||
|
final List<SoftwareModule> modules) {
|
||||||
this.device = device;
|
this.device = device;
|
||||||
this.spSenderService = spSenderService;
|
this.spSenderService = spSenderService;
|
||||||
this.actionId = actionId;
|
this.actionId = actionId;
|
||||||
this.eventbus = eventbus;
|
this.eventbus = eventbus;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
this.modules = modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (device.getProgress() <= 0 && modules != null) {
|
||||||
|
device.setUpdateStatus(simulateDownloads(device.getTargetSecurityToken()));
|
||||||
|
if (isErrorResponse(device.getUpdateStatus())) {
|
||||||
|
callback.updateFinished(device, actionId);
|
||||||
|
eventbus.post(new ProgressUpdate(device));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final double newProgress = device.getProgress() + 0.2;
|
final double newProgress = device.getProgress() + 0.2;
|
||||||
device.setProgress(newProgress);
|
device.setProgress(newProgress);
|
||||||
if (newProgress < 1.0) {
|
if (newProgress < 1.0) {
|
||||||
threadPool.schedule(
|
threadPool.schedule(
|
||||||
new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback),
|
new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback, modules),
|
||||||
rndSleep.nextInt(5_000), TimeUnit.MILLISECONDS);
|
rndSleep.nextInt(5_000), TimeUnit.MILLISECONDS);
|
||||||
} else {
|
} else {
|
||||||
callback.updateFinished(device, actionId);
|
callback.updateFinished(device, actionId);
|
||||||
}
|
}
|
||||||
eventbus.post(new ProgressUpdate(device));
|
eventbus.post(new ProgressUpdate(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private UpdateStatus simulateDownloads(final String targetToken) {
|
||||||
|
final List<UpdateStatus> status = new ArrayList<>();
|
||||||
|
|
||||||
|
LOGGER.info("Simulate downloads for {}", device.getId());
|
||||||
|
|
||||||
|
modules.forEach(module -> module.getArtifacts()
|
||||||
|
.forEach(artifact -> handleArtifacts(targetToken, status, artifact)));
|
||||||
|
|
||||||
|
final UpdateStatus result = new UpdateStatus(ResponseStatus.SUCCESSFUL);
|
||||||
|
result.getStatusMessages().add("Simulation complete!");
|
||||||
|
status.forEach(download -> {
|
||||||
|
result.getStatusMessages().addAll(download.getStatusMessages());
|
||||||
|
if (isErrorResponse(download)) {
|
||||||
|
result.setResponseStatus(ResponseStatus.ERROR);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LOGGER.info("Download simulations complete for {}", device.getId());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isErrorResponse(final UpdateStatus status) {
|
||||||
|
if (status == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseStatus.ERROR.equals(status.getResponseStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void handleArtifacts(final String targetToken, final List<UpdateStatus> status,
|
||||||
|
final Artifact artifact) {
|
||||||
|
artifact.getUrls().entrySet().forEach(entry -> {
|
||||||
|
switch (entry.getKey()) {
|
||||||
|
case HTTP:
|
||||||
|
case HTTPS:
|
||||||
|
status.add(downloadUrl(entry.getValue(), targetToken, artifact.getHashes().getSha1(),
|
||||||
|
artifact.getSize()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// not supported yet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UpdateStatus downloadUrl(final String url, final String targetToken, final String sha1Hash,
|
||||||
|
final long size) {
|
||||||
|
LOGGER.debug("Downloading {} with token {}, expected sha1 hash {} and size {}", url,
|
||||||
|
hideTokenDetails(targetToken), sha1Hash, size);
|
||||||
|
|
||||||
|
long overallread = 0;
|
||||||
|
try {
|
||||||
|
final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts();
|
||||||
|
final HttpGet request = new HttpGet(url);
|
||||||
|
request.addHeader(HttpHeaders.AUTHORIZATION, "TargetToken " + targetToken);
|
||||||
|
|
||||||
|
final String sha1HashResult;
|
||||||
|
try (final CloseableHttpResponse response = httpclient.execute(request)) {
|
||||||
|
|
||||||
|
if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
|
||||||
|
final String message = wrongStatusCode(url, response);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.getEntity().getContentLength() != size) {
|
||||||
|
final String message = wrongContentLength(url, size, response);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
final File tempFile = File.createTempFile("uploadFile", null);
|
||||||
|
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||||
|
|
||||||
|
try (final DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(tempFile), md)) {
|
||||||
|
try (final BufferedOutputStream bdos = new BufferedOutputStream(dos)) {
|
||||||
|
try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) {
|
||||||
|
overallread = ByteStreams.copy(bis, bdos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (tempFile != null && !tempFile.delete()) {
|
||||||
|
LOGGER.error("Could not delete temporary file: {}", tempFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (overallread != size) {
|
||||||
|
final String message = incompleteRead(url, size, overallread);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) {
|
||||||
|
final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
|
||||||
|
LOGGER.error("Failed to download {} with {}", url, e.getMessage());
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
final String message = "Downloaded " + url + " (" + overallread + " bytes)";
|
||||||
|
LOGGER.debug(message);
|
||||||
|
return new UpdateStatus(ResponseStatus.SUCCESSFUL, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String hideTokenDetails(final String targetToken) {
|
||||||
|
if (targetToken.isEmpty()) {
|
||||||
|
return "<EMTPTY!>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetToken.length() <= MINIMUM_TOKENLENGTH_FOR_HINT) {
|
||||||
|
return "***";
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetToken.substring(0, 2) + "***"
|
||||||
|
+ targetToken.substring(targetToken.length() - 2, targetToken.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String wrongHash(final String url, final String sha1Hash, final long overallread,
|
||||||
|
final String sha1HashResult) {
|
||||||
|
final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash
|
||||||
|
+ " but got: " + sha1HashResult + ") (" + overallread + " bytes)";
|
||||||
|
LOGGER.error(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String incompleteRead(final String url, final long size, final long overallread) {
|
||||||
|
final String message = "Download " + url + " is incomplete (Expected: " + size + " but got: " + overallread
|
||||||
|
+ ")";
|
||||||
|
LOGGER.error(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String wrongContentLength(final String url, final long size,
|
||||||
|
final CloseableHttpResponse response) {
|
||||||
|
final String message = "Download " + url + " has wrong content length (Expected: " + size + " but got: "
|
||||||
|
+ response.getEntity().getContentLength() + ")";
|
||||||
|
LOGGER.error(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String wrongStatusCode(final String url, final CloseableHttpResponse response) {
|
||||||
|
final String message = "Download " + url + " failed (" + response.getStatusLine().getStatusCode() + ")";
|
||||||
|
LOGGER.error(message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CloseableHttpClient createHttpClientThatAcceptsAllServerCerts()
|
||||||
|
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
|
||||||
|
final SSLContextBuilder builder = new SSLContextBuilder();
|
||||||
|
builder.loadTrustMaterial(null, (chain, authType) -> true);
|
||||||
|
final SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build());
|
||||||
|
return HttpClients.custom().setSSLSocketFactory(sslsf).build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback interface which is called when the simulated update process has
|
* Callback interface which is called when the simulated update process has
|
||||||
* been finished and the caller of starting the simulated update process can
|
* been finished and the caller of starting the simulated update process can
|
||||||
* send the result to the hawkbit update server back.
|
* send the result back to the hawkBit update server.
|
||||||
*
|
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface UpdaterCallback {
|
public interface UpdaterCallback {
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ import com.google.common.eventbus.EventBus;
|
|||||||
/**
|
/**
|
||||||
* Poll time trigger which executes the {@link DDISimulatedDevice#poll()} every
|
* Poll time trigger which executes the {@link DDISimulatedDevice#poll()} every
|
||||||
* second.
|
* second.
|
||||||
*
|
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class NextPollTimeController {
|
public class NextPollTimeController {
|
||||||
@@ -59,16 +56,15 @@ public class NextPollTimeController {
|
|||||||
|
|
||||||
devices.forEach(device -> {
|
devices.forEach(device -> {
|
||||||
int nextCounter = device.getNextPollCounterSec() - 1;
|
int nextCounter = device.getNextPollCounterSec() - 1;
|
||||||
if (nextCounter < 0) {
|
if (nextCounter < 0 && device instanceof DDISimulatedDevice) {
|
||||||
if (device instanceof DDISimulatedDevice) {
|
try {
|
||||||
try {
|
pollService.submit(() -> ((DDISimulatedDevice) device).poll());
|
||||||
pollService.submit(() -> ((DDISimulatedDevice) device).poll());
|
} catch (final IllegalStateException e) {
|
||||||
} catch (final IllegalStateException e) {
|
LOGGER.trace("Device could not be polled", e);
|
||||||
LOGGER.trace("Device could not be polled", e);
|
|
||||||
}
|
|
||||||
nextCounter = ((DDISimulatedDevice) device).getPollDelaySec();
|
|
||||||
}
|
}
|
||||||
|
nextCounter = ((DDISimulatedDevice) device).getPollDelaySec();
|
||||||
}
|
}
|
||||||
|
|
||||||
device.setNextPollCounterSec(nextCounter);
|
device.setNextPollCounterSec(nextCounter);
|
||||||
});
|
});
|
||||||
eventBus.post(new NextPollCounterUpdate(devices));
|
eventBus.post(new NextPollCounterUpdate(devices));
|
||||||
|
|||||||
@@ -9,8 +9,6 @@
|
|||||||
package org.eclipse.hawkbit.simulator;
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
||||||
import org.eclipse.hawkbit.simulator.http.ControllerResource;
|
import org.eclipse.hawkbit.simulator.http.ControllerResource;
|
||||||
@@ -24,15 +22,9 @@ import feign.Logger;
|
|||||||
/**
|
/**
|
||||||
* The simulated device factory to create either {@link DMFSimulatedDevice} or
|
* The simulated device factory to create either {@link DMFSimulatedDevice} or
|
||||||
* {@link DDISimulatedDevice#}.
|
* {@link DDISimulatedDevice#}.
|
||||||
*
|
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class SimulatedDeviceFactory {
|
public class SimulatedDeviceFactory {
|
||||||
|
|
||||||
private static final ScheduledExecutorService pollThreadPool = Executors.newScheduledThreadPool(4);
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceSimulatorUpdater deviceUpdater;
|
private DeviceSimulatorUpdater deviceUpdater;
|
||||||
|
|
||||||
@@ -47,7 +39,8 @@ public class SimulatedDeviceFactory {
|
|||||||
* the protocol of the device
|
* the protocol of the device
|
||||||
* @return the created simulated device
|
* @return the created simulated device
|
||||||
*/
|
*/
|
||||||
public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol) {
|
public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant,
|
||||||
|
final Protocol protocol) {
|
||||||
return createSimulatedDevice(id, tenant, protocol, 30, null, null);
|
return createSimulatedDevice(id, tenant, protocol, 30, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,7 +73,7 @@ public class SimulatedDeviceFactory {
|
|||||||
final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger())
|
final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger())
|
||||||
.requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC)
|
.requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC)
|
||||||
.target(ControllerResource.class, baseEndpoint.toString());
|
.target(ControllerResource.class, baseEndpoint.toString());
|
||||||
return new DDISimulatedDevice(id, tenant, pollDelaySec, controllerResource, pollThreadPool, deviceUpdater);
|
return new DDISimulatedDevice(id, tenant, pollDelaySec, controllerResource, deviceUpdater);
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Protocol " + protocol + " unknown");
|
throw new IllegalArgumentException("Protocol " + protocol + " unknown");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,10 @@ public class SimulationController {
|
|||||||
final String deviceId = name + i;
|
final String deviceId = name + i;
|
||||||
repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint),
|
repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint),
|
||||||
gatewayToken));
|
gatewayToken));
|
||||||
spSenderService.createOrUpdateThing(tenant, deviceId);
|
|
||||||
|
if (protocol == Protocol.DMF_AMQP) {
|
||||||
|
spSenderService.createOrUpdateThing(tenant, deviceId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResponseEntity.ok("Updated " + amount + " DMF connected targets!");
|
return ResponseEntity.ok("Updated " + amount + " DMF connected targets!");
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ package org.eclipse.hawkbit.simulator;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
||||||
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.ApplicationListener;
|
import org.springframework.context.ApplicationListener;
|
||||||
import org.springframework.context.event.ContextRefreshedEvent;
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -24,6 +26,7 @@ import org.springframework.stereotype.Component;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@ConditionalOnProperty(prefix = "hawkbit.device.simulator", name = "autostart", matchIfMissing = true)
|
||||||
public class SimulatorStartup implements ApplicationListener<ContextRefreshedEvent> {
|
public class SimulatorStartup implements ApplicationListener<ContextRefreshedEvent> {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorStartup.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorStartup.class);
|
||||||
|
|
||||||
@@ -52,7 +55,9 @@ public class SimulatorStartup implements ApplicationListener<ContextRefreshedEve
|
|||||||
LOGGER.error("Creation of simulated device at startup failed.", e);
|
LOGGER.error("Creation of simulated device at startup failed.", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
spSenderService.createOrUpdateThing(autostart.getTenant(), deviceId);
|
if (autostart.getApi() == Protocol.DMF_AMQP) {
|
||||||
|
spSenderService.createOrUpdateThing(autostart.getTenant(), deviceId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* 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.simulator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update status of the simulated update.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class UpdateStatus {
|
||||||
|
private ResponseStatus responseStatus;
|
||||||
|
private List<String> statusMessages;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param responseStatus
|
||||||
|
* of the update
|
||||||
|
*/
|
||||||
|
public UpdateStatus(final ResponseStatus responseStatus) {
|
||||||
|
this.responseStatus = responseStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor including status message.
|
||||||
|
*
|
||||||
|
* @param responseStatus
|
||||||
|
* of the update
|
||||||
|
* @param message
|
||||||
|
* of the update status
|
||||||
|
*/
|
||||||
|
public UpdateStatus(final ResponseStatus responseStatus, final String message) {
|
||||||
|
this(responseStatus);
|
||||||
|
statusMessages = new ArrayList<>();
|
||||||
|
statusMessages.add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseStatus getResponseStatus() {
|
||||||
|
return responseStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseStatus(final ResponseStatus responseStatus) {
|
||||||
|
this.responseStatus = responseStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStatusMessages() {
|
||||||
|
if (statusMessages == null) {
|
||||||
|
statusMessages = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status to response to the hawkBit update server if an simulated
|
||||||
|
* update process should be respond with successful or failure update.
|
||||||
|
*/
|
||||||
|
public enum ResponseStatus {
|
||||||
|
/**
|
||||||
|
* Update has been successful and response the successful update.
|
||||||
|
*/
|
||||||
|
SUCCESSFUL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update has been not successful and response the error update.
|
||||||
|
*/
|
||||||
|
ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -39,6 +39,12 @@ public class AmqpProperties {
|
|||||||
*/
|
*/
|
||||||
private String deadLetterExchange = "simulator.deadletter";
|
private String deadLetterExchange = "simulator.deadletter";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message time to live (ttl) for the deadletter queue. Default ttl is 1
|
||||||
|
* hour.
|
||||||
|
*/
|
||||||
|
private int deadLetterTtl = 60_000;
|
||||||
|
|
||||||
public String getReceiverConnectorQueueFromSp() {
|
public String getReceiverConnectorQueueFromSp() {
|
||||||
return receiverConnectorQueueFromSp;
|
return receiverConnectorQueueFromSp;
|
||||||
}
|
}
|
||||||
@@ -70,4 +76,12 @@ public class AmqpProperties {
|
|||||||
public void setSenderForSpExchange(final String senderForSpExchange) {
|
public void setSenderForSpExchange(final String senderForSpExchange) {
|
||||||
this.senderForSpExchange = senderForSpExchange;
|
this.senderForSpExchange = senderForSpExchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getDeadLetterTtl() {
|
||||||
|
return deadLetterTtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeadLetterTtl(final int deadLetterTtl) {
|
||||||
|
this.deadLetterTtl = deadLetterTtl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.messaging.handler.annotation.Header;
|
import org.springframework.messaging.handler.annotation.Header;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle all incoming Messages from hawkBit update server.
|
* Handle all incoming Messages from hawkBit update server.
|
||||||
*
|
*
|
||||||
@@ -88,6 +90,8 @@ public class SpReceiverService extends ReceiverService {
|
|||||||
if (eventHeader == null) {
|
if (eventHeader == null) {
|
||||||
logAndThrowMessageError(message, "Event Topic is not set");
|
logAndThrowMessageError(message, "Event Topic is not set");
|
||||||
}
|
}
|
||||||
|
// Exception squid:S2259 - Checked before
|
||||||
|
@SuppressWarnings({ "squid:S2259" })
|
||||||
final EventTopic eventTopic = EventTopic.valueOf(eventHeader.toString());
|
final EventTopic eventTopic = EventTopic.valueOf(eventHeader.toString());
|
||||||
switch (eventTopic) {
|
switch (eventTopic) {
|
||||||
case DOWNLOAD_AND_INSTALL:
|
case DOWNLOAD_AND_INSTALL:
|
||||||
@@ -109,7 +113,7 @@ public class SpReceiverService extends ReceiverService {
|
|||||||
final Long actionId = convertMessage(message, Long.class);
|
final Long actionId = convertMessage(message, Long.class);
|
||||||
|
|
||||||
final SimulatedUpdate update = new SimulatedUpdate(tenant, thingId, actionId);
|
final SimulatedUpdate update = new SimulatedUpdate(tenant, thingId, actionId);
|
||||||
spSenderService.finishUpdateProcess(update, "Simulation canceled");
|
spSenderService.finishUpdateProcess(update, Lists.newArrayList("Simulation canceled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleUpdateProcess(final Message message, final String thingId) {
|
private void handleUpdateProcess(final Message message, final String thingId) {
|
||||||
@@ -120,19 +124,20 @@ public class SpReceiverService extends ReceiverService {
|
|||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = convertMessage(message,
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = convertMessage(message,
|
||||||
DownloadAndUpdateRequest.class);
|
DownloadAndUpdateRequest.class);
|
||||||
final Long actionId = downloadAndUpdateRequest.getActionId();
|
final Long actionId = downloadAndUpdateRequest.getActionId();
|
||||||
|
final String targetSecurityToken = downloadAndUpdateRequest.getTargetSecurityToken();
|
||||||
|
|
||||||
deviceUpdater.startUpdate(tenant, thingId, actionId,
|
deviceUpdater.startUpdate(tenant, thingId, actionId, null, downloadAndUpdateRequest.getSoftwareModules(),
|
||||||
downloadAndUpdateRequest.getSoftwareModules().get(0).getModuleVersion(), (device, actionId1) -> {
|
targetSecurityToken, (device, actionId1) -> {
|
||||||
switch (device.getResponseStatus()) {
|
switch (device.getUpdateStatus().getResponseStatus()) {
|
||||||
case SUCCESSFUL:
|
case SUCCESSFUL:
|
||||||
spSenderService.finishUpdateProcess(
|
spSenderService.finishUpdateProcess(
|
||||||
new SimulatedUpdate(device.getTenant(), device.getId(), actionId1),
|
new SimulatedUpdate(device.getTenant(), device.getId(), actionId1),
|
||||||
"Simulation complete!");
|
device.getUpdateStatus().getStatusMessages());
|
||||||
break;
|
break;
|
||||||
case ERROR:
|
case ERROR:
|
||||||
spSenderService.finishUpdateProcessWithError(
|
spSenderService.finishUpdateProcessWithError(
|
||||||
new SimulatedUpdate(device.getTenant(), device.getId(), actionId1),
|
new SimulatedUpdate(device.getTenant(), device.getId(), actionId1),
|
||||||
"Simulation complete with error!");
|
device.getUpdateStatus().getStatusMessages());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator.amqp;
|
package org.eclipse.hawkbit.simulator.amqp;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
|
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
|
||||||
@@ -23,13 +24,9 @@ import org.springframework.amqp.core.MessageProperties;
|
|||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sender service to send message to SP.
|
* Sender service to send messages to update server.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class SpSenderService extends SenderService {
|
public class SpSenderService extends SenderService {
|
||||||
@@ -59,8 +56,9 @@ public class SpSenderService extends SenderService {
|
|||||||
* @param description
|
* @param description
|
||||||
* a description according the update process
|
* a description according the update process
|
||||||
*/
|
*/
|
||||||
public void finishUpdateProcess(final SimulatedUpdate update, final String description) {
|
public void finishUpdateProcess(final SimulatedUpdate update, final List<String> updateResultMessages) {
|
||||||
final Message updateResultMessage = createUpdateResultMessage(update, ActionStatus.FINISHED, description);
|
final Message updateResultMessage = createUpdateResultMessage(update, ActionStatus.FINISHED,
|
||||||
|
updateResultMessages);
|
||||||
sendMessage(spExchange, updateResultMessage);
|
sendMessage(spExchange, updateResultMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,9 +70,9 @@ public class SpSenderService extends SenderService {
|
|||||||
* @param messageDescription
|
* @param messageDescription
|
||||||
* a description according the update process
|
* a description according the update process
|
||||||
*/
|
*/
|
||||||
public void finishUpdateProcessWithError(final SimulatedUpdate update, final String messageDescription) {
|
public void finishUpdateProcessWithError(final SimulatedUpdate update, final List<String> updateResultMessages) {
|
||||||
sendErrorgMessage(update, messageDescription);
|
sendErrorgMessage(update, updateResultMessages);
|
||||||
LOGGER.debug("Update process finished with error \"{}\" reported by thing {}", messageDescription,
|
LOGGER.debug("Update process finished with error \"{}\" reported by thing {}", updateResultMessages,
|
||||||
update.getThingId());
|
update.getThingId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,8 +86,8 @@ public class SpSenderService extends SenderService {
|
|||||||
* @param actionId
|
* @param actionId
|
||||||
* the ID of the action for the error message
|
* the ID of the action for the error message
|
||||||
*/
|
*/
|
||||||
public void sendErrorMessage(final String tenant, final String messageDescription, final Long actionId) {
|
public void sendErrorMessage(final String tenant, final List<String> updateResultMessages, final Long actionId) {
|
||||||
final Message message = createActionStatusMessage(tenant, ActionStatus.ERROR, messageDescription, actionId);
|
final Message message = createActionStatusMessage(tenant, ActionStatus.ERROR, updateResultMessages, actionId);
|
||||||
sendMessage(spExchange, message);
|
sendMessage(spExchange, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,8 +99,8 @@ public class SpSenderService extends SenderService {
|
|||||||
* @param warningMessage
|
* @param warningMessage
|
||||||
* a warning description
|
* a warning description
|
||||||
*/
|
*/
|
||||||
public void sendWarningMessage(final SimulatedUpdate update, final String warningMessage) {
|
public void sendWarningMessage(final SimulatedUpdate update, final List<String> updateResultMessages) {
|
||||||
final Message message = createActionStatusMessage(update, warningMessage, ActionStatus.WARNING);
|
final Message message = createActionStatusMessage(update, updateResultMessages, ActionStatus.WARNING);
|
||||||
sendMessage(spExchange, message);
|
sendMessage(spExchange, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,8 +117,8 @@ public class SpSenderService extends SenderService {
|
|||||||
* the cached value
|
* the cached value
|
||||||
*/
|
*/
|
||||||
public void sendActionStatusMessage(final String tenant, final ActionStatus actionStatus,
|
public void sendActionStatusMessage(final String tenant, final ActionStatus actionStatus,
|
||||||
final String actionMessage, final Long actionId) {
|
final List<String> updateResultMessages, final Long actionId) {
|
||||||
final Message message = createActionStatusMessage(tenant, actionStatus, actionMessage, actionId);
|
final Message message = createActionStatusMessage(tenant, actionStatus, updateResultMessages, actionId);
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -162,11 +160,11 @@ public class SpSenderService extends SenderService {
|
|||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* the current context
|
* the current context
|
||||||
* @param messageDescription
|
* @param updateResultMessages
|
||||||
* a description according the update process
|
* a list of descriptions according the update process
|
||||||
*/
|
*/
|
||||||
private void sendErrorgMessage(final SimulatedUpdate update, final String messageDescription) {
|
private void sendErrorgMessage(final SimulatedUpdate update, final List<String> updateResultMessages) {
|
||||||
final Message message = createActionStatusMessage(update, messageDescription, ActionStatus.ERROR);
|
final Message message = createActionStatusMessage(update, updateResultMessages, ActionStatus.ERROR);
|
||||||
sendMessage(spExchange, message);
|
sendMessage(spExchange, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +181,7 @@ public class SpSenderService extends SenderService {
|
|||||||
* the cacheValue value
|
* the cacheValue value
|
||||||
*/
|
*/
|
||||||
private Message createActionStatusMessage(final String tenant, final ActionStatus actionStatus,
|
private Message createActionStatusMessage(final String tenant, final ActionStatus actionStatus,
|
||||||
final String actionMessage, final Long actionId) {
|
final List<String> updateResultMessages, final Long actionId) {
|
||||||
final MessageProperties messageProperties = new MessageProperties();
|
final MessageProperties messageProperties = new MessageProperties();
|
||||||
final Map<String, Object> headers = messageProperties.getHeaders();
|
final Map<String, Object> headers = messageProperties.getHeaders();
|
||||||
final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus();
|
final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus();
|
||||||
@@ -192,15 +190,14 @@ public class SpSenderService extends SenderService {
|
|||||||
headers.put(MessageHeaderKey.TENANT, tenant);
|
headers.put(MessageHeaderKey.TENANT, tenant);
|
||||||
headers.put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
|
headers.put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
|
||||||
headers.put(MessageHeaderKey.CONTENT_TYPE, MessageProperties.CONTENT_TYPE_JSON);
|
headers.put(MessageHeaderKey.CONTENT_TYPE, MessageProperties.CONTENT_TYPE_JSON);
|
||||||
if (!StringUtils.isEmpty(actionMessage)) {
|
actionUpdateStatus.getMessage().addAll(updateResultMessages);
|
||||||
actionUpdateStatus.getMessage().add(actionMessage);
|
|
||||||
}
|
|
||||||
actionUpdateStatus.setActionId(actionId);
|
actionUpdateStatus.setActionId(actionId);
|
||||||
return convertMessage(actionUpdateStatus, messageProperties);
|
return convertMessage(actionUpdateStatus, messageProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message createUpdateResultMessage(final SimulatedUpdate cacheValue, final ActionStatus actionStatus,
|
private Message createUpdateResultMessage(final SimulatedUpdate cacheValue, final ActionStatus actionStatus,
|
||||||
final String updateResultMessage) {
|
final List<String> updateResultMessages) {
|
||||||
final MessageProperties messageProperties = new MessageProperties();
|
final MessageProperties messageProperties = new MessageProperties();
|
||||||
final Map<String, Object> headers = messageProperties.getHeaders();
|
final Map<String, Object> headers = messageProperties.getHeaders();
|
||||||
final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus();
|
final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus();
|
||||||
@@ -209,14 +206,14 @@ public class SpSenderService extends SenderService {
|
|||||||
headers.put(MessageHeaderKey.TENANT, cacheValue.getTenant());
|
headers.put(MessageHeaderKey.TENANT, cacheValue.getTenant());
|
||||||
headers.put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
|
headers.put(MessageHeaderKey.TOPIC, EventTopic.UPDATE_ACTION_STATUS.name());
|
||||||
headers.put(MessageHeaderKey.CONTENT_TYPE, MessageProperties.CONTENT_TYPE_JSON);
|
headers.put(MessageHeaderKey.CONTENT_TYPE, MessageProperties.CONTENT_TYPE_JSON);
|
||||||
actionUpdateStatus.getMessage().add(updateResultMessage);
|
actionUpdateStatus.getMessage().addAll(updateResultMessages);
|
||||||
actionUpdateStatus.setActionId(cacheValue.getActionId());
|
actionUpdateStatus.setActionId(cacheValue.getActionId());
|
||||||
return convertMessage(actionUpdateStatus, messageProperties);
|
return convertMessage(actionUpdateStatus, messageProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Message createActionStatusMessage(final SimulatedUpdate update, final String messageDescription,
|
private Message createActionStatusMessage(final SimulatedUpdate update, final List<String> updateResultMessages,
|
||||||
final ActionStatus status) {
|
final ActionStatus status) {
|
||||||
return createActionStatusMessage(update.getTenant(), status, messageDescription, update.getActionId());
|
return createActionStatusMessage(update.getTenant(), status, updateResultMessages, update.getActionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice;
|
|||||||
* Event definition object which is published if the simulated device updated
|
* Event definition object which is published if the simulated device updated
|
||||||
* its update progress.
|
* its update progress.
|
||||||
*
|
*
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ProgressUpdate {
|
public class ProgressUpdate {
|
||||||
|
|
||||||
|
|||||||
@@ -8,21 +8,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator.ui;
|
package org.eclipse.hawkbit.simulator.ui;
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice;
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice;
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.ResponseStatus;
|
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Status;
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Status;
|
||||||
import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository;
|
import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository;
|
||||||
import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory;
|
import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory;
|
||||||
|
import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus;
|
||||||
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
||||||
import org.eclipse.hawkbit.simulator.event.InitUpdate;
|
import org.eclipse.hawkbit.simulator.event.InitUpdate;
|
||||||
import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate;
|
import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate;
|
||||||
import org.eclipse.hawkbit.simulator.event.ProgressUpdate;
|
import org.eclipse.hawkbit.simulator.event.ProgressUpdate;
|
||||||
import org.eclipse.hawkbit.simulator.ui.GenerateDialog.GenerateDialogCallback;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@@ -53,12 +51,26 @@ import com.vaadin.ui.renderers.ProgressBarRenderer;
|
|||||||
* current simulated devices in a grid with their current status and update
|
* current simulated devices in a grid with their current status and update
|
||||||
* progress.
|
* progress.
|
||||||
*
|
*
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringView(name = "")
|
@SpringView(name = "")
|
||||||
public class SimulatorView extends VerticalLayout implements View {
|
public class SimulatorView extends VerticalLayout implements View {
|
||||||
|
|
||||||
|
private static final String NEXT_POLL_COUNTER_SEC_COL = "nextPollCounterSec";
|
||||||
|
|
||||||
|
private static final String RESPONSE_STATUS_COL = "responseStatus";
|
||||||
|
|
||||||
|
private static final String PROTOCOL_COL = "protocol";
|
||||||
|
|
||||||
|
private static final String TENANT_COL = "tenant";
|
||||||
|
|
||||||
|
private static final String PROGRESS_COL = "progress";
|
||||||
|
|
||||||
|
private static final String SWVERSION_COL = "swversion";
|
||||||
|
|
||||||
|
private static final String STATUS_COL = "status";
|
||||||
|
|
||||||
|
private static final String ID_COL = "id";
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -79,6 +91,7 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
|
|
||||||
private BeanContainer<String, AbstractSimulatedDevice> beanContainer;
|
private BeanContainer<String, AbstractSimulatedDevice> beanContainer;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void enter(final ViewChangeEvent event) {
|
public void enter(final ViewChangeEvent event) {
|
||||||
eventbus.register(this);
|
eventbus.register(this);
|
||||||
@@ -91,7 +104,7 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
createToolbar();
|
createToolbar();
|
||||||
|
|
||||||
beanContainer = new BeanContainer<>(AbstractSimulatedDevice.class);
|
beanContainer = new BeanContainer<>(AbstractSimulatedDevice.class);
|
||||||
beanContainer.setBeanIdProperty("id");
|
beanContainer.setBeanIdProperty(ID_COL);
|
||||||
|
|
||||||
grid.setSizeFull();
|
grid.setSizeFull();
|
||||||
grid.setCellStyleGenerator(new CellStyleGenerator() {
|
grid.setCellStyleGenerator(new CellStyleGenerator() {
|
||||||
@@ -100,28 +113,28 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getStyle(final CellReference cellReference) {
|
public String getStyle(final CellReference cellReference) {
|
||||||
return cellReference.getPropertyId().equals("status") ? "centeralign" : null;
|
return cellReference.getPropertyId().equals(STATUS_COL) ? "centeralign" : null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
grid.setSelectionMode(SelectionMode.NONE);
|
grid.setSelectionMode(SelectionMode.NONE);
|
||||||
grid.setContainerDataSource(beanContainer);
|
grid.setContainerDataSource(beanContainer);
|
||||||
grid.appendHeaderRow().getCell("responseStatus").setComponent(responseComboBox);
|
grid.appendHeaderRow().getCell(RESPONSE_STATUS_COL).setComponent(responseComboBox);
|
||||||
grid.setColumnOrder("id", "status", "swversion", "progress", "tenant", "protocol", "responseStatus",
|
grid.setColumnOrder(ID_COL, STATUS_COL, SWVERSION_COL, PROGRESS_COL, TENANT_COL, PROTOCOL_COL,
|
||||||
"nextPollCounterSec");
|
RESPONSE_STATUS_COL, NEXT_POLL_COUNTER_SEC_COL);
|
||||||
// header widths
|
// header widths
|
||||||
grid.getColumn("status").setMaximumWidth(80);
|
grid.getColumn(STATUS_COL).setMaximumWidth(80);
|
||||||
grid.getColumn("protocol").setMaximumWidth(180);
|
grid.getColumn(PROTOCOL_COL).setMaximumWidth(180);
|
||||||
grid.getColumn("responseStatus").setMaximumWidth(240);
|
grid.getColumn(RESPONSE_STATUS_COL).setMaximumWidth(240);
|
||||||
grid.getColumn("nextPollCounterSec").setMaximumWidth(210);
|
grid.getColumn(NEXT_POLL_COUNTER_SEC_COL).setMaximumWidth(210);
|
||||||
|
|
||||||
grid.getColumn("nextPollCounterSec").setHeaderCaption("Next Poll in (sec)");
|
grid.getColumn(NEXT_POLL_COUNTER_SEC_COL).setHeaderCaption("Next Poll in (sec)");
|
||||||
grid.getColumn("swversion").setHeaderCaption("SW Version");
|
grid.getColumn(SWVERSION_COL).setHeaderCaption("SW Version");
|
||||||
grid.getColumn("responseStatus").setHeaderCaption("Response Update Status");
|
grid.getColumn(RESPONSE_STATUS_COL).setHeaderCaption("Response Update Status");
|
||||||
grid.getColumn("progress").setRenderer(new ProgressBarRenderer());
|
grid.getColumn(PROGRESS_COL).setRenderer(new ProgressBarRenderer());
|
||||||
grid.getColumn("protocol").setConverter(createProtocolConverter());
|
grid.getColumn(PROTOCOL_COL).setConverter(createProtocolConverter());
|
||||||
grid.getColumn("status").setRenderer(new HtmlRenderer(), createStatusConverter());
|
grid.getColumn(STATUS_COL).setRenderer(new HtmlRenderer(), createStatusConverter());
|
||||||
grid.removeColumn("tenant");
|
grid.removeColumn(TENANT_COL);
|
||||||
|
|
||||||
// grid combobox
|
// grid combobox
|
||||||
responseComboBox.setItemIcon(ResponseStatus.SUCCESSFUL, FontAwesome.CHECK_CIRCLE);
|
responseComboBox.setItemIcon(ResponseStatus.SUCCESSFUL, FontAwesome.CHECK_CIRCLE);
|
||||||
@@ -129,8 +142,8 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
responseComboBox.setNullSelectionAllowed(false);
|
responseComboBox.setNullSelectionAllowed(false);
|
||||||
responseComboBox.setValue(ResponseStatus.SUCCESSFUL);
|
responseComboBox.setValue(ResponseStatus.SUCCESSFUL);
|
||||||
responseComboBox.addValueChangeListener(valueChangeEvent -> {
|
responseComboBox.addValueChangeListener(valueChangeEvent -> {
|
||||||
beanContainer.getItemIds().forEach(itemId -> beanContainer.getItem(itemId).getItemProperty("responseStatus")
|
beanContainer.getItemIds().forEach(itemId -> beanContainer.getItem(itemId)
|
||||||
.setValue(valueChangeEvent.getProperty().getValue()));
|
.getItemProperty(RESPONSE_STATUS_COL).setValue(valueChangeEvent.getProperty().getValue()));
|
||||||
});
|
});
|
||||||
|
|
||||||
// add all components
|
// add all components
|
||||||
@@ -141,7 +154,7 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
setExpandRatio(grid, 1.0F);
|
setExpandRatio(grid, 1.0F);
|
||||||
|
|
||||||
// load beans
|
// load beans
|
||||||
repository.getAll().forEach(device -> beanContainer.addBean(device));
|
repository.getAll().forEach(beanContainer::addBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -150,21 +163,16 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
eventbus.unregister(this);
|
eventbus.unregister(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void pollCounterUpdate(final NextPollCounterUpdate update) {
|
public void pollCounterUpdate(final NextPollCounterUpdate update) {
|
||||||
final List<AbstractSimulatedDevice> devices = update.getDevices();
|
final List<AbstractSimulatedDevice> devices = update.getDevices();
|
||||||
this.getUI().access(new Runnable() {
|
this.getUI().access(() -> devices.forEach(device -> {
|
||||||
|
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());
|
||||||
@Override
|
if (item != null) {
|
||||||
public void run() {
|
item.getItemProperty(NEXT_POLL_COUNTER_SEC_COL).setValue(device.getNextPollCounterSec());
|
||||||
devices.forEach(device -> {
|
|
||||||
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());
|
|
||||||
if (item != null) {
|
|
||||||
item.getItemProperty("nextPollCounterSec").setValue(device.getNextPollCounterSec());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,21 +181,19 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
* @param update
|
* @param update
|
||||||
* the update event posted on the event bus
|
* the update event posted on the event bus
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void initUpdate(final InitUpdate update) {
|
public void initUpdate(final InitUpdate update) {
|
||||||
final AbstractSimulatedDevice device = update.getDevice();
|
final AbstractSimulatedDevice device = update.getDevice();
|
||||||
this.getUI().access(new Runnable() {
|
this.getUI().access(() -> {
|
||||||
|
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());
|
||||||
@Override
|
if (item == null) {
|
||||||
public void run() {
|
return;
|
||||||
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());
|
|
||||||
if (item != null) {
|
|
||||||
item.getItemProperty("progress").setValue(device.getProgress());
|
|
||||||
item.getItemProperty("status").setValue(Status.PEDNING);
|
|
||||||
item.getItemProperty("swversion").setValue(device.getSwversion());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.getItemProperty(PROGRESS_COL).setValue(device.getProgress());
|
||||||
|
item.getItemProperty(STATUS_COL).setValue(Status.PEDNING);
|
||||||
|
item.getItemProperty(SWVERSION_COL).setValue(device.getSwversion());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,35 +203,37 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
* @param update
|
* @param update
|
||||||
* the update event posted on the event bus
|
* the update event posted on the event bus
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void progessUpdate(final ProgressUpdate update) {
|
public void progessUpdate(final ProgressUpdate update) {
|
||||||
final AbstractSimulatedDevice device = update.getDevice();
|
final AbstractSimulatedDevice device = update.getDevice();
|
||||||
this.getUI().access(new Runnable() {
|
this.getUI().access(() -> {
|
||||||
@Override
|
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());
|
||||||
public void run() {
|
if (item != null) {
|
||||||
final BeanItem<AbstractSimulatedDevice> item = beanContainer.getItem(device.getId());
|
item.getItemProperty(PROGRESS_COL).setValue(device.getProgress());
|
||||||
if (item != null) {
|
setStatusColumn(device, item);
|
||||||
item.getItemProperty("progress").setValue(device.getProgress());
|
|
||||||
if (device.getProgress() >= 1) {
|
|
||||||
switch (device.getResponseStatus()) {
|
|
||||||
case SUCCESSFUL:
|
|
||||||
item.getItemProperty("status").setValue(Status.FINISH);
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
item.getItemProperty("status").setValue(Status.ERROR);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
item.getItemProperty("status").setValue(Status.UNKNWON);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
item.getItemProperty("status").setValue(Status.PEDNING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void setStatusColumn(final AbstractSimulatedDevice device, final BeanItem<AbstractSimulatedDevice> item) {
|
||||||
|
if (device.getProgress() >= 1) {
|
||||||
|
switch (device.getUpdateStatus().getResponseStatus()) {
|
||||||
|
case SUCCESSFUL:
|
||||||
|
item.getItemProperty(STATUS_COL).setValue(Status.FINISH);
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
item.getItemProperty(STATUS_COL).setValue(Status.ERROR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
item.getItemProperty(STATUS_COL).setValue(Status.UNKNWON);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.getItemProperty(STATUS_COL).setValue(Status.PEDNING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createToolbar() {
|
private void createToolbar() {
|
||||||
final Button createDevicesButton = new Button("generate...");
|
final Button createDevicesButton = new Button("generate...");
|
||||||
createDevicesButton.setIcon(FontAwesome.GEARS);
|
createDevicesButton.setIcon(FontAwesome.GEARS);
|
||||||
@@ -246,18 +254,15 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void openGenerateDialog() {
|
private void openGenerateDialog() {
|
||||||
UI.getCurrent().addWindow(new GenerateDialog(new GenerateDialogCallback() {
|
UI.getCurrent().addWindow(
|
||||||
@Override
|
new GenerateDialog((namePrefix, tenant, amount, pollDelay, basePollUrl, gatewayToken, protocol) -> {
|
||||||
public void okButton(final String namePrefix, final String tenant, final int amount, final int pollDelay,
|
for (int index = 0; index < amount; index++) {
|
||||||
final URL basePollUrl, final String gatewayToken, final Protocol protocol) {
|
final String deviceId = namePrefix + index;
|
||||||
for (int index = 0; index < amount; index++) {
|
beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId,
|
||||||
final String deviceId = namePrefix + index;
|
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
|
||||||
beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId,
|
spSenderService.createOrUpdateThing(tenant, deviceId);
|
||||||
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
|
}
|
||||||
spSenderService.createOrUpdateThing(tenant, deviceId);
|
}));
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Converter<String, Protocol> createProtocolConverter() {
|
private Converter<String, Protocol> createProtocolConverter() {
|
||||||
|
|||||||
@@ -4,16 +4,20 @@ The hawkBit example application is a standalone spring-boot application with an
|
|||||||
We have have described several options for you to get access to the example.
|
We have have described several options for you to get access to the example.
|
||||||
|
|
||||||
## Try out the example application in our hawkBit sandbox on Bluemix
|
## Try out the example application in our hawkBit sandbox on Bluemix
|
||||||
- try out Management UI https://hawkbit.eu-gb.mybluemix.net/UI
|
- try out Management UI https://hawkbit.eu-gb.mybluemix.net/UI (username: admin, passwd: admin)
|
||||||
- try out Management API https://hawkbit.eu-gb.mybluemix.net/rest/v1/targets (don't forget basic auth header)
|
- try out Management API https://hawkbit.eu-gb.mybluemix.net/rest/v1/targets (don't forget basic auth header; username: admin, passwd: admin)
|
||||||
- try out DDI API https://hawkbit.eu-gb.mybluemix.net/DEFAULT/controller/v1/MYTESTDEVICE
|
- try out DDI API https://hawkbit.eu-gb.mybluemix.net/DEFAULT/controller/v1/MYTESTDEVICE (authentication disabled)
|
||||||
|
|
||||||
## On your own workstation
|
## On your own workstation
|
||||||
### Run
|
### Run
|
||||||
```
|
```
|
||||||
java -jar examples/hawkbit-example-app/target/hawkbit-example-app-*-SNAPSHOT.jar
|
java -jar examples/hawkbit-example-app/target/hawkbit-example-app-*-SNAPSHOT.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
|
_(Note: you have to add the JDBC driver also to your class path if you intend to use another database than H2.)_
|
||||||
|
|
||||||
Or:
|
Or:
|
||||||
|
|
||||||
```
|
```
|
||||||
run org eclipse.hawkbit.app.Start
|
run org eclipse.hawkbit.app.Start
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ import com.vaadin.spring.annotation.SpringUI;
|
|||||||
* login path. The easiest way to get an hawkBit login UI running is to extend
|
* login path. The easiest way to get an hawkBit login UI running is to extend
|
||||||
* the {@link HawkbitLoginUI} and to annotated it with {@link SpringUI} as in
|
* the {@link HawkbitLoginUI} and to annotated it with {@link SpringUI} as in
|
||||||
* this example to the defined {@link HawkbitTheme#LOGIN_UI_PATH}.
|
* this example to the defined {@link HawkbitTheme#LOGIN_UI_PATH}.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringUI(path = HawkbitTheme.LOGIN_UI_PATH)
|
@SpringUI(path = HawkbitTheme.LOGIN_UI_PATH)
|
||||||
|
// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from
|
||||||
|
// Vaadin.
|
||||||
|
@SuppressWarnings({ "squid:MaximumInheritanceDepth" })
|
||||||
public class MyLoginUI extends HawkbitLoginUI {
|
public class MyLoginUI extends HawkbitLoginUI {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|||||||
@@ -29,6 +29,9 @@ import com.vaadin.spring.annotation.SpringUI;
|
|||||||
*/
|
*/
|
||||||
@SpringUI
|
@SpringUI
|
||||||
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET)
|
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET)
|
||||||
|
// Exception squid:MaximumInheritanceDepth - Most of the inheritance comes from
|
||||||
|
// Vaadin.
|
||||||
|
@SuppressWarnings({ "squid:MaximumInheritanceDepth" })
|
||||||
public class MyUI extends HawkbitUI {
|
public class MyUI extends HawkbitUI {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ public class Start {
|
|||||||
* @param args
|
* @param args
|
||||||
* the VM arguments.
|
* the VM arguments.
|
||||||
*/
|
*/
|
||||||
|
// Exception squid:S2095 - Spring boot standard behavior
|
||||||
|
@SuppressWarnings({ "squid:S2095" })
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
SpringApplication.run(Start.class, args);
|
SpringApplication.run(Start.class, args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,3 +8,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
vaadin.servlet.productionMode=true
|
vaadin.servlet.productionMode=true
|
||||||
|
|
||||||
|
hawkbit.artifact.url.coap.enabled=false
|
||||||
|
hawkbit.artifact.url.http.enabled=false
|
||||||
|
hawkbit.artifact.url.https.enabled=true
|
||||||
|
hawkbit.artifact.url.https.pattern={protocol}://{hostname}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
|
||||||
|
hawkbit.artifact.url.https.hostname=hawkbit.eu-gb.mybluemix.net
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
|
||||||
|
# This profile adds basic configurations for a MySQL DB usage.
|
||||||
|
# Keep in mind that you need the MariaDB driver in your classpath on compile.
|
||||||
|
# see https://github.com/eclipse/hawkbit/wiki/Run-hawkBit
|
||||||
|
|
||||||
|
spring.jpa.database=MYSQL
|
||||||
|
spring.datasource.url=jdbc:mysql://localhost:3306/hawkbit
|
||||||
|
spring.datasource.username=root
|
||||||
|
spring.datasource.password=
|
||||||
|
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
|
||||||
|
|
||||||
|
spring.datasource.max-active=100
|
||||||
|
spring.datasource.max-idle=10
|
||||||
|
spring.datasource.min-idle=10
|
||||||
|
spring.datasource.initial-size=10
|
||||||
|
spring.datasource.validation-query=select 1 from dual
|
||||||
|
spring.datasource.validation-interval=30000
|
||||||
|
spring.datasource.test-on-borrow=true
|
||||||
|
spring.datasource.test-on-return=false
|
||||||
|
spring.datasource.test-while-idle=true
|
||||||
|
spring.datasource.time-between-eviction-runs-millis=30000
|
||||||
|
spring.datasource.min-evictable-idle-time-millis=60000
|
||||||
|
spring.datasource.max-wait=10000
|
||||||
|
spring.datasource.jmx-enabled=true
|
||||||
@@ -7,21 +7,28 @@
|
|||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# DDI authentication configuration
|
||||||
hawkbit.server.ddi.security.authentication.anonymous.enabled=true
|
hawkbit.server.ddi.security.authentication.anonymous.enabled=true
|
||||||
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
|
hawkbit.server.ddi.security.authentication.targettoken.enabled=true
|
||||||
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
|
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true
|
||||||
|
|
||||||
spring.profiles.active=amqp
|
# Download URL generation config
|
||||||
|
hawkbit.artifact.url.coap.enabled=false
|
||||||
|
hawkbit.artifact.url.http.enabled=true
|
||||||
|
hawkbit.artifact.url.http.port=8080
|
||||||
|
hawkbit.artifact.url.https.enabled=false
|
||||||
|
|
||||||
|
## Vaadin configuration
|
||||||
vaadin.servlet.productionMode=false
|
vaadin.servlet.productionMode=false
|
||||||
|
|
||||||
## Configuration for RabbitMQ integration
|
## Configuration for DMF/RabbitMQ integration
|
||||||
|
spring.profiles.active=amqp
|
||||||
spring.rabbitmq.username=guest
|
spring.rabbitmq.username=guest
|
||||||
spring.rabbitmq.password=guest
|
spring.rabbitmq.password=guest
|
||||||
spring.rabbitmq.virtualHost=/
|
spring.rabbitmq.virtualHost=/
|
||||||
spring.rabbitmq.host=localhost
|
spring.rabbitmq.host=localhost
|
||||||
spring.rabbitmq.port=5672
|
spring.rabbitmq.port=5672
|
||||||
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter
|
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter_ttl
|
||||||
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
|
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
|
||||||
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver
|
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.artifact.repository;
|
package org.eclipse.hawkbit.artifact.repository;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.security.DigestOutputStream;
|
import java.security.DigestOutputStream;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@@ -122,7 +125,11 @@ public class ArtifactStore implements ArtifactRepository {
|
|||||||
LOGGER.debug("storing file {} of content {}", filename, contentType);
|
LOGGER.debug("storing file {} of content {}", filename, contentType);
|
||||||
tempFile = File.createTempFile("uploadFile", null);
|
tempFile = File.createTempFile("uploadFile", null);
|
||||||
try (final FileOutputStream os = new FileOutputStream(tempFile)) {
|
try (final FileOutputStream os = new FileOutputStream(tempFile)) {
|
||||||
return store(content, contentType, os, tempFile, hash);
|
try (BufferedOutputStream bos = new BufferedOutputStream(os)) {
|
||||||
|
try (BufferedInputStream bis = new BufferedInputStream(content)) {
|
||||||
|
return store(content, contentType, bos, tempFile, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (final IOException | MongoException e1) {
|
} catch (final IOException | MongoException e1) {
|
||||||
throw new ArtifactStoreException(e1.getMessage(), e1);
|
throw new ArtifactStoreException(e1.getMessage(), e1);
|
||||||
@@ -162,7 +169,7 @@ public class ArtifactStore implements ArtifactRepository {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DbArtifact store(final InputStream content, final String contentType, final FileOutputStream os,
|
private DbArtifact store(final InputStream content, final String contentType, final OutputStream os,
|
||||||
final File tempFile, final DbArtifactHash hash) {
|
final File tempFile, final DbArtifactHash hash) {
|
||||||
final GridFsArtifact storedArtifact;
|
final GridFsArtifact storedArtifact;
|
||||||
try {
|
try {
|
||||||
@@ -185,7 +192,8 @@ public class ArtifactStore implements ArtifactRepository {
|
|||||||
throw new ArtifactStoreException(e.getMessage(), e);
|
throw new ArtifactStoreException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hash != null && hash.getMd5() != null && !storedArtifact.getHashes().getMd5().equals(hash.getMd5())) {
|
if (hash != null && hash.getMd5() != null
|
||||||
|
&& !storedArtifact.getHashes().getMd5().equalsIgnoreCase(hash.getMd5())) {
|
||||||
throw new HashNotMatchException("The given md5 hash " + hash.getMd5()
|
throw new HashNotMatchException("The given md5 hash " + hash.getMd5()
|
||||||
+ " not matching the calculated md5 hash " + storedArtifact.getHashes().getMd5(),
|
+ " not matching the calculated md5 hash " + storedArtifact.getHashes().getMd5(),
|
||||||
HashNotMatchException.MD5);
|
HashNotMatchException.MD5);
|
||||||
@@ -195,14 +203,14 @@ public class ArtifactStore implements ArtifactRepository {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String computeSHA1Hash(final InputStream stream, final FileOutputStream os,
|
private static String computeSHA1Hash(final InputStream stream, final OutputStream os, final String providedSHA1Sum)
|
||||||
final String providedSHA1Sum) throws NoSuchAlgorithmException, IOException {
|
throws NoSuchAlgorithmException, IOException {
|
||||||
String sha1Hash;
|
String sha1Hash;
|
||||||
// compute digest
|
// compute digest
|
||||||
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||||
final DigestOutputStream dos = new DigestOutputStream(os, md);
|
try (final DigestOutputStream dos = new DigestOutputStream(os, md)) {
|
||||||
ByteStreams.copy(stream, dos);
|
ByteStreams.copy(stream, dos);
|
||||||
dos.close();
|
}
|
||||||
sha1Hash = BaseEncoding.base16().lowerCase().encode(md.digest());
|
sha1Hash = BaseEncoding.base16().lowerCase().encode(md.digest());
|
||||||
if (providedSHA1Sum != null && !providedSHA1Sum.equalsIgnoreCase(sha1Hash)) {
|
if (providedSHA1Sum != null && !providedSHA1Sum.equalsIgnoreCase(sha1Hash)) {
|
||||||
throw new HashNotMatchException(
|
throw new HashNotMatchException(
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ public class MongoConfiguration extends AbstractMongoConfiguration {
|
|||||||
@Override
|
@Override
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
|
// Closed by pre-destroy
|
||||||
|
@SuppressWarnings({ "squid:S2095" })
|
||||||
public Mongo mongo() throws UnknownHostException {
|
public Mongo mongo() throws UnknownHostException {
|
||||||
final MongoClientURI uri = new MongoClientURI(properties.getUri(), createBuilderOutOfOptions(options));
|
final MongoClientURI uri = new MongoClientURI(properties.getUri(), createBuilderOutOfOptions(options));
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,6 @@ hawkbit.controller.minPollingTime=00:00:30
|
|||||||
|
|
||||||
|
|
||||||
# Configuration for RabbitMQ integration
|
# Configuration for RabbitMQ integration
|
||||||
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter
|
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter_ttl
|
||||||
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
|
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
|
||||||
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver
|
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver
|
||||||
3
hawkbit-core/README.md
Normal file
3
hawkbit-core/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# hawkBit Core
|
||||||
|
|
||||||
|
Various internal interfaces and utility classes.
|
||||||
@@ -22,11 +22,10 @@ import org.springframework.core.io.support.ResourcePatternResolver;
|
|||||||
* This resource bundles using specified basenames, to resource loading. This
|
* This resource bundles using specified basenames, to resource loading. This
|
||||||
* MessageSource implementation supports more than 1 properties file with the
|
* MessageSource implementation supports more than 1 properties file with the
|
||||||
* same name. All properties files will be merged.
|
* same name. All properties files will be merged.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class DistributedResourceBundleMessageSource extends ReloadableResourceBundleMessageSource {
|
public class DistributedResourceBundleMessageSource extends ReloadableResourceBundleMessageSource {
|
||||||
|
// Exception squid:S2387 - Follows our upper case convention
|
||||||
|
@SuppressWarnings({ "squid:S2387" })
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedResourceBundleMessageSource.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedResourceBundleMessageSource.class);
|
||||||
private static final String PROPERTIES_SUFFIX = ".properties";
|
private static final String PROPERTIES_SUFFIX = ".properties";
|
||||||
private ResourceLoader resourceLoader;
|
private ResourceLoader resourceLoader;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ package org.eclipse.hawkbit.api;
|
|||||||
* URLs to specific artifacts.
|
* URLs to specific artifacts.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@FunctionalInterface
|
|
||||||
public interface ArtifactUrlHandler {
|
public interface ArtifactUrlHandler {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -34,4 +33,11 @@ public interface ArtifactUrlHandler {
|
|||||||
*/
|
*/
|
||||||
String getUrl(String controllerId, final Long softwareModuleId, final String filename, final String sha1Hash,
|
String getUrl(String controllerId, final Long softwareModuleId, final String filename, final String sha1Hash,
|
||||||
final UrlProtocol protocol);
|
final UrlProtocol protocol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param protocol
|
||||||
|
* to check support for
|
||||||
|
* @return <code>true</code> of the handler supports given protocol.
|
||||||
|
*/
|
||||||
|
boolean protocolSupported(UrlProtocol protocol);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
* @return the pattern to build the URL.
|
* @return the pattern to build the URL.
|
||||||
*/
|
*/
|
||||||
String getPattern();
|
String getPattern();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <code>true</code> if the {@link ProtocolProperties} is
|
||||||
|
* enabled.
|
||||||
|
*/
|
||||||
|
boolean isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -94,6 +100,20 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
*/
|
*/
|
||||||
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables HTTP URI generation in DDI and DMF.
|
||||||
|
*/
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(final boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
@@ -144,6 +164,20 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
*/
|
*/
|
||||||
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables HTTPS URI generation in DDI and DMF.
|
||||||
|
*/
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(final boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
@@ -194,6 +228,20 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
*/
|
*/
|
||||||
private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}";
|
private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables CoAP URI generation in DMF.
|
||||||
|
*/
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(final boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
|
|||||||
@@ -84,4 +84,15 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
|
|||||||
return replaceMap;
|
return replaceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean protocolSupported(final UrlProtocol protocol) {
|
||||||
|
final String protocolString = protocol.name().toLowerCase();
|
||||||
|
final ProtocolProperties properties = urlHandlerProperties.getProperties(protocolString);
|
||||||
|
if (properties == null || properties.getPattern() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return properties.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ public class TenantConfigurationPollingDurationValidator implements TenantConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
// Exception squid:S1166 - Hide origin exception
|
||||||
|
@SuppressWarnings({ "squid:S1166" })
|
||||||
public void validate(final Object tenantConfigurationObject) {
|
public void validate(final Object tenantConfigurationObject) {
|
||||||
TenantConfigurationValidator.super.validate(tenantConfigurationObject);
|
TenantConfigurationValidator.super.validate(tenantConfigurationObject);
|
||||||
final String tenantConfigurationString = (String) tenantConfigurationObject;
|
final String tenantConfigurationString = (String) tenantConfigurationObject;
|
||||||
|
|||||||
@@ -145,9 +145,11 @@ public class DdiArtifactStoreController implements DdiDlArtifactStoreControllerR
|
|||||||
actionStatus.setStatus(Status.DOWNLOAD);
|
actionStatus.setStatus(Status.DOWNLOAD);
|
||||||
|
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
actionStatus.addMessage("It is a partial download request: " + range);
|
actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads range " + range
|
||||||
|
+ " of: " + request.getRequestURI());
|
||||||
} else {
|
} else {
|
||||||
actionStatus.addMessage("Target downloads");
|
actionStatus.addMessage(
|
||||||
|
ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads: " + request.getRequestURI());
|
||||||
}
|
}
|
||||||
controllerManagement.addActionStatusMessage(actionStatus);
|
controllerManagement.addActionStatusMessage(actionStatus);
|
||||||
return action;
|
return action;
|
||||||
|
|||||||
@@ -182,9 +182,11 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
statusMessage.setStatus(Status.DOWNLOAD);
|
statusMessage.setStatus(Status.DOWNLOAD);
|
||||||
|
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
statusMessage.addMessage("It is a partial download request: " + range);
|
statusMessage.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads range " + range
|
||||||
|
+ " of: " + request.getRequestURI());
|
||||||
} else {
|
} else {
|
||||||
statusMessage.addMessage("Controller downloads");
|
statusMessage.addMessage(
|
||||||
|
ControllerManagement.SERVER_MESSAGE_PREFIX + "Target downloads " + request.getRequestURI());
|
||||||
}
|
}
|
||||||
controllerManagement.addActionStatusMessage(statusMessage);
|
controllerManagement.addActionStatusMessage(statusMessage);
|
||||||
return action;
|
return action;
|
||||||
@@ -304,13 +306,13 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
LOG.debug("Controller confirmed cancel (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
LOG.debug("Controller confirmed cancel (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
||||||
targetid, feedback.getStatus().getExecution());
|
targetid, feedback.getStatus().getExecution());
|
||||||
actionStatus.setStatus(Status.CANCELED);
|
actionStatus.setStatus(Status.CANCELED);
|
||||||
actionStatus.addMessage("Controller confirmed cancelation");
|
actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target confirmed cancelation.");
|
||||||
break;
|
break;
|
||||||
case REJECTED:
|
case REJECTED:
|
||||||
LOG.info("Controller reported internal error (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
LOG.info("Controller reported internal error (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
||||||
targetid, feedback.getStatus().getExecution());
|
targetid, feedback.getStatus().getExecution());
|
||||||
actionStatus.setStatus(Status.WARNING);
|
actionStatus.setStatus(Status.WARNING);
|
||||||
actionStatus.addMessage("Controller reported internal ERROR and REJECTED update.");
|
actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target REJECTED update.");
|
||||||
break;
|
break;
|
||||||
case CLOSED:
|
case CLOSED:
|
||||||
handleClosedUpdateStatus(feedback, targetid, actionid, actionStatus);
|
handleClosedUpdateStatus(feedback, targetid, actionid, actionStatus);
|
||||||
@@ -337,7 +339,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
LOG.debug("Controller reported intermediate status (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
LOG.debug("Controller reported intermediate status (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
||||||
targetid, feedback.getStatus().getExecution());
|
targetid, feedback.getStatus().getExecution());
|
||||||
actionStatus.setStatus(Status.RUNNING);
|
actionStatus.setStatus(Status.RUNNING);
|
||||||
actionStatus.addMessage("Controller reported: " + feedback.getStatus().getExecution());
|
actionStatus.addMessage(
|
||||||
|
ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported " + feedback.getStatus().getExecution());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleClosedUpdateStatus(final DdiActionFeedback feedback, final String targetid,
|
private static void handleClosedUpdateStatus(final DdiActionFeedback feedback, final String targetid,
|
||||||
@@ -346,10 +349,10 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
feedback.getStatus().getExecution());
|
feedback.getStatus().getExecution());
|
||||||
if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) {
|
if (feedback.getStatus().getResult().getFinished() == FinalResult.FAILURE) {
|
||||||
actionStatus.setStatus(Status.ERROR);
|
actionStatus.setStatus(Status.ERROR);
|
||||||
actionStatus.addMessage("Controller reported CLOSED with ERROR!");
|
actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported CLOSED with ERROR!");
|
||||||
} else {
|
} else {
|
||||||
actionStatus.setStatus(Status.FINISHED);
|
actionStatus.setStatus(Status.FINISHED);
|
||||||
actionStatus.addMessage("Controller reported CLOSED with OK!");
|
actionStatus.addMessage(ControllerManagement.SERVER_MESSAGE_PREFIX + "Target reported CLOSED with OK!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,8 +390,8 @@ public class DdiRootController implements DdiRootControllerRestApi {
|
|||||||
|
|
||||||
LOG.debug("Found an active CancelAction for target {}. returning cancel: {}", targetid, cancel);
|
LOG.debug("Found an active CancelAction for target {}. returning cancel: {}", targetid, cancel);
|
||||||
|
|
||||||
controllerManagement.registerRetrieved(action,
|
controllerManagement.registerRetrieved(action, ControllerManagement.SERVER_MESSAGE_PREFIX
|
||||||
"Controller retrieved cancel action and should start now the cancelation.");
|
+ "Target retrieved cancel action and should start now the cancelation.");
|
||||||
|
|
||||||
return new ResponseEntity<>(cancel, HttpStatus.OK);
|
return new ResponseEntity<>(cancel, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
|
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
|
||||||
import org.springframework.amqp.core.Binding;
|
import org.springframework.amqp.core.Binding;
|
||||||
import org.springframework.amqp.core.BindingBuilder;
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
@@ -18,6 +15,7 @@ import org.springframework.amqp.core.FanoutExchange;
|
|||||||
import org.springframework.amqp.core.Queue;
|
import org.springframework.amqp.core.Queue;
|
||||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||||
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.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
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;
|
||||||
@@ -31,15 +29,31 @@ import org.springframework.context.annotation.Bean;
|
|||||||
* {@code amqp} to use a AMQP for communication with SP enabled devices.
|
* {@code amqp} to use a AMQP for communication with SP enabled devices.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@EnableConfigurationProperties(AmqpProperties.class)
|
@EnableConfigurationProperties({ AmqpProperties.class, AmqpDeadletterProperties.class })
|
||||||
public class AmqpConfiguration {
|
public class AmqpConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected AmqpProperties amqpProperties;
|
protected AmqpProperties amqpProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected AmqpDeadletterProperties amqpDeadletterProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConnectionFactory connectionFactory;
|
private ConnectionFactory connectionFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link RabbitAdmin} and ignore declaration exceptions.
|
||||||
|
* {@link RabbitAdmin#setIgnoreDeclarationExceptions(boolean)}
|
||||||
|
*
|
||||||
|
* @return the bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RabbitAdmin rabbitAdmin() {
|
||||||
|
final RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
|
||||||
|
rabbitAdmin.setIgnoreDeclarationExceptions(true);
|
||||||
|
return rabbitAdmin;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to set the Jackson2JsonMessageConverter.
|
* Method to set the Jackson2JsonMessageConverter.
|
||||||
*
|
*
|
||||||
@@ -59,7 +73,8 @@ public class AmqpConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Queue receiverQueue() {
|
public Queue receiverQueue() {
|
||||||
return new Queue(amqpProperties.getReceiverQueue(), true, false, false, getDeadLetterExchangeArgs());
|
return new Queue(amqpProperties.getReceiverQueue(), true, false, false,
|
||||||
|
amqpDeadletterProperties.getDeadLetterExchangeArgs(amqpProperties.getDeadLetterExchange()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,7 +94,7 @@ public class AmqpConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Queue deadLetterQueue() {
|
public Queue deadLetterQueue() {
|
||||||
return new Queue(amqpProperties.getDeadLetterQueue());
|
return amqpDeadletterProperties.createDeadletterQueue(amqpProperties.getDeadLetterQueue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -149,10 +164,4 @@ public class AmqpConfiguration {
|
|||||||
return containerFactory;
|
return containerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> getDeadLetterExchangeArgs() {
|
|
||||||
final Map<String, Object> args = new HashMap<>();
|
|
||||||
args.put("x-dead-letter-exchange", amqpProperties.getDeadLetterExchange());
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
|||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter;
|
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousDownload;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousDownload;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter;
|
||||||
@@ -97,7 +96,6 @@ public class AmqpControllerAuthentfication {
|
|||||||
filterChain.add(anonymousDownloadFilter);
|
filterChain.add(anonymousDownloadFilter);
|
||||||
|
|
||||||
filterChain.add(new ControllerPreAuthenticatedAnonymousFilter(ddiSecruityProperties));
|
filterChain.add(new ControllerPreAuthenticatedAnonymousFilter(ddiSecruityProperties));
|
||||||
filterChain.add(new CoapAnonymousPreAuthenticatedFilter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* 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 java.time.Duration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.Queue;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bean which holds the necessary properties for configuring the AMQP deadletter
|
||||||
|
* queue.
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties("hawkbit.dmf.rabbitmq.deadLetter")
|
||||||
|
public class AmqpDeadletterProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message time to live (ttl) for the deadletter queue. Default ttl is 3
|
||||||
|
* weeks.
|
||||||
|
*/
|
||||||
|
private long ttl = Duration.ofDays(21).toMillis();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the deadletter arguments.
|
||||||
|
*
|
||||||
|
* @param exchange
|
||||||
|
* the deadletter exchange
|
||||||
|
* @return map which holds the properties
|
||||||
|
*/
|
||||||
|
public Map<String, Object> getDeadLetterExchangeArgs(final String exchange) {
|
||||||
|
final Map<String, Object> args = new HashMap<>();
|
||||||
|
args.put("x-dead-letter-exchange", exchange);
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a deadletter queue with ttl for messages
|
||||||
|
*
|
||||||
|
* @param queueName
|
||||||
|
* the deadlette queue name
|
||||||
|
* @return the deadletter queue
|
||||||
|
*/
|
||||||
|
public Queue createDeadletterQueue(final String queueName) {
|
||||||
|
return new Queue(queueName, true, false, false, getTTLArgs());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> getTTLArgs() {
|
||||||
|
final Map<String, Object> args = new HashMap<>();
|
||||||
|
args.put("x-message-ttl", getTtl());
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTtl() {
|
||||||
|
return ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTtl(final long ttl) {
|
||||||
|
this.ttl = ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -82,6 +82,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
.getSoftwareModules();
|
.getSoftwareModules();
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = new DownloadAndUpdateRequest();
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = new DownloadAndUpdateRequest();
|
||||||
downloadAndUpdateRequest.setActionId(targetAssignDistributionSetEvent.getActionId());
|
downloadAndUpdateRequest.setActionId(targetAssignDistributionSetEvent.getActionId());
|
||||||
|
downloadAndUpdateRequest.setTargetSecurityToken(targetAssignDistributionSetEvent.getTargetToken());
|
||||||
|
|
||||||
for (final org.eclipse.hawkbit.repository.model.SoftwareModule softwareModule : modules) {
|
for (final org.eclipse.hawkbit.repository.model.SoftwareModule softwareModule : modules) {
|
||||||
final SoftwareModule amqpSoftwareModule = convertToAmqpSoftwareModule(controllerId, softwareModule);
|
final SoftwareModule amqpSoftwareModule = convertToAmqpSoftwareModule(controllerId, softwareModule);
|
||||||
@@ -154,18 +155,26 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
|
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
|
||||||
final Artifact artifact = new Artifact();
|
final Artifact artifact = new Artifact();
|
||||||
|
|
||||||
artifact.getUrls().put(Artifact.UrlProtocol.COAP,
|
if (artifactUrlHandler.protocolSupported(UrlProtocol.COAP)) {
|
||||||
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
artifact.getUrls().put(Artifact.UrlProtocol.COAP,
|
||||||
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.COAP));
|
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
||||||
artifact.getUrls().put(Artifact.UrlProtocol.HTTP,
|
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.COAP));
|
||||||
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
}
|
||||||
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTP));
|
|
||||||
artifact.getUrls().put(Artifact.UrlProtocol.HTTPS,
|
if (artifactUrlHandler.protocolSupported(UrlProtocol.HTTP)) {
|
||||||
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
artifact.getUrls().put(Artifact.UrlProtocol.HTTP,
|
||||||
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTPS));
|
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
||||||
|
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTP));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (artifactUrlHandler.protocolSupported(UrlProtocol.HTTPS)) {
|
||||||
|
artifact.getUrls().put(Artifact.UrlProtocol.HTTPS,
|
||||||
|
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
||||||
|
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTPS));
|
||||||
|
}
|
||||||
|
|
||||||
artifact.setFilename(localArtifact.getFilename());
|
artifact.setFilename(localArtifact.getFilename());
|
||||||
artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), null));
|
artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), localArtifact.getMd5Hash()));
|
||||||
artifact.setSize(localArtifact.getSize());
|
artifact.setSize(localArtifact.getSize());
|
||||||
return artifact;
|
return artifact;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,7 +305,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
final List<SoftwareModule> softwareModuleList = controllerManagement
|
final List<SoftwareModule> softwareModuleList = controllerManagement
|
||||||
.findSoftwareModulesByDistributionSet(distributionSet);
|
.findSoftwareModulesByDistributionSet(distributionSet);
|
||||||
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(),
|
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(),
|
||||||
target.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress()));
|
target.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress(),
|
||||||
|
target.getSecurityToken()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,9 +337,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
final Action action = checkActionExist(message, actionUpdateStatus);
|
final Action action = checkActionExist(message, actionUpdateStatus);
|
||||||
|
|
||||||
final ActionStatus actionStatus = new ActionStatus();
|
final ActionStatus actionStatus = new ActionStatus();
|
||||||
final List<String> messageText = actionUpdateStatus.getMessage();
|
actionUpdateStatus.getMessage().forEach(actionStatus::addMessage);
|
||||||
final String messageString = String.join(", ", messageText);
|
|
||||||
actionStatus.addMessage(messageString);
|
|
||||||
actionStatus.setAction(action);
|
actionStatus.setAction(action);
|
||||||
actionStatus.setOccurredAt(System.currentTimeMillis());
|
actionStatus.setOccurredAt(System.currentTimeMillis());
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class AmqpProperties {
|
|||||||
/**
|
/**
|
||||||
* DMF API dead letter queue.
|
* DMF API dead letter queue.
|
||||||
*/
|
*/
|
||||||
private String deadLetterQueue = "dmf_connector_deadletter";
|
private String deadLetterQueue = "dmf_connector_deadletter_ttl";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DMF API dead letter exchange.
|
* DMF API dead letter exchange.
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
@@ -23,6 +23,7 @@ import static org.mockito.Mockito.when;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
||||||
import org.eclipse.hawkbit.TestDataUtil;
|
import org.eclipse.hawkbit.TestDataUtil;
|
||||||
@@ -58,6 +59,12 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
@Stories("AmqpMessage Dispatcher Service Test")
|
@Stories("AmqpMessage Dispatcher Service Test")
|
||||||
public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWithMongoDB {
|
public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
private static final String TENANT = "default";
|
||||||
|
|
||||||
|
private static final URI AMQP_URI = IpUtil.createAmqpUri("vHost", "mytest");
|
||||||
|
|
||||||
|
private static final String TEST_TOKEN = "testToken";
|
||||||
|
|
||||||
private AmqpMessageDispatcherService amqpMessageDispatcherService;
|
private AmqpMessageDispatcherService amqpMessageDispatcherService;
|
||||||
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
private RabbitTemplate rabbitTemplate;
|
||||||
@@ -89,8 +96,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
@Description("Verfies that download and install event with no software modul works")
|
@Description("Verfies that download and install event with no software modul works")
|
||||||
public void testSendDownloadRequesWithEmptySoftwareModules() {
|
public void testSendDownloadRequesWithEmptySoftwareModules() {
|
||||||
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, new ArrayList<SoftwareModule>(),
|
1L, TENANT, CONTROLLER_ID, 1L, new ArrayList<SoftwareModule>(), AMQP_URI, TEST_TOKEN);
|
||||||
IpUtil.createAmqpUri("vHost", "mytest"));
|
|
||||||
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
||||||
@@ -104,7 +110,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("vHost", "mytest"));
|
1L, TENANT, CONTROLLER_ID, 1L, dsA.getModules(), AMQP_URI, TEST_TOKEN);
|
||||||
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
||||||
@@ -143,7 +149,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
Mockito.when(rabbitTemplate.convertSendAndReceive(any())).thenReturn(receivedList);
|
Mockito.when(rabbitTemplate.convertSendAndReceive(any())).thenReturn(receivedList);
|
||||||
|
|
||||||
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("vHost", "mytest"));
|
1L, TENANT, CONTROLLER_ID, 1L, dsA.getModules(), AMQP_URI, TEST_TOKEN);
|
||||||
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
||||||
@@ -154,7 +160,19 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
if (!softwareModule.getModuleId().equals(module.getId())) {
|
if (!softwareModule.getModuleId().equals(module.getId())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assertFalse("The software module artifacts should not be empty", softwareModule.getArtifacts().isEmpty());
|
assertThat(softwareModule.getArtifacts().size()).isEqualTo(module.getArtifacts().size()).isGreaterThan(0);
|
||||||
|
|
||||||
|
module.getArtifacts().forEach(dbArtifact -> {
|
||||||
|
final Optional<org.eclipse.hawkbit.dmf.json.model.Artifact> found = softwareModule.getArtifacts()
|
||||||
|
.stream().filter(dmfartifact -> dmfartifact.getFilename()
|
||||||
|
.equals(((LocalArtifact) dbArtifact).getFilename()))
|
||||||
|
.findFirst();
|
||||||
|
|
||||||
|
assertTrue("The artifact should exist in message", found.isPresent());
|
||||||
|
assertThat(found.get().getSize()).isEqualTo(dbArtifact.getSize());
|
||||||
|
assertThat(found.get().getHashes().getMd5()).isEqualTo(dbArtifact.getMd5Hash());
|
||||||
|
assertThat(found.get().getHashes().getSha1()).isEqualTo(dbArtifact.getSha1Hash());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +180,7 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
@Description("Verfies that send cancel event works")
|
@Description("Verfies that send cancel event works")
|
||||||
public void testSendCancelRequest() {
|
public void testSendCancelRequest() {
|
||||||
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
|
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, IpUtil.createAmqpUri("vHost", "mytest"));
|
1L, TENANT, CONTROLLER_ID, 1L, AMQP_URI);
|
||||||
amqpMessageDispatcherService
|
amqpMessageDispatcherService
|
||||||
.targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent);
|
.targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(cancelTargetAssignmentDistributionSetEvent.getTargetAdress());
|
final Message sendMessage = createArgumentCapture(cancelTargetAssignmentDistributionSetEvent.getTargetAdress());
|
||||||
@@ -187,13 +205,12 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
downloadAndUpdateRequest.getActionId(), Long.valueOf(1));
|
downloadAndUpdateRequest.getActionId(), Long.valueOf(1));
|
||||||
assertEquals("The topic of the event shuold contain DOWNLOAD_AND_INSTALL", EventTopic.DOWNLOAD_AND_INSTALL,
|
assertEquals("The topic of the event shuold contain DOWNLOAD_AND_INSTALL", EventTopic.DOWNLOAD_AND_INSTALL,
|
||||||
sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC));
|
sendMessage.getMessageProperties().getHeaders().get(MessageHeaderKey.TOPIC));
|
||||||
|
assertEquals("Security token of target", downloadAndUpdateRequest.getTargetSecurityToken(), TEST_TOKEN);
|
||||||
|
|
||||||
return downloadAndUpdateRequest;
|
return downloadAndUpdateRequest;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param sendMessage
|
|
||||||
*/
|
|
||||||
private void assertEventMessage(final Message sendMessage) {
|
private void assertEventMessage(final Message sendMessage) {
|
||||||
assertNotNull("The message should not be null", sendMessage);
|
assertNotNull("The message should not be null", sendMessage);
|
||||||
|
|
||||||
|
|||||||
@@ -333,20 +333,22 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
assertThat(downloadResponse.getResponseCode()).as("Message body response code is wrong")
|
assertThat(downloadResponse.getResponseCode()).as("Message body response code is wrong")
|
||||||
.isEqualTo(HttpStatus.OK.value());
|
.isEqualTo(HttpStatus.OK.value());
|
||||||
assertThat(downloadResponse.getArtifact().getSize()).as("Wrong artifact size in message body").isEqualTo(1L);
|
assertThat(downloadResponse.getArtifact().getSize()).as("Wrong artifact size in message body").isEqualTo(1L);
|
||||||
|
assertThat(downloadResponse.getArtifact().getHashes().getSha1()).as("Wrong sha1 hash").isEqualTo("sha1");
|
||||||
|
assertThat(downloadResponse.getArtifact().getHashes().getMd5()).as("Wrong md5 hash").isEqualTo("md5");
|
||||||
assertThat(downloadResponse.getDownloadUrl()).as("download url is wrong")
|
assertThat(downloadResponse.getDownloadUrl()).as("download url is wrong")
|
||||||
.startsWith("http://localhost/api/v1/downloadserver/downloadId/");
|
.startsWith("http://localhost/api/v1/downloadserver/downloadId/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests TODO")
|
@Description("Tests TODO")
|
||||||
public void lookupNextUpdateActionAfterFinished() throws IllegalArgumentException, IllegalAccessException {
|
public void lookupNextUpdateActionAfterFinished() throws IllegalAccessException {
|
||||||
|
|
||||||
// Mock
|
// Mock
|
||||||
final Action action = createActionWithTarget(22L, Status.FINISHED);
|
final Action action = createActionWithTarget(22L, Status.FINISHED);
|
||||||
when(controllerManagementMock.findActionWithDetails(Matchers.any())).thenReturn(action);
|
when(controllerManagementMock.findActionWithDetails(Matchers.any())).thenReturn(action);
|
||||||
when(controllerManagementMock.addUpdateActionStatus(Matchers.any(), Matchers.any())).thenReturn(action);
|
when(controllerManagementMock.addUpdateActionStatus(Matchers.any(), Matchers.any())).thenReturn(action);
|
||||||
// for the test the same action can be used
|
// for the test the same action can be used
|
||||||
final List<Action> actionList = new ArrayList<Action>();
|
final List<Action> actionList = new ArrayList<>();
|
||||||
actionList.add(action);
|
actionList.add(action);
|
||||||
when(controllerManagementMock.findActionByTargetAndActive(Matchers.any())).thenReturn(actionList);
|
when(controllerManagementMock.findActionByTargetAndActive(Matchers.any())).thenReturn(actionList);
|
||||||
|
|
||||||
@@ -372,6 +374,8 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
assertThat(targetAssignDistributionSetEvent.getControllerId()).as("event has wrong controller id")
|
assertThat(targetAssignDistributionSetEvent.getControllerId()).as("event has wrong controller id")
|
||||||
.isEqualTo("target1");
|
.isEqualTo("target1");
|
||||||
|
assertThat(targetAssignDistributionSetEvent.getTargetToken()).as("targetoken not filled correctly")
|
||||||
|
.isEqualTo(action.getTarget().getSecurityToken());
|
||||||
assertThat(targetAssignDistributionSetEvent.getActionId()).as("event has wrong action id").isEqualTo(22L);
|
assertThat(targetAssignDistributionSetEvent.getActionId()).as("event has wrong action id").isEqualTo(22L);
|
||||||
assertThat(targetAssignDistributionSetEvent.getSoftwareModules()).as("event has wrong sofware modules")
|
assertThat(targetAssignDistributionSetEvent.getSoftwareModules()).as("event has wrong sofware modules")
|
||||||
.isEqualTo(softwareModuleList);
|
.isEqualTo(softwareModuleList);
|
||||||
@@ -379,7 +383,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ActionUpdateStatus createActionUpdateStatus(final ActionStatus status) {
|
private ActionUpdateStatus createActionUpdateStatus(final ActionStatus status) {
|
||||||
return createActionUpdateStatus(status, 2l);
|
return createActionUpdateStatus(status, 2L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ActionUpdateStatus createActionUpdateStatus(final ActionStatus status, final Long id) {
|
private ActionUpdateStatus createActionUpdateStatus(final ActionStatus status, final Long id) {
|
||||||
@@ -404,15 +408,14 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<SoftwareModule> createSoftwareModuleList() {
|
private List<SoftwareModule> createSoftwareModuleList() {
|
||||||
final List<SoftwareModule> softwareModuleList = new ArrayList<SoftwareModule>();
|
final List<SoftwareModule> softwareModuleList = new ArrayList<>();
|
||||||
final SoftwareModule softwareModule = new SoftwareModule();
|
final SoftwareModule softwareModule = new SoftwareModule();
|
||||||
softwareModule.setId(777L);
|
softwareModule.setId(777L);
|
||||||
softwareModuleList.add(softwareModule);
|
softwareModuleList.add(softwareModule);
|
||||||
return softwareModuleList;
|
return softwareModuleList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action createActionWithTarget(final Long targetId, final Status status)
|
private Action createActionWithTarget(final Long targetId, final Status status) throws IllegalAccessException {
|
||||||
throws IllegalArgumentException, IllegalAccessException {
|
|
||||||
// is needed for the creation of targets
|
// is needed for the creation of targets
|
||||||
initalizeSecurityTokenGenerator();
|
initalizeSecurityTokenGenerator();
|
||||||
|
|
||||||
@@ -427,7 +430,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initalizeSecurityTokenGenerator() throws IllegalArgumentException, IllegalAccessException {
|
private void initalizeSecurityTokenGenerator() throws IllegalAccessException {
|
||||||
final SecurityTokenGeneratorHolder instance = SecurityTokenGeneratorHolder.getInstance();
|
final SecurityTokenGeneratorHolder instance = SecurityTokenGeneratorHolder.getInstance();
|
||||||
final Field[] fields = instance.getClass().getDeclaredFields();
|
final Field[] fields = instance.getClass().getDeclaredFields();
|
||||||
for (final Field field : fields) {
|
for (final Field field : fields) {
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ public class BaseAmqpServiceTest {
|
|||||||
final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus();
|
final ActionUpdateStatus actionUpdateStatus = new ActionUpdateStatus();
|
||||||
actionUpdateStatus.setActionId(1L);
|
actionUpdateStatus.setActionId(1L);
|
||||||
actionUpdateStatus.setSoftwareModuleId(2L);
|
actionUpdateStatus.setSoftwareModuleId(2L);
|
||||||
|
actionUpdateStatus.getMessage().add("Message 1");
|
||||||
|
actionUpdateStatus.getMessage().add("Message 2");
|
||||||
|
|
||||||
final Message message = rabbitTemplate.getMessageConverter().toMessage(actionUpdateStatus,
|
final Message message = rabbitTemplate.getMessageConverter().toMessage(actionUpdateStatus,
|
||||||
new MessageProperties());
|
new MessageProperties());
|
||||||
|
|||||||
@@ -13,10 +13,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON representation of artifact hash.
|
* JSON representation of artifact hash.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class ArtifactHash {
|
public class ArtifactHash {
|
||||||
|
|
||||||
|
|||||||
@@ -19,15 +19,16 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
/**
|
/**
|
||||||
* JSON representation of download and update request.
|
* JSON representation of download and update request.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@JsonInclude(Include.NON_NULL)
|
@JsonInclude(Include.NON_NULL)
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class DownloadAndUpdateRequest {
|
public class DownloadAndUpdateRequest {
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private Long actionId;
|
private Long actionId;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private String targetSecurityToken;
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private final List<SoftwareModule> softwareModules = new LinkedList<>();
|
private final List<SoftwareModule> softwareModules = new LinkedList<>();
|
||||||
|
|
||||||
@@ -39,6 +40,14 @@ public class DownloadAndUpdateRequest {
|
|||||||
this.actionId = correlator;
|
this.actionId = correlator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTargetSecurityToken() {
|
||||||
|
return targetSecurityToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTargetSecurityToken(final String targetSecurityToken) {
|
||||||
|
this.targetSecurityToken = targetSecurityToken;
|
||||||
|
}
|
||||||
|
|
||||||
public List<SoftwareModule> getSoftwareModules() {
|
public List<SoftwareModule> getSoftwareModules() {
|
||||||
return softwareModules;
|
return softwareModules;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
public class TenantSecurityToken {
|
public class TenantSecurityToken {
|
||||||
|
|
||||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization";
|
|
||||||
public static final String COAP_TOKEN_VALUE = "CoapToken";
|
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private final String tenant;
|
private final String tenant;
|
||||||
|
|||||||
34
hawkbit-mgmt-ui/README.md
Normal file
34
hawkbit-mgmt-ui/README.md
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# hawkBit User Interface
|
||||||
|
|
||||||
|
The hawkBit user interface is based on the Vaadin and Vaadin-Spring framework and allows to manage software updates and large scale roll-outs via a user interface.
|
||||||
|
|
||||||
|
## Debugging client-side code
|
||||||
|
### Debug using SuperDevMode
|
||||||
|
The SuperDevMode can be used to debug client side code without any browser plugin.
|
||||||
|
|
||||||
|
#### Using SuperDevMode with chrome :
|
||||||
|
|
||||||
|
- Add required maven dependencies
|
||||||
|
- Add vaadin-client-compiler dependency
|
||||||
|
- Add jetty dependencies (version : 8.1x)
|
||||||
|
- Set redirect property in the AppWidgetSet.gwt.xml module descriptor as follows
|
||||||
|
- < set-configuration-property name="devModeRedirectEnabled" value="true" />
|
||||||
|
- Create launch configuration for the SuperDevMode
|
||||||
|
- The main class to execute should be com.google.gwt.dev.codeserver.CodeServer.
|
||||||
|
- Add fully-qualified class name of widgetset (org.eclipse.hawkbit.ui.AppWidgetSet) as parameter
|
||||||
|
- Enable debug in chrome
|
||||||
|
- Chrome inspector window ▸ Click on settings icon ▸ Scripts ▸ Enable source maps option
|
||||||
|
- Run the SuperDevMode Code Server with the launch configuration created above
|
||||||
|
- Open http://localhost:8080/UI/?debug .Click on "SuperDev" button in debug console (Alternatively can directly add ?superdevmode parameter to URL)
|
||||||
|
- Widgetset is compiled and you can see the java code files loaded in 'Chrome inspector window ▸ Source tab'
|
||||||
|
|
||||||
|
|
||||||
|
#### Using SuperDevMode with Eclipse :
|
||||||
|
|
||||||
|
- Install the plugin from http://sdbg.github.io/p2
|
||||||
|
- Start the server and Super Dev Mode as mentioned above
|
||||||
|
- Create a new launch configuration in Eclipse
|
||||||
|
- Type is "Launch Chrome"
|
||||||
|
- http://localhost:8080/UI/?superdevmode
|
||||||
|
- Launch the new configuration in debug mode
|
||||||
|
- Now breakpoints in eclipse can be set
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<version>0.2.0-SNAPSHOT</version>
|
<version>0.2.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>hawkbit-mgmt-ui</artifactId>
|
<artifactId>hawkbit-mgmt-ui</artifactId>
|
||||||
<name>hawkBit :: Mgmt UI</name>
|
<name>hawkBit :: UI</name>
|
||||||
<description>Bosch IoT Software Provisioning server web application</description>
|
<description>Bosch IoT Software Provisioning server web application</description>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent;
|
|||||||
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetInfoUpdateEvent;
|
||||||
import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetTagCreatedBulkEvent;
|
||||||
import org.eclipse.hawkbit.eventbus.event.TargetTagDeletedEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetTagDeletedEvent;
|
||||||
|
import org.eclipse.hawkbit.eventbus.event.TargetTagUpdateEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default hawkbit event provider.
|
* The default hawkbit event provider.
|
||||||
@@ -39,6 +40,7 @@ public class HawkbitEventProvider implements UIEventProvider {
|
|||||||
SINGLE_EVENTS.add(DistributionSetTagUpdateEvent.class);
|
SINGLE_EVENTS.add(DistributionSetTagUpdateEvent.class);
|
||||||
SINGLE_EVENTS.add(RolloutGroupChangeEvent.class);
|
SINGLE_EVENTS.add(RolloutGroupChangeEvent.class);
|
||||||
SINGLE_EVENTS.add(RolloutChangeEvent.class);
|
SINGLE_EVENTS.add(RolloutChangeEvent.class);
|
||||||
|
SINGLE_EVENTS.add(TargetTagUpdateEvent.class);
|
||||||
|
|
||||||
BULK_EVENTS.add(TargetCreatedEvent.class);
|
BULK_EVENTS.add(TargetCreatedEvent.class);
|
||||||
BULK_EVENTS.add(TargetInfoUpdateEvent.class);
|
BULK_EVENTS.add(TargetInfoUpdateEvent.class);
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ public class UiProperties {
|
|||||||
/**
|
/**
|
||||||
* Demo user password.
|
* Demo user password.
|
||||||
*/
|
*/
|
||||||
|
// Exception squid:S2068 - Empty password
|
||||||
|
@SuppressWarnings({ "squid:S2068" })
|
||||||
private String password = "";
|
private String password = "";
|
||||||
|
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
@@ -64,6 +66,7 @@ public class UiProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Links to potentially other systems (e.g. support, user management,
|
* Links to potentially other systems (e.g. support, user management,
|
||||||
* documentation etc.).
|
* documentation etc.).
|
||||||
@@ -227,6 +230,7 @@ public class UiProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration of login view.
|
* Configuration of login view.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
|||||||
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;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
@@ -101,8 +102,8 @@ public class BaseSwModuleBeanQuery extends AbstractBeanQuery<ProxyBaseSoftwareMo
|
|||||||
proxy.setVersion(bean.getVersion());
|
proxy.setVersion(bean.getVersion());
|
||||||
proxy.setVendor(bean.getVendor());
|
proxy.setVendor(bean.getVendor());
|
||||||
proxy.setDescription(bean.getDescription());
|
proxy.setDescription(bean.getDescription());
|
||||||
proxy.setCreatedByUser(HawkbitCommonUtil.getIMUser(bean.getCreatedBy()));
|
proxy.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(bean));
|
||||||
proxy.setModifiedByUser(HawkbitCommonUtil.getIMUser(bean.getLastModifiedBy()));
|
proxy.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(bean));
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ public class SoftwareModuleAddUpdateWindow implements Serializable {
|
|||||||
SPUIDefinitions.CREATE_UPDATE_WINDOW);
|
SPUIDefinitions.CREATE_UPDATE_WINDOW);
|
||||||
window.setContent(mainLayout);
|
window.setContent(mainLayout);
|
||||||
window.setModal(true);
|
window.setModal(true);
|
||||||
|
nameTextField.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDescriptionTextChangeListener() {
|
private void addDescriptionTextChangeListener() {
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C
|
|||||||
mainLayout = new HorizontalLayout();
|
mainLayout = new HorizontalLayout();
|
||||||
mainLayout.addComponent(fieldButtonLayout);
|
mainLayout.addComponent(fieldButtonLayout);
|
||||||
setCompositionRoot(mainLayout);
|
setCompositionRoot(mainLayout);
|
||||||
|
typeName.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addListeners() {
|
private void addListeners() {
|
||||||
@@ -553,7 +554,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C
|
|||||||
.findSoftwareModuleTypeByName(typeName.getValue());
|
.findSoftwareModuleTypeByName(typeName.getValue());
|
||||||
if (createOptiongroup.getValue().equals(createTypeStr)) {
|
if (createOptiongroup.getValue().equals(createTypeStr)) {
|
||||||
if (!checkIsKeyDuplicate(typeKey.getValue()) && !checkIsDuplicate(existingType)) {
|
if (!checkIsKeyDuplicate(typeKey.getValue()) && !checkIsDuplicate(existingType)) {
|
||||||
crateNewSWModuleType();
|
createNewSWModuleType();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -610,9 +611,9 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C
|
|||||||
/**
|
/**
|
||||||
* Create new tag.
|
* Create new tag.
|
||||||
*/
|
*/
|
||||||
private void crateNewSWModuleType() {
|
private void createNewSWModuleType() {
|
||||||
int assignNumber = 0;
|
int assignNumber = 0;
|
||||||
final String colorPicked = getColorPickedSting();
|
final String colorPicked = getColorPickedString();
|
||||||
final String typeNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeName.getValue());
|
final String typeNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeName.getValue());
|
||||||
final String typeKeyValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeKey.getValue());
|
final String typeKeyValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeKey.getValue());
|
||||||
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeDesc.getValue());
|
final String typeDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(typeDesc.getValue());
|
||||||
@@ -649,7 +650,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C
|
|||||||
*
|
*
|
||||||
* @return String of color picked value.
|
* @return String of color picked value.
|
||||||
*/
|
*/
|
||||||
private String getColorPickedSting() {
|
private String getColorPickedString() {
|
||||||
return "rgb(" + getSelPreview().getColor().getRed() + "," + getSelPreview().getColor().getGreen() + ","
|
return "rgb(" + getSelPreview().getColor().getRed() + "," + getSelPreview().getColor().getGreen() + ","
|
||||||
+ getSelPreview().getColor().getBlue() + ")";
|
+ getSelPreview().getColor().getBlue() + ")";
|
||||||
}
|
}
|
||||||
@@ -675,7 +676,7 @@ public class CreateUpdateSoftwareTypeLayout extends CustomComponent implements C
|
|||||||
|
|
||||||
existingType.setDescription(null != typeDescValue ? typeDescValue : null);
|
existingType.setDescription(null != typeDescValue ? typeDescValue : null);
|
||||||
|
|
||||||
existingType.setColour(getColorPickedSting());
|
existingType.setColour(getColorPickedString());
|
||||||
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();
|
closeWindow();
|
||||||
|
|||||||
@@ -37,20 +37,12 @@ import com.vaadin.ui.Upload.SucceededListener;
|
|||||||
* {@link StreamVariable} upload variants.
|
* {@link StreamVariable} upload variants.
|
||||||
*
|
*
|
||||||
* The handler manages the output to the user and at the same time ensures that
|
* The handler manages the output to the user and at the same time ensures that
|
||||||
* the upload does not exceed the configued max file size.
|
* the upload does not exceed the configured max file size.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class UploadHandler implements StreamVariable, Receiver, SucceededListener, FailedListener, FinishedListener,
|
public class UploadHandler implements StreamVariable, Receiver, SucceededListener, FailedListener, FinishedListener,
|
||||||
ProgressListener, StartedListener {
|
ProgressListener, StartedListener {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(UploadHandler.class);
|
private static final Logger LOG = LoggerFactory.getLogger(UploadHandler.class);
|
||||||
@@ -108,7 +100,7 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene
|
|||||||
public OutputStream receiveUpload(final String fileName, final String mimeType) {
|
public OutputStream receiveUpload(final String fileName, final String mimeType) {
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
//reset has directory flag before upload
|
// reset has directory flag before upload
|
||||||
view.setHasDirectory(false);
|
view.setHasDirectory(false);
|
||||||
try {
|
try {
|
||||||
if (view.checkIfSoftwareModuleIsSelected()) {
|
if (view.checkIfSoftwareModuleIsSelected()) {
|
||||||
@@ -343,11 +335,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#hashCode()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
@@ -356,11 +343,6 @@ public class UploadHandler implements StreamVariable, Receiver, SucceededListene
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see java.lang.Object#equals(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(final Object obj) {
|
public boolean equals(final Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
|
|||||||
@@ -0,0 +1,187 @@
|
|||||||
|
/**
|
||||||
|
* 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.ui.common;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.eclipse.hawkbit.im.authentication.UserPrincipal;
|
||||||
|
import org.eclipse.hawkbit.repository.model.BaseEntity;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
||||||
|
|
||||||
|
import com.vaadin.server.VaadinService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Utility class to user details e.g. username
|
||||||
|
*/
|
||||||
|
public final class UserDetailsFormatter {
|
||||||
|
|
||||||
|
private static final String TRIM_APPENDIX = "...";
|
||||||
|
private static final String DETAIL_SEPERATOR = ", ";
|
||||||
|
|
||||||
|
private UserDetailsFormatter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load user details by the user name and format the user name to max 100
|
||||||
|
* characters.
|
||||||
|
*
|
||||||
|
* @see {@link UserDetailsFormatter#loadAndFormatUsername(String, int)}
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* the user name
|
||||||
|
* @return the formatted user name (max 100 characters) cannot be <null>
|
||||||
|
*/
|
||||||
|
public static String loadAndFormatUsername(final String username) {
|
||||||
|
return loadAndFormatUsername(username, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load user details by {@link BaseEntity#getCreatedBy()} and format the
|
||||||
|
* user name. Use {@link UserDetailsFormatter#loadAndFormatUsername(String)}
|
||||||
|
*
|
||||||
|
* @param baseEntity
|
||||||
|
* the entity
|
||||||
|
* @return the formatted 'created at user name' (max 100 characters) cannot
|
||||||
|
* be <null>
|
||||||
|
*/
|
||||||
|
public static String loadAndFormatCreatedBy(final BaseEntity baseEntity) {
|
||||||
|
if (baseEntity == null || baseEntity.getCreatedBy() == null) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadAndFormatUsername(baseEntity.getCreatedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load user details by {@link BaseEntity#getLastModifiedBy()} and format
|
||||||
|
* the user name. Use
|
||||||
|
* {@link UserDetailsFormatter#loadAndFormatUsername(String)}
|
||||||
|
*
|
||||||
|
* @param baseEntity
|
||||||
|
* the entity
|
||||||
|
* @return the formatted 'last modefied by user name' (max 100 characters)
|
||||||
|
* cannot be <null>
|
||||||
|
*/
|
||||||
|
public static String loadAndFormatLastModifiedBy(final BaseEntity baseEntity) {
|
||||||
|
if (baseEntity == null || baseEntity.getLastModifiedBy() == null) {
|
||||||
|
return StringUtils.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadAndFormatUsername(baseEntity.getLastModifiedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load user details by the current session information and format the user
|
||||||
|
* name to max 12 characters. @see
|
||||||
|
* {@link UserDetailsFormatter#loadAndFormatUsername(String, int)}
|
||||||
|
*
|
||||||
|
* @return the formatted user name (max 12 characters) cannot be <null>
|
||||||
|
*/
|
||||||
|
public static String formatCurrentUsername() {
|
||||||
|
return loadAndFormatUsername(getCurrentUser().getUsername(), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load user details by the user name and format the user name. If the
|
||||||
|
* loaded {@link UserDetails} is not an instance of a {@link UserPrincipal},
|
||||||
|
* then just the {@link UserDetails#getUsername()} will return.
|
||||||
|
*
|
||||||
|
* If first and last name available, they will combined. Otherwise the
|
||||||
|
* {@link UserPrincipal#getLoginname()} will formatted. The formatted name
|
||||||
|
* is reduced to 100 characters.
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* the user name
|
||||||
|
* @param expectedNameLength
|
||||||
|
* the name size of each name part
|
||||||
|
* @return the formatted user name (max expectedNameLength characters)
|
||||||
|
* cannot be <null>
|
||||||
|
*/
|
||||||
|
public static String loadAndFormatUsername(final String username, final int expectedNameLength) {
|
||||||
|
final UserDetails userDetails = loadUserByUsername(username);
|
||||||
|
return formatUserName(expectedNameLength, userDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatUserName(final int expectedNameLength, final UserDetails userDetails) {
|
||||||
|
if (!(userDetails instanceof UserPrincipal)) {
|
||||||
|
return userDetails.getUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
final UserPrincipal userPrincipal = (UserPrincipal) userDetails;
|
||||||
|
|
||||||
|
String firstname = StringUtils.defaultIfEmpty(userPrincipal.getFirstname(), StringUtils.EMPTY);
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(firstname)) {
|
||||||
|
firstname += DETAIL_SEPERATOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String firstAndLastname = firstname
|
||||||
|
+ StringUtils.defaultIfEmpty(userPrincipal.getLastname(), StringUtils.EMPTY);
|
||||||
|
|
||||||
|
final String trimmedUsername = trimAndFormatDetail(firstAndLastname, expectedNameLength);
|
||||||
|
|
||||||
|
if (StringUtils.isEmpty(trimmedUsername)) {
|
||||||
|
return trimAndFormatDetail(userPrincipal.getLoginname(), expectedNameLength);
|
||||||
|
}
|
||||||
|
return trimmedUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the current tenant. The information is loaded by the current
|
||||||
|
* session information.
|
||||||
|
*
|
||||||
|
* @return the formatted user name (max 8 characters) can be <null>
|
||||||
|
*/
|
||||||
|
public static String formatCurrentTenant() {
|
||||||
|
final UserDetails userDetails = getCurrentUser();
|
||||||
|
if (!(userDetails instanceof UserPrincipal)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final UserPrincipal userPrincipal = (UserPrincipal) userDetails;
|
||||||
|
return trimAndFormatDetail(userPrincipal.getTenant(), 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UserDetails getCurrentUser() {
|
||||||
|
final SecurityContext context = (SecurityContext) VaadinService.getCurrentRequest().getWrappedSession()
|
||||||
|
.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
||||||
|
return (UserDetails) context.getAuthentication().getPrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String trimAndFormatDetail(final String formatString, final int expectedDetailLength) {
|
||||||
|
final String detail = StringUtils.defaultIfEmpty(formatString, StringUtils.EMPTY);
|
||||||
|
final String trimmedDetail = StringUtils.substring(detail, 0, expectedDetailLength);
|
||||||
|
if (StringUtils.length(detail) > expectedDetailLength) {
|
||||||
|
return trimmedDetail + TRIM_APPENDIX;
|
||||||
|
}
|
||||||
|
return trimmedDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exception squid:S1166 - exception has to be hidden
|
||||||
|
@SuppressWarnings({ "squid:S1166" })
|
||||||
|
private static UserDetails loadUserByUsername(final String username) {
|
||||||
|
final UserDetailsService userDetailsService = SpringContextHelper.getBean(UserDetailsService.class);
|
||||||
|
try {
|
||||||
|
final UserDetails loadUserByUsername = userDetailsService.loadUserByUsername(username);
|
||||||
|
if (loadUserByUsername == null) {
|
||||||
|
throw new UsernameNotFoundException("User not found " + username);
|
||||||
|
}
|
||||||
|
return loadUserByUsername;
|
||||||
|
} catch (final UsernameNotFoundException e) {
|
||||||
|
return new User(username, "", Collections.emptyList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -150,20 +150,20 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
|||||||
|
|
||||||
private void buildLayout() {
|
private void buildLayout() {
|
||||||
final HorizontalLayout nameEditLayout = new HorizontalLayout();
|
final HorizontalLayout nameEditLayout = new HorizontalLayout();
|
||||||
nameEditLayout.setWidth(100.0f, Unit.PERCENTAGE);
|
nameEditLayout.setWidth(100.0F, Unit.PERCENTAGE);
|
||||||
nameEditLayout.addComponent(caption);
|
nameEditLayout.addComponent(caption);
|
||||||
nameEditLayout.setComponentAlignment(caption, Alignment.MIDDLE_LEFT);
|
nameEditLayout.setComponentAlignment(caption, Alignment.TOP_LEFT);
|
||||||
if (hasEditPermission()) {
|
if (hasEditPermission()) {
|
||||||
nameEditLayout.addComponent(editButton);
|
nameEditLayout.addComponent(editButton);
|
||||||
nameEditLayout.setComponentAlignment(editButton, Alignment.MIDDLE_RIGHT);
|
nameEditLayout.setComponentAlignment(editButton, Alignment.TOP_RIGHT);
|
||||||
}
|
}
|
||||||
nameEditLayout.setExpandRatio(caption, 1.0f);
|
nameEditLayout.setExpandRatio(caption, 1.0F);
|
||||||
nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
|
nameEditLayout.addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
|
||||||
|
|
||||||
addComponent(nameEditLayout);
|
addComponent(nameEditLayout);
|
||||||
setComponentAlignment(nameEditLayout, Alignment.MIDDLE_CENTER);
|
setComponentAlignment(nameEditLayout, Alignment.TOP_CENTER);
|
||||||
addComponent(detailsTab);
|
addComponent(detailsTab);
|
||||||
setComponentAlignment(nameEditLayout, Alignment.MIDDLE_CENTER);
|
setComponentAlignment(nameEditLayout, Alignment.TOP_CENTER);
|
||||||
|
|
||||||
setSizeFull();
|
setSizeFull();
|
||||||
setHeightUndefined();
|
setHeightUndefined();
|
||||||
@@ -171,9 +171,7 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Label createHeaderCaption() {
|
private Label createHeaderCaption() {
|
||||||
final Label captionLabel = SPUIComponentProvider.getLabel(getDefaultCaption(),
|
return SPUIComponentProvider.getLabel(getDefaultCaption(), SPUILabelDefinitions.SP_WIDGET_CAPTION);
|
||||||
SPUILabelDefinitions.SP_WIDGET_CAPTION);
|
|
||||||
return captionLabel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected VerticalLayout getTabLayout() {
|
protected VerticalLayout getTabLayout() {
|
||||||
@@ -213,22 +211,22 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
|||||||
populateDetailsWidget();
|
populateDetailsWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateLogLayout(final VerticalLayout changeLogLayout, final Long lastModifiedAt,
|
protected void populateLog() {
|
||||||
final String lastModifiedBy, final Long createdAt, final String createdBy, final I18N i18n) {
|
logLayout.removeAllComponents();
|
||||||
changeLogLayout.removeAllComponents();
|
|
||||||
changeLogLayout.addComponent(SPUIComponentProvider.createNameValueLabel(i18n.get("label.created.at"),
|
|
||||||
createdAt == null ? "" : SPDateTimeUtil.getFormattedDate(createdAt)));
|
|
||||||
|
|
||||||
changeLogLayout.addComponent(SPUIComponentProvider.createNameValueLabel(i18n.get("label.created.by"),
|
logLayout.addComponent(SPUIComponentProvider.createNameValueLabel(i18n.get("label.created.at"),
|
||||||
createdBy == null ? "" : HawkbitCommonUtil.getIMUser(createdBy)));
|
SPDateTimeUtil.formatCreatedAt(selectedBaseEntity)));
|
||||||
|
|
||||||
if (null != lastModifiedAt) {
|
logLayout.addComponent(SPUIComponentProvider.createCreatedByLabel(i18n, selectedBaseEntity));
|
||||||
changeLogLayout.addComponent(SPUIComponentProvider.createNameValueLabel(i18n.get("label.modified.date"),
|
|
||||||
SPDateTimeUtil.getFormattedDate(lastModifiedAt)));
|
|
||||||
|
|
||||||
changeLogLayout.addComponent(SPUIComponentProvider.createNameValueLabel(i18n.get("label.modified.by"),
|
if (selectedBaseEntity == null || selectedBaseEntity.getLastModifiedAt() == null) {
|
||||||
lastModifiedBy == null ? "" : HawkbitCommonUtil.getIMUser(lastModifiedBy)));
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logLayout.addComponent(SPUIComponentProvider.createNameValueLabel(i18n.get("label.modified.date"),
|
||||||
|
SPDateTimeUtil.formatLastModifiedAt(selectedBaseEntity)));
|
||||||
|
|
||||||
|
logLayout.addComponent(SPUIComponentProvider.createLastModifiedByLabel(i18n, selectedBaseEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateDescriptionLayout(final String descriptionLabel, final String description) {
|
protected void updateDescriptionLayout(final String descriptionLabel, final String description) {
|
||||||
@@ -320,19 +318,6 @@ public abstract class AbstractTableDetailsLayout<T extends NamedEntity> extends
|
|||||||
return detailsLayout;
|
return detailsLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VerticalLayout getLogLayout() {
|
|
||||||
return logLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateLog() {
|
|
||||||
if (selectedBaseEntity == null) {
|
|
||||||
updateLogLayout(getLogLayout(), null, StringUtils.EMPTY, null, null, i18n);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateLogLayout(getLogLayout(), selectedBaseEntity.getLastModifiedAt(), selectedBaseEntity.getLastModifiedBy(),
|
|
||||||
selectedBaseEntity.getCreatedAt(), selectedBaseEntity.getCreatedBy(), i18n);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void populateDescription() {
|
private void populateDescription() {
|
||||||
if (selectedBaseEntity != null) {
|
if (selectedBaseEntity != null) {
|
||||||
updateDescriptionLayout(i18n.get("label.description"), selectedBaseEntity.getDescription());
|
updateDescriptionLayout(i18n.get("label.description"), selectedBaseEntity.getDescription());
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import javax.annotation.PreDestroy;
|
|||||||
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
import org.eclipse.hawkbit.repository.model.NamedEntity;
|
||||||
import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent;
|
import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent;
|
||||||
import org.eclipse.hawkbit.ui.common.ManagmentEntityState;
|
import org.eclipse.hawkbit.ui.common.ManagmentEntityState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
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.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
@@ -212,9 +212,9 @@ public abstract class AbstractTable<E extends NamedEntity, I> extends Table {
|
|||||||
item.getItemProperty(SPUILabelDefinitions.VAR_ID).setValue(baseEntity.getId());
|
item.getItemProperty(SPUILabelDefinitions.VAR_ID).setValue(baseEntity.getId());
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_DESC).setValue(baseEntity.getDescription());
|
item.getItemProperty(SPUILabelDefinitions.VAR_DESC).setValue(baseEntity.getDescription());
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_CREATED_BY)
|
item.getItemProperty(SPUILabelDefinitions.VAR_CREATED_BY)
|
||||||
.setValue(HawkbitCommonUtil.getIMUser(baseEntity.getCreatedBy()));
|
.setValue(UserDetailsFormatter.loadAndFormatCreatedBy(baseEntity));
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY)
|
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY)
|
||||||
.setValue(HawkbitCommonUtil.getIMUser(baseEntity.getLastModifiedBy()));
|
.setValue(UserDetailsFormatter.loadAndFormatLastModifiedBy(baseEntity));
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_CREATED_DATE)
|
item.getItemProperty(SPUILabelDefinitions.VAR_CREATED_DATE)
|
||||||
.setValue(SPDateTimeUtil.getFormattedDate(baseEntity.getCreatedAt()));
|
.setValue(SPDateTimeUtil.getFormattedDate(baseEntity.getCreatedAt()));
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE)
|
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE)
|
||||||
@@ -329,6 +329,17 @@ public abstract class AbstractTable<E extends NamedEntity, I> extends Table {
|
|||||||
columnList.add(
|
columnList.add(
|
||||||
new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.1F));
|
new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.1F));
|
||||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.get("header.description"), 0.2F));
|
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.get("header.description"), 0.2F));
|
||||||
|
setItemDescriptionGenerator((source, itemId, propertyId) -> {
|
||||||
|
|
||||||
|
if (SPUILabelDefinitions.VAR_CREATED_BY.equals(propertyId)) {
|
||||||
|
return getItem(itemId).getItemProperty(SPUILabelDefinitions.VAR_CREATED_BY).getValue().toString();
|
||||||
|
}
|
||||||
|
if (SPUILabelDefinitions.VAR_LAST_MODIFIED_BY.equals(propertyId)) {
|
||||||
|
return getItem(itemId).getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY).getValue().toString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
return columnList;
|
return columnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ public abstract class AbstractTableHeader extends VerticalLayout {
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected transient EventBus.SessionEventBus eventbus;
|
protected transient EventBus.SessionEventBus eventbus;
|
||||||
|
|
||||||
|
|
||||||
private Label headerCaption;
|
private Label headerCaption;
|
||||||
|
|
||||||
private TextField searchField;
|
private TextField searchField;
|
||||||
@@ -171,8 +170,8 @@ public abstract class AbstractTableHeader extends VerticalLayout {
|
|||||||
}
|
}
|
||||||
titleFilterIconsLayout.addComponent(maxMinIcon);
|
titleFilterIconsLayout.addComponent(maxMinIcon);
|
||||||
titleFilterIconsLayout.setComponentAlignment(maxMinIcon, Alignment.TOP_RIGHT);
|
titleFilterIconsLayout.setComponentAlignment(maxMinIcon, Alignment.TOP_RIGHT);
|
||||||
titleFilterIconsLayout.setExpandRatio(headerCaption, 0.4f);
|
titleFilterIconsLayout.setExpandRatio(headerCaption, 0.4F);
|
||||||
titleFilterIconsLayout.setExpandRatio(searchField, 0.6f);
|
titleFilterIconsLayout.setExpandRatio(searchField, 0.6F);
|
||||||
|
|
||||||
addComponent(titleFilterIconsLayout);
|
addComponent(titleFilterIconsLayout);
|
||||||
|
|
||||||
@@ -192,10 +191,10 @@ public abstract class AbstractTableHeader extends VerticalLayout {
|
|||||||
|
|
||||||
dropHintDropFilterLayout.addComponent(dropFilterLayout);
|
dropHintDropFilterLayout.addComponent(dropFilterLayout);
|
||||||
dropHintDropFilterLayout.setComponentAlignment(dropFilterLayout, Alignment.TOP_CENTER);
|
dropHintDropFilterLayout.setComponentAlignment(dropFilterLayout, Alignment.TOP_CENTER);
|
||||||
dropHintDropFilterLayout.setExpandRatio(dropFilterLayout, 1.0f);
|
dropHintDropFilterLayout.setExpandRatio(dropFilterLayout, 1.0F);
|
||||||
}
|
}
|
||||||
addComponent(dropHintDropFilterLayout);
|
addComponent(dropHintDropFilterLayout);
|
||||||
setComponentAlignment(dropHintDropFilterLayout, Alignment.MIDDLE_CENTER);
|
setComponentAlignment(dropHintDropFilterLayout, Alignment.TOP_CENTER);
|
||||||
addStyleName("bordered-layout");
|
addStyleName("bordered-layout");
|
||||||
addStyleName("no-border-bottom");
|
addStyleName("no-border-bottom");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ public class ProxyTarget extends Target {
|
|||||||
|
|
||||||
private DistributionSet installedDistributionSet;
|
private DistributionSet installedDistributionSet;
|
||||||
|
|
||||||
|
private DistributionSet assignedDistributionSet;
|
||||||
|
|
||||||
private TargetIdName targetIdName;
|
private TargetIdName targetIdName;
|
||||||
|
|
||||||
private String assignedDistNameVersion;
|
private String assignedDistNameVersion;
|
||||||
@@ -249,6 +251,21 @@ public class ProxyTarget extends Target {
|
|||||||
this.installedDistributionSet = installedDistributionSet;
|
this.installedDistributionSet = installedDistributionSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the assignedDistributionSet
|
||||||
|
*/
|
||||||
|
public DistributionSet getAssignedDistributionSet() {
|
||||||
|
return assignedDistributionSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param assignedDistributionSet
|
||||||
|
* the assignedDistributionSet to set
|
||||||
|
*/
|
||||||
|
public void setAssignedDistributionSet(DistributionSet assignedDistributionSet) {
|
||||||
|
this.assignedDistributionSet = assignedDistributionSet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the targetIdName
|
* @return the targetIdName
|
||||||
*/
|
*/
|
||||||
@@ -297,4 +314,5 @@ public class ProxyTarget extends Target {
|
|||||||
public void setStatus(final Status status) {
|
public void setStatus(final Status status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Map;
|
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.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
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;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUIHeaderLayoutDecorator;
|
import org.eclipse.hawkbit.ui.decorators.SPUIHeaderLayoutDecorator;
|
||||||
@@ -20,6 +22,7 @@ import org.eclipse.hawkbit.ui.decorators.SPUILabelDecorator;
|
|||||||
import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator;
|
import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator;
|
import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator;
|
||||||
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
import org.eclipse.hawkbit.ui.decorators.SPUIWindowDecorator;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -328,6 +331,50 @@ public final class SPUIComponentProvider {
|
|||||||
return nameValueLabel;
|
return nameValueLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Label createUsernameLabel(final String label, final String username) {
|
||||||
|
String loadAndFormatUsername = StringUtils.EMPTY;
|
||||||
|
if (!StringUtils.isEmpty(username)) {
|
||||||
|
loadAndFormatUsername = UserDetailsFormatter.loadAndFormatUsername(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Label nameValueLabel = new Label(getBoldHTMLText(label) + loadAndFormatUsername, ContentMode.HTML);
|
||||||
|
nameValueLabel.setSizeFull();
|
||||||
|
nameValueLabel.addStyleName(SPUIDefinitions.TEXT_STYLE);
|
||||||
|
nameValueLabel.addStyleName("label-style");
|
||||||
|
nameValueLabel.setDescription(loadAndFormatUsername);
|
||||||
|
return nameValueLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create label which represents the {@link BaseEntity#getCreatedBy()} by
|
||||||
|
* user name
|
||||||
|
*
|
||||||
|
* @param i18n
|
||||||
|
* the i18n
|
||||||
|
* @param baseEntity
|
||||||
|
* the entity
|
||||||
|
* @return the label
|
||||||
|
*/
|
||||||
|
public static Label createCreatedByLabel(final I18N i18n, final BaseEntity baseEntity) {
|
||||||
|
return createUsernameLabel(i18n.get("label.created.by"),
|
||||||
|
baseEntity == null ? StringUtils.EMPTY : baseEntity.getCreatedBy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create label which represents the
|
||||||
|
* {@link BaseEntity#getLastModifiedBy()()} by user name
|
||||||
|
*
|
||||||
|
* @param i18n
|
||||||
|
* the i18n
|
||||||
|
* @param baseEntity
|
||||||
|
* the entity
|
||||||
|
* @return the label
|
||||||
|
*/
|
||||||
|
public static Label createLastModifiedByLabel(final I18N i18n, final BaseEntity baseEntity) {
|
||||||
|
return createUsernameLabel(i18n.get("label.modified.by"),
|
||||||
|
baseEntity == null ? StringUtils.EMPTY : baseEntity.getLastModifiedBy());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Bold Text.
|
* Get Bold Text.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,29 +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.ui.customrenderers.client;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.customrenderers.renderers.LinkRenderer;
|
|
||||||
|
|
||||||
import com.vaadin.client.connectors.ButtonRendererConnector;
|
|
||||||
import com.vaadin.shared.ui.Connect;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* A connector for {@link LinkRenderer}.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Connect(org.eclipse.hawkbit.ui.customrenderers.renderers.LinkRenderer.class)
|
|
||||||
public class LinkRendererConnector extends ButtonRendererConnector {
|
|
||||||
private static final long serialVersionUID = 7987417436367399331L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public org.eclipse.hawkbit.ui.customrenderers.client.renderers.LinkRenderer getRenderer() {
|
|
||||||
return (org.eclipse.hawkbit.ui.customrenderers.client.renderers.LinkRenderer) super.getRenderer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* 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.ui.customrenderers.client;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
|
|
||||||
|
import com.google.web.bindery.event.shared.HandlerRegistration;
|
||||||
|
import com.vaadin.client.connectors.ClickableRendererConnector;
|
||||||
|
import com.vaadin.client.renderers.ClickableRenderer.RendererClickHandler;
|
||||||
|
import com.vaadin.shared.ui.Connect;
|
||||||
|
|
||||||
|
import elemental.json.JsonObject;
|
||||||
|
/**
|
||||||
|
* A connector for {@link CustomObjectRenderer }.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Connect(org.eclipse.hawkbit.ui.customrenderers.renderers.RolloutRenderer.class)
|
||||||
|
public class RolloutRendererConnector extends ClickableRendererConnector<RolloutRendererData> {
|
||||||
|
private static final long serialVersionUID = 7734682321931830566L;
|
||||||
|
|
||||||
|
public org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRenderer getRenderer() {
|
||||||
|
return (org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRenderer) super.getRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HandlerRegistration addClickHandler(
|
||||||
|
RendererClickHandler<JsonObject> handler) {
|
||||||
|
return getRenderer().addClickHandler(handler);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,42 +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.ui.customrenderers.client.renderers;
|
|
||||||
|
|
||||||
import com.google.gwt.user.client.ui.Button;
|
|
||||||
import com.vaadin.client.renderers.ButtonRenderer;
|
|
||||||
import com.vaadin.client.ui.VButton;
|
|
||||||
import com.vaadin.client.widget.grid.RendererCellReference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Renders link with provided text.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class LinkRenderer extends ButtonRenderer {
|
|
||||||
@Override
|
|
||||||
public void render(RendererCellReference cell, String text, Button button) {
|
|
||||||
button.setText(text);
|
|
||||||
applystyle(button);
|
|
||||||
// this is to allow the button to disappear, if the text is null
|
|
||||||
button.setVisible(text != null);
|
|
||||||
button.getElement().setId(new StringBuilder("link").append(".").append(text).toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applystyle(Button button) {
|
|
||||||
button.setStyleName(VButton.CLASSNAME);
|
|
||||||
button.addStyleName(getStyle("borderless"));
|
|
||||||
button.addStyleName(getStyle("small"));
|
|
||||||
button.addStyleName(getStyle("on-focus-no-border"));
|
|
||||||
button.addStyleName(getStyle("link"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getStyle(final String style) {
|
|
||||||
return new StringBuilder(style).append(" ").append(VButton.CLASSNAME).append("-").append(style).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* 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.ui.customrenderers.client.renderers;
|
||||||
|
|
||||||
|
import com.google.gwt.core.shared.GWT;
|
||||||
|
import com.vaadin.client.renderers.ClickableRenderer;
|
||||||
|
import com.vaadin.client.ui.VButton;
|
||||||
|
import com.vaadin.client.widget.grid.RendererCellReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders button with provided CustomObject.
|
||||||
|
* Used to display button with link.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class RolloutRenderer extends ClickableRenderer<RolloutRendererData, VButton> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public VButton createWidget() {
|
||||||
|
VButton b = GWT.create(VButton.class);
|
||||||
|
b.addClickHandler(this);
|
||||||
|
b.setStylePrimaryName("v-nativebutton");
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(RendererCellReference cell, RolloutRendererData text, VButton button) {
|
||||||
|
final String creating = "CREATING";
|
||||||
|
button.setText(text.getName());
|
||||||
|
applystyle(button);
|
||||||
|
// this is to allow the button to disappear, if the text is null
|
||||||
|
button.setVisible(text.getName() != null);
|
||||||
|
button.getElement().setId(new StringBuilder("link").append(".").append(text.getName()).toString());
|
||||||
|
/*
|
||||||
|
* checking Rollout Status for applying button style. If Rollout status
|
||||||
|
* is not "CREATING", then the Rollout button is applying hyperlink
|
||||||
|
* style
|
||||||
|
*/
|
||||||
|
final boolean isStatusCreate = text.getStatus() != null && creating.equalsIgnoreCase(text.getStatus());
|
||||||
|
if (isStatusCreate) {
|
||||||
|
button.addStyleName(getStyle("boldhide"));
|
||||||
|
button.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
button.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applystyle(VButton button) {
|
||||||
|
button.setStyleName(VButton.CLASSNAME);
|
||||||
|
button.addStyleName(getStyle("borderless"));
|
||||||
|
button.addStyleName(getStyle("small"));
|
||||||
|
button.addStyleName(getStyle("on-focus-no-border"));
|
||||||
|
button.addStyleName(getStyle("link"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStyle(final String style) {
|
||||||
|
return new StringBuilder(style).append(" ").append(VButton.CLASSNAME).append("-").append(style).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* 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.ui.customrenderers.client.renderers;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RendererData class with Name and Status.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class RolloutRendererData implements Serializable {
|
||||||
|
private static final long serialVersionUID = -5018181529953620263L;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the RendererData.
|
||||||
|
*/
|
||||||
|
public RolloutRendererData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the RendererData.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* Name of the Rollout.
|
||||||
|
* @param status
|
||||||
|
* Status of Rollout.
|
||||||
|
*/
|
||||||
|
public RolloutRendererData(String name, String status) {
|
||||||
|
super();
|
||||||
|
this.name = name;
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(String status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,37 +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.ui.customrenderers.renderers;
|
|
||||||
|
|
||||||
import com.vaadin.ui.renderers.ButtonRenderer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Renders link with provided text.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class LinkRenderer extends ButtonRenderer {
|
|
||||||
private static final long serialVersionUID = -1242995370043404892L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intialise link renderer.
|
|
||||||
*/
|
|
||||||
public LinkRenderer() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intialise link renderer with {@link RendererClickListener}
|
|
||||||
*
|
|
||||||
* @param listener
|
|
||||||
* RendererClickListener
|
|
||||||
*/
|
|
||||||
public LinkRenderer(RendererClickListener listener) {
|
|
||||||
super(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* 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.ui.customrenderers.renderers;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
|
|
||||||
|
import com.vaadin.ui.renderers.ClickableRenderer;
|
||||||
|
|
||||||
|
import elemental.json.JsonValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders button with provided CustomObject.
|
||||||
|
* Used to display button with link.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class RolloutRenderer extends ClickableRenderer<RolloutRendererData> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -8754180585906263554L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new custom object renderer.
|
||||||
|
*/
|
||||||
|
public RolloutRenderer() {
|
||||||
|
super(RolloutRendererData.class, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize custom object renderer with {@link Class<CustomObject>}
|
||||||
|
*
|
||||||
|
* @param presentationType
|
||||||
|
* Class<CustomObject>
|
||||||
|
*/
|
||||||
|
|
||||||
|
public RolloutRenderer(Class<RolloutRendererData> presentationType) {
|
||||||
|
super(presentationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new custom object renderer and adds the given click listener to it.
|
||||||
|
*
|
||||||
|
* @param listener
|
||||||
|
* the click listener to register
|
||||||
|
*/
|
||||||
|
public RolloutRenderer(RendererClickListener listener) {
|
||||||
|
this();
|
||||||
|
addClickListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JsonValue encode(RolloutRendererData resource) {
|
||||||
|
return super.encode(resource, RolloutRendererData.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -299,6 +299,7 @@ public class CreateUpdateDistSetTypeLayout extends CustomComponent implements Co
|
|||||||
mainWindowLayout.addComponent(colorLayout);
|
mainWindowLayout.addComponent(colorLayout);
|
||||||
mainWindowLayout.addComponent(buttonLayout);
|
mainWindowLayout.addComponent(buttonLayout);
|
||||||
setCompositionRoot(mainWindowLayout);
|
setCompositionRoot(mainWindowLayout);
|
||||||
|
typeName.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HorizontalLayout createTwinColumnLayout() {
|
private HorizontalLayout createTwinColumnLayout() {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
|||||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
@@ -113,8 +114,8 @@ public class ManageDistBeanQuery extends AbstractBeanQuery<ProxyDistribution> {
|
|||||||
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
||||||
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
||||||
proxyDistribution.setDescription(distributionSet.getDescription());
|
proxyDistribution.setDescription(distributionSet.getDescription());
|
||||||
proxyDistribution.setCreatedByUser(HawkbitCommonUtil.getIMUser(distributionSet.getCreatedBy()));
|
proxyDistribution.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(distributionSet));
|
||||||
proxyDistribution.setModifiedByUser(HawkbitCommonUtil.getIMUser(distributionSet.getLastModifiedBy()));
|
proxyDistribution.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(distributionSet));
|
||||||
proxyDistribution.setIsComplete(distributionSet.isComplete());
|
proxyDistribution.setIsComplete(distributionSet.isComplete());
|
||||||
proxyDistributions.add(proxyDistribution);
|
proxyDistributions.add(proxyDistribution);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.eclipse.hawkbit.repository.SoftwareManagement;
|
|||||||
import org.eclipse.hawkbit.repository.model.CustomSoftwareModule;
|
import org.eclipse.hawkbit.repository.model.CustomSoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
@@ -99,8 +100,8 @@ public class SwModuleBeanQuery extends AbstractBeanQuery<ProxyBaseSwModuleItem>
|
|||||||
proxyItem.setVersion(bean.getVersion());
|
proxyItem.setVersion(bean.getVersion());
|
||||||
proxyItem.setVendor(bean.getVendor());
|
proxyItem.setVendor(bean.getVendor());
|
||||||
proxyItem.setDescription(bean.getDescription());
|
proxyItem.setDescription(bean.getDescription());
|
||||||
proxyItem.setCreatedByUser(HawkbitCommonUtil.getIMUser(bean.getCreatedBy()));
|
proxyItem.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(bean));
|
||||||
proxyItem.setModifiedByUser(HawkbitCommonUtil.getIMUser(bean.getLastModifiedBy()));
|
proxyItem.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(bean));
|
||||||
proxyItem.setAssigned(customSoftwareModule.isAssigned());
|
proxyItem.setAssigned(customSoftwareModule.isAssigned());
|
||||||
proxyItem.setColour(bean.getType().getColour());
|
proxyItem.setColour(bean.getType().getColour());
|
||||||
proxyItem.setTypeId(bean.getType().getId());
|
proxyItem.setTypeId(bean.getType().getId());
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
|
|
||||||
private static final long serialVersionUID = 7474232427119031474L;
|
private static final long serialVersionUID = 7474232427119031474L;
|
||||||
|
|
||||||
|
private static final String breadcrumbCustomFilters = "breadcrumb.target.filter.custom.filters";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private I18N i18n;
|
private I18N i18n;
|
||||||
|
|
||||||
@@ -93,6 +95,12 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
@Qualifier("uiExecutor")
|
@Qualifier("uiExecutor")
|
||||||
private transient Executor executor;
|
private transient Executor executor;
|
||||||
|
|
||||||
|
private HorizontalLayout breadcrumbLayout;
|
||||||
|
|
||||||
|
private Button breadcrumbButton;
|
||||||
|
|
||||||
|
private Label breadcrumbName;
|
||||||
|
|
||||||
private Label headerCaption;
|
private Label headerCaption;
|
||||||
|
|
||||||
private TextField queryTextField;
|
private TextField queryTextField;
|
||||||
@@ -169,6 +177,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
oldFilterName = filterManagementUIState.getTfQuery().get().getName();
|
oldFilterName = filterManagementUIState.getTfQuery().get().getName();
|
||||||
oldFilterQuery = filterManagementUIState.getTfQuery().get().getQuery();
|
oldFilterQuery = filterManagementUIState.getTfQuery().get().getQuery();
|
||||||
}
|
}
|
||||||
|
breadcrumbName.setValue(nameLabel.getValue());
|
||||||
showValidationSuccesIcon();
|
showValidationSuccesIcon();
|
||||||
titleFilterIconsLayout.addStyleName(SPUIStyleDefinitions.TARGET_FILTER_CAPTION_LAYOUT);
|
titleFilterIconsLayout.addStyleName(SPUIStyleDefinitions.TARGET_FILTER_CAPTION_LAYOUT);
|
||||||
headerCaption.setVisible(false);
|
headerCaption.setVisible(false);
|
||||||
@@ -177,6 +186,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
|
|
||||||
private void resetComponents() {
|
private void resetComponents() {
|
||||||
headerCaption.setVisible(true);
|
headerCaption.setVisible(true);
|
||||||
|
breadcrumbName.setValue(headerCaption.getValue());
|
||||||
nameLabel.setValue("");
|
nameLabel.setValue("");
|
||||||
queryTextField.setValue("");
|
queryTextField.setValue("");
|
||||||
setInitialStatusIconStyle(validationIcon);
|
setInitialStatusIconStyle(validationIcon);
|
||||||
@@ -201,6 +211,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void createComponents() {
|
private void createComponents() {
|
||||||
|
|
||||||
|
breadcrumbButton = createBreadcrumbButton();
|
||||||
|
|
||||||
headerCaption = SPUIComponentProvider.getLabel(SPUILabelDefinitions.VAR_CREATE_FILTER,
|
headerCaption = SPUIComponentProvider.getLabel(SPUILabelDefinitions.VAR_CREATE_FILTER,
|
||||||
SPUILabelDefinitions.SP_WIDGET_CAPTION);
|
SPUILabelDefinitions.SP_WIDGET_CAPTION);
|
||||||
|
|
||||||
@@ -221,12 +234,23 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
closeIcon = createSearchResetIcon();
|
closeIcon = createSearchResetIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Button createBreadcrumbButton() {
|
||||||
|
final Button createFilterViewLink = SPUIComponentProvider.getButton(null, "", "", null, false, null,
|
||||||
|
SPUIButtonStyleSmallNoBorder.class);
|
||||||
|
createFilterViewLink.setStyleName(ValoTheme.LINK_SMALL + " " + "on-focus-no-border link rollout-caption-links");
|
||||||
|
createFilterViewLink.setDescription(i18n.get(breadcrumbCustomFilters));
|
||||||
|
createFilterViewLink.setCaption(i18n.get(breadcrumbCustomFilters));
|
||||||
|
createFilterViewLink.addClickListener(value -> showCustomFiltersView());
|
||||||
|
|
||||||
|
return createFilterViewLink;
|
||||||
|
}
|
||||||
|
|
||||||
private TextField createNameTextField() {
|
private TextField createNameTextField() {
|
||||||
final TextField nameField = SPUIComponentProvider.getTextField("", ValoTheme.TEXTFIELD_TINY, false, null,
|
final TextField nameField = SPUIComponentProvider.getTextField("", ValoTheme.TEXTFIELD_TINY, false, null,
|
||||||
i18n.get("textfield.customfiltername"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
i18n.get("textfield.customfiltername"), true, SPUILabelDefinitions.TEXT_FIELD_MAX_LENGTH);
|
||||||
nameField.setId(SPUIComponetIdProvider.CUSTOM_FILTER_ADD_NAME);
|
nameField.setId(SPUIComponetIdProvider.CUSTOM_FILTER_ADD_NAME);
|
||||||
nameField.setPropertyDataSource(nameLabel);
|
nameField.setPropertyDataSource(nameLabel);
|
||||||
nameField.addTextChangeListener(event -> onFiterNameChange(event));
|
nameField.addTextChangeListener(event -> onFilterNameChange(event));
|
||||||
return nameField;
|
return nameField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +280,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFiterNameChange(final TextChangeEvent event) {
|
private void onFilterNameChange(final TextChangeEvent event) {
|
||||||
if (isNameAndQueryEmpty(event.getText(), queryTextField.getValue())
|
if (isNameAndQueryEmpty(event.getText(), queryTextField.getValue())
|
||||||
|| (event.getText().equals(oldFilterName) && queryTextField.getValue().equals(oldFilterQuery))) {
|
|| (event.getText().equals(oldFilterName) && queryTextField.getValue().equals(oldFilterQuery))) {
|
||||||
saveButton.setEnabled(false);
|
saveButton.setEnabled(false);
|
||||||
@@ -276,6 +300,13 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
titleFilterIconsLayout.addComponents(headerCaption, captionLayout);
|
titleFilterIconsLayout.addComponents(headerCaption, captionLayout);
|
||||||
titleFilterIconsLayout.setSpacing(true);
|
titleFilterIconsLayout.setSpacing(true);
|
||||||
|
|
||||||
|
breadcrumbLayout = new HorizontalLayout();
|
||||||
|
breadcrumbLayout.addComponent(breadcrumbButton);
|
||||||
|
breadcrumbLayout.addComponent(new Label(">"));
|
||||||
|
breadcrumbName = SPUIComponentProvider.getLabel(null, SPUILabelDefinitions.SP_WIDGET_CAPTION);
|
||||||
|
breadcrumbLayout.addComponent(breadcrumbName);
|
||||||
|
breadcrumbName.addStyleName("breadcrumbPaddingLeft");
|
||||||
|
|
||||||
final HorizontalLayout titleFilterLayout = new HorizontalLayout();
|
final HorizontalLayout titleFilterLayout = new HorizontalLayout();
|
||||||
titleFilterLayout.setSizeFull();
|
titleFilterLayout.setSizeFull();
|
||||||
titleFilterLayout.addComponents(titleFilterIconsLayout, closeIcon);
|
titleFilterLayout.addComponents(titleFilterIconsLayout, closeIcon);
|
||||||
@@ -290,7 +321,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
searchLayout.setSpacing(false);
|
searchLayout.setSpacing(false);
|
||||||
searchLayout.addComponents(validationIcon, queryTextField);
|
searchLayout.addComponents(validationIcon, queryTextField);
|
||||||
searchLayout.addStyleName("custom-search-layout");
|
searchLayout.addStyleName("custom-search-layout");
|
||||||
searchLayout.setComponentAlignment(validationIcon, Alignment.MIDDLE_CENTER);
|
searchLayout.setComponentAlignment(validationIcon, Alignment.TOP_CENTER);
|
||||||
|
|
||||||
final HorizontalLayout iconLayout = new HorizontalLayout();
|
final HorizontalLayout iconLayout = new HorizontalLayout();
|
||||||
iconLayout.setSizeUndefined();
|
iconLayout.setSizeUndefined();
|
||||||
@@ -302,10 +333,12 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
queryLayout.setSpacing(true);
|
queryLayout.setSpacing(true);
|
||||||
queryLayout.addComponents(searchLayout, iconLayout);
|
queryLayout.addComponents(searchLayout, iconLayout);
|
||||||
|
|
||||||
|
addComponent(breadcrumbLayout);
|
||||||
addComponent(titleFilterLayout);
|
addComponent(titleFilterLayout);
|
||||||
addComponent(queryLayout);
|
addComponent(queryLayout);
|
||||||
setSpacing(true);
|
setSpacing(true);
|
||||||
addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
|
addStyleName(SPUIStyleDefinitions.WIDGET_TITLE);
|
||||||
|
addStyleName("bordered-layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpCaptionLayout(final boolean isCreateView) {
|
private void setUpCaptionLayout(final boolean isCreateView) {
|
||||||
@@ -524,4 +557,8 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showCustomFiltersView() {
|
||||||
|
eventBus.publish(this, CustomFilterUIEvent.SHOW_FILTER_MANAGEMENT);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,12 @@ import java.util.Map;
|
|||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
|
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
|
||||||
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
|
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.AssignInstalledDSTooltipGenerator;
|
||||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
|
||||||
@@ -69,6 +71,10 @@ public class CreateOrUpdateFilterTable extends Table {
|
|||||||
|
|
||||||
private static final int PROPERTY_DEPT = 3;
|
private static final int PROPERTY_DEPT = 3;
|
||||||
|
|
||||||
|
private static final String ASSIGN_DIST_SET = "assignedDistributionSet";
|
||||||
|
|
||||||
|
private static final String INSTALL_DIST_SET = "installedDistributionSet";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the Action History Table.
|
* Initialize the Action History Table.
|
||||||
*/
|
*/
|
||||||
@@ -87,6 +93,7 @@ public class CreateOrUpdateFilterTable extends Table {
|
|||||||
setId(SPUIComponetIdProvider.CUSTOM_FILTER_TARGET_TABLE_ID);
|
setId(SPUIComponetIdProvider.CUSTOM_FILTER_TARGET_TABLE_ID);
|
||||||
setSelectable(false);
|
setSelectable(false);
|
||||||
eventBus.subscribe(this);
|
eventBus.subscribe(this);
|
||||||
|
setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
@@ -160,6 +167,9 @@ public class CreateOrUpdateFilterTable extends Table {
|
|||||||
private void setCollapsibleColumns() {
|
private void setCollapsibleColumns() {
|
||||||
setColumnCollapsed(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, true);
|
setColumnCollapsed(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, true);
|
||||||
setColumnCollapsed(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, true);
|
setColumnCollapsed(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, true);
|
||||||
|
|
||||||
|
setColumnCollapsed(ASSIGN_DIST_SET, true);
|
||||||
|
setColumnCollapsed(INSTALL_DIST_SET, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,10 +182,13 @@ public class CreateOrUpdateFilterTable extends Table {
|
|||||||
container.addContainerProperty(SPUILabelDefinitions.VAR_CREATED_DATE, Date.class, null);
|
container.addContainerProperty(SPUILabelDefinitions.VAR_CREATED_DATE, Date.class, null);
|
||||||
container.addContainerProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, String.class, null, false, true);
|
container.addContainerProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, String.class, null, false, true);
|
||||||
container.addContainerProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, String.class, null, false, true);
|
container.addContainerProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, String.class, null, false, true);
|
||||||
container.addContainerProperty(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER, String.class, "");
|
|
||||||
container.addContainerProperty(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER, String.class, null);
|
|
||||||
container.addContainerProperty(SPUILabelDefinitions.VAR_TARGET_STATUS, TargetUpdateStatus.class, null);
|
container.addContainerProperty(SPUILabelDefinitions.VAR_TARGET_STATUS, TargetUpdateStatus.class, null);
|
||||||
container.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, "", false, true);
|
container.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, "", false, true);
|
||||||
|
|
||||||
|
container.addContainerProperty(ASSIGN_DIST_SET, DistributionSet.class, null, false, true);
|
||||||
|
container.addContainerProperty(INSTALL_DIST_SET, DistributionSet.class, null, false, true);
|
||||||
|
container.addContainerProperty(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER, String.class, "");
|
||||||
|
container.addContainerProperty(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER, String.class, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<TableColumn> getVisbleColumns() {
|
private List<TableColumn> getVisbleColumns() {
|
||||||
@@ -186,12 +199,9 @@ public class CreateOrUpdateFilterTable extends Table {
|
|||||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, i18n.get("header.modifiedBy"), 0.1F));
|
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY, i18n.get("header.modifiedBy"), 0.1F));
|
||||||
columnList.add(
|
columnList.add(
|
||||||
new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.1F));
|
new TableColumn(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE, i18n.get("header.modifiedDate"), 0.1F));
|
||||||
columnList.add(new TableColumn(SPUILabelDefinitions.ASSIGNED_DISTRIBUTION_NAME_VER,
|
|
||||||
i18n.get("header.assigned.ds"), 0.125F));
|
|
||||||
columnList.add(new TableColumn(SPUILabelDefinitions.INSTALLED_DISTRIBUTION_NAME_VER,
|
|
||||||
i18n.get("header.installed.ds"), 0.125F));
|
|
||||||
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.get("header.description"), 0.1F));
|
columnList.add(new TableColumn(SPUILabelDefinitions.VAR_DESC, i18n.get("header.description"), 0.1F));
|
||||||
columnList.add(new TableColumn(SPUILabelDefinitions.STATUS_ICON, i18n.get("header.status"), 0.1F));
|
columnList.add(new TableColumn(SPUILabelDefinitions.STATUS_ICON, i18n.get("header.status"), 0.1F));
|
||||||
|
|
||||||
return columnList;
|
return columnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,4 +254,5 @@ public class CreateOrUpdateFilterTable extends Table {
|
|||||||
populateTableData();
|
populateTableData();
|
||||||
eventBus.publish(this, CustomFilterUIEvent.UPDATE_TARGET_FILTER_SEARCH_ICON);
|
eventBus.publish(this, CustomFilterUIEvent.UPDATE_TARGET_FILTER_SEARCH_ICON);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||||
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.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyTarget;
|
import org.eclipse.hawkbit.ui.components.ProxyTarget;
|
||||||
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
|
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
@@ -118,22 +118,9 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
prxyTarget.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(targ.getLastModifiedAt()));
|
prxyTarget.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(targ.getLastModifiedAt()));
|
||||||
prxyTarget.setCreatedDate(SPDateTimeUtil.getFormattedDate(targ.getCreatedAt()));
|
prxyTarget.setCreatedDate(SPDateTimeUtil.getFormattedDate(targ.getCreatedAt()));
|
||||||
prxyTarget.setCreatedAt(targ.getCreatedAt());
|
prxyTarget.setCreatedAt(targ.getCreatedAt());
|
||||||
prxyTarget.setCreatedByUser(HawkbitCommonUtil.getIMUser(targ.getCreatedBy()));
|
prxyTarget.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(targ));
|
||||||
prxyTarget.setModifiedByUser(HawkbitCommonUtil.getIMUser(targ.getLastModifiedBy()));
|
prxyTarget.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(targ));
|
||||||
final Target target = getTargetManagement().findTargetByControllerIDWithDetails(targ.getControllerId());
|
|
||||||
final DistributionSet installedDistributionSet = target.getTargetInfo().getInstalledDistributionSet();
|
|
||||||
prxyTarget.setInstalledDistributionSet(installedDistributionSet);
|
|
||||||
final DistributionSet assignedDistributionSet = target.getAssignedDistributionSet();
|
|
||||||
prxyTarget.setAssignedDistributionSet(assignedDistributionSet);
|
|
||||||
|
|
||||||
if (null != assignedDistributionSet) {
|
|
||||||
prxyTarget.setAssignedDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion(
|
|
||||||
assignedDistributionSet.getName(), assignedDistributionSet.getVersion()));
|
|
||||||
}
|
|
||||||
if (null != installedDistributionSet) {
|
|
||||||
prxyTarget.setInstalledDistNameVersion(HawkbitCommonUtil.getFormattedNameVersion(
|
|
||||||
installedDistributionSet.getName(), installedDistributionSet.getVersion()));
|
|
||||||
}
|
|
||||||
prxyTarget.setUpdateStatus(targ.getTargetInfo().getUpdateStatus());
|
prxyTarget.setUpdateStatus(targ.getTargetInfo().getUpdateStatus());
|
||||||
prxyTarget.setLastTargetQuery(targ.getTargetInfo().getLastTargetQuery());
|
prxyTarget.setLastTargetQuery(targ.getTargetInfo().getLastTargetQuery());
|
||||||
prxyTarget.setTargetInfo(targ.getTargetInfo());
|
prxyTarget.setTargetInfo(targ.getTargetInfo());
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ public class FilterManagementView extends VerticalLayout implements View {
|
|||||||
} else if (custFilterUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK
|
} else if (custFilterUIEvent == CustomFilterUIEvent.CREATE_NEW_FILTER_CLICK
|
||||||
|| custFilterUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY) {
|
|| custFilterUIEvent == CustomFilterUIEvent.FILTER_TARGET_BY_QUERY) {
|
||||||
this.getUI().access(() -> viewCreateTargetFilterLayout());
|
this.getUI().access(() -> viewCreateTargetFilterLayout());
|
||||||
} else if (custFilterUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW) {
|
} else if (custFilterUIEvent == CustomFilterUIEvent.EXIT_CREATE_OR_UPDATE_FILTRER_VIEW
|
||||||
|
|| custFilterUIEvent == CustomFilterUIEvent.SHOW_FILTER_MANAGEMENT) {
|
||||||
UI.getCurrent().access(() -> viewListView());
|
UI.getCurrent().access(() -> viewListView());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,11 +122,11 @@ public class FilterManagementView extends VerticalLayout implements View {
|
|||||||
tableHeaderLayout.setComponentAlignment(createNewFilterHeader, Alignment.TOP_CENTER);
|
tableHeaderLayout.setComponentAlignment(createNewFilterHeader, Alignment.TOP_CENTER);
|
||||||
tableHeaderLayout.addComponent(createNewFilterTable);
|
tableHeaderLayout.addComponent(createNewFilterTable);
|
||||||
tableHeaderLayout.setComponentAlignment(createNewFilterTable, Alignment.TOP_CENTER);
|
tableHeaderLayout.setComponentAlignment(createNewFilterTable, Alignment.TOP_CENTER);
|
||||||
tableHeaderLayout.setExpandRatio(createNewFilterTable, 1.0f);
|
tableHeaderLayout.setExpandRatio(createNewFilterTable, 1.0F);
|
||||||
|
|
||||||
addComponent(tableHeaderLayout);
|
addComponent(tableHeaderLayout);
|
||||||
setComponentAlignment(tableHeaderLayout, Alignment.TOP_CENTER);
|
setComponentAlignment(tableHeaderLayout, Alignment.TOP_CENTER);
|
||||||
setExpandRatio(tableHeaderLayout, 1.0f);
|
setExpandRatio(tableHeaderLayout, 1.0F);
|
||||||
|
|
||||||
final HorizontalLayout targetsCountmessageLabelLayout = addTargetFilterMessageLabel();
|
final HorizontalLayout targetsCountmessageLabelLayout = addTargetFilterMessageLabel();
|
||||||
addComponent(targetsCountmessageLabelLayout);
|
addComponent(targetsCountmessageLabelLayout);
|
||||||
@@ -135,17 +136,17 @@ public class FilterManagementView extends VerticalLayout implements View {
|
|||||||
|
|
||||||
private void viewListView() {
|
private void viewListView() {
|
||||||
removeAllComponents();
|
removeAllComponents();
|
||||||
final VerticalLayout tableHeaderLayout = new VerticalLayout();
|
final VerticalLayout tableListViewLayout = new VerticalLayout();
|
||||||
tableHeaderLayout.setSizeFull();
|
tableListViewLayout.setSizeFull();
|
||||||
tableHeaderLayout.setSpacing(false);
|
tableListViewLayout.setSpacing(false);
|
||||||
tableHeaderLayout.setMargin(false);
|
tableListViewLayout.setMargin(false);
|
||||||
tableHeaderLayout.setStyleName("table-layout");
|
tableListViewLayout.setStyleName("table-layout");
|
||||||
tableHeaderLayout.addComponent(targetFilterHeader);
|
tableListViewLayout.addComponent(targetFilterHeader);
|
||||||
tableHeaderLayout.setComponentAlignment(targetFilterHeader, Alignment.TOP_CENTER);
|
tableListViewLayout.setComponentAlignment(targetFilterHeader, Alignment.TOP_CENTER);
|
||||||
tableHeaderLayout.addComponent(targetFilterTable);
|
tableListViewLayout.addComponent(targetFilterTable);
|
||||||
tableHeaderLayout.setComponentAlignment(targetFilterTable, Alignment.TOP_CENTER);
|
tableListViewLayout.setComponentAlignment(targetFilterTable, Alignment.TOP_CENTER);
|
||||||
tableHeaderLayout.setExpandRatio(targetFilterTable, 1.0f);
|
tableListViewLayout.setExpandRatio(targetFilterTable, 1.0F);
|
||||||
addComponent(tableHeaderLayout);
|
addComponent(tableListViewLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
private HorizontalLayout addTargetFilterMessageLabel() {
|
private HorizontalLayout addTargetFilterMessageLabel() {
|
||||||
|
|||||||
@@ -31,10 +31,7 @@ import cz.jirutka.rsql.parser.RSQLParserException;
|
|||||||
*
|
*
|
||||||
* Validates the target filter query.
|
* Validates the target filter query.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public final class FilterQueryValidation {
|
public final class FilterQueryValidation {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(FilterQueryValidation.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(FilterQueryValidation.class);
|
||||||
@@ -103,6 +100,9 @@ public final class FilterQueryValidation {
|
|||||||
* @param expectedTokens
|
* @param expectedTokens
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
// Exception squid:S2095 - see
|
||||||
|
// https://jira.sonarsource.com/browse/SONARJAVA-1478
|
||||||
|
@SuppressWarnings({ "squid:S2095" })
|
||||||
public static List<String> processExpectedTokens(final List<Integer> expectedTokens) {
|
public static List<String> processExpectedTokens(final List<Integer> expectedTokens) {
|
||||||
final List<String> expectToken = new ArrayList<>();
|
final List<String> expectToken = new ArrayList<>();
|
||||||
if (expectedTokens.size() == 2 && expectedTokens.contains(9) && expectedTokens.contains(4)) {
|
if (expectedTokens.size() == 2 && expectedTokens.contains(9) && expectedTokens.contains(4)) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyTargetFilter;
|
import org.eclipse.hawkbit.ui.components.ProxyTargetFilter;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
@@ -93,9 +94,9 @@ public class TargetFilterBeanQuery extends AbstractBeanQuery<ProxyTargetFilter>
|
|||||||
proxyTarFilter.setName(tarFilterQuery.getName());
|
proxyTarFilter.setName(tarFilterQuery.getName());
|
||||||
proxyTarFilter.setId(tarFilterQuery.getId());
|
proxyTarFilter.setId(tarFilterQuery.getId());
|
||||||
proxyTarFilter.setCreatedDate(SPDateTimeUtil.getFormattedDate(tarFilterQuery.getCreatedAt()));
|
proxyTarFilter.setCreatedDate(SPDateTimeUtil.getFormattedDate(tarFilterQuery.getCreatedAt()));
|
||||||
proxyTarFilter.setCreatedBy(HawkbitCommonUtil.getIMUser(tarFilterQuery.getCreatedBy()));
|
proxyTarFilter.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(tarFilterQuery));
|
||||||
proxyTarFilter.setModifiedDate(SPDateTimeUtil.getFormattedDate(tarFilterQuery.getLastModifiedAt()));
|
proxyTarFilter.setModifiedDate(SPDateTimeUtil.getFormattedDate(tarFilterQuery.getLastModifiedAt()));
|
||||||
proxyTarFilter.setLastModifiedBy(HawkbitCommonUtil.getIMUser(tarFilterQuery.getLastModifiedBy()));
|
proxyTarFilter.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(tarFilterQuery));
|
||||||
proxyTarFilter.setQuery(tarFilterQuery.getQuery());
|
proxyTarFilter.setQuery(tarFilterQuery.getQuery());
|
||||||
proxyTargetFilter.add(proxyTarFilter);
|
proxyTargetFilter.add(proxyTarFilter);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,5 @@ package org.eclipse.hawkbit.ui.filtermanagement.event;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public enum CustomFilterUIEvent {
|
public enum CustomFilterUIEvent {
|
||||||
FILTER_TARGET_BY_QUERY, FILTER_BY_CUST_FILTER_TEXT, FILTER_BY_CUST_FILTER_TEXT_REMOVE, CREATE_NEW_FILTER_CLICK, EXIT_CREATE_OR_UPDATE_FILTRER_VIEW, TARGET_FILTER_DETAIL_VIEW, TARGET_DETAILS_VIEW, CREATE_TARGET_FILTER_QUERY, UPDATED_TARGET_FILTER_QUERY, UPDATE_TARGET_FILTER_SEARCH_ICON
|
FILTER_TARGET_BY_QUERY, FILTER_BY_CUST_FILTER_TEXT, FILTER_BY_CUST_FILTER_TEXT_REMOVE, CREATE_NEW_FILTER_CLICK, EXIT_CREATE_OR_UPDATE_FILTRER_VIEW, TARGET_FILTER_DETAIL_VIEW, TARGET_DETAILS_VIEW, CREATE_TARGET_FILTER_QUERY, UPDATED_TARGET_FILTER_QUERY, UPDATE_TARGET_FILTER_SEARCH_ICON, SHOW_FILTER_MANAGEMENT
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ public class LoginView extends VerticalLayout implements View {
|
|||||||
final String linkStyle = "v-link";
|
final String linkStyle = "v-link";
|
||||||
|
|
||||||
if (!uiProperties.getLinks().getDocumentation().getRoot().isEmpty()) {
|
if (!uiProperties.getLinks().getDocumentation().getRoot().isEmpty()) {
|
||||||
final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENATION,
|
final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENTATION,
|
||||||
i18n.get("link.documentation.name"), uiProperties.getLinks().getDocumentation().getRoot(),
|
i18n.get("link.documentation.name"), uiProperties.getLinks().getDocumentation().getRoot(),
|
||||||
FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true);
|
FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true);
|
||||||
links.addComponent(docuLink);
|
links.addComponent(docuLink);
|
||||||
|
|||||||
@@ -148,8 +148,9 @@ public class DistributionAddUpdateWindowLayout extends VerticalLayout {
|
|||||||
|
|
||||||
addComponent(buttonsLayout);
|
addComponent(buttonsLayout);
|
||||||
setComponentAlignment(madatoryLabel, Alignment.MIDDLE_LEFT);
|
setComponentAlignment(madatoryLabel, Alignment.MIDDLE_LEFT);
|
||||||
|
distNameTextField.focus();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create required UI components.
|
* Create required UI components.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilte
|
|||||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
@@ -129,8 +130,8 @@ public class DistributionBeanQuery extends AbstractBeanQuery<ProxyDistribution>
|
|||||||
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
||||||
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
||||||
proxyDistribution.setDescription(distributionSet.getDescription());
|
proxyDistribution.setDescription(distributionSet.getDescription());
|
||||||
proxyDistribution.setCreatedByUser(HawkbitCommonUtil.getIMUser(distributionSet.getCreatedBy()));
|
proxyDistribution.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(distributionSet));
|
||||||
proxyDistribution.setModifiedByUser(HawkbitCommonUtil.getIMUser(distributionSet.getLastModifiedBy()));
|
proxyDistribution.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(distributionSet));
|
||||||
proxyDistribution.setNameVersion(
|
proxyDistribution.setNameVersion(
|
||||||
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
|
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
|
||||||
proxyDistributions.add(proxyDistribution);
|
proxyDistributions.add(proxyDistribution);
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ import com.vaadin.ui.themes.ValoTheme;
|
|||||||
@SpringComponent
|
@SpringComponent
|
||||||
@VaadinSessionScope
|
@VaadinSessionScope
|
||||||
public class CreateUpdateDistributionTagLayoutWindow extends CreateUpdateTagLayout {
|
public class CreateUpdateDistributionTagLayoutWindow extends CreateUpdateTagLayout {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 444276149954167545L;
|
private static final long serialVersionUID = 444276149954167545L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -288,16 +284,22 @@ public class CreateUpdateDistributionTagLayoutWindow extends CreateUpdateTagLayo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
|
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
|
||||||
populateTagNameCombo();
|
populateTagNameCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) {
|
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) {
|
||||||
populateTagNameCombo();
|
populateTagNameCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
|
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
|
||||||
populateTagNameCombo();
|
populateTagNameCombo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,16 +61,22 @@ public class DistributionTagButtons extends AbstractFilterButtons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
|
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
|
||||||
refreshTagTable();
|
refreshTagTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) {
|
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) {
|
||||||
refreshTagTable();
|
refreshTagTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
|
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
|
||||||
refreshTagTable();
|
refreshTagTable();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ public abstract class CreateUpdateTagLayout extends CustomComponent implements C
|
|||||||
fieldLayout.addComponent(tagName);
|
fieldLayout.addComponent(tagName);
|
||||||
fieldLayout.addComponent(tagDesc);
|
fieldLayout.addComponent(tagDesc);
|
||||||
|
|
||||||
|
|
||||||
final HorizontalLayout colorLabelLayout = new HorizontalLayout();
|
final HorizontalLayout colorLabelLayout = new HorizontalLayout();
|
||||||
colorLabelLayout.addComponents(colorLabel, tagColorPreviewBtn);
|
colorLabelLayout.addComponents(colorLabel, tagColorPreviewBtn);
|
||||||
fieldLayout.addComponent(colorLabelLayout);
|
fieldLayout.addComponent(colorLabelLayout);
|
||||||
@@ -257,8 +258,8 @@ public abstract class CreateUpdateTagLayout extends CustomComponent implements C
|
|||||||
|
|
||||||
mainLayout = new HorizontalLayout();
|
mainLayout = new HorizontalLayout();
|
||||||
mainLayout.addComponent(fieldButtonLayout);
|
mainLayout.addComponent(fieldButtonLayout);
|
||||||
|
|
||||||
setCompositionRoot(mainLayout);
|
setCompositionRoot(mainLayout);
|
||||||
|
tagName.focus();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class TargetAddUpdateWindowLayout extends CustomComponent {
|
|||||||
madatoryLabel.setVisible(Boolean.FALSE);
|
madatoryLabel.setVisible(Boolean.FALSE);
|
||||||
}
|
}
|
||||||
mainLayout.addComponents(madatoryLabel, controllerIDTextField, nameTextField, descTextArea, buttonsLayout);
|
mainLayout.addComponents(madatoryLabel, controllerIDTextField, nameTextField, descTextArea, buttonsLayout);
|
||||||
|
nameTextField.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addListeners() {
|
private void addListeners() {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ 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.TargetFilterQuery;
|
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyTarget;
|
import org.eclipse.hawkbit.ui.components.ProxyTarget;
|
||||||
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
@@ -130,8 +131,8 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
|||||||
prxyTarget.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(targ.getLastModifiedAt()));
|
prxyTarget.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(targ.getLastModifiedAt()));
|
||||||
prxyTarget.setCreatedDate(SPDateTimeUtil.getFormattedDate(targ.getCreatedAt()));
|
prxyTarget.setCreatedDate(SPDateTimeUtil.getFormattedDate(targ.getCreatedAt()));
|
||||||
prxyTarget.setCreatedAt(targ.getCreatedAt());
|
prxyTarget.setCreatedAt(targ.getCreatedAt());
|
||||||
prxyTarget.setCreatedByUser(HawkbitCommonUtil.getIMUser(targ.getCreatedBy()));
|
prxyTarget.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(targ));
|
||||||
prxyTarget.setModifiedByUser(HawkbitCommonUtil.getIMUser(targ.getLastModifiedBy()));
|
prxyTarget.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(targ));
|
||||||
|
|
||||||
if (pinnedDistId == null) {
|
if (pinnedDistId == null) {
|
||||||
prxyTarget.setInstalledDistributionSet(null);
|
prxyTarget.setInstalledDistributionSet(null);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import org.eclipse.hawkbit.repository.model.TargetInfo;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
|
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.ui.common.ManagmentEntityState;
|
import org.eclipse.hawkbit.ui.common.ManagmentEntityState;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.common.table.AbstractTable;
|
import org.eclipse.hawkbit.ui.common.table.AbstractTable;
|
||||||
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
|
||||||
import org.eclipse.hawkbit.ui.filter.FilterExpression;
|
import org.eclipse.hawkbit.ui.filter.FilterExpression;
|
||||||
@@ -51,6 +52,7 @@ import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
|
|||||||
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent;
|
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent;
|
||||||
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
|
||||||
import org.eclipse.hawkbit.ui.management.state.TargetTableFilters;
|
import org.eclipse.hawkbit.ui.management.state.TargetTableFilters;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.AssignInstalledDSTooltipGenerator;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
||||||
@@ -136,6 +138,7 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> implements
|
|||||||
addActionHandler(this);
|
addActionHandler(this);
|
||||||
actionSelectAll = new ShortcutAction(i18n.get("action.target.table.selectall"));
|
actionSelectAll = new ShortcutAction(i18n.get("action.target.table.selectall"));
|
||||||
actionUnSelectAll = new ShortcutAction(i18n.get("action.target.table.clear"));
|
actionUnSelectAll = new ShortcutAction(i18n.get("action.target.table.clear"));
|
||||||
|
setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -739,7 +742,7 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> implements
|
|||||||
.setValue(updatedTarget.getTargetInfo().getLastTargetQuery());
|
.setValue(updatedTarget.getTargetInfo().getLastTargetQuery());
|
||||||
|
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY)
|
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_BY)
|
||||||
.setValue(HawkbitCommonUtil.getIMUser(updatedTarget.getLastModifiedBy()));
|
.setValue(UserDetailsFormatter.loadAndFormatLastModifiedBy(updatedTarget));
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE)
|
item.getItemProperty(SPUILabelDefinitions.VAR_LAST_MODIFIED_DATE)
|
||||||
.setValue(SPDateTimeUtil.getFormattedDate(updatedTarget.getLastModifiedAt()));
|
.setValue(SPDateTimeUtil.getFormattedDate(updatedTarget.getLastModifiedAt()));
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_DESC).setValue(updatedTarget.getDescription());
|
item.getItemProperty(SPUILabelDefinitions.VAR_DESC).setValue(updatedTarget.getDescription());
|
||||||
|
|||||||
@@ -85,16 +85,22 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
|
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
|
||||||
populateTagNameCombo();
|
populateTagNameCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) {
|
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) {
|
||||||
populateTagNameCombo();
|
populateTagNameCombo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onEventTargetTagUpdateEvent(final TargetTagUpdateEvent event) {
|
void onEventTargetTagUpdateEvent(final TargetTagUpdateEvent event) {
|
||||||
populateTagNameCombo();
|
populateTagNameCombo();
|
||||||
}
|
}
|
||||||
@@ -144,7 +150,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout {
|
|||||||
final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue());
|
final TargetTag existingTag = tagManagement.findTargetTag(tagName.getValue());
|
||||||
if (optiongroup.getValue().equals(createTagNw)) {
|
if (optiongroup.getValue().equals(createTagNw)) {
|
||||||
if (!checkIsDuplicate(existingTag)) {
|
if (!checkIsDuplicate(existingTag)) {
|
||||||
crateNewTag();
|
createNewTag();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@@ -182,8 +188,8 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout {
|
|||||||
/**
|
/**
|
||||||
* Create new tag.
|
* Create new tag.
|
||||||
*/
|
*/
|
||||||
private void crateNewTag() {
|
private void createNewTag() {
|
||||||
final String colorPicked = getColorPickedSting();
|
final String colorPicked = getColorPickedString();
|
||||||
final String tagNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagName.getValue());
|
final String tagNameValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagName.getValue());
|
||||||
final String tagDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
final String tagDescValue = HawkbitCommonUtil.trimAndNullIfEmpty(tagDesc.getValue());
|
||||||
if (null != tagNameValue) {
|
if (null != tagNameValue) {
|
||||||
@@ -214,7 +220,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout {
|
|||||||
if (null != nameUpdateValue) {
|
if (null != nameUpdateValue) {
|
||||||
targetObj.setName(nameUpdateValue);
|
targetObj.setName(nameUpdateValue);
|
||||||
targetObj.setDescription(null != descUpdateValue ? descUpdateValue : null);
|
targetObj.setDescription(null != descUpdateValue ? descUpdateValue : null);
|
||||||
targetObj.setColour(getColorPickedSting());
|
targetObj.setColour(getColorPickedString());
|
||||||
tagManagement.updateTargetTag(targetObj);
|
tagManagement.updateTargetTag(targetObj);
|
||||||
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() }));
|
uiNotification.displaySuccess(i18n.get("message.update.success", new Object[] { targetObj.getName() }));
|
||||||
closeWindow();
|
closeWindow();
|
||||||
@@ -244,7 +250,7 @@ public class CreateUpdateTargetTagLayout extends CreateUpdateTagLayout {
|
|||||||
*
|
*
|
||||||
* @return String of color picked value.
|
* @return String of color picked value.
|
||||||
*/
|
*/
|
||||||
private String getColorPickedSting() {
|
private String getColorPickedString() {
|
||||||
return "rgb(" + getSelPreview().getColor().getRed() + "," + getSelPreview().getColor().getGreen() + ","
|
return "rgb(" + getSelPreview().getColor().getRed() + "," + getSelPreview().getColor().getGreen() + ","
|
||||||
+ getSelPreview().getColor().getBlue() + ")";
|
+ getSelPreview().getColor().getBlue() + ")";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -267,16 +267,22 @@ public class TargetTagFilterButtons extends AbstractFilterButtons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onEvent(final TargetTagUpdateEvent event) {
|
void onEvent(final TargetTagUpdateEvent event) {
|
||||||
refreshContainer();
|
refreshContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
|
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
|
||||||
refreshContainer();
|
refreshContainer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
|
// Exception squid:S1172 - event not needed
|
||||||
|
@SuppressWarnings({ "squid:S1172" })
|
||||||
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) {
|
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) {
|
||||||
refreshContainer();
|
refreshContainer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,23 +18,20 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.hawkbit.HawkbitServerProperties;
|
import org.eclipse.hawkbit.HawkbitServerProperties;
|
||||||
import org.eclipse.hawkbit.im.authentication.PermissionService;
|
import org.eclipse.hawkbit.im.authentication.PermissionService;
|
||||||
import org.eclipse.hawkbit.im.authentication.UserPrincipal;
|
|
||||||
import org.eclipse.hawkbit.ui.UiProperties;
|
import org.eclipse.hawkbit.ui.UiProperties;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent;
|
import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent;
|
||||||
import org.eclipse.hawkbit.ui.utils.I18N;
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
|
||||||
|
|
||||||
import com.vaadin.server.FontAwesome;
|
import com.vaadin.server.FontAwesome;
|
||||||
import com.vaadin.server.Page;
|
import com.vaadin.server.Page;
|
||||||
import com.vaadin.server.ThemeResource;
|
import com.vaadin.server.ThemeResource;
|
||||||
import com.vaadin.server.VaadinService;
|
|
||||||
import com.vaadin.shared.ui.label.ContentMode;
|
import com.vaadin.shared.ui.label.ContentMode;
|
||||||
import com.vaadin.spring.annotation.SpringComponent;
|
import com.vaadin.spring.annotation.SpringComponent;
|
||||||
import com.vaadin.spring.annotation.UIScope;
|
import com.vaadin.spring.annotation.UIScope;
|
||||||
@@ -115,9 +112,9 @@ public final class DashboardMenu extends CustomComponent {
|
|||||||
final VerticalLayout links = buildLinksAndVersion();
|
final VerticalLayout links = buildLinksAndVersion();
|
||||||
menus.addComponent(links);
|
menus.addComponent(links);
|
||||||
menus.setComponentAlignment(links, Alignment.BOTTOM_CENTER);
|
menus.setComponentAlignment(links, Alignment.BOTTOM_CENTER);
|
||||||
menus.setExpandRatio(links, 1.0f);
|
menus.setExpandRatio(links, 1.0F);
|
||||||
menuContent.addComponent(menus);
|
menuContent.addComponent(menus);
|
||||||
menuContent.setExpandRatio(menus, 1.0f);
|
menuContent.setExpandRatio(menus, 1.0F);
|
||||||
|
|
||||||
dashboardMenuLayout.addComponent(menuContent);
|
dashboardMenuLayout.addComponent(menuContent);
|
||||||
return dashboardMenuLayout;
|
return dashboardMenuLayout;
|
||||||
@@ -139,7 +136,7 @@ public final class DashboardMenu extends CustomComponent {
|
|||||||
final Label logo = new Label("<strong>" + i18n.get("menu.title") + "</strong>", ContentMode.HTML);
|
final Label logo = new Label("<strong>" + i18n.get("menu.title") + "</strong>", ContentMode.HTML);
|
||||||
logo.setSizeUndefined();
|
logo.setSizeUndefined();
|
||||||
final HorizontalLayout logoWrapper = new HorizontalLayout(logo);
|
final HorizontalLayout logoWrapper = new HorizontalLayout(logo);
|
||||||
logoWrapper.setComponentAlignment(logo, Alignment.MIDDLE_CENTER);
|
logoWrapper.setComponentAlignment(logo, Alignment.TOP_CENTER);
|
||||||
logoWrapper.addStyleName("valo-menu-title");
|
logoWrapper.addStyleName("valo-menu-title");
|
||||||
return logoWrapper;
|
return logoWrapper;
|
||||||
}
|
}
|
||||||
@@ -151,7 +148,7 @@ public final class DashboardMenu extends CustomComponent {
|
|||||||
final String linkStyle = "v-link";
|
final String linkStyle = "v-link";
|
||||||
|
|
||||||
if (!uiProperties.getLinks().getDocumentation().getRoot().isEmpty()) {
|
if (!uiProperties.getLinks().getDocumentation().getRoot().isEmpty()) {
|
||||||
final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENATION,
|
final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENTATION,
|
||||||
i18n.get("link.documentation.name"), uiProperties.getLinks().getDocumentation().getRoot(),
|
i18n.get("link.documentation.name"), uiProperties.getLinks().getDocumentation().getRoot(),
|
||||||
FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true);
|
FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true);
|
||||||
docuLink.setDescription(i18n.get("link.documentation.name"));
|
docuLink.setDescription(i18n.get("link.documentation.name"));
|
||||||
@@ -189,63 +186,27 @@ public final class DashboardMenu extends CustomComponent {
|
|||||||
return links;
|
return links;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserDetails getCurrentUser() {
|
|
||||||
final SecurityContext context = (SecurityContext) VaadinService.getCurrentRequest().getWrappedSession()
|
|
||||||
.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
|
||||||
return (UserDetails) context.getAuthentication().getPrincipal();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Component buildUserMenu() {
|
private Component buildUserMenu() {
|
||||||
final MenuBar settings = new MenuBar();
|
final MenuBar settings = new MenuBar();
|
||||||
settings.addStyleName("user-menu");
|
settings.addStyleName("user-menu");
|
||||||
final UserDetails user = getCurrentUser();
|
settings.setHtmlContentAllowed(true);
|
||||||
final MenuItem settingsItem = settings.addItem("", new ThemeResource("images/profile-pic-57px.jpg"), null);
|
final MenuItem settingsItem = settings.addItem("", new ThemeResource("images/profile-pic-57px.jpg"), null);
|
||||||
if (user instanceof UserPrincipal
|
|
||||||
&& (((UserPrincipal) user).getFirstname() != null || ((UserPrincipal) user).getLastname() != null)) {
|
final String formattedTenant = UserDetailsFormatter.formatCurrentTenant();
|
||||||
settingsItem.setText(trimTanent(((UserPrincipal) user).getTenant()) + "\n"
|
final String formattedUsername = UserDetailsFormatter.formatCurrentUsername();
|
||||||
+ concateFNameLName(((UserPrincipal) user).getFirstname(), ((UserPrincipal) user).getLastname()));
|
String tenantAndUsernameHtml = "";
|
||||||
settingsItem.setDescription(
|
if (!StringUtils.isEmpty(formattedTenant)) {
|
||||||
((UserPrincipal) user).getFirstname() + " / " + ((UserPrincipal) user).getLastname());
|
tenantAndUsernameHtml += formattedTenant + "<br>";
|
||||||
} else if (user instanceof UserPrincipal) {
|
|
||||||
if (((UserPrincipal) user).getLoginname().length() > 10) {
|
|
||||||
settingsItem.setText(trimTanent(((UserPrincipal) user).getTenant()) + "\n"
|
|
||||||
+ ((UserPrincipal) user).getLoginname().substring(0, 10) + "..");
|
|
||||||
} else {
|
|
||||||
settingsItem.setText(
|
|
||||||
trimTanent(((UserPrincipal) user).getTenant()) + "\n" + ((UserPrincipal) user).getLoginname());
|
|
||||||
}
|
|
||||||
settingsItem.setDescription(((UserPrincipal) user).getLoginname());
|
|
||||||
} else if (user != null) {
|
|
||||||
settingsItem.setText(user.getUsername());
|
|
||||||
settingsItem.setDescription(user.getUsername());
|
|
||||||
}
|
}
|
||||||
|
tenantAndUsernameHtml += formattedUsername;
|
||||||
|
settingsItem.setText(tenantAndUsernameHtml);
|
||||||
|
settingsItem.setDescription(formattedUsername);
|
||||||
|
settingsItem.setStyleName("user-menuitem");
|
||||||
|
|
||||||
settingsItem.addItem("Sign Out", selectedItem -> Page.getCurrent().setLocation("/UI/logout"));
|
settingsItem.addItem("Sign Out", selectedItem -> Page.getCurrent().setLocation("/UI/logout"));
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String concateFNameLName(final String fName, final String lName) {
|
|
||||||
final StringBuilder userName = new StringBuilder();
|
|
||||||
if (fName != null && fName.length() > 6) {
|
|
||||||
userName.append(fName.substring(0, 6) + ".." + ", ");
|
|
||||||
} else {
|
|
||||||
userName.append(fName).append(", ");
|
|
||||||
}
|
|
||||||
if (lName != null && lName.length() > 6) {
|
|
||||||
userName.append(lName.substring(0, 6) + "..");
|
|
||||||
} else {
|
|
||||||
userName.append(lName);
|
|
||||||
}
|
|
||||||
return userName.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String trimTanent(final String tanent) {
|
|
||||||
if (tanent != null && tanent.length() > 8) {
|
|
||||||
return tanent.substring(0, 8) + "..";
|
|
||||||
}
|
|
||||||
return tanent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Component buildToggleButton() {
|
private Component buildToggleButton() {
|
||||||
final Button valoMenuToggleButton = new Button("Menu", (ClickListener) event -> {
|
final Button valoMenuToggleButton = new Button("Menu", (ClickListener) event -> {
|
||||||
if (getCompositionRoot().getStyleName().contains(STYLE_VISIBLE)) {
|
if (getCompositionRoot().getStyleName().contains(STYLE_VISIBLE)) {
|
||||||
@@ -264,7 +225,7 @@ public final class DashboardMenu extends CustomComponent {
|
|||||||
private VerticalLayout buildMenuItems() {
|
private VerticalLayout buildMenuItems() {
|
||||||
final VerticalLayout menuItemsLayout = new VerticalLayout();
|
final VerticalLayout menuItemsLayout = new VerticalLayout();
|
||||||
menuItemsLayout.addStyleName("valo-menuitems");
|
menuItemsLayout.addStyleName("valo-menuitems");
|
||||||
menuItemsLayout.setHeight(100.0f, Unit.PERCENTAGE);
|
menuItemsLayout.setHeight(100.0F, Unit.PERCENTAGE);
|
||||||
|
|
||||||
final List<DashboardMenuItem> accessibleViews = getAccessibleViews();
|
final List<DashboardMenuItem> accessibleViews = getAccessibleViews();
|
||||||
if (accessibleViews.isEmpty()) {
|
if (accessibleViews.isEmpty()) {
|
||||||
|
|||||||
@@ -209,6 +209,7 @@ public class AddUpdateRolloutWindowLayout extends CustomComponent {
|
|||||||
actionTypeOptionGroupLayout, linkToHelp, getSaveDiscardButtonLayout());
|
actionTypeOptionGroupLayout, linkToHelp, getSaveDiscardButtonLayout());
|
||||||
mainLayout.setComponentAlignment(linkToHelp, Alignment.BOTTOM_RIGHT);
|
mainLayout.setComponentAlignment(linkToHelp, Alignment.BOTTOM_RIGHT);
|
||||||
setCompositionRoot(mainLayout);
|
setCompositionRoot(mainLayout);
|
||||||
|
rolloutName.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
private HorizontalLayout getGroupDetailsLayout() {
|
private HorizontalLayout getGroupDetailsLayout() {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.DistributionSetFilter;
|
|||||||
import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder;
|
import org.eclipse.hawkbit.repository.DistributionSetFilter.DistributionSetFilterBuilder;
|
||||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
import org.eclipse.hawkbit.ui.components.ProxyDistribution;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
@@ -62,7 +63,8 @@ public class DistributionBeanQuery extends AbstractBeanQuery<ProxyDistribution>
|
|||||||
sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortPropertyIds[0]);
|
sort = new Sort(sortStates[0] ? Direction.ASC : Direction.DESC, (String) sortPropertyIds[0]);
|
||||||
// Add sort
|
// Add sort
|
||||||
for (int distId = 1; distId < sortPropertyIds.length; distId++) {
|
for (int distId = 1; distId < sortPropertyIds.length; distId++) {
|
||||||
sort.and(new Sort(sortStates[distId] ? Direction.ASC : Direction.DESC, (String) sortPropertyIds[distId]));
|
sort.and(new Sort(sortStates[distId] ? Direction.ASC : Direction.DESC,
|
||||||
|
(String) sortPropertyIds[distId]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,8 +105,8 @@ public class DistributionBeanQuery extends AbstractBeanQuery<ProxyDistribution>
|
|||||||
final List<ProxyDistribution> proxyDistributions = new ArrayList<>();
|
final List<ProxyDistribution> proxyDistributions = new ArrayList<>();
|
||||||
for (final DistributionSet distributionSet : distBeans) {
|
for (final DistributionSet distributionSet : distBeans) {
|
||||||
final ProxyDistribution proxyDistribution = new ProxyDistribution();
|
final ProxyDistribution proxyDistribution = new ProxyDistribution();
|
||||||
proxyDistribution.setName(HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(),
|
proxyDistribution.setName(
|
||||||
distributionSet.getVersion()));
|
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
|
||||||
proxyDistribution.setDescription(distributionSet.getDescription());
|
proxyDistribution.setDescription(distributionSet.getDescription());
|
||||||
proxyDistribution.setDistId(distributionSet.getId());
|
proxyDistribution.setDistId(distributionSet.getId());
|
||||||
proxyDistribution.setId(distributionSet.getId());
|
proxyDistribution.setId(distributionSet.getId());
|
||||||
@@ -112,8 +114,8 @@ public class DistributionBeanQuery extends AbstractBeanQuery<ProxyDistribution>
|
|||||||
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
proxyDistribution.setCreatedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getCreatedAt()));
|
||||||
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
proxyDistribution.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(distributionSet.getLastModifiedAt()));
|
||||||
proxyDistribution.setDescription(distributionSet.getDescription());
|
proxyDistribution.setDescription(distributionSet.getDescription());
|
||||||
proxyDistribution.setCreatedByUser(HawkbitCommonUtil.getIMUser(distributionSet.getCreatedBy()));
|
proxyDistribution.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(distributionSet));
|
||||||
proxyDistribution.setModifiedByUser(HawkbitCommonUtil.getIMUser(distributionSet.getLastModifiedBy()));
|
proxyDistribution.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(distributionSet));
|
||||||
proxyDistribution.setIsComplete(distributionSet.isComplete());
|
proxyDistribution.setIsComplete(distributionSet.isComplete());
|
||||||
proxyDistributions.add(proxyDistribution);
|
proxyDistributions.add(proxyDistribution);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.rollout.rollout;
|
package org.eclipse.hawkbit.ui.rollout.rollout;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
|
|
||||||
import com.vaadin.server.FontAwesome;
|
import com.vaadin.server.FontAwesome;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proxy rollout with suctome properties.
|
* Proxy rollout with custom properties.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ProxyRollout extends Rollout {
|
public class ProxyRollout extends Rollout {
|
||||||
@@ -30,8 +34,92 @@ public class ProxyRollout extends Rollout {
|
|||||||
|
|
||||||
private Boolean isActionRecieved = Boolean.FALSE;
|
private Boolean isActionRecieved = Boolean.FALSE;
|
||||||
|
|
||||||
|
private Boolean isRequiredMigrationStep = Boolean.FALSE;
|
||||||
|
|
||||||
private String totalTargetsCount;
|
private String totalTargetsCount;
|
||||||
|
|
||||||
|
private RolloutRendererData rolloutRendererData;
|
||||||
|
|
||||||
|
private String discription;
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
private Set<SoftwareModule> swModules;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the isRequiredMigrationStep
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Boolean getIsRequiredMigrationStep() {
|
||||||
|
return isRequiredMigrationStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param isRequiredMigrationStep
|
||||||
|
* the isRequiredMigrationStep to set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void setIsRequiredMigrationStep(Boolean isRequiredMigrationStep) {
|
||||||
|
this.isRequiredMigrationStep = isRequiredMigrationStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the discription
|
||||||
|
*/
|
||||||
|
|
||||||
|
public String getDiscription() {
|
||||||
|
return discription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param discription
|
||||||
|
* the discription to set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void setDiscription(String discription) {
|
||||||
|
this.discription = discription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the type
|
||||||
|
*/
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param type
|
||||||
|
* the type to set
|
||||||
|
*/
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return the Set of Software modules
|
||||||
|
*/
|
||||||
|
public Set<SoftwareModule> getSwModules() {
|
||||||
|
return swModules;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param swModules
|
||||||
|
* Set<SoftwareModule> to set
|
||||||
|
*/
|
||||||
|
public void setSwModules(Set<SoftwareModule> swModules) {
|
||||||
|
this.swModules = swModules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RolloutRendererData getRolloutRendererData() {
|
||||||
|
return rolloutRendererData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRolloutRendererData(RolloutRendererData rendererData) {
|
||||||
|
this.rolloutRendererData = rendererData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the distributionSetNameVersion
|
* @return the distributionSetNameVersion
|
||||||
*/
|
*/
|
||||||
@@ -122,7 +210,6 @@ public class ProxyRollout extends Rollout {
|
|||||||
this.totalTargetsCount = totalTargetsCount;
|
this.totalTargetsCount = totalTargetsCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getAction() {
|
public String getAction() {
|
||||||
return FontAwesome.CIRCLE_O.getHtml();
|
return FontAwesome.CIRCLE_O.getHtml();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import org.eclipse.hawkbit.repository.TargetFilterQueryManagement;
|
|||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState;
|
import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
@@ -119,22 +121,29 @@ public class RolloutBeanQuery extends AbstractBeanQuery<ProxyRollout> {
|
|||||||
proxyRollout.setName(rollout.getName());
|
proxyRollout.setName(rollout.getName());
|
||||||
proxyRollout.setDescription(rollout.getDescription());
|
proxyRollout.setDescription(rollout.getDescription());
|
||||||
final DistributionSet distributionSet = rollout.getDistributionSet();
|
final DistributionSet distributionSet = rollout.getDistributionSet();
|
||||||
proxyRollout.setDistributionSetNameVersion(HawkbitCommonUtil.getFormattedNameVersion(
|
proxyRollout.setDistributionSetNameVersion(
|
||||||
distributionSet.getName(), distributionSet.getVersion()));
|
HawkbitCommonUtil.getFormattedNameVersion(distributionSet.getName(), distributionSet.getVersion()));
|
||||||
proxyRollout.setDistributionSet(distributionSet);
|
proxyRollout.setDistributionSet(distributionSet);
|
||||||
proxyRollout.setNumberOfGroups(Long.valueOf(rollout.getRolloutGroups().size()));
|
proxyRollout.setNumberOfGroups(Long.valueOf(rollout.getRolloutGroups().size()));
|
||||||
proxyRollout.setCreatedDate(SPDateTimeUtil.getFormattedDate(rollout.getCreatedAt()));
|
proxyRollout.setCreatedDate(SPDateTimeUtil.getFormattedDate(rollout.getCreatedAt()));
|
||||||
proxyRollout.setModifiedDate(SPDateTimeUtil.getFormattedDate(rollout.getLastModifiedAt()));
|
proxyRollout.setModifiedDate(SPDateTimeUtil.getFormattedDate(rollout.getLastModifiedAt()));
|
||||||
proxyRollout.setCreatedBy(HawkbitCommonUtil.getIMUser(rollout.getCreatedBy()));
|
proxyRollout.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(rollout));
|
||||||
proxyRollout.setLastModifiedBy(HawkbitCommonUtil.getIMUser(rollout.getLastModifiedBy()));
|
proxyRollout.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(rollout));
|
||||||
proxyRollout.setForcedTime(rollout.getForcedTime());
|
proxyRollout.setForcedTime(rollout.getForcedTime());
|
||||||
proxyRollout.setId(rollout.getId());
|
proxyRollout.setId(rollout.getId());
|
||||||
proxyRollout.setStatus(rollout.getStatus());
|
proxyRollout.setStatus(rollout.getStatus());
|
||||||
|
proxyRollout
|
||||||
|
.setRolloutRendererData(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
|
||||||
|
|
||||||
final TotalTargetCountStatus totalTargetCountActionStatus = rollout.getTotalTargetCountStatus();
|
final TotalTargetCountStatus totalTargetCountActionStatus = rollout.getTotalTargetCountStatus();
|
||||||
proxyRollout.setTotalTargetCountStatus(totalTargetCountActionStatus);
|
proxyRollout.setTotalTargetCountStatus(totalTargetCountActionStatus);
|
||||||
proxyRollout.setTotalTargetsCount(String.valueOf(rollout.getTotalTargets()));
|
proxyRollout.setTotalTargetsCount(String.valueOf(rollout.getTotalTargets()));
|
||||||
|
|
||||||
|
proxyRollout.setDescription(distributionSet.getDescription());
|
||||||
|
proxyRollout.setType(distributionSet.getType().getName());
|
||||||
|
proxyRollout.setIsRequiredMigrationStep(distributionSet.isRequiredMigrationStep());
|
||||||
|
proxyRollout.setSwModules(distributionSet.getModules());
|
||||||
|
|
||||||
proxyRolloutList.add(proxyRollout);
|
proxyRolloutList.add(proxyRollout);
|
||||||
}
|
}
|
||||||
return proxyRolloutList;
|
return proxyRolloutList;
|
||||||
@@ -148,7 +157,8 @@ public class RolloutBeanQuery extends AbstractBeanQuery<ProxyRollout> {
|
|||||||
* .util.List, java.util.List, java.util.List)
|
* .util.List, java.util.List, java.util.List)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void saveBeans(final List<ProxyRollout> arg0, final List<ProxyRollout> arg1, final List<ProxyRollout> arg2) {
|
protected void saveBeans(final List<ProxyRollout> arg0, final List<ProxyRollout> arg1,
|
||||||
|
final List<ProxyRollout> arg2) {
|
||||||
/**
|
/**
|
||||||
* CRUD operations on Target will be done through repository methods
|
* CRUD operations on Target will be done through repository methods
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,23 +8,31 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.rollout.rollout;
|
package org.eclipse.hawkbit.ui.rollout.rollout;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_LI_CLOSE_TAG;
|
||||||
|
import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_LI_OPEN_TAG;
|
||||||
|
import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_UL_CLOSE_TAG;
|
||||||
|
import static org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil.HTML_UL_OPEN_TAG;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.RolloutChangeEvent;
|
import org.eclipse.hawkbit.eventbus.event.RolloutChangeEvent;
|
||||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||||
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout;
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
|
||||||
|
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.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.renderers.HtmlButtonRenderer;
|
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlButtonRenderer;
|
||||||
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlLabelRenderer;
|
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlLabelRenderer;
|
||||||
import org.eclipse.hawkbit.ui.customrenderers.renderers.LinkRenderer;
|
import org.eclipse.hawkbit.ui.customrenderers.renderers.RolloutRenderer;
|
||||||
import org.eclipse.hawkbit.ui.rollout.DistributionBarHelper;
|
import org.eclipse.hawkbit.ui.rollout.DistributionBarHelper;
|
||||||
import org.eclipse.hawkbit.ui.rollout.StatusFontIcon;
|
import org.eclipse.hawkbit.ui.rollout.StatusFontIcon;
|
||||||
import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent;
|
import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent;
|
||||||
@@ -77,6 +85,13 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
private static final String START_OPTION = "Start";
|
private static final String START_OPTION = "Start";
|
||||||
|
|
||||||
|
private static final String DS_TYPE = "type";
|
||||||
|
|
||||||
|
private static final String SW_MODULES = "swModules";
|
||||||
|
|
||||||
|
private static final String IS_REQUIRED_MIGRATION_STEP = "isRequiredMigrationStep";
|
||||||
|
|
||||||
|
private static final String ROLLOUT_RENDERER_DATA = "rolloutRendererData";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private transient RolloutManagement rolloutManagement;
|
private transient RolloutManagement rolloutManagement;
|
||||||
@@ -95,7 +110,10 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
private transient Map<RolloutStatus, StatusFontIcon> statusIconMap = new EnumMap<>(RolloutStatus.class);
|
private transient Map<RolloutStatus, StatusFontIcon> statusIconMap = new EnumMap<>(RolloutStatus.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the RolloutEvent to refresh Grid.
|
||||||
|
*
|
||||||
|
*/
|
||||||
@EventBusListenerMethod(scope = EventScope.SESSION)
|
@EventBusListenerMethod(scope = EventScope.SESSION)
|
||||||
void onEvent(final RolloutEvent event) {
|
void onEvent(final RolloutEvent event) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
@@ -132,10 +150,16 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rollout.getStatus());
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setValue(totalTargetCountStatus);
|
item.getItemProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setValue(totalTargetCountStatus);
|
||||||
final Long groupCount = (Long) item.getItemProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).getValue();
|
final Long groupCount = (Long) item.getItemProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).getValue();
|
||||||
if (rollout.getRolloutGroups() != null && groupCount != rollout.getRolloutGroups().size()) {
|
final int groupsCreated = rollout.getRolloutGroupsCreated();
|
||||||
|
if (groupsCreated != 0) {
|
||||||
|
item.getItemProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setValue(Long.valueOf(groupsCreated));
|
||||||
|
} else if (rollout.getRolloutGroups() != null && groupCount != rollout.getRolloutGroups().size()) {
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS)
|
item.getItemProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS)
|
||||||
.setValue(Long.valueOf(rollout.getRolloutGroups().size()));
|
.setValue(Long.valueOf(rollout.getRolloutGroups().size()));
|
||||||
}
|
}
|
||||||
|
item.getItemProperty(ROLLOUT_RENDERER_DATA)
|
||||||
|
.setValue(new RolloutRendererData(rollout.getName(), rollout.getStatus().toString()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -149,7 +173,11 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
protected void addContainerProperties() {
|
protected void addContainerProperties() {
|
||||||
final LazyQueryContainer rolloutGridContainer = (LazyQueryContainer) getContainerDataSource();
|
final LazyQueryContainer rolloutGridContainer = (LazyQueryContainer) getContainerDataSource();
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", false, false);
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", false, false);
|
||||||
|
rolloutGridContainer.addContainerProperty(DS_TYPE, String.class, null, false, false);
|
||||||
|
rolloutGridContainer.addContainerProperty(SW_MODULES, Set.class, null, false, false);
|
||||||
|
rolloutGridContainer.addContainerProperty(ROLLOUT_RENDERER_DATA, RolloutRendererData.class, null, false, false);
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, null, false, false);
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, null, false, false);
|
||||||
|
rolloutGridContainer.addContainerProperty(IS_REQUIRED_MIGRATION_STEP, boolean.class, null, false, false);
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_STATUS, RolloutStatus.class, null, false,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_STATUS, RolloutStatus.class, null, false,
|
||||||
false);
|
false);
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DIST_NAME_VERSION, String.class, null, false,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DIST_NAME_VERSION, String.class, null, false,
|
||||||
@@ -163,7 +191,7 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
false);
|
false);
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_MODIFIED_BY, String.class, null, false,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_MODIFIED_BY, String.class, null, false,
|
||||||
false);
|
false);
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS, Integer.class, 0, false,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS, Long.class, 0, false,
|
||||||
false);
|
false);
|
||||||
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS, String.class, "0", false,
|
rolloutGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS, String.class, "0", false,
|
||||||
false);
|
false);
|
||||||
@@ -177,8 +205,9 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setColumnExpandRatio() {
|
protected void setColumnExpandRatio() {
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setMinimumWidth(40);
|
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setMaximumWidth(150);
|
getColumn(ROLLOUT_RENDERER_DATA).setMinimumWidth(40);
|
||||||
|
getColumn(ROLLOUT_RENDERER_DATA).setMaximumWidth(150);
|
||||||
|
|
||||||
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setMinimumWidth(40);
|
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setMinimumWidth(40);
|
||||||
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setMaximumWidth(150);
|
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setMaximumWidth(150);
|
||||||
@@ -202,7 +231,10 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setColumnHeaderNames() {
|
protected void setColumnHeaderNames() {
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setHeaderCaption(i18n.get("header.name"));
|
getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.get("header.name"));
|
||||||
|
getColumn(DS_TYPE).setHeaderCaption("Type");
|
||||||
|
getColumn(SW_MODULES).setHeaderCaption("swModules");
|
||||||
|
getColumn(IS_REQUIRED_MIGRATION_STEP).setHeaderCaption("IsRequiredMigrationStep");
|
||||||
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setHeaderCaption(i18n.get("header.distributionset"));
|
getColumn(SPUILabelDefinitions.VAR_DIST_NAME_VERSION).setHeaderCaption(i18n.get("header.distributionset"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setHeaderCaption(i18n.get("header.numberofgroups"));
|
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setHeaderCaption(i18n.get("header.numberofgroups"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setHeaderCaption(i18n.get("header.total.targets"));
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setHeaderCaption(i18n.get("header.total.targets"));
|
||||||
@@ -225,8 +257,11 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
@Override
|
@Override
|
||||||
protected void setColumnProperties() {
|
protected void setColumnProperties() {
|
||||||
final List<Object> columnList = new ArrayList<>();
|
final List<Object> columnList = new ArrayList<>();
|
||||||
columnList.add(SPUILabelDefinitions.VAR_NAME);
|
columnList.add(ROLLOUT_RENDERER_DATA);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_DIST_NAME_VERSION);
|
columnList.add(SPUILabelDefinitions.VAR_DIST_NAME_VERSION);
|
||||||
|
columnList.add(DS_TYPE);
|
||||||
|
columnList.add(SW_MODULES);
|
||||||
|
columnList.add(IS_REQUIRED_MIGRATION_STEP);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_STATUS);
|
columnList.add(SPUILabelDefinitions.VAR_STATUS);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS);
|
columnList.add(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS);
|
||||||
@@ -245,11 +280,15 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
@Override
|
@Override
|
||||||
protected void setHiddenColumns() {
|
protected void setHiddenColumns() {
|
||||||
final List<Object> columnsToBeHidden = new ArrayList<>();
|
final List<Object> columnsToBeHidden = new ArrayList<>();
|
||||||
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_NAME);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_DATE);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_DATE);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_BY);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_BY);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_DESC);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_DESC);
|
||||||
|
columnsToBeHidden.add(IS_REQUIRED_MIGRATION_STEP);
|
||||||
|
columnsToBeHidden.add(DS_TYPE);
|
||||||
|
columnsToBeHidden.add(SW_MODULES);
|
||||||
for (final Object propertyId : columnsToBeHidden) {
|
for (final Object propertyId : columnsToBeHidden) {
|
||||||
getColumn(propertyId).setHidden(true);
|
getColumn(propertyId).setHidden(true);
|
||||||
}
|
}
|
||||||
@@ -263,6 +302,8 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addColumnRenderes() {
|
protected void addColumnRenderes() {
|
||||||
|
getColumn(SPUILabelDefinitions.VAR_NUMBER_OF_GROUPS).setRenderer(new HtmlRenderer(),
|
||||||
|
new TotalTargetGroupsConverter());
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setRenderer(new HtmlRenderer(),
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setRenderer(new HtmlRenderer(),
|
||||||
new TotalTargetCountStatusConverter());
|
new TotalTargetCountStatusConverter());
|
||||||
|
|
||||||
@@ -270,7 +311,11 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
getColumn(SPUILabelDefinitions.VAR_STATUS).setRenderer(new HtmlLabelRenderer(), new RolloutStatusConverter());
|
getColumn(SPUILabelDefinitions.VAR_STATUS).setRenderer(new HtmlLabelRenderer(), new RolloutStatusConverter());
|
||||||
|
|
||||||
getColumn(SPUILabelDefinitions.ACTION).setRenderer(new HtmlButtonRenderer(event -> onClickOfActionBtn(event)));
|
getColumn(SPUILabelDefinitions.ACTION).setRenderer(new HtmlButtonRenderer(event -> onClickOfActionBtn(event)));
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setRenderer(new LinkRenderer(event -> onClickOfRolloutName(event)));
|
|
||||||
|
final RolloutRenderer customObjectRenderer = new RolloutRenderer(RolloutRendererData.class);
|
||||||
|
customObjectRenderer.addClickListener(event -> onClickOfRolloutName(event));
|
||||||
|
getColumn(ROLLOUT_RENDERER_DATA).setRenderer(customObjectRenderer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRolloutStatusToFontMap() {
|
private void createRolloutStatusToFontMap() {
|
||||||
@@ -403,6 +448,9 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
((LazyQueryContainer) getContainerDataSource()).refresh();
|
((LazyQueryContainer) getContainerDataSource()).refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generator to generate fontIcon by String.
|
||||||
|
*/
|
||||||
public final class FontIconGenerator extends PropertyValueGenerator<String> {
|
public final class FontIconGenerator extends PropertyValueGenerator<String> {
|
||||||
|
|
||||||
private static final long serialVersionUID = 2544026030795375748L;
|
private static final long serialVersionUID = 2544026030795375748L;
|
||||||
@@ -428,15 +476,54 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
return cell.getProperty().getValue().toString().toLowerCase();
|
return cell.getProperty().getValue().toString().toLowerCase();
|
||||||
} else if (SPUILabelDefinitions.ACTION.equals(cell.getPropertyId())) {
|
} else if (SPUILabelDefinitions.ACTION.equals(cell.getPropertyId())) {
|
||||||
return SPUILabelDefinitions.ACTION.toLowerCase();
|
return SPUILabelDefinitions.ACTION.toLowerCase();
|
||||||
} else if (SPUILabelDefinitions.VAR_NAME.equals(cell.getPropertyId())) {
|
} else if (ROLLOUT_RENDERER_DATA.equals(cell.getPropertyId())) {
|
||||||
return cell.getProperty().getValue().toString();
|
return ((RolloutRendererData) cell.getProperty().getValue()).getName();
|
||||||
} else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) {
|
} else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) {
|
||||||
return DistributionBarHelper
|
return DistributionBarHelper
|
||||||
.getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap());
|
.getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap());
|
||||||
|
} else if (SPUILabelDefinitions.VAR_DIST_NAME_VERSION.equals(cell.getPropertyId())) {
|
||||||
|
return getDSDetails(cell.getItem());
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getDSDetails(final Item rolloutItem) {
|
||||||
|
final StringBuilder swModuleNames = new StringBuilder();
|
||||||
|
final StringBuilder swModuleVendors = new StringBuilder();
|
||||||
|
final Set<SoftwareModule> swModules = (Set<SoftwareModule>) rolloutItem.getItemProperty(SW_MODULES).getValue();
|
||||||
|
swModules.forEach(swModule -> {
|
||||||
|
swModuleNames.append(swModule.getName());
|
||||||
|
swModuleNames.append(" , ");
|
||||||
|
swModuleVendors.append(swModule.getVendor());
|
||||||
|
swModuleVendors.append(" , ");
|
||||||
|
});
|
||||||
|
final StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append(HTML_UL_OPEN_TAG);
|
||||||
|
stringBuilder.append(HTML_LI_OPEN_TAG);
|
||||||
|
stringBuilder.append(" DistributionSet Description : ")
|
||||||
|
.append((String) rolloutItem.getItemProperty(SPUILabelDefinitions.VAR_DESC).getValue());
|
||||||
|
stringBuilder.append(HTML_LI_CLOSE_TAG);
|
||||||
|
stringBuilder.append(HTML_LI_OPEN_TAG);
|
||||||
|
stringBuilder.append(" DistributionSet Type : ")
|
||||||
|
.append((String) rolloutItem.getItemProperty(DS_TYPE).getValue());
|
||||||
|
stringBuilder.append(HTML_LI_CLOSE_TAG);
|
||||||
|
stringBuilder.append(HTML_LI_OPEN_TAG);
|
||||||
|
stringBuilder.append("Required Migration step : ")
|
||||||
|
.append((boolean) rolloutItem.getItemProperty(IS_REQUIRED_MIGRATION_STEP).getValue() ? "Yes" : "No");
|
||||||
|
stringBuilder.append(HTML_LI_CLOSE_TAG);
|
||||||
|
|
||||||
|
stringBuilder.append(HTML_LI_OPEN_TAG);
|
||||||
|
stringBuilder.append("SoftWare Modules : ").append(swModuleNames.toString());
|
||||||
|
stringBuilder.append(HTML_LI_CLOSE_TAG);
|
||||||
|
|
||||||
|
stringBuilder.append(HTML_LI_OPEN_TAG);
|
||||||
|
stringBuilder.append("Vendor(s) : ").append(swModuleVendors.toString());
|
||||||
|
stringBuilder.append(HTML_LI_CLOSE_TAG);
|
||||||
|
|
||||||
|
stringBuilder.append(HTML_UL_CLOSE_TAG);
|
||||||
|
return stringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
enum ACTION {
|
enum ACTION {
|
||||||
PAUSE, RESUME, START, UPDATE
|
PAUSE, RESUME, START, UPDATE
|
||||||
}
|
}
|
||||||
@@ -568,4 +655,39 @@ public class RolloutListGrid extends AbstractGrid {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converter to convert 0 to empty, if total target groups is zero.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class TotalTargetGroupsConverter implements Converter<String, Long> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6589305227035220369L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long convertToModel(final String value, final Class<? extends Long> targetType, final Locale locale)
|
||||||
|
throws com.vaadin.data.util.converter.Converter.ConversionException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToPresentation(final Long value, final Class<? extends String> targetType,
|
||||||
|
final Locale locale) throws com.vaadin.data.util.converter.Converter.ConversionException {
|
||||||
|
if (value == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Long> getModelType() {
|
||||||
|
return Long.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<String> getPresentationType() {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,200 +9,211 @@
|
|||||||
package org.eclipse.hawkbit.ui.rollout.rolloutgroup;
|
package org.eclipse.hawkbit.ui.rollout.rolloutgroup;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Proxy rollout group with suctome properties.
|
* Proxy rollout group with renderer properties.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ProxyRolloutGroup extends RolloutGroup {
|
public class ProxyRolloutGroup extends RolloutGroup {
|
||||||
|
|
||||||
private static final long serialVersionUID = -2745056813306692356L;
|
private static final long serialVersionUID = -2745056813306692356L;
|
||||||
|
|
||||||
private String createdDate;
|
private String createdDate;
|
||||||
|
|
||||||
private String modifiedDate;
|
private String modifiedDate;
|
||||||
|
|
||||||
private String finishedPercentage;
|
private String finishedPercentage;
|
||||||
|
|
||||||
private Long runningTargetsCount;
|
private Long runningTargetsCount;
|
||||||
|
|
||||||
private Long scheduledTargetsCount;
|
private Long scheduledTargetsCount;
|
||||||
|
|
||||||
private Long cancelledTargetsCount;
|
private Long cancelledTargetsCount;
|
||||||
|
|
||||||
private Long errorTargetsCount;
|
private Long errorTargetsCount;
|
||||||
|
|
||||||
private Long finishedTargetsCount;
|
private Long finishedTargetsCount;
|
||||||
|
|
||||||
private Long notStartedTargetsCount;
|
private Long notStartedTargetsCount;
|
||||||
|
|
||||||
private Boolean isActionRecieved = Boolean.FALSE;
|
private Boolean isActionRecieved = Boolean.FALSE;
|
||||||
|
|
||||||
private String totalTargetsCount;
|
private String totalTargetsCount;
|
||||||
|
|
||||||
/**
|
private RolloutRendererData rolloutRendererData;
|
||||||
* @return the createdDate
|
|
||||||
*/
|
|
||||||
public String getCreatedDate() {
|
|
||||||
return createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public RolloutRendererData getRolloutRendererData() {
|
||||||
* @param createdDate
|
return rolloutRendererData;
|
||||||
* the createdDate to set
|
}
|
||||||
*/
|
|
||||||
public void setCreatedDate(final String createdDate) {
|
|
||||||
this.createdDate = createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public void setRolloutRendererData(RolloutRendererData rendererData) {
|
||||||
* @return the modifiedDate
|
this.rolloutRendererData = rendererData;
|
||||||
*/
|
}
|
||||||
public String getModifiedDate() {
|
|
||||||
return modifiedDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param modifiedDate
|
* @return the createdDate
|
||||||
* the modifiedDate to set
|
*/
|
||||||
*/
|
public String getCreatedDate() {
|
||||||
public void setModifiedDate(final String modifiedDate) {
|
return createdDate;
|
||||||
this.modifiedDate = modifiedDate;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the finishedPercentage
|
* @param createdDate
|
||||||
*/
|
* the createdDate to set
|
||||||
public String getFinishedPercentage() {
|
*/
|
||||||
return finishedPercentage;
|
public void setCreatedDate(final String createdDate) {
|
||||||
}
|
this.createdDate = createdDate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param finishedPercentage
|
* @return the modifiedDate
|
||||||
* the finishedPercentage to set
|
*/
|
||||||
*/
|
public String getModifiedDate() {
|
||||||
public void setFinishedPercentage(final String finishedPercentage) {
|
return modifiedDate;
|
||||||
this.finishedPercentage = finishedPercentage;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the runningTargetsCount
|
* @param modifiedDate
|
||||||
*/
|
* the modifiedDate to set
|
||||||
public Long getRunningTargetsCount() {
|
*/
|
||||||
return runningTargetsCount;
|
public void setModifiedDate(final String modifiedDate) {
|
||||||
}
|
this.modifiedDate = modifiedDate;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param runningTargetsCount
|
* @return the finishedPercentage
|
||||||
* the runningTargetsCount to set
|
*/
|
||||||
*/
|
public String getFinishedPercentage() {
|
||||||
public void setRunningTargetsCount(final Long runningTargetsCount) {
|
return finishedPercentage;
|
||||||
this.runningTargetsCount = runningTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the scheduledTargetsCount
|
* @param finishedPercentage
|
||||||
*/
|
* the finishedPercentage to set
|
||||||
public Long getScheduledTargetsCount() {
|
*/
|
||||||
return scheduledTargetsCount;
|
public void setFinishedPercentage(final String finishedPercentage) {
|
||||||
}
|
this.finishedPercentage = finishedPercentage;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param scheduledTargetsCount
|
* @return the runningTargetsCount
|
||||||
* the scheduledTargetsCount to set
|
*/
|
||||||
*/
|
public Long getRunningTargetsCount() {
|
||||||
public void setScheduledTargetsCount(final Long scheduledTargetsCount) {
|
return runningTargetsCount;
|
||||||
this.scheduledTargetsCount = scheduledTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the cancelledTargetsCount
|
* @param runningTargetsCount
|
||||||
*/
|
* the runningTargetsCount to set
|
||||||
public Long getCancelledTargetsCount() {
|
*/
|
||||||
return cancelledTargetsCount;
|
public void setRunningTargetsCount(final Long runningTargetsCount) {
|
||||||
}
|
this.runningTargetsCount = runningTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cancelledTargetsCount
|
* @return the scheduledTargetsCount
|
||||||
* the cancelledTargetsCount to set
|
*/
|
||||||
*/
|
public Long getScheduledTargetsCount() {
|
||||||
public void setCancelledTargetsCount(final Long cancelledTargetsCount) {
|
return scheduledTargetsCount;
|
||||||
this.cancelledTargetsCount = cancelledTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the errorTargetsCount
|
* @param scheduledTargetsCount
|
||||||
*/
|
* the scheduledTargetsCount to set
|
||||||
public Long getErrorTargetsCount() {
|
*/
|
||||||
return errorTargetsCount;
|
public void setScheduledTargetsCount(final Long scheduledTargetsCount) {
|
||||||
}
|
this.scheduledTargetsCount = scheduledTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param errorTargetsCount
|
* @return the cancelledTargetsCount
|
||||||
* the errorTargetsCount to set
|
*/
|
||||||
*/
|
public Long getCancelledTargetsCount() {
|
||||||
public void setErrorTargetsCount(final Long errorTargetsCount) {
|
return cancelledTargetsCount;
|
||||||
this.errorTargetsCount = errorTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the finishedTargetsCount
|
* @param cancelledTargetsCount
|
||||||
*/
|
* the cancelledTargetsCount to set
|
||||||
public Long getFinishedTargetsCount() {
|
*/
|
||||||
return finishedTargetsCount;
|
public void setCancelledTargetsCount(final Long cancelledTargetsCount) {
|
||||||
}
|
this.cancelledTargetsCount = cancelledTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param finishedTargetsCount
|
* @return the errorTargetsCount
|
||||||
* the finishedTargetsCount to set
|
*/
|
||||||
*/
|
public Long getErrorTargetsCount() {
|
||||||
public void setFinishedTargetsCount(final Long finishedTargetsCount) {
|
return errorTargetsCount;
|
||||||
this.finishedTargetsCount = finishedTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the notStartedTargetsCount
|
* @param errorTargetsCount
|
||||||
*/
|
* the errorTargetsCount to set
|
||||||
public Long getNotStartedTargetsCount() {
|
*/
|
||||||
return notStartedTargetsCount;
|
public void setErrorTargetsCount(final Long errorTargetsCount) {
|
||||||
}
|
this.errorTargetsCount = errorTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param notStartedTargetsCount
|
* @return the finishedTargetsCount
|
||||||
* the notStartedTargetsCount to set
|
*/
|
||||||
*/
|
public Long getFinishedTargetsCount() {
|
||||||
public void setNotStartedTargetsCount(final Long notStartedTargetsCount) {
|
return finishedTargetsCount;
|
||||||
this.notStartedTargetsCount = notStartedTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the isActionRecieved
|
* @param finishedTargetsCount
|
||||||
*/
|
* the finishedTargetsCount to set
|
||||||
public Boolean getIsActionRecieved() {
|
*/
|
||||||
return isActionRecieved;
|
public void setFinishedTargetsCount(final Long finishedTargetsCount) {
|
||||||
}
|
this.finishedTargetsCount = finishedTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param isActionRecieved
|
* @return the notStartedTargetsCount
|
||||||
* the isActionRecieved to set
|
*/
|
||||||
*/
|
public Long getNotStartedTargetsCount() {
|
||||||
public void setIsActionRecieved(final Boolean isActionRecieved) {
|
return notStartedTargetsCount;
|
||||||
this.isActionRecieved = isActionRecieved;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the totalTargetsCount
|
* @param notStartedTargetsCount
|
||||||
*/
|
* the notStartedTargetsCount to set
|
||||||
public String getTotalTargetsCount() {
|
*/
|
||||||
return totalTargetsCount;
|
public void setNotStartedTargetsCount(final Long notStartedTargetsCount) {
|
||||||
}
|
this.notStartedTargetsCount = notStartedTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param totalTargetsCount
|
* @return the isActionRecieved
|
||||||
* the totalTargetsCount to set
|
*/
|
||||||
*/
|
public Boolean getIsActionRecieved() {
|
||||||
public void setTotalTargetsCount(final String totalTargetsCount) {
|
return isActionRecieved;
|
||||||
this.totalTargetsCount = totalTargetsCount;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* @param isActionRecieved
|
||||||
|
* the isActionRecieved to set
|
||||||
|
*/
|
||||||
|
public void setIsActionRecieved(final Boolean isActionRecieved) {
|
||||||
|
this.isActionRecieved = isActionRecieved;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the totalTargetsCount
|
||||||
|
*/
|
||||||
|
public String getTotalTargetsCount() {
|
||||||
|
return totalTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param totalTargetsCount
|
||||||
|
* the totalTargetsCount to set
|
||||||
|
*/
|
||||||
|
public void setTotalTargetsCount(final String totalTargetsCount) {
|
||||||
|
this.totalTargetsCount = totalTargetsCount;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import java.util.Map;
|
|||||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||||
import org.eclipse.hawkbit.repository.RolloutManagement;
|
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
|
import org.eclipse.hawkbit.ui.customrenderers.client.renderers.RolloutRendererData;
|
||||||
import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState;
|
import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
|
||||||
@@ -110,8 +112,8 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery<ProxyRolloutGroup>
|
|||||||
proxyRolloutGroup.setDescription(rolloutGroup.getDescription());
|
proxyRolloutGroup.setDescription(rolloutGroup.getDescription());
|
||||||
proxyRolloutGroup.setCreatedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getCreatedAt()));
|
proxyRolloutGroup.setCreatedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getCreatedAt()));
|
||||||
proxyRolloutGroup.setModifiedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getLastModifiedAt()));
|
proxyRolloutGroup.setModifiedDate(SPDateTimeUtil.getFormattedDate(rolloutGroup.getLastModifiedAt()));
|
||||||
proxyRolloutGroup.setCreatedBy(HawkbitCommonUtil.getIMUser(rolloutGroup.getCreatedBy()));
|
proxyRolloutGroup.setCreatedBy(UserDetailsFormatter.loadAndFormatCreatedBy(rolloutGroup));
|
||||||
proxyRolloutGroup.setLastModifiedBy(HawkbitCommonUtil.getIMUser(rolloutGroup.getLastModifiedBy()));
|
proxyRolloutGroup.setLastModifiedBy(UserDetailsFormatter.loadAndFormatLastModifiedBy(rolloutGroup));
|
||||||
proxyRolloutGroup.setId(rolloutGroup.getId());
|
proxyRolloutGroup.setId(rolloutGroup.getId());
|
||||||
proxyRolloutGroup.setStatus(rolloutGroup.getStatus());
|
proxyRolloutGroup.setStatus(rolloutGroup.getStatus());
|
||||||
proxyRolloutGroup.setErrorAction(rolloutGroup.getErrorAction());
|
proxyRolloutGroup.setErrorAction(rolloutGroup.getErrorAction());
|
||||||
@@ -122,6 +124,8 @@ public class RolloutGroupBeanQuery extends AbstractBeanQuery<ProxyRolloutGroup>
|
|||||||
proxyRolloutGroup.setSuccessConditionExp(rolloutGroup.getSuccessConditionExp());
|
proxyRolloutGroup.setSuccessConditionExp(rolloutGroup.getSuccessConditionExp());
|
||||||
proxyRolloutGroup.setFinishedPercentage(calculateFinishedPercentage(rolloutGroup));
|
proxyRolloutGroup.setFinishedPercentage(calculateFinishedPercentage(rolloutGroup));
|
||||||
|
|
||||||
|
proxyRolloutGroup.setRolloutRendererData(new RolloutRendererData(rolloutGroup.getName(), null));
|
||||||
|
|
||||||
proxyRolloutGroup.setTotalTargetsCount(String.valueOf(rolloutGroup.getTotalTargets()));
|
proxyRolloutGroup.setTotalTargetsCount(String.valueOf(rolloutGroup.getTotalTargets()));
|
||||||
proxyRolloutGroup.setTotalTargetCountStatus(rolloutGroup.getTotalTargetCountStatus());
|
proxyRolloutGroup.setTotalTargetCountStatus(rolloutGroup.getTotalTargetCountStatus());
|
||||||
|
|
||||||
|
|||||||
@@ -17,13 +17,15 @@ import java.util.Map;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.RolloutGroupChangeEvent;
|
import org.eclipse.hawkbit.eventbus.event.RolloutGroupChangeEvent;
|
||||||
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.RolloutManagement;
|
||||||
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
import org.eclipse.hawkbit.repository.SpPermissionChecker;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus;
|
||||||
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.renderers.HtmlLabelRenderer;
|
import org.eclipse.hawkbit.ui.customrenderers.renderers.HtmlLabelRenderer;
|
||||||
import org.eclipse.hawkbit.ui.customrenderers.renderers.LinkRenderer;
|
import org.eclipse.hawkbit.ui.customrenderers.renderers.RolloutRenderer;
|
||||||
import org.eclipse.hawkbit.ui.rollout.DistributionBarHelper;
|
import org.eclipse.hawkbit.ui.rollout.DistributionBarHelper;
|
||||||
import org.eclipse.hawkbit.ui.rollout.StatusFontIcon;
|
import org.eclipse.hawkbit.ui.rollout.StatusFontIcon;
|
||||||
import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent;
|
import org.eclipse.hawkbit.ui.rollout.event.RolloutEvent;
|
||||||
@@ -59,9 +61,14 @@ import com.vaadin.ui.renderers.HtmlRenderer;
|
|||||||
public class RolloutGroupListGrid extends AbstractGrid {
|
public class RolloutGroupListGrid extends AbstractGrid {
|
||||||
private static final long serialVersionUID = 4060904914954370524L;
|
private static final long serialVersionUID = 4060904914954370524L;
|
||||||
|
|
||||||
|
private static final String ROLLOUT_RENDERER_DATA = "rolloutRendererData";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private transient RolloutGroupManagement rolloutGroupManagement;
|
private transient RolloutGroupManagement rolloutGroupManagement;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private transient RolloutManagement rolloutManagement;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private transient RolloutUIState rolloutUIState;
|
private transient RolloutUIState rolloutUIState;
|
||||||
|
|
||||||
@@ -103,6 +110,13 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rolloutGroup.getStatus());
|
item.getItemProperty(SPUILabelDefinitions.VAR_STATUS).setValue(rolloutGroup.getStatus());
|
||||||
item.getItemProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
item.getItemProperty(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
||||||
.setValue(rolloutGroup.getTotalTargetCountStatus());
|
.setValue(rolloutGroup.getTotalTargetCountStatus());
|
||||||
|
item.getItemProperty(SPUILabelDefinitions.ROLLOUT_GROUP_INSTALLED_PERCENTAGE)
|
||||||
|
.setValue(calculateFinishedPercentage(rolloutGroup));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateFinishedPercentage(final RolloutGroup rolloutGroup) {
|
||||||
|
return HawkbitCommonUtil.formattingFinishedPercentage(rolloutGroup,
|
||||||
|
rolloutManagement.getFinishedPercentForRunningGroup(rolloutGroup.getRollout().getId(), rolloutGroup));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -116,6 +130,9 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
protected void addContainerProperties() {
|
protected void addContainerProperties() {
|
||||||
final LazyQueryContainer rolloutGroupGridContainer = (LazyQueryContainer) getContainerDataSource();
|
final LazyQueryContainer rolloutGroupGridContainer = (LazyQueryContainer) getContainerDataSource();
|
||||||
rolloutGroupGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", false, false);
|
rolloutGroupGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_NAME, String.class, "", false, false);
|
||||||
|
|
||||||
|
rolloutGroupGridContainer.addContainerProperty(ROLLOUT_RENDERER_DATA, RolloutRendererData.class, null, false,
|
||||||
|
false);
|
||||||
rolloutGroupGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, null, false, false);
|
rolloutGroupGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_DESC, String.class, null, false, false);
|
||||||
rolloutGroupGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_STATUS, RolloutGroupStatus.class, null,
|
rolloutGroupGridContainer.addContainerProperty(SPUILabelDefinitions.VAR_STATUS, RolloutGroupStatus.class, null,
|
||||||
false, false);
|
false, false);
|
||||||
@@ -145,8 +162,8 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setColumnExpandRatio() {
|
protected void setColumnExpandRatio() {
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setMinimumWidth(40);
|
getColumn(ROLLOUT_RENDERER_DATA).setMinimumWidth(40);
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setMaximumWidth(200);
|
getColumn(ROLLOUT_RENDERER_DATA).setMaximumWidth(200);
|
||||||
|
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setMinimumWidth(40);
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setMinimumWidth(40);
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setMaximumWidth(100);
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS).setMaximumWidth(100);
|
||||||
@@ -170,7 +187,7 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setColumnHeaderNames() {
|
protected void setColumnHeaderNames() {
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME).setHeaderCaption(i18n.get("header.name"));
|
getColumn(ROLLOUT_RENDERER_DATA).setHeaderCaption(i18n.get("header.name"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_STATUS).setHeaderCaption(i18n.get("header.status"));
|
getColumn(SPUILabelDefinitions.VAR_STATUS).setHeaderCaption(i18n.get("header.status"));
|
||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS)
|
||||||
.setHeaderCaption(i18n.get("header.detail.status"));
|
.setHeaderCaption(i18n.get("header.detail.status"));
|
||||||
@@ -196,7 +213,7 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
@Override
|
@Override
|
||||||
protected void setColumnProperties() {
|
protected void setColumnProperties() {
|
||||||
final List<Object> columnList = new ArrayList<>();
|
final List<Object> columnList = new ArrayList<>();
|
||||||
columnList.add(SPUILabelDefinitions.VAR_NAME);
|
columnList.add(ROLLOUT_RENDERER_DATA);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_STATUS);
|
columnList.add(SPUILabelDefinitions.VAR_STATUS);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS);
|
||||||
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS);
|
columnList.add(SPUILabelDefinitions.VAR_TOTAL_TARGETS);
|
||||||
@@ -221,14 +238,15 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setRenderer(new HtmlRenderer(),
|
getColumn(SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS).setRenderer(new HtmlRenderer(),
|
||||||
new TotalTargetCountStatusConverter());
|
new TotalTargetCountStatusConverter());
|
||||||
if (permissionChecker.hasRolloutTargetsReadPermission()) {
|
if (permissionChecker.hasRolloutTargetsReadPermission()) {
|
||||||
getColumn(SPUILabelDefinitions.VAR_NAME)
|
getColumn(ROLLOUT_RENDERER_DATA)
|
||||||
.setRenderer(new LinkRenderer(event -> onClickOfRolloutGroupName(event)));
|
.setRenderer(new RolloutRenderer(event -> onClickOfRolloutGroupName(event)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setHiddenColumns() {
|
protected void setHiddenColumns() {
|
||||||
final List<Object> columnsToBeHidden = new ArrayList<>();
|
final List<Object> columnsToBeHidden = new ArrayList<>();
|
||||||
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_NAME);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_DATE);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_CREATED_USER);
|
||||||
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_DATE);
|
columnsToBeHidden.add(SPUILabelDefinitions.VAR_MODIFIED_DATE);
|
||||||
@@ -268,8 +286,8 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
return cell.getProperty().getValue().toString().toLowerCase();
|
return cell.getProperty().getValue().toString().toLowerCase();
|
||||||
} else if (SPUILabelDefinitions.ACTION.equals(cell.getPropertyId())) {
|
} else if (SPUILabelDefinitions.ACTION.equals(cell.getPropertyId())) {
|
||||||
return SPUILabelDefinitions.ACTION.toLowerCase();
|
return SPUILabelDefinitions.ACTION.toLowerCase();
|
||||||
} else if (SPUILabelDefinitions.VAR_NAME.equals(cell.getPropertyId())) {
|
} else if (ROLLOUT_RENDERER_DATA.equals(cell.getPropertyId())) {
|
||||||
return cell.getProperty().getValue().toString();
|
return ((RolloutRendererData) cell.getProperty().getValue()).getName();
|
||||||
} else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) {
|
} else if (SPUILabelDefinitions.VAR_TOTAL_TARGETS_COUNT_STATUS.equals(cell.getPropertyId())) {
|
||||||
return DistributionBarHelper
|
return DistributionBarHelper
|
||||||
.getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap());
|
.getTooltip(((TotalTargetCountStatus) cell.getValue()).getStatusTotalCountMap());
|
||||||
@@ -306,14 +324,14 @@ public class RolloutGroupListGrid extends AbstractGrid {
|
|||||||
@Override
|
@Override
|
||||||
public TotalTargetCountStatus convertToModel(final String value,
|
public TotalTargetCountStatus convertToModel(final String value,
|
||||||
final Class<? extends TotalTargetCountStatus> targetType, final Locale locale)
|
final Class<? extends TotalTargetCountStatus> targetType, final Locale locale)
|
||||||
throws com.vaadin.data.util.converter.Converter.ConversionException {
|
throws com.vaadin.data.util.converter.Converter.ConversionException {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertToPresentation(final TotalTargetCountStatus value,
|
public String convertToPresentation(final TotalTargetCountStatus value,
|
||||||
final Class<? extends String> targetType, final Locale locale)
|
final Class<? extends String> targetType, final Locale locale)
|
||||||
throws com.vaadin.data.util.converter.Converter.ConversionException {
|
throws com.vaadin.data.util.converter.Converter.ConversionException {
|
||||||
return DistributionBarHelper.getDistributionBarAsHTMLString(value.getStatusTotalCountMap());
|
return DistributionBarHelper.getDistributionBarAsHTMLString(value.getStatusTotalCountMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ public class RolloutGroupsListHeader extends AbstractGridHeader {
|
|||||||
final HorizontalLayout headerCaptionLayout = new HorizontalLayout();
|
final HorizontalLayout headerCaptionLayout = new HorizontalLayout();
|
||||||
headerCaptionLayout.addComponent(rolloutsListViewLink);
|
headerCaptionLayout.addComponent(rolloutsListViewLink);
|
||||||
headerCaptionLayout.addComponent(new Label(">"));
|
headerCaptionLayout.addComponent(new Label(">"));
|
||||||
|
headerCaption.addStyleName("breadcrumbPaddingLeft");
|
||||||
headerCaptionLayout.addComponent(headerCaption);
|
headerCaptionLayout.addComponent(headerCaption);
|
||||||
|
|
||||||
return headerCaptionLayout;
|
return headerCaptionLayout;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.eclipse.hawkbit.repository.RolloutManagement;
|
|||||||
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
import org.eclipse.hawkbit.repository.model.RolloutGroup;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetWithActionStatus;
|
import org.eclipse.hawkbit.repository.model.TargetWithActionStatus;
|
||||||
|
import org.eclipse.hawkbit.ui.common.UserDetailsFormatter;
|
||||||
import org.eclipse.hawkbit.ui.components.ProxyTarget;
|
import org.eclipse.hawkbit.ui.components.ProxyTarget;
|
||||||
import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState;
|
import org.eclipse.hawkbit.ui.rollout.state.RolloutUIState;
|
||||||
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
|
||||||
@@ -105,8 +106,8 @@ public class RolloutGroupTargetsBeanQuery extends AbstractBeanQuery<ProxyTarget>
|
|||||||
prxyTarget.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(targ.getLastModifiedAt()));
|
prxyTarget.setLastModifiedDate(SPDateTimeUtil.getFormattedDate(targ.getLastModifiedAt()));
|
||||||
prxyTarget.setCreatedDate(SPDateTimeUtil.getFormattedDate(targ.getCreatedAt()));
|
prxyTarget.setCreatedDate(SPDateTimeUtil.getFormattedDate(targ.getCreatedAt()));
|
||||||
prxyTarget.setCreatedAt(targ.getCreatedAt());
|
prxyTarget.setCreatedAt(targ.getCreatedAt());
|
||||||
prxyTarget.setCreatedByUser(HawkbitCommonUtil.getIMUser(targ.getCreatedBy()));
|
prxyTarget.setCreatedByUser(UserDetailsFormatter.loadAndFormatCreatedBy(targ));
|
||||||
prxyTarget.setModifiedByUser(HawkbitCommonUtil.getIMUser(targ.getLastModifiedBy()));
|
prxyTarget.setModifiedByUser(UserDetailsFormatter.loadAndFormatLastModifiedBy(targ));
|
||||||
if (targetWithActionStatus.getStatus() != null) {
|
if (targetWithActionStatus.getStatus() != null) {
|
||||||
prxyTarget.setStatus(targetWithActionStatus.getStatus());
|
prxyTarget.setStatus(targetWithActionStatus.getStatus());
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user