Optimisation and bug fixing of UI push events (#310)

Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-10-17 21:59:53 +02:00
committed by GitHub
parent 43511ed63e
commit c7129e6ed7
114 changed files with 1743 additions and 1129 deletions

View File

@@ -11,8 +11,8 @@ package org.eclipse.hawkbit.app;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.hawkbit.ui.HawkbitUI;
import org.eclipse.hawkbit.ui.UIEventProvider;
import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy;
import org.eclipse.hawkbit.ui.push.UIEventProvider;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.eventbus.EventBus;

View File

@@ -177,8 +177,8 @@ public class DeviceSimulatorUpdater {
LOGGER.info("Simulate downloads for {}", device.getId());
modules.forEach(module -> module.getArtifacts()
.forEach(artifact -> handleArtifacts(targetToken, status, artifact)));
modules.forEach(
module -> module.getArtifacts().forEach(artifact -> handleArtifact(targetToken, status, artifact)));
final UpdateStatus result = new UpdateStatus(ResponseStatus.SUCCESSFUL);
result.getStatusMessages().add("Simulation complete!");
@@ -202,7 +202,7 @@ public class DeviceSimulatorUpdater {
return ResponseStatus.ERROR.equals(status.getResponseStatus());
}
private static void handleArtifacts(final String targetToken, final List<UpdateStatus> status,
private static void handleArtifact(final String targetToken, final List<UpdateStatus> status,
final Artifact artifact) {
if (artifact.getUrls().containsKey("HTTPS")) {

View File

@@ -32,22 +32,6 @@ public class SimulatedDeviceFactory {
@Autowired
private SpSenderService spSenderService;
/**
* Creating a simulated devices.
*
* @param id
* the ID of the simulated device
* @param tenant
* the tenant of the simulated device
* @param protocol
* the protocol of the device
* @return the created simulated device
*/
public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant,
final Protocol protocol) {
return createSimulatedDevice(id, tenant, protocol, 1800, null, null);
}
/**
* Creating a simulated device.
*
@@ -70,10 +54,19 @@ public class SimulatedDeviceFactory {
*/
public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol,
final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) {
return createSimulatedDevice(id, tenant, protocol, pollDelaySec, baseEndpoint, gatewayToken, false);
}
private AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol,
final int pollDelaySec, final URL baseEndpoint, final String gatewayToken, final boolean pollImmediatly) {
switch (protocol) {
case DMF_AMQP:
spSenderService.createOrUpdateThing(tenant, id);
return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec);
final AbstractSimulatedDevice device = new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec);
device.setNextPollCounterSec(pollDelaySec);
if (pollImmediatly) {
spSenderService.createOrUpdateThing(tenant, id);
}
return device;
case DDI_HTTP:
final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger())
.requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC)
@@ -83,4 +76,30 @@ public class SimulatedDeviceFactory {
throw new IllegalArgumentException("Protocol " + protocol + " unknown");
}
}
/**
* Creating a simulated device and send an immediate DMF poll to update
* server.
*
* @param id
* the ID of the simulated device
* @param tenant
* the tenant of the simulated device
* @param protocol
* the protocol which should be used be the simulated device
* @param pollDelaySec
* the poll delay time in seconds which should be used for
* {@link DDISimulatedDevice}s and {@link DMFSimulatedDevice}
* @param baseEndpoint
* the http base endpoint which should be used for
* {@link DDISimulatedDevice}s
* @param gatewayToken
* the gatewayToken to be used to authenticate
* {@link DDISimulatedDevice}s at the endpoint
* @return the created simulated device
*/
public AbstractSimulatedDevice createSimulatedDeviceWithImmediatePoll(final String id, final String tenant,
final Protocol protocol, final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) {
return createSimulatedDevice(id, tenant, protocol, pollDelaySec, baseEndpoint, gatewayToken, true);
}
}

View File

@@ -89,8 +89,8 @@ public class SimulationController {
for (int i = 0; i < amount; i++) {
final String deviceId = name + i;
repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint),
gatewayToken));
repository.add(deviceFactory.createSimulatedDeviceWithImmediatePoll(deviceId, tenant, protocol, pollDelay,
new URL(endpoint), gatewayToken));
}
return ResponseEntity.ok("Updated " + amount + " " + protocol + " connected targets!");

View File

@@ -48,9 +48,9 @@ public class SimulatorStartup implements ApplicationListener<ContextRefreshedEve
final String deviceId = autostart.getName() + i;
try {
if (amqpProperties.isEnabled()) {
repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(),
autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()),
autostart.getGatewayToken()));
repository.add(deviceFactory.createSimulatedDeviceWithImmediatePoll(deviceId,
autostart.getTenant(), autostart.getApi(), autostart.getPollDelay(),
new URL(autostart.getEndpoint()), autostart.getGatewayToken()));
}
} catch (final MalformedURLException e) {

View File

@@ -268,8 +268,9 @@ public class SimulatorView extends VerticalLayout implements View {
new GenerateDialog((namePrefix, tenant, amount, pollDelay, basePollUrl, gatewayToken, protocol) -> {
for (int index = 0; index < amount; index++) {
final String deviceId = namePrefix + index;
beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId,
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
beanContainer
.addBean(repository.add(deviceFactory.createSimulatedDeviceWithImmediatePoll(deviceId,
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
}
}, amqpProperties.isEnabled()));
}

View File

@@ -11,8 +11,8 @@ package org.eclipse.hawkbit.app;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.hawkbit.ui.HawkbitUI;
import org.eclipse.hawkbit.ui.UIEventProvider;
import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy;
import org.eclipse.hawkbit.ui.push.UIEventProvider;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.eventbus.EventBus;

View File

@@ -11,9 +11,11 @@ package org.eclipse.hawkbit.mgmt.client;
import org.eclipse.hawkbit.feign.core.client.FeignClientConfiguration;
import org.eclipse.hawkbit.feign.core.client.IgnoreMultipleConsumersProducersSpringMvcContract;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetTagClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtRolloutClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetTagClientResource;
import org.eclipse.hawkbit.mgmt.client.scenarios.ConfigurableScenario;
import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample;
import org.eclipse.hawkbit.mgmt.client.scenarios.upload.FeignMultipartEncoder;
@@ -27,7 +29,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.hateoas.hal.Jackson2HalModule;
@@ -43,7 +44,6 @@ import feign.slf4j.Slf4jLogger;
@SpringBootApplication
@EnableFeignClients("org.eclipse.hawkbit.mgmt.client.resource")
@EnableConfigurationProperties(ClientConfigurationProperties.class)
@Configuration
@AutoConfigureAfter(FeignClientConfiguration.class)
@Import(FeignClientConfiguration.class)
public class Application implements CommandLineRunner {
@@ -78,10 +78,12 @@ public class Application implements CommandLineRunner {
public ConfigurableScenario configurableScenario(final MgmtDistributionSetClientResource distributionSetResource,
final MgmtSoftwareModuleClientResource softwareModuleResource,
final MgmtTargetClientResource targetResource, final MgmtRolloutClientResource rolloutResource,
final MgmtTargetTagClientResource targetTagResource,
final MgmtDistributionSetTagClientResource distributionSetTagResource,
final ClientConfigurationProperties clientConfigurationProperties) {
return new ConfigurableScenario(distributionSetResource, softwareModuleResource,
uploadSoftwareModule(clientConfigurationProperties), targetResource, rolloutResource,
clientConfigurationProperties);
uploadSoftwareModule(clientConfigurationProperties), targetResource, rolloutResource, targetTagResource,
distributionSetTagResource, clientConfigurationProperties);
}
@Bean
@@ -89,8 +91,8 @@ public class Application implements CommandLineRunner {
return new CreateStartedRolloutExample();
}
@Bean
public MgmtSoftwareModuleClientResource uploadSoftwareModule(final ClientConfigurationProperties configuration) {
private static MgmtSoftwareModuleClientResource uploadSoftwareModule(
final ClientConfigurationProperties configuration) {
final ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new Jackson2HalModule());

View File

@@ -55,8 +55,19 @@ public class ClientConfigurationProperties {
private int artifactsPerSM = 1;
private String targetAddress = "amqp:/simulator.replyTo";
private boolean runRollouts = true;
private short rolloutSuccessThreshold = 80;
private int rolloutDeploymentGroups = 4;
/**
* Targets tags per page.
*/
private int targetTags;
/**
* Distribution Set tags per set
*/
private int dsTags = 5;
/**
* Artifact size. Values can use the suffixed "MB" or "KB" to indicate a
* Megabyte or Kilobyte size.
@@ -167,6 +178,30 @@ public class ClientConfigurationProperties {
this.appModulesPerDistributionSet = appModulesPerDistributionSet;
}
public void setTargetTags(final int targetTags) {
this.targetTags = targetTags;
}
public int getTargetTags() {
return targetTags;
}
public int getDsTags() {
return dsTags;
}
public void setDsTags(final int dsTags) {
this.dsTags = dsTags;
}
public short getRolloutSuccessThreshold() {
return rolloutSuccessThreshold;
}
public void setRolloutSuccessThreshold(final short rolloutSuccessThreshold) {
this.rolloutSuccessThreshold = rolloutSuccessThreshold;
}
}
public List<Scenario> getScenarios() {

View File

@@ -11,23 +11,31 @@ package org.eclipse.hawkbit.mgmt.client.scenarios;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties;
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetTagClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtRolloutClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetTagClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.RolloutBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.TagBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder;
import org.eclipse.hawkbit.mgmt.client.scenarios.upload.ArtifactFile;
import org.eclipse.hawkbit.mgmt.json.model.PagedList;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody;
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedDistributionSetRequestBody;
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtAssignedTargetRequestBody;
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -41,7 +49,7 @@ import org.slf4j.LoggerFactory;
*/
public class ConfigurableScenario {
private static final int PAGE_SIZE = 100;
private static final int PAGE_SIZE = 500;
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurableScenario.class);
@@ -51,22 +59,32 @@ public class ConfigurableScenario {
private final MgmtTargetClientResource targetResource;
private final MgmtTargetTagClientResource targetTagResource;
private final MgmtDistributionSetTagClientResource distributionSetTagResource;
private final MgmtRolloutClientResource rolloutResource;
private final ClientConfigurationProperties clientConfigurationProperties;
private final MgmtSoftwareModuleClientResource uploadSoftwareModule;
// Exception - squid:S00107 - this is a simulator that leverages multiple
// resouces/feign beans.
@SuppressWarnings("squid:S00107")
public ConfigurableScenario(final MgmtDistributionSetClientResource distributionSetResource,
final MgmtSoftwareModuleClientResource softwareModuleResource,
final MgmtSoftwareModuleClientResource uploadSoftwareModule, final MgmtTargetClientResource targetResource,
final MgmtRolloutClientResource rolloutResource,
final MgmtRolloutClientResource rolloutResource, final MgmtTargetTagClientResource targetTagResource,
final MgmtDistributionSetTagClientResource distributionSetTagResource,
final ClientConfigurationProperties clientConfigurationProperties) {
this.targetTagResource = targetTagResource;
this.distributionSetResource = distributionSetResource;
this.softwareModuleResource = softwareModuleResource;
this.uploadSoftwareModule = uploadSoftwareModule;
this.targetResource = targetResource;
this.rolloutResource = rolloutResource;
this.distributionSetTagResource = distributionSetTagResource;
this.clientConfigurationProperties = clientConfigurationProperties;
}
@@ -111,7 +129,8 @@ public class ConfigurableScenario {
PagedList<MgmtSoftwareModule> modules;
do {
modules = softwareModuleResource.getSoftwareModules(0, PAGE_SIZE, null, null).getBody();
modules.getContent().forEach(module -> softwareModuleResource.deleteSoftwareModule(module.getModuleId()));
modules.getContent().parallelStream()
.forEach(module -> softwareModuleResource.deleteSoftwareModule(module.getModuleId()));
} while (modules.getTotal() > PAGE_SIZE);
}
@@ -119,16 +138,40 @@ public class ConfigurableScenario {
PagedList<MgmtDistributionSet> distributionSets;
do {
distributionSets = distributionSetResource.getDistributionSets(0, PAGE_SIZE, null, null).getBody();
distributionSets.getContent().forEach(set -> distributionSetResource.deleteDistributionSet(set.getDsId()));
distributionSets.getContent().parallelStream()
.forEach(set -> distributionSetResource.deleteDistributionSet(set.getDsId()));
} while (distributionSets.getTotal() > PAGE_SIZE);
deleteDistributionSetTags();
}
private void deleteDistributionSetTags() {
PagedList<MgmtTag> dsTags;
do {
dsTags = distributionSetTagResource.getDistributionSetTags(0, PAGE_SIZE, null, null).getBody();
dsTags.getContent().parallelStream()
.forEach(ds -> distributionSetTagResource.deleteDistributionSetTag(ds.getTagId()));
} while (dsTags.getTotal() > PAGE_SIZE);
}
private void deleteTargets() {
PagedList<MgmtTarget> targets;
do {
targets = targetResource.getTargets(0, PAGE_SIZE, null, null).getBody();
targets.getContent().forEach(target -> targetResource.deleteTarget(target.getControllerId()));
targets.getContent().parallelStream()
.forEach(target -> targetResource.deleteTarget(target.getControllerId()));
} while (targets.getTotal() > PAGE_SIZE);
deleteTargetTags();
}
private void deleteTargetTags() {
PagedList<MgmtTag> targetTags;
do {
targetTags = targetTagResource.getTargetTags(0, PAGE_SIZE, null, null).getBody();
targetTags.getContent().parallelStream()
.forEach(target -> targetTagResource.deleteTargetTag(target.getTagId()));
} while (targetTags.getTotal() > PAGE_SIZE);
}
private void runRollouts(final Scenario scenario) {
@@ -140,10 +183,10 @@ public class ConfigurableScenario {
private void runRollout(final MgmtDistributionSet set, final Scenario scenario) {
LOGGER.info("Run rollout for set {}", set.getDsId());
// create a Rollout
final MgmtRolloutResponseBody rolloutResponseBody = rolloutResource
.create(new RolloutBuilder().name("Rollout" + set.getName() + set.getVersion())
.groupSize(scenario.getRolloutDeploymentGroups()).targetFilterQuery("name==*")
.distributionSetId(set.getDsId()).successThreshold("80").errorThreshold("5").build())
final MgmtRolloutResponseBody rolloutResponseBody = rolloutResource.create(new RolloutBuilder()
.name("Rollout" + set.getName() + set.getVersion()).groupSize(scenario.getRolloutDeploymentGroups())
.targetFilterQuery("name==*").distributionSetId(set.getDsId())
.successThreshold(String.valueOf(scenario.getRolloutSuccessThreshold())).errorThreshold("5").build())
.getBody();
// start the created Rollout
@@ -164,21 +207,44 @@ public class ConfigurableScenario {
private void createDistributionSets(final Scenario scenario) {
LOGGER.info("Creating {} distribution sets", scenario.getDistributionSets());
final byte[] artifact = generateArtifact(scenario);
distributionSetResource.createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName())
.type("os_app").version("1.0.").buildAsList(scenario.getDistributionSets())).getBody()
.forEach(dsSet -> {
final List<MgmtSoftwareModule> modules = addModules(scenario, dsSet, artifact);
final List<MgmtDistributionSet> sets = distributionSetResource
.createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app")
.version("1.0.").buildAsList(scenario.getDistributionSets()))
.getBody();
final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder();
modules.forEach(module -> assign.id(module.getModuleId()));
distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build());
});
assignSoftwareModulesTo(scenario, sets);
tagDistributionSets(scenario, sets);
LOGGER.info("Creating {} distribution sets -> Done", scenario.getDistributionSets());
}
private void tagDistributionSets(final Scenario scenario, final List<MgmtDistributionSet> sets) {
for (int i = 0; i < scenario.getDsTags(); i++) {
final MgmtTag tag = distributionSetTagResource
.createDistributionSetTags(
new TagBuilder().name("DS Tag" + i).description("DS tag for DS " + i).build())
.getBody().get(0);
distributionSetTagResource.assignDistributionSets(tag.getTagId(),
sets.stream().map(
set -> new MgmtAssignedDistributionSetRequestBody().setDistributionSetId(set.getDsId()))
.collect(Collectors.toList()));
}
}
private void assignSoftwareModulesTo(final Scenario scenario, final List<MgmtDistributionSet> sets) {
final byte[] artifact = generateArtifact(scenario);
sets.forEach(dsSet -> {
final List<MgmtSoftwareModule> modules = addModules(scenario, dsSet, artifact);
final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder();
modules.forEach(module -> assign.id(module.getModuleId()));
distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build());
});
}
private List<MgmtSoftwareModule> addModules(final Scenario scenario, final MgmtDistributionSet dsSet,
final byte[] artifact) {
final List<MgmtSoftwareModule> modules = softwareModuleResource
@@ -191,8 +257,10 @@ public class ConfigurableScenario {
.getBody());
for (int iArtifact = 0; iArtifact < scenario.getArtifactsPerSM(); iArtifact++) {
final int count = iArtifact;
modules.forEach(module -> {
final ArtifactFile file = new ArtifactFile("dummyfile.dummy", null, "multipart/form-data", artifact);
final ArtifactFile file = new ArtifactFile("dummyfile.dummy" + count, null, "multipart/form-data",
artifact);
uploadSoftwareModule.uploadArtifact(module.getModuleId(), file, null, null, null);
});
}
@@ -202,17 +270,44 @@ public class ConfigurableScenario {
private void createTargets(final Scenario scenario) {
LOGGER.info("Creating {} targets", scenario.getTargets());
for (int i = 0; i < (scenario.getTargets() / PAGE_SIZE); i++) {
targetResource.createTargets(
new TargetBuilder().controllerId(scenario.getTargetName()).address(scenario.getTargetAddress())
.buildAsList(i * PAGE_SIZE, (i + 1) * PAGE_SIZE > scenario.getTargets()
? (scenario.getTargets() - (i * PAGE_SIZE)) : PAGE_SIZE));
}
IntStream.range(0, scenario.getTargets() / PAGE_SIZE).parallel().forEach(i -> createTargetPage(scenario, i));
LOGGER.info("Creating {} targets -> Done", scenario.getTargets());
}
private void createTargetPage(final Scenario scenario, final int page) {
final List<MgmtTarget> targets = createTargets(scenario, page);
tagTargets(scenario, page, targets);
}
private List<MgmtTarget> createTargets(final Scenario scenario, final int page) {
return targetResource
.createTargets(
new TargetBuilder().controllerId(scenario.getTargetName()).address(scenario.getTargetAddress())
.buildAsList(calculateOffset(page),
(page + 1) * PAGE_SIZE > scenario.getTargets()
? (scenario.getTargets() - calculateOffset(page)) : PAGE_SIZE))
.getBody();
}
private void tagTargets(final Scenario scenario, final int page, final List<MgmtTarget> targets) {
if (scenario.getTargetTags() > 0) {
targetTagResource
.createTargetTags(new TagBuilder().name("Page " + page)
.description("Target tag for target page " + page).buildAsList(scenario.getTargetTags()))
.getBody().forEach(
tag -> targetTagResource.assignTargets(tag.getTagId(),
targets.stream()
.map(target -> new MgmtAssignedTargetRequestBody()
.setControllerId(target.getControllerId()))
.collect(Collectors.toList())));
}
}
private static int calculateOffset(final int page) {
return page * PAGE_SIZE;
}
private static int parseSize(final String s) {
final String size = s.toUpperCase();
if (size.endsWith("KB")) {

View File

@@ -11,7 +11,9 @@ hawkbit.url=http://localhost:8080
hawkbit.username=admin
hawkbit.password=admin
spring.main.show-banner=false
spring.main.banner-mode=off
feign.hystrix.enabled=false
hawkbit.scenarios.[0].cleanRepository=false
hawkbit.scenarios.[0].targets=0

View File

@@ -12,7 +12,7 @@
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="feign.Logger" level="debug" />
<logger name="org.eclipse.hawkbit.mgmt.client.resource" level="info" />
<Root level="INFO">
<appender-ref ref="CONSOLE" />

View File

@@ -9,8 +9,8 @@
package org.eclipse.hawkbit.autoconfigure.ui;
import org.eclipse.hawkbit.DistributedResourceBundleMessageSource;
import org.eclipse.hawkbit.ui.HawkbitEventProvider;
import org.eclipse.hawkbit.ui.UIEventProvider;
import org.eclipse.hawkbit.ui.push.HawkbitEventProvider;
import org.eclipse.hawkbit.ui.push.UIEventProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@@ -14,11 +14,17 @@ security.basic.realm=HawkBit
security.user.name=admin
security.user.password=admin
# JPA / Datasource
spring.jpa.eclipselink.eclipselink.weaving=false
### JPA / Datasource - START
spring.jpa.database=H2
spring.jpa.show-sql=false
spring.datasource.driverClassName=org.h2.Driver
# Logging
spring.datasource.eclipselink.logging.logger=JavaLogger
spring.jpa.properties.eclipselink.logging.level=off
# Cluster aware
spring.datasource.eclipselink.query-results-cache=false
spring.datasource.eclipselink.cache.shared.default=false
### JPA / Datasource - END
# MongoDB for artifact-repository
spring.data.mongodb.uri=mongodb://localhost/artifactrepo

View File

@@ -1,81 +0,0 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.eventbus.event;
import java.net.URI;
/**
* Event that gets sent when the assignment of a distribution set to a target
* gets canceled.
*
*
*
*/
public class CancelTargetAssignmentEvent extends DefaultEvent {
private final String controllerId;
private final Long actionId;
private final URI targetAdress;
/**
* Creates a new {@link CancelTargetAssignmentEvent}.
*
* @param revision
* the revision for this event
* @param tenant
* the tenant for this event
* @param controllerId
* the ID of the controller
* @param actionId
* the action id of the assignment
* @param targetAdress
* the targetAdress of the target
*/
public CancelTargetAssignmentEvent(final long revision, final String tenant, final String controllerId,
final Long actionId, final URI targetAdress) {
super(revision, tenant);
this.controllerId = controllerId;
this.actionId = actionId;
this.targetAdress = targetAdress;
}
/**
* @return the action id of the assignment
*/
public Long getActionId() {
return actionId;
}
/**
* @return the controllerId of the Target which has been assigned to the
* distribution set
*/
public String getControllerId() {
return controllerId;
}
/**
*
* @return the targetr adress.
*/
public URI getTargetAdress() {
return targetAdress;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "TargetAssignDistributionSetEvent [targetAdress=" + targetAdress + ", controllerId=" + controllerId
+ ", actionId=" + actionId + "]";
}
}

View File

@@ -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.eventbus.event;
/**
* The event when a target is deleted.
*/
public class TargetDeletedEvent extends AbstractDistributedEvent {
private static final long serialVersionUID = 1L;
private final long targetId;
/**
* @param tenant
* the tenant for this event
* @param targetId
* the ID of the target which has been deleted
*/
public TargetDeletedEvent(final String tenant, final long targetId) {
super(-1, tenant);
this.targetId = targetId;
}
/**
* @return the targetId
*/
public long getTargetId() {
return targetId;
}
}

View File

@@ -41,7 +41,6 @@ import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
import org.eclipse.hawkbit.rest.util.RestResourceConversionHelper;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
@@ -130,14 +129,6 @@ public class DdiRootController implements DdiRootControllerRestApi {
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(controllerId, IpUtil
.getClientIpFromRequest(requestResponseContextHolder.getHttpServletRequest(), securityProperties));
if (target.getTargetInfo().getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
LOG.debug("target with {} extsisted but was in status UNKNOWN -> REGISTERED)", controllerId);
controllerManagement.updateTargetStatus(target.getTargetInfo(), TargetUpdateStatus.REGISTERED,
System.currentTimeMillis(), IpUtil.getClientIpFromRequest(
requestResponseContextHolder.getHttpServletRequest(), securityProperties));
}
return new ResponseEntity<>(
DataConversionHelper.fromTarget(target, controllerManagement.findOldestActiveActionByTarget(target),
controllerManagement.getPollingTime(), tenantAware),

View File

@@ -48,6 +48,7 @@ import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import com.google.common.collect.Lists;
import com.jayway.jsonpath.JsonPath;
import ru.yandex.qatools.allure.annotations.Description;
@@ -934,13 +935,9 @@ public class DdiDeploymentBaseTest extends AbstractRestIntegrationTestWithMongoD
.accept(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isNotFound());
final List<Target> toAssign = new ArrayList<Target>();
toAssign.add(savedTarget);
final List<Target> toAssign2 = new ArrayList<Target>();
toAssign2.add(savedTarget2);
final List<Target> toAssign = Lists.newArrayList(savedTarget);
final List<Target> toAssign2 = Lists.newArrayList(savedTarget2);
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.UNKNOWN);
savedTarget = deploymentManagement.assignDistributionSet(savedSet, toAssign).getAssignedEntity().iterator()
.next();
deploymentManagement.assignDistributionSet(savedSet2, toAssign2);

View File

@@ -12,7 +12,7 @@
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<Logger name="org.eclipse.hawkbit.rest.util.MockMvcResultPrinter" level="DEBUG" />
<!-- <Logger name="org.eclipse.hawkbit.rest.util.MockMvcResultPrinter" level="DEBUG" /> -->
<Root level="INFO">
<appender-ref ref="CONSOLE" />

View File

@@ -26,8 +26,8 @@ import org.eclipse.hawkbit.dmf.json.model.ArtifactHash;
import org.eclipse.hawkbit.dmf.json.model.DownloadAndUpdateRequest;
import org.eclipse.hawkbit.dmf.json.model.SoftwareModule;
import org.eclipse.hawkbit.eventbus.EventSubscriber;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.Target;
@@ -125,12 +125,13 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
@Subscribe
public void targetCancelAssignmentToDistributionSet(
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent) {
final String controllerId = cancelTargetAssignmentDistributionSetEvent.getControllerId();
final String controllerId = cancelTargetAssignmentDistributionSetEvent.getTarget().getControllerId();
final Long actionId = cancelTargetAssignmentDistributionSetEvent.getActionId();
final Message message = getMessageConverter().toMessage(actionId, createConnectorMessageProperties(
cancelTargetAssignmentDistributionSetEvent.getTenant(), controllerId, EventTopic.CANCEL_DOWNLOAD));
amqpSenderService.sendMessage(message, cancelTargetAssignmentDistributionSetEvent.getTargetAdress());
amqpSenderService.sendMessage(message,
cancelTargetAssignmentDistributionSetEvent.getTarget().getTargetInfo().getAddress());
}

View File

@@ -21,12 +21,12 @@ import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.RepositoryConstants;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException;
@@ -194,8 +194,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
if (action.get().isCancelingOrCanceled()) {
amqpMessageDispatcherService.targetCancelAssignmentToDistributionSet(
new CancelTargetAssignmentEvent(target.getOptLockRevision(), target.getTenant(),
target.getControllerId(), action.get().getId(), target.getTargetInfo().getAddress()));
new CancelTargetAssignmentEvent(target, action.get().getId()));
return;
}
@@ -328,7 +327,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
// cancel action rejected, write warning status message and fall
// back to running action status
} else {
logAndThrowMessageError(message,
"Cancel recjected message is not allowed, if action is on state: " + action.getStatus());

View File

@@ -29,8 +29,8 @@ import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DownloadAndUpdateRequest;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.SystemManagement;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -202,10 +202,11 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
@Description("Verfies that send cancel event works")
public void testSendCancelRequest() {
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
1L, TENANT, CONTROLLER_ID, 1L, AMQP_URI);
testTarget, 1L);
amqpMessageDispatcherService
.targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent);
final Message sendMessage = createArgumentCapture(cancelTargetAssignmentDistributionSetEvent.getTargetAdress());
final Message sendMessage = createArgumentCapture(
cancelTargetAssignmentDistributionSetEvent.getTarget().getTargetInfo().getAddress());
assertCancelMessage(sendMessage);
}

View File

@@ -129,7 +129,7 @@ public interface MgmtDistributionSetTagRestApi {
* Handles the POST request to toggle the assignment of distribution sets by
* the given tag id.
*
* @param distributionsetTagIds
* @param distributionsetTagId
* the ID of the distribution set tag to retrieve
* @param assignedDSRequestBodies
* list of distribution set ids to be toggled

View File

@@ -127,7 +127,7 @@ public interface MgmtTargetTagRestApi {
* @param targetTagId
* the ID of the target tag to retrieve
* @param assignedTargetRequestBodies
* list of target ids to be toggled
* list of controller ids to be toggled
*
* @return the list of assigned targets and unassigned targets.
*/
@@ -143,7 +143,7 @@ public interface MgmtTargetTagRestApi {
* @param targetTagId
* the ID of the target tag to retrieve
* @param assignedTargetRequestBodies
* list of target ids to be assigned
* list of controller ids to be assigned
*
* @return the list of assigned targets.
*/

View File

@@ -427,7 +427,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].description", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].controllerId", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].updateStatus", contains("unknown")))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].updateStatus", contains("registered")))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].lastControllerRequestAt", notNullValue()))
// idB
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")]._links.self.href",
@@ -436,7 +436,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].description", contains(idB)))
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].controllerId", contains(idB)))
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].updateStatus", contains("unknown")))
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].updateStatus", contains("registered")))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].lastControllerRequestAt", notNullValue()))
// idC
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")]._links.self.href",
@@ -445,7 +445,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].description", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].controllerId", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].updateStatus", contains("unknown")))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].updateStatus", contains("registered")))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].lastControllerRequestAt", notNullValue()));
}
@@ -471,7 +471,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].description", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].controllerId", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].updateStatus", contains("unknown")));
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].updateStatus", contains("registered")));
}
@Test
@@ -500,7 +500,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].description", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].controllerId", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].updateStatus", contains("unknown")))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].updateStatus", contains("registered")))
// idB
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")]._links.self.href",
contains(linksHrefPrefix + idD)))
@@ -508,7 +508,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].description", contains(idD)))
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].controllerId", contains(idD)))
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].updateStatus", contains("unknown")))
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].updateStatus", contains("registered")))
// idC
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")]._links.self.href",
contains(linksHrefPrefix + idE)))
@@ -516,7 +516,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].description", contains(idE)))
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].controllerId", contains(idE)))
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].createdBy", contains("bumlux")))
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].updateStatus", contains("unknown")));
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].updateStatus", contains("registered")));
}
@Test

View File

@@ -23,7 +23,7 @@
<Logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR" />
<Logger name="org.eclipse.hawkbit.rest.util.MockMvcResultPrinter" level="DEBUG" />
<!-- <Logger name="org.eclipse.hawkbit.rest.util.MockMvcResultPrinter" level="DEBUG" /> -->
<!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" />

View File

@@ -187,13 +187,16 @@ public interface ArtifactManagement {
void deleteExternalArtifact(@NotNull Long id);
/**
* Deletes a local artifact.
* Garbage collects local artifact binary file if only referenced by given
* {@link LocalArtifact} metadata object.
*
* @param existing
* @param onlyByThisReferenced
* the related local artifact
*
* @return <code>true</code> if an binary was actually garbage collected
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
void deleteLocalArtifact(@NotNull LocalArtifact existing);
boolean clearLocalArtifactBinary(@NotNull LocalArtifact onlyByThisReferenced);
/**
* Deletes {@link Artifact} based on given id.

View File

@@ -255,7 +255,8 @@ public interface ControllerManagement {
/**
* Refreshes the time of the last time the controller has been connected to
* the server.
* the server. Switches {@link TargetUpdateStatus#UNKNOWN} to
* {@link TargetUpdateStatus#REGISTERED} if necessary.
*
* @param controllerId
* of the target to to update

View File

@@ -142,7 +142,7 @@ public interface RolloutGroupManagement {
@NotNull Pageable pageable);
/**
* Get count of targets in different status in rollout group.
* Get {@link RolloutGroup} by Id.
*
* @param rolloutGroupId
* rollout group id

View File

@@ -188,6 +188,15 @@ public interface TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET)
void deleteTargets(@NotEmpty Long... targetIDs);
/**
* Deletes all targets with the given IDs.
*
* @param targetIDs
* the technical IDs of the targets to be deleted
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET)
void deleteTargets(@NotEmpty Collection<Long> targetIDs);
/**
* finds all {@link Target#getControllerId()} which are currently in the
* database.

View File

@@ -1,70 +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.repository.eventbus.event;
import java.util.Arrays;
import java.util.List;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/**
*
* A abstract typesafe bulkevent which contains all changed base entities.
*
* @param <E>
*/
public abstract class AbstractEntityBulkEvent<E extends TenantAwareBaseEntity> implements EntityBulkEvent<E> {
private static final long serialVersionUID = 1L;
private List<E> entities;
private String tenant;
/**
* Constructor.
*
* @param tenant
* the tenant
* @param entities
* the changed entities
*/
public AbstractEntityBulkEvent(final String tenant, final List<E> entities) {
this.entities = entities;
this.tenant = tenant;
}
/**
* Constructor.
*
* @param tenant
* the tenant
* @param entitiy
* the changed entity
*/
public AbstractEntityBulkEvent(final String tenant, final E entitiy) {
this(tenant, Arrays.asList(entitiy));
}
@Override
public List<E> getEntities() {
return entities;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.Target;
/**
* Event that gets sent when the assignment of a distribution set to a target
* gets canceled.
*
*
*
*/
public class CancelTargetAssignmentEvent implements Event {
private final Target target;
private final Long actionId;
/**
* Creates a new {@link CancelTargetAssignmentEvent}.
*
* @param target
* entity
* @param actionId
* the action id of the assignment
*/
public CancelTargetAssignmentEvent(final Target target, final Long actionId) {
this.target = target;
this.actionId = actionId;
}
/**
* @return the action id of the assignment
*/
public Long getActionId() {
return actionId;
}
/**
* @return target where the action got canceled
*/
public Target getTarget() {
return target;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return target.getTenant();
}
}

View File

@@ -8,27 +8,43 @@
*/
package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
/**
* A event for assignment target tag.
*/
public class DistributionSetTagAssigmentResultEvent {
public class DistributionSetTagAssigmentResultEvent implements Event {
private final DistributionSetTagAssignmentResult assigmentResult;
private final String tenant;
/**
* Constructor.
*
* @param assigmentResult
* the assignment result-
* the assignment result
* @param tenant
* current
*/
public DistributionSetTagAssigmentResultEvent(final DistributionSetTagAssignmentResult assigmentResult) {
public DistributionSetTagAssigmentResultEvent(final DistributionSetTagAssignmentResult assigmentResult,
final String tenant) {
this.assigmentResult = assigmentResult;
this.tenant = tenant;
}
public DistributionSetTagAssignmentResult getAssigmentResult() {
return assigmentResult;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -1,46 +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.repository.eventbus.event;
import java.util.List;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* * A bulk event which contains one or many new ds tag after creating.
*/
public class DistributionSetTagCreatedBulkEvent extends AbstractEntityBulkEvent<DistributionSetTag> {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*
* @param tenant
* the tenant
* @param entities
* the new ds tags
*/
public DistributionSetTagCreatedBulkEvent(final String tenant, final List<DistributionSetTag> entities) {
super(tenant, entities);
}
/**
* Constructor.
*
* @param tenant
* the tenant.
* @param entity
* the new ds tag
*/
public DistributionSetTagCreatedBulkEvent(final String tenant, final DistributionSetTag entity) {
super(tenant, entity);
}
}

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} for creation of a new
* {@link DistributionSetTag}.
*
*/
public class DistributionSetTagCreatedEvent extends AbstractBaseEntityEvent<DistributionSetTag> {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*
* @param tag
* the tag which is updated
*/
public DistributionSetTagCreatedEvent(final DistributionSetTag tag) {
super(tag);
}
}

View File

@@ -1,35 +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.repository.eventbus.event;
import java.io.Serializable;
import java.util.List;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity;
/**
* An event interface which declares event types that an entities has been
* changed.
*
* @param <E>
* the entity type
*/
public interface EntityBulkEvent<E extends TenantAwareBaseEntity> extends Serializable, Event {
/**
* A typesafe way to retrieve the the entities from the event, which might
* be loaded lazy in case the event has been distributed from another node.
*
* @return the entities might be lazy loaded. Might be {@code null} in case
* the entity e.g. is queried lazy on a different node and has been
* already deleted from the database
*/
List<E> getEntities();
}

View File

@@ -8,22 +8,27 @@
*/
package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
/**
* A event for assignment target tag.
*/
public class TargetTagAssigmentResultEvent {
public class TargetTagAssigmentResultEvent implements Event {
private final TargetTagAssignmentResult assigmentResult;
private final String tenant;
/**
* Constructor.
*
* @param assigmentResult
* the assignment result-
* @param tenant
* current
*/
public TargetTagAssigmentResultEvent(final TargetTagAssignmentResult assigmentResult) {
public TargetTagAssigmentResultEvent(final TargetTagAssignmentResult assigmentResult, final String tenant) {
this.tenant = tenant;
this.assigmentResult = assigmentResult;
}
@@ -31,4 +36,14 @@ public class TargetTagAssigmentResultEvent {
return assigmentResult;
}
@Override
public long getRevision() {
return -1;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -1,46 +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.repository.eventbus.event;
import java.util.List;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* A bulk event which contains one or many new target tags after creating.
*/
public class TargetTagCreatedBulkEvent extends AbstractEntityBulkEvent<TargetTag> {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*
* @param tenant
* the tenant
* @param entities
* the new targets
*/
public TargetTagCreatedBulkEvent(final String tenant, final List<TargetTag> entities) {
super(tenant, entities);
}
/**
* Constructor.
*
* @param tenant
* the tenant
* @param entity
* one new target
*/
public TargetTagCreatedBulkEvent(final String tenant, final TargetTag entity) {
super(tenant, entity);
}
}

View File

@@ -0,0 +1,31 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.repository.model.TargetTag;
/**
* Defines the {@link AbstractBaseEntityEvent} for creation of a new
* {@link TargetTag}.
*
*/
public class TargetTagCreatedEvent extends AbstractBaseEntityEvent<TargetTag> {
private static final long serialVersionUID = 1L;
/**
* Constructor.
*
* @param tag
* the tag which has been created
*/
public TargetTagCreatedEvent(final TargetTag tag) {
super(tag);
}
}

View File

@@ -10,13 +10,16 @@ package org.eclipse.hawkbit.repository.model;
import java.util.List;
import org.eclipse.hawkbit.eventbus.event.Event;
/**
* Result object for {@link DistributionSetTag} assignments.
*
*/
public class DistributionSetTagAssignmentResult extends AssignmentResult<DistributionSet> {
public class DistributionSetTagAssignmentResult extends AssignmentResult<DistributionSet> implements Event {
private final DistributionSetTag distributionSetTag;
private final String tenant;
/**
* Constructor.
@@ -36,14 +39,24 @@ public class DistributionSetTagAssignmentResult extends AssignmentResult<Distrib
*/
public DistributionSetTagAssignmentResult(final int alreadyAssigned, final int assigned, final int unassigned,
final List<DistributionSet> assignedDs, final List<DistributionSet> unassignedDs,
final DistributionSetTag distributionSetTag) {
super(assigned, alreadyAssigned,unassigned, assignedDs, unassignedDs);
final DistributionSetTag distributionSetTag, final String tenant) {
super(assigned, alreadyAssigned, unassigned, assignedDs, unassignedDs);
this.distributionSetTag = distributionSetTag;
this.tenant = tenant;
}
public DistributionSetTag getDistributionSetTag() {
return distributionSetTag;
}
@Override
public long getRevision() {
return 0;
}
@Override
public String getTenant() {
return tenant;
}
}

View File

@@ -70,13 +70,13 @@ public interface Target extends NamedEntity {
* @return <code>true</code> if tag could be added sucessfully (i.e. was not
* already in the list).
*/
public boolean addTag(TargetTag tag);
boolean addTag(TargetTag tag);
/**
* @param tag
* to remove
* @return <code>true</code> if tag was in the list and removed
*/
public boolean removeTag(TargetTag tag);
boolean removeTag(TargetTag tag);
}

View File

@@ -207,15 +207,14 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Override
protected Map<String, Object> getVendorProperties() {
final Map<String, Object> properties = Maps.newHashMapWithExpectedSize(5);
final Map<String, Object> properties = Maps.newHashMapWithExpectedSize(4);
// Turn off dynamic weaving to disable LTW lookup in static weaving mode
properties.put("eclipselink.weaving", "false");
// needed for reports
properties.put("eclipselink.jdbc.allow-native-sql-queries", "true");
// flyway
properties.put("eclipselink.ddl-generation", "none");
properties.put("eclipselink.persistence-context.flush-mode", "auto");
// Embeed into hawkBit logging
properties.put("eclipselink.logging.logger", "JavaLogger");
return properties;

View File

@@ -8,7 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
@@ -60,15 +59,4 @@ public class EclipseLinkTargetInfoRepository implements TargetInfoRepository {
}
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
public void deleteByTargetIdIn(final Collection<Long> targetIDs) {
final javax.persistence.Query query = entityManager
.createQuery("DELETE FROM JpaTargetInfo ti where ti.targetId IN :target");
query.setParameter("target", targetIDs);
}
}

View File

@@ -150,28 +150,22 @@ public class JpaArtifactManagement implements ArtifactManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteLocalArtifact(final LocalArtifact existing) {
if (existing == null) {
return;
}
public boolean clearLocalArtifactBinary(final LocalArtifact existing) {
boolean artifactIsOnlyUsedByOneSoftwareModule = true;
for (final LocalArtifact lArtifact : localArtifactRepository
.findByGridFsFileName(((JpaLocalArtifact) existing).getGridFsFileName())) {
if (!lArtifact.getSoftwareModule().isDeleted()
&& Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) {
artifactIsOnlyUsedByOneSoftwareModule = false;
break;
return false;
}
}
if (artifactIsOnlyUsedByOneSoftwareModule) {
try {
LOG.debug("deleting artifact from repository {}", ((JpaLocalArtifact) existing).getGridFsFileName());
artifactRepository.deleteBySha1(((JpaLocalArtifact) existing).getGridFsFileName());
} catch (final ArtifactStoreException e) {
throw new ArtifactDeleteFailedException(e);
}
try {
LOG.debug("deleting artifact from repository {}", ((JpaLocalArtifact) existing).getGridFsFileName());
artifactRepository.deleteBySha1(((JpaLocalArtifact) existing).getGridFsFileName());
return true;
} catch (final ArtifactStoreException e) {
throw new ArtifactDeleteFailedException(e);
}
}
@@ -185,7 +179,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
return;
}
deleteLocalArtifact(existing);
clearLocalArtifactBinary(existing);
existing.getSoftwareModule().removeArtifact(existing);
softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule());

View File

@@ -225,6 +225,11 @@ public class JpaControllerManagement implements ControllerManagement {
if (address != null) {
mtargetInfo.setAddress(address.toString());
}
if (mtargetInfo.getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
mtargetInfo.setUpdateStatus(TargetUpdateStatus.REGISTERED);
}
return targetInfoRepository.save(mtargetInfo);
}

View File

@@ -28,11 +28,11 @@ import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Root;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
@@ -83,6 +83,7 @@ import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
@@ -353,17 +354,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return actionForTarget;
}
/**
* Sends the {@link TargetAssignDistributionSetEvent} for a specific target
* to the {@link EventBus}.
*
* @param target
* the Target which has been assigned to a distribution set
* @param actionId
* the action id of the assignment
* @param modules
* the software modules which have been assigned
*/
private void assignDistributionSetEvent(final JpaTarget target, final Long actionId,
final List<JpaSoftwareModule> modules) {
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
@@ -457,8 +447,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
* the action id of the assignment
*/
private void cancelAssignDistributionSetEvent(final Target target, final Long actionId) {
afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target.getOptLockRevision(),
target.getTenant(), target.getControllerId(), actionId, target.getTargetInfo().getAddress())));
afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target, actionId)));
}
@Override
@@ -517,7 +506,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_COMMITTED)
@Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public Action startScheduledAction(final Action action) {
final JpaAction mergedAction = (JpaAction) entityManager.merge(action);
@@ -618,7 +607,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return convertAcPage(actions, pageable);
}
private Specification<JpaAction> createSpecificationFor(final Target target, final String rsqlParam) {
private static Specification<JpaAction> createSpecificationFor(final Target target, final String rsqlParam) {
final Specification<JpaAction> spec = RSQLUtility.parse(rsqlParam, ActionFields.class);
return (root, query, cb) -> cb.and(spec.toPredicate(root, query, cb),
cb.equal(root.get(JpaAction_.target), target));

View File

@@ -142,15 +142,17 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
}
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0,
toBeChangedDSs.size(), Collections.emptyList(),
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag);
Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag,
tenantAware.getCurrentTenant());
} else {
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(),
0, Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)),
Collections.emptyList(), myTag);
Collections.emptyList(), myTag, tenantAware.getCurrentTenant());
}
final DistributionSetTagAssignmentResult resultAssignment = result;
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagAssigmentResultEvent(resultAssignment)));
afterCommit.afterCommit(() -> eventBus
.post(new DistributionSetTagAssigmentResultEvent(resultAssignment, tenantAware.getCurrentTenant())));
// no reason to persist the tag
entityManager.detach(myTag);
@@ -708,8 +710,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
afterCommit.afterCommit(() -> {
final DistributionSetTagAssignmentResult result = new DistributionSetTagAssignmentResult(0, save.size(), 0,
save, Collections.emptyList(), tag);
eventBus.post(new DistributionSetTagAssigmentResultEvent(result));
save, Collections.emptyList(), tag, tenantAware.getCurrentTenant());
eventBus.post(new DistributionSetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant()));
});
return save;

View File

@@ -243,7 +243,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) {
for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) {
artifactManagement.deleteLocalArtifact(localArtifact);
artifactManagement.clearLocalArtifactBinary(localArtifact);
}
}

View File

@@ -17,10 +17,10 @@ import java.util.List;
import org.eclipse.hawkbit.repository.TagFields;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
@@ -92,8 +92,7 @@ public class JpaTagManagement implements TagManagement {
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
afterCommit
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
afterCommit.afterCommit(() -> eventBus.post(new TargetTagCreatedEvent(save)));
return save;
}
@@ -112,8 +111,7 @@ public class JpaTagManagement implements TagManagement {
});
final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags));
afterCommit
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new TargetTagCreatedEvent(tag))));
return save;
}
@@ -195,8 +193,7 @@ public class JpaTagManagement implements TagManagement {
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit(
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagCreatedEvent(save)));
return save;
}
@@ -215,8 +212,7 @@ public class JpaTagManagement implements TagManagement {
}
final List<DistributionSetTag> save = Collections
.unmodifiableList(distributionSetTagRepository.save(distributionSetTags));
afterCommit.afterCommit(
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new DistributionSetTagCreatedEvent(tag))));
return save;
}

View File

@@ -202,19 +202,16 @@ public class JpaTargetManagement implements TargetManagement {
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargets(final Long... targetIDs) {
// we need to select the target IDs first to check the if the targetIDs
// belonging to the
// tenant! Delete statement are not automatically enhanced with the
// @FilterDef of the
// hibernate session.
final List<Long> targetsForCurrentTenant = targetRepository.findAll(Lists.newArrayList(targetIDs)).stream()
.map(Target::getId).collect(Collectors.toList());
if (!targetsForCurrentTenant.isEmpty()) {
targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant);
targetRepository.deleteByIdIn(targetsForCurrentTenant);
}
targetsForCurrentTenant
.forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId)));
deleteTargets(Lists.newArrayList(targetIDs));
}
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargets(final Collection<Long> targetIDs) {
targetRepository.deleteByIdIn(targetIDs);
targetIDs.forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId)));
}
@Override
@@ -348,7 +345,8 @@ public class JpaTargetManagement implements TargetManagement {
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(0, 0, alreadyAssignedTargets.size(),
Collections.emptyList(), alreadyAssignedTargets, tag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result)));
afterCommit.afterCommit(
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
return result;
}
@@ -359,7 +357,8 @@ public class JpaTargetManagement implements TargetManagement {
allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)),
Collections.emptyList(), tag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result)));
afterCommit.afterCommit(
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
// no reason to persist the tag
entityManager.detach(tag);
@@ -369,9 +368,9 @@ public class JpaTargetManagement implements TargetManagement {
@Override
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
public List<Target> assignTag(final Collection<String> targetIds, final TargetTag tag) {
public List<Target> assignTag(final Collection<String> controllerIds, final TargetTag tag) {
final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds));
allTargets.forEach(target -> target.addTag(tag));
final List<Target> save = Collections.unmodifiableList(targetRepository.save(allTargets));
@@ -379,7 +378,7 @@ public class JpaTargetManagement implements TargetManagement {
afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save,
Collections.emptyList(), tag);
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult));
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
});
return save;
@@ -395,7 +394,7 @@ public class JpaTargetManagement implements TargetManagement {
afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(),
Collections.emptyList(), save, tag);
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult));
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
});
return save;
}
@@ -563,8 +562,8 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull Pageable pageRequest,
Long distributionSetId, @NotNull TargetFilterQuery targetFilterQuery) {
public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull final Pageable pageRequest,
final Long distributionSetId, @NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
@@ -577,7 +576,8 @@ public class JpaTargetManagement implements TargetManagement {
}
@Override
public Long countTargetsByTargetFilterQueryAndNonDS(Long distributionSetId, @NotNull TargetFilterQuery targetFilterQuery) {
public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId,
@NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class);
final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
specList.add(spec);

View File

@@ -8,8 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Optional;
import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.report.model.TenantUsage;
import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -46,15 +44,8 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
final TenantUsage result = new TenantUsage(tenant);
result.setTargets(targetRepository.count());
final Long artifacts = artifactRepository.countBySoftwareModuleDeleted(false);
result.setArtifacts(artifacts);
final Optional<Long> artifactsSize = artifactRepository.getSumOfUndeletedArtifactSize();
if (artifactsSize.isPresent()) {
result.setOverallArtifactVolumeInBytes(artifactsSize.get());
}
result.setArtifacts(artifactRepository.countBySoftwareModuleDeleted(false));
artifactRepository.getSumOfUndeletedArtifactSize().map(result::setOverallArtifactVolumeInBytes);
result.setActions(actionRepository.count());
return result;

View File

@@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation;
@@ -107,6 +108,20 @@ public interface RolloutGroupRepository
*/
List<JpaRolloutGroup> findByParentAndStatus(JpaRolloutGroup rolloutGroup, RolloutGroupStatus status);
/**
* Updates all {@link RolloutGroup#getStatus()} of children for given
* parent.
*
* @param parent
* the parent rolloutgroup
* @param status
* the status of the rolloutgroups
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@Query("UPDATE JpaRolloutGroup g SET g.status = :status WHERE g.parent = :parent")
void setStatusForCildren(@Param("status") RolloutGroupStatus status, @Param("parent") RolloutGroup parent);
/**
* Retrieves all {@link RolloutGroup} for a specific rollout and status not
* having ordered by ID DESC, latest top.

View File

@@ -62,7 +62,10 @@ public interface RolloutRepository
List<JpaRollout> findByLastCheckAndStatus(long lastCheck, RolloutStatus status);
/**
* Retrieves all {@link Rollout} for a specific {@code name}
* Retrieves all {@link Rollout} for a specific {@code name}.
*
* @param pageable
* for paging information
*
* @param name
* the rollout name

View File

@@ -8,7 +8,6 @@
*/
package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List;
import javax.persistence.Entity;
@@ -56,15 +55,4 @@ public interface TargetInfoRepository {
*/
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends JpaTargetInfo> S save(S entity);
/**
* Deletes info entries by ID.
*
* @param targetIDs
* to delete
*/
@Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
void deleteByTargetIdIn(final Collection<Long> targetIDs);
}

View File

@@ -68,6 +68,7 @@ public interface TargetRepository extends BaseEntityRepository<JpaTarget, Long>,
@Transactional(isolation = Isolation.READ_UNCOMMITTED)
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM JpaTarget t WHERE t.id IN ?1")
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
void deleteByIdIn(final Collection<Long> targetIDs);
/**

View File

@@ -181,7 +181,8 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
@Override
public String toString() {
return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]";
return "JpaAction [distributionSet=" + distributionSet.getId() + ", version=" + getOptLockRevision() + ", id="
+ getId() + "]";
}
@Override

View File

@@ -78,12 +78,14 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Column(name = "required_migration_step")
private boolean requiredMigrationStep;
@CascadeOnDelete
@ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY)
@JoinTable(name = "sp_ds_module", joinColumns = {
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = {
@JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) })
private Set<SoftwareModule> modules;
@CascadeOnDelete
@ManyToMany(targetEntity = JpaDistributionSetTag.class)
@JoinTable(name = "sp_ds_dstag", joinColumns = {
@JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = {
@@ -276,9 +278,8 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count();
if (allready >= softwareModule.getType().getMaxAssignments()) {
final Optional<SoftwareModule> sameKey = modules.stream()
.filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst();
modules.remove(sameKey.get());
modules.stream().filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey()))
.findFirst().map(modules::remove);
}
if (modules.add(softwareModule)) {
@@ -326,14 +327,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return null;
}
final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type))
.findFirst();
if (result.isPresent()) {
return result.get();
}
return null;
return modules.stream().filter(module -> module.getType().equals(type)).findFirst().orElse(null);
}
@Override

View File

@@ -76,9 +76,11 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
@Size(max = 256)
private String vendor;
@CascadeOnDelete
@OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = JpaLocalArtifact.class)
private List<LocalArtifact> artifacts;
@CascadeOnDelete
@OneToMany(mappedBy = "softwareModule", cascade = { CascadeType.ALL }, targetEntity = JpaExternalArtifact.class)
private List<ExternalArtifact> externalArtifacts;

View File

@@ -82,6 +82,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@Transient
private boolean entityNew;
@CascadeOnDelete
@ManyToMany(targetEntity = JpaTargetTag.class)
@JoinTable(name = "sp_target_target_tag", joinColumns = {
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = {

View File

@@ -111,12 +111,12 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareE
/**
* Read only on management API. Are commited by controller.
*/
@CascadeOnDelete
@ElementCollection
@Column(name = "attribute_value", length = 128)
@MapKeyColumn(name = "attribute_key", nullable = false, length = 32)
@CollectionTable(name = "sp_target_attributes", joinColumns = {
@JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target"))
private final Map<String, String> controllerAttributes = Collections.synchronizedMap(new HashMap<String, String>());
// set default request controller attributes to true, because we want to

View File

@@ -61,7 +61,9 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi
rolloutGroup, Action.Status.SCHEDULED);
logger.debug("{} Next actions to start for rollout {} and parent group {}", rolloutGroupActions.size(), rollout,
rolloutGroup);
rolloutGroupActions.forEach(action -> deploymentManagement.startScheduledAction(action));
rolloutGroupActions.forEach(deploymentManagement::startScheduledAction);
logger.debug("{} actions started for rollout {} and parent group {}", rolloutGroupActions.size(), rollout,
rolloutGroup);
if (!rolloutGroupActions.isEmpty()) {
// get all next scheduled groups based on the found actions and set
// them in state running

View File

@@ -0,0 +1,27 @@
alter table sp_ds_module drop constraint fk_ds_module_ds;
alter table sp_ds_module
add constraint fk_ds_module_ds
foreign key (ds_id)
references sp_distribution_set (id)
on delete cascade;
alter table sp_ds_module drop constraint fk_ds_module_module;
alter table sp_ds_module
add constraint fk_ds_module_module
foreign key (module_id)
references sp_base_software_module (id)
on delete cascade;
alter table sp_external_artifact drop constraint fk_external_assigned_sm;
alter table sp_external_artifact
add constraint fk_external_assigned_sm
foreign key (software_module)
references sp_base_software_module (id)
on delete cascade;
alter table sp_artifact drop constraint fk_assigned_sm;
alter table sp_artifact
add constraint fk_assigned_sm
foreign key (software_module)
references sp_base_software_module (id)
on delete cascade;

View File

@@ -0,0 +1,27 @@
alter table sp_ds_module drop FOREIGN KEY fk_ds_module_ds;
alter table sp_ds_module
add constraint fk_ds_module_ds
foreign key (ds_id)
references sp_distribution_set (id)
on delete cascade;
alter table sp_ds_module drop FOREIGN KEY fk_ds_module_module;
alter table sp_ds_module
add constraint fk_ds_module_module
foreign key (module_id)
references sp_base_software_module (id)
on delete cascade;
alter table sp_external_artifact drop FOREIGN KEY fk_external_assigned_sm;
alter table sp_external_artifact
add constraint fk_external_assigned_sm
foreign key (software_module)
references sp_base_software_module (id)
on delete cascade;
alter table sp_artifact drop FOREIGN KEY fk_assigned_sm;
alter table sp_artifact
add constraint fk_assigned_sm
foreign key (software_module)
references sp_base_software_module (id)
on delete cascade;

View File

@@ -21,9 +21,9 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.ActionStatusFields;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException;

View File

@@ -1,68 +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;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
/**
* The default hawkbit event provider.
*/
public class HawkbitEventProvider implements UIEventProvider {
private static final Set<Class<? extends Event>> SINGLE_EVENTS = new HashSet<>(9);
private static final Set<Class<? extends Event>> BULK_EVENTS = new HashSet<>(5);
static {
SINGLE_EVENTS.add(TargetTagCreatedBulkEvent.class);
SINGLE_EVENTS.add(DistributionSetTagCreatedBulkEvent.class);
SINGLE_EVENTS.add(DistributionSetTagDeletedEvent.class);
SINGLE_EVENTS.add(TargetTagDeletedEvent.class);
SINGLE_EVENTS.add(DistributionSetTagUpdateEvent.class);
SINGLE_EVENTS.add(RolloutGroupChangeEvent.class);
SINGLE_EVENTS.add(RolloutChangeEvent.class);
SINGLE_EVENTS.add(TargetTagUpdateEvent.class);
SINGLE_EVENTS.add(DistributionSetUpdateEvent.class);
BULK_EVENTS.add(TargetCreatedEvent.class);
BULK_EVENTS.add(TargetInfoUpdateEvent.class);
BULK_EVENTS.add(TargetDeletedEvent.class);
BULK_EVENTS.add(DistributionDeletedEvent.class);
BULK_EVENTS.add(DistributionCreatedEvent.class);
BULK_EVENTS.add(TargetUpdatedEvent.class);
}
@Override
public Set<Class<? extends Event>> getSingleEvents() {
return SINGLE_EVENTS;
}
@Override
public Set<Class<? extends Event>> getBulkEvents() {
return BULK_EVENTS;
}
}

View File

@@ -1,60 +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;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.eventbus.event.Event;
/**
* The UI event provider hold all supported repository events which will
* delegated to the UI. A event type can delegated as single event or bulk
* event. Bulk event means, that all events from one type is collected by the
* provider. The delegater and delegated as a list of this events.
*/
public interface UIEventProvider {
/**
* Return all supported repository single event types. All events which this
* type are delegated to the UI as single event.
*
* @return list of provided event types. Should not be null
*/
default Set<Class<? extends Event>> getSingleEvents() {
return Collections.emptySet();
}
/**
* Return all supported repository bulk event types. All events which this
* type are delegated to the UI as a list. This list contains all collected
* events from one type.
*
* @return list of provided bulk event types. Should not be null
*/
default Set<Class<? extends Event>> getBulkEvents() {
return Collections.emptySet();
}
/**
* Return all filtered bulk event types by the given events. The default
* maps the events by class.
*
* @param allEvents
* the events
* @return list of provided bulk event types which are filtered. Should not
* be null
*/
default Set<Class<?>> getFilteredBulkEventsType(final List<Event> allEvents) {
return allEvents.stream().map(Event::getClass).filter(getBulkEvents()::contains).collect(Collectors.toSet());
}
}

View File

@@ -32,10 +32,10 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -146,11 +146,10 @@ public class ArtifactDetailsLayout extends VerticalLayout {
}
private void createComponents() {
String labelStr = "";
if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) {
final SoftwareModule softwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get();
labelStr = HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion());
}
final String labelStr = artifactUploadState.getSelectedBaseSoftwareModule()
.map(softwareModule -> HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(),
softwareModule.getVersion()))
.orElse("");
titleOfArtifactDetails = new LabelBuilder().name(HawkbitCommonUtil.getArtifactoryDetailsLabelId(labelStr))
.buildCaptionLabel();
titleOfArtifactDetails.setContentMode(ContentMode.HTML);

View File

@@ -19,13 +19,13 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
@@ -39,7 +39,7 @@ import com.vaadin.ui.themes.ValoTheme;
*/
@SpringComponent
@VaadinSessionScope
@ViewScope
public class DistributionSetMetadatadetailslayout extends Table {
private static final long serialVersionUID = 2913758299611837718L;

View File

@@ -13,6 +13,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@@ -112,7 +113,7 @@ public abstract class AbstractTable<E extends NamedEntity, I> extends Table {
if (values == null) {
values = Collections.emptySet();
}
return values;
return values.stream().filter(item -> item != null).collect(Collectors.toSet());
}
private void onValueChange() {

View File

@@ -50,6 +50,8 @@ import com.vaadin.ui.themes.ValoTheme;
*/
public abstract class AbstractTagToken<T extends BaseEntity> implements Serializable {
private static final String ID_PROPERTY = "id";
private static final String NAME_PROPERTY = "name";
private static final String COLOR_PROPERTY = "color";
private static final long serialVersionUID = 6599386705285184783L;
@@ -120,7 +122,7 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
tokenField.setImmediate(true);
tokenField.addStyleName(ValoTheme.COMBOBOX_TINY);
tokenField.setSizeFull();
tokenField.setTokenCaptionPropertyId("name");
tokenField.setTokenCaptionPropertyId(NAME_PROPERTY);
}
protected void repopulateToken() {
@@ -130,8 +132,8 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
private Container createContainer() {
container = new IndexedContainer();
container.addContainerProperty("name", String.class, "");
container.addContainerProperty("id", Long.class, "");
container.addContainerProperty(NAME_PROPERTY, String.class, "");
container.addContainerProperty(ID_PROPERTY, Long.class, "");
container.addContainerProperty(COLOR_PROPERTY, String.class, "");
return container;
}
@@ -142,7 +144,13 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
}
private void removeTagAssignedFromCombo(final Long tagId) {
tokensAdded.put(tagId, new TagData(tagId, getTagName(tagId), getColor(tagId)));
// might not yet exist or not anymore due to unprocessed events
final Item item = tokenField.getContainerDataSource().getItem(tagId);
if (item == null) {
return;
}
tokensAdded.put(tagId, new TagData(tagId, getTagName(item), getColor(item)));
container.removeItem(tagId);
}
@@ -150,13 +158,17 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
final TagData tagData = tagDetails.putIfAbsent(tagId, new TagData(tagId, tagName, tagColor));
if (tagData == null) {
final Item item = container.addItem(tagId);
item.getItemProperty("id").setValue(tagId);
if (item == null) {
return;
}
item.getItemProperty(ID_PROPERTY).setValue(tagId);
updateItem(tagName, tagColor, item);
}
}
protected void updateItem(final String tagName, final String tagColor, final Item item) {
item.getItemProperty("name").setValue(tagName);
item.getItemProperty(NAME_PROPERTY).setValue(tagName);
item.getItemProperty(COLOR_PROPERTY).setValue(tagColor);
}
@@ -202,7 +214,12 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
}
private void updateTokenStyle(final Object tokenId, final Button button) {
final String color = getColor(tokenId);
final Item item = tokenField.getContainerDataSource().getItem(tokenId);
if (item == null) {
return;
}
final String color = getColor(item);
button.setCaption("<span style=\"color:" + color + " !important;\">" + FontAwesome.CIRCLE.getHtml()
+ "</span>" + " " + getItemNameProperty(tokenId).getValue().toString().concat(" ×"));
button.setCaptionAsHtml(true);
@@ -215,20 +232,19 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
private void tokenClick(final Object tokenId) {
final Item item = tokenField.getContainerDataSource().addItem(tokenId);
item.getItemProperty("name").setValue(tagDetails.get(tokenId).getName());
item.getItemProperty(NAME_PROPERTY).setValue(tagDetails.get(tokenId).getName());
item.getItemProperty(COLOR_PROPERTY).setValue(tagDetails.get(tokenId).getColor());
unassignTag(tagDetails.get(tokenId).getName());
}
private Property getItemNameProperty(final Object tokenId) {
final Item item = tokenField.getContainerDataSource().getItem(tokenId);
return item.getItemProperty("name");
return item.getItemProperty(NAME_PROPERTY);
}
}
private String getColor(final Object tokenId) {
final Item item = tokenField.getContainerDataSource().getItem(tokenId);
private static String getColor(final Item item) {
if (item.getItemProperty(COLOR_PROPERTY).getValue() != null) {
return (String) item.getItemProperty(COLOR_PROPERTY).getValue();
} else {
@@ -236,9 +252,8 @@ public abstract class AbstractTagToken<T extends BaseEntity> implements Serializ
}
}
private String getTagName(final Object tokenId) {
final Item item = tokenField.getContainerDataSource().getItem(tokenId);
return (String) item.getItemProperty("name").getValue();
private static String getTagName(final Item item) {
return (String) item.getItemProperty(NAME_PROPERTY).getValue();
}
protected void removePreviouslyAddedTokens() {

View File

@@ -8,15 +8,19 @@
*/
package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.List;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.BaseEntity;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.ui.push.TargetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetTagDeletedEventContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.data.Item;
/**
* /** Abstract class for target tag token layout.
*
@@ -31,16 +35,25 @@ public abstract class AbstractTargetTagToken<T extends BaseEntity> extends Abstr
protected transient TagManagement tagManagement;
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
for (final TargetTag tag : event.getEntities()) {
setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour());
}
void onEventTargetTagCreated(final TargetTagCreatedEventContainer container) {
container.getEvents().stream().map(event -> event.getEntity())
.forEach(tag -> setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()));
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetDeletedEvent(final TargetTagDeletedEvent event) {
final Long deletedTagId = getTagIdByTagName(event.getEntity().getName());
removeTagFromCombo(deletedTagId);
void onTargetTagDeletedEvent(final TargetTagDeletedEventContainer container) {
container.getEvents().stream().map(event -> getTagIdByTagName(event.getEntity().getName()))
.forEach(this::removeTagFromCombo);
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetTagUpdateEvent(final List<TargetTagUpdateEvent> events) {
events.stream().map(event -> event.getEntity()).forEach(entity -> {
final Item item = container.getItem(entity.getId());
if (item != null) {
updateItem(entity.getName(), entity.getColour(), item);
}
});
}
}

View File

@@ -8,27 +8,26 @@
*/
package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.TagManagement;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.push.DistributionSetTagAssignmentResultEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.collect.Sets;
import com.vaadin.data.Item;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
@@ -74,10 +73,8 @@ public class DistributionTagToken extends AbstractTagToken<DistributionSet> {
}
private DistributionSetTagAssignmentResult toggleAssignment(final String tagNameSelected) {
final Set<Long> distributionList = new HashSet<>();
distributionList.add(selectedEntity.getId());
final DistributionSetTagAssignmentResult result = distributionSetManagement
.toggleTagAssignment(distributionList, tagNameSelected);
.toggleTagAssignment(Sets.newHashSet(selectedEntity.getId()), tagNameSelected);
uinotification.displaySuccess(HawkbitCommonUtil.createAssignmentMessage(tagNameSelected, result, i18n));
return result;
}
@@ -120,42 +117,42 @@ public class DistributionTagToken extends AbstractTagToken<DistributionSet> {
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
for (final DistributionSetTag distributionSetTag : event.getEntities()) {
setContainerPropertValues(distributionSetTag.getId(), distributionSetTag.getName(),
distributionSetTag.getColour());
}
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedEventContainer eventContainer) {
eventContainer.getEvents().stream().map(event -> event.getEntity())
.forEach(distributionSetTag -> setContainerPropertValues(distributionSetTag.getId(),
distributionSetTag.getName(), distributionSetTag.getColour()));
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onDistributionSetTagDeletedEventBulkEvent(final DistributionSetTagDeletedEvent event) {
final Long deletedTagId = getTagIdByTagName(event.getEntity().getName());
removeTagFromCombo(deletedTagId);
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEventContainer eventContainer) {
eventContainer.getEvents().stream().map(event -> getTagIdByTagName(event.getEntity().getName()))
.forEach(this::removeTagFromCombo);
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
final DistributionSetTag entity = event.getEntity();
final Item item = container.getItem(entity.getId());
if (item != null) {
updateItem(entity.getName(), entity.getColour(), item);
}
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdatedEventContainer eventContainer) {
eventContainer.getEvents().stream().map(event -> event.getEntity()).forEach(entity -> {
final Item item = container.getItem(entity.getId());
if (item != null) {
updateItem(entity.getName(), entity.getColour(), item);
}
});
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetTagAssigmentResultEvent(final DistributionSetTagAssigmentResultEvent event) {
final DistributionSetTagAssignmentResult assignmentResult = event.getAssigmentResult();
final DistributionSetTag tag = assignmentResult.getDistributionSetTag();
if (isAssign(assignmentResult)) {
addNewToken(tag.getId());
} else if (isUnassign(assignmentResult)) {
removeTokenItem(tag.getId(), tag.getName());
}
void onTargetTagAssigmentResultEvent(final DistributionSetTagAssignmentResultEventContainer eventContainer) {
eventContainer.getEvents().stream().map(event -> event.getAssigmentResult()).forEach(assignmentResult -> {
final DistributionSetTag tag = assignmentResult.getDistributionSetTag();
if (isAssign(assignmentResult)) {
addNewToken(tag.getId());
} else if (isUnassign(assignmentResult)) {
removeTokenItem(tag.getId(), tag.getName());
}
});
}
protected boolean isAssign(final DistributionSetTagAssignmentResult assignmentResult) {
if (assignmentResult.getAssigned() > 0) {
if (assignmentResult.getAssigned() > 0 && managementUIState.getLastSelectedDsIdName() != null) {
final List<Long> assignedDsNames = assignmentResult.getAssignedEntity().stream().map(t -> t.getId())
.collect(Collectors.toList());
if (assignedDsNames.contains(managementUIState.getLastSelectedDsIdName().getId())) {
@@ -166,7 +163,7 @@ public class DistributionTagToken extends AbstractTagToken<DistributionSet> {
}
protected boolean isUnassign(final DistributionSetTagAssignmentResult assignmentResult) {
if (assignmentResult.getUnassigned() > 0) {
if (assignmentResult.getUnassigned() > 0 && managementUIState.getLastSelectedDsIdName() != null) {
final List<Long> assignedDsNames = assignmentResult.getUnassignedEntity().stream().map(t -> t.getId())
.collect(Collectors.toList());
if (assignedDsNames.contains(managementUIState.getLastSelectedDsIdName().getId())) {

View File

@@ -9,24 +9,20 @@
package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.push.TargetTagAssigmentResultEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.data.Item;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
@@ -110,44 +106,32 @@ public class TargetTagToken extends AbstractTargetTagToken<Target> {
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetTagUpdateEvent(final TargetTagUpdateEvent event) {
final TargetTag entity = event.getEntity();
final Item item = container.getItem(entity.getId());
if (item != null) {
updateItem(entity.getName(), entity.getColour(), item);
}
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetTagAssigmentResultEvent(final TargetTagAssigmentResultEvent event) {
final TargetTagAssignmentResult assignmentResult = event.getAssigmentResult();
final TargetTag targetTag = assignmentResult.getTargetTag();
if (isAssign(assignmentResult)) {
addNewToken(targetTag.getId());
} else if (isUnassign(assignmentResult)) {
removeTokenItem(targetTag.getId(), targetTag.getName());
}
void onTargetTagAssigmentResultEvent(final TargetTagAssigmentResultEventContainer holder) {
holder.getEvents().stream().map(event -> event.getAssigmentResult()).forEach(assignmentResult -> {
final TargetTag targetTag = assignmentResult.getTargetTag();
if (isAssign(assignmentResult)) {
addNewToken(targetTag.getId());
} else if (isUnassign(assignmentResult)) {
removeTokenItem(targetTag.getId(), targetTag.getName());
}
});
}
protected boolean isAssign(final TargetTagAssignmentResult assignmentResult) {
if (assignmentResult.getAssigned() > 0) {
final List<String> assignedTargetNames = assignmentResult.getAssignedEntity().stream()
.map(t -> t.getControllerId()).collect(Collectors.toList());
if (assignedTargetNames.contains(managementUIState.getLastSelectedTargetIdName().getControllerId())) {
return true;
}
if (assignmentResult.getAssigned() > 0 && managementUIState.getLastSelectedTargetIdName() != null) {
return assignmentResult.getAssignedEntity().stream().map(t -> t.getControllerId())
.anyMatch(controllerId -> controllerId
.equals(managementUIState.getLastSelectedTargetIdName().getControllerId()));
}
return false;
}
protected boolean isUnassign(final TargetTagAssignmentResult assignmentResult) {
if (assignmentResult.getUnassigned() > 0) {
final List<String> unassignedTargetNamesList = assignmentResult.getUnassignedEntity().stream()
.map(t -> t.getControllerId()).collect(Collectors.toList());
if (unassignedTargetNamesList.contains(managementUIState.getLastSelectedTargetIdName().getControllerId())) {
return true;
}
if (assignmentResult.getUnassigned() > 0 && managementUIState.getLastSelectedTargetIdName() != null) {
return assignmentResult.getUnassignedEntity().stream().map(t -> t.getControllerId())
.anyMatch(controllerId -> controllerId
.equals(managementUIState.getLastSelectedTargetIdName().getControllerId()));
}
return false;
}

View File

@@ -26,9 +26,9 @@ import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent;
import org.eclipse.hawkbit.ui.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum;
import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -405,7 +405,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout<Distri
eventBus.publish(this,
new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType));
} else {
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory"));
uiNotification.displayValidationError(i18n.get("message.type.update.mandatory "));
}
}

View File

@@ -21,7 +21,6 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -42,12 +41,15 @@ import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent;
import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
import org.eclipse.hawkbit.ui.management.event.DistributionTableFilterEvent;
import org.eclipse.hawkbit.ui.push.DistributionCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -124,30 +126,56 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final DistributionSetUpdateEvent event) {
final DistributionSet ds = event.getEntity();
final DistributionSetIdName lastSelectedDsIdName = manageDistUIState.getLastSelectedDistribution().isPresent()
? manageDistUIState.getLastSelectedDistribution().get() : null;
void onDistributionSetUpdateEvents(final DistributionSetUpdatedEventContainer eventContainer) {
final List<DistributionSetIdName> visibleItemIds = (List<DistributionSetIdName>) getVisibleItemIds();
// refresh the details tabs only if selected ds is updated
if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) {
// update table row+details layout
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, ds));
} else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) {
// update the name/version details visible in table
UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity()));
}
handleSelectedAndUpdatedDs(eventContainer.getEvents());
updateVisableTableEntries(eventContainer.getEvents(), visibleItemIds);
}
private void handleSelectedAndUpdatedDs(final List<DistributionSetUpdateEvent> events) {
manageDistUIState.getLastSelectedDistribution()
.ifPresent(lastSelectedDsIdName -> events.stream().map(event -> event.getEntity())
.filter(set -> set.getId().equals(lastSelectedDsIdName.getId())).findFirst()
.ifPresent(selectedSetUpdated -> eventBus.publish(this,
new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedSetUpdated))));
}
private void updateVisableTableEntries(final List<DistributionSetUpdateEvent> events,
final List<DistributionSetIdName> visibleItemIds) {
events.stream().filter(event -> event.getEntity().isComplete())
.filter(event -> visibleItemIds.contains(DistributionSetIdName.generate(event.getEntity())))
.forEach(event -> updateDistributionInTable(event.getEntity()));
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final List<?> events) {
final Object firstEvent = events.get(0);
if (DistributionCreatedEvent.class.isInstance(firstEvent)) {
refreshDistributions();
} else if (DistributionDeletedEvent.class.isInstance(firstEvent)) {
onDistributionDeleteEvent((List<DistributionDeletedEvent>) events);
void onDistributionCreatedEvents(final DistributionCreatedEventContainer eventContainer) {
refreshDistributions();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onDistributionDeletedEvents(final DistributionDeletedEventContainer eventContainer) {
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shouldRefreshDs = false;
for (final DistributionDeletedEvent deletedEvent : eventContainer.getEvents()) {
final Long distributionSetId = deletedEvent.getDistributionSetId();
final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null);
if (visibleItemIds.contains(targetIdName)) {
dsContainer.removeItem(targetIdName);
} else {
shouldRefreshDs = true;
}
}
if (shouldRefreshDs) {
refreshOnDelete();
} else {
dsContainer.commit();
}
reSelectItemsAfterDeletionEvent();
}
@Override
@@ -454,7 +482,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final SaveActionWindowEvent event) {
if (event == SaveActionWindowEvent.DELETED_DISTRIBUTIONS || event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) {
UI.getCurrent().access(() -> refreshFilter());
UI.getCurrent().access(this::refreshFilter);
}
}
@@ -469,7 +497,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
if (event == DistributionTableFilterEvent.FILTER_BY_TEXT
|| event == DistributionTableFilterEvent.REMOVE_FILTER_BY_TEXT
|| event == DistributionTableFilterEvent.FILTER_BY_TAG) {
UI.getCurrent().access(() -> refreshFilter());
UI.getCurrent().access(this::refreshFilter);
}
}
@@ -566,28 +594,6 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
updateEntity(editedDs, item);
}
private void onDistributionDeleteEvent(final List<DistributionDeletedEvent> events) {
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shouldRefreshDs = false;
for (final DistributionDeletedEvent deletedEvent : events) {
final Long distributionSetId = deletedEvent.getDistributionSetId();
final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null);
if (visibleItemIds.contains(targetIdName)) {
dsContainer.removeItem(targetIdName);
} else {
shouldRefreshDs = true;
}
}
if (shouldRefreshDs) {
refreshOnDelete();
} else {
dsContainer.commit();
}
reSelectItemsAfterDeletionEvent();
}
private void refreshOnDelete() {
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
final int size = dsContainer.size();

View File

@@ -15,9 +15,9 @@ import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
@@ -100,13 +100,11 @@ public class TargetFilterCountMessageLabel extends Label {
setDescription(null);
}
targetMessage.append(totalTargets);
targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE);
targetMessage.append(i18n.get("label.filter.shown"));
if (totalTargets > SPUIDefinitions.MAX_TABLE_ENTRIES) {
targetMessage.append(HawkbitCommonUtil.SP_STRING_PIPE);
targetMessage.append(i18n.get("label.filter.shown"));
targetMessage.append(SPUIDefinitions.MAX_TABLE_ENTRIES);
} else {
targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE);
targetMessage.append(totalTargets);
}
setCaption(targetMessage.toString());

View File

@@ -12,6 +12,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -19,7 +20,6 @@ import org.apache.commons.lang3.StringUtils;
import org.eclipse.hawkbit.repository.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -41,6 +41,9 @@ import org.eclipse.hawkbit.ui.management.event.ManagementViewAcceptCriteria;
import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.push.DistributionCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
@@ -113,44 +116,95 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final List<?> events) {
final Object firstEvent = events.get(0);
if (DistributionDeletedEvent.class.isInstance(firstEvent)) {
onDistributionDeleteEvent((List<DistributionDeletedEvent>) events);
} else if (DistributionCreatedEvent.class.isInstance(firstEvent)
&& ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) {
void onDistributionCreatedEvents(final DistributionCreatedEventContainer eventContainer) {
if (eventContainer.getEvents().stream().anyMatch(event -> event.getEntity().isComplete())) {
refreshDistributions();
}
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final DistributionSetUpdateEvent event) {
final DistributionSet ds = event.getEntity();
void onDistributionDeleteEvents(final DistributionDeletedEventContainer eventContainer) {
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shouldRefreshDs = false;
for (final DistributionDeletedEvent deletedEvent : eventContainer.getEvents()) {
final Long distributionSetId = deletedEvent.getDistributionSetId();
final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null);
if (visibleItemIds.contains(targetIdName)) {
dsContainer.removeItem(targetIdName);
} else {
shouldRefreshDs = true;
}
}
if (shouldRefreshDs) {
refreshOnDelete();
} else {
dsContainer.commit();
}
reSelectItemsAfterDeletionEvent();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onDistributionSetUpdateEvents(final DistributionSetUpdatedEventContainer eventContainer) {
final List<DistributionSetIdName> visibleItemIds = (List<DistributionSetIdName>) getVisibleItemIds();
final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst()
.isPresent();
if (allOfThemAffectCompletedSetsThatAreNotVisible(eventContainer.getEvents(), visibleItemIds)) {
refreshDistributions();
} else if (!checkAndHandleIfVisibleDsSwitchesFromCompleteToIncomplete(eventContainer.getEvents(),
visibleItemIds)) {
updateVisableTableEntries(eventContainer.getEvents(), visibleItemIds);
}
if (ds.isComplete() && !dsVisible) {
final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName();
// refresh the details tabs only if selected ds is updated
if (lastSelectedDsIdName != null) {
final Optional<DistributionSet> selectedSetUpdated = eventContainer.getEvents().stream()
.map(event -> event.getEntity()).filter(set -> set.getId().equals(lastSelectedDsIdName.getId()))
.findFirst();
if (selectedSetUpdated.isPresent()) {
// update table row+details layout
eventBus.publish(this,
new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, selectedSetUpdated.get()));
}
}
}
private static boolean allOfThemAffectCompletedSetsThatAreNotVisible(final List<DistributionSetUpdateEvent> events,
final List<DistributionSetIdName> visibleItemIds) {
return events.stream().map(event -> event.getEntity())
.allMatch(set -> set.isComplete() && !visibleItemIds.contains(DistributionSetIdName.generate(set)));
}
private void updateVisableTableEntries(final List<DistributionSetUpdateEvent> events,
final List<DistributionSetIdName> visibleItemIds) {
events.stream().filter(event -> event.getEntity().isComplete())
.filter(event -> visibleItemIds.contains(DistributionSetIdName.generate(event.getEntity())))
.forEach(event -> updateDistributionInTable(event.getEntity()));
}
private boolean checkAndHandleIfVisibleDsSwitchesFromCompleteToIncomplete(
final List<DistributionSetUpdateEvent> events, final List<DistributionSetIdName> visibleItemIds) {
final List<DistributionSet> setsThatAreVisibleButNotCompleteAnymore = events.stream()
.map(event -> event.getEntity()).filter(set -> !set.isComplete())
.filter(set -> visibleItemIds.contains(DistributionSetIdName.generate(set)))
.collect(Collectors.toList());
if (!setsThatAreVisibleButNotCompleteAnymore.isEmpty()) {
refreshDistributions();
} else if (!ds.isComplete() && dsVisible) {
refreshDistributions();
if (ds.getId().equals(managementUIState.getLastSelectedDsIdName().getId())) {
if (setsThatAreVisibleButNotCompleteAnymore.stream()
.anyMatch(set -> set.getId().equals(managementUIState.getLastSelectedDsIdName().getId()))) {
managementUIState.setLastSelectedDistribution(null);
managementUIState.setLastSelectedEntity(null);
}
} else if (dsVisible) {
UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity()));
}
final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName();
// refresh the details tabs only if selected ds is updated
if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) {
// update table row+details layout
eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, ds));
return true;
}
return false;
}
/**
@@ -717,28 +771,6 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null));
}
private void onDistributionDeleteEvent(final List<DistributionDeletedEvent> events) {
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shouldRefreshDs = false;
for (final DistributionDeletedEvent deletedEvent : events) {
final Long distributionSetId = deletedEvent.getDistributionSetId();
final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null);
if (visibleItemIds.contains(targetIdName)) {
dsContainer.removeItem(targetIdName);
} else {
shouldRefreshDs = true;
}
}
if (shouldRefreshDs) {
refreshOnDelete();
} else {
dsContainer.commit();
}
reSelectItemsAfterDeletionEvent();
}
private void reSelectItemsAfterDeletionEvent() {
Set<Object> values = new HashSet<>();
if (isMultiSelect()) {

View File

@@ -13,13 +13,13 @@ import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import java.util.List;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants;
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
import org.eclipse.hawkbit.ui.push.DistributionSetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.springframework.beans.factory.annotation.Autowired;
@@ -28,7 +28,6 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.UI;
/**
@@ -49,21 +48,21 @@ public class CreateUpdateDistributionTagLayoutWindow extends AbstractCreateUpdat
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedEventContainer eventContainer) {
populateTagNameCombo();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) {
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEventContainer eventContainer) {
populateTagNameCombo();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdatedEventContainer eventContainer) {
populateTagNameCombo();
}

View File

@@ -11,9 +11,6 @@ package org.eclipse.hawkbit.ui.management.dstag;
import java.util.Collections;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtonClickBehaviour;
import org.eclipse.hawkbit.ui.common.filterlayout.AbstractFilterButtons;
@@ -21,11 +18,14 @@ import org.eclipse.hawkbit.ui.management.event.DistributionTagDropEvent;
import org.eclipse.hawkbit.ui.management.event.DragEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.management.tag.TagIdName;
import org.eclipse.hawkbit.ui.push.DistributionSetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.DistributionSetTagUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
@@ -66,21 +66,21 @@ public class DistributionTagButtons extends AbstractFilterButtons {
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedBulkEvent event) {
void onDistributionSetTagCreatedBulkEvent(final DistributionSetTagCreatedEventContainer eventContainer) {
refreshTagTable();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEvent event) {
void onDistributionSetTagDeletedEvent(final DistributionSetTagDeletedEventContainer eventContainer) {
refreshTagTable();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdateEvent event) {
void onDistributionSetTagUpdateEvent(final DistributionSetTagUpdatedEventContainer eventContainer) {
refreshTagTable();
}

View File

@@ -14,9 +14,7 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
@@ -26,15 +24,15 @@ import org.eclipse.hawkbit.ui.management.state.TargetTableFilters;
import org.eclipse.hawkbit.ui.management.targettable.TargetTable;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings;
import com.google.common.base.Optional;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent;
@@ -131,17 +129,17 @@ public class CountMessageLabel extends Label {
private void displayTargetCountStatus() {
final TargetTableFilters targFilParams = managementUIState.getTargetTableFilters();
final StringBuilder message = getTotalTargetMessage(targFilParams);
final String filteredTargets = i18n.get("label.filter.targets");
final StringBuilder message = getTotalTargetMessage();
if (targFilParams.hasFilter()) {
message.append(filteredTargets);
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
message.append(i18n.get("label.filter.targets"));
if (managementUIState.getTargetsTruncated() != null) {
message.append(targetTable.size() + managementUIState.getTargetsTruncated());
} else {
message.append(targetTable.size());
}
message.append(HawkbitCommonUtil.SP_STRING_SPACE);
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
final String status = i18n.get("label.filter.status");
final String tags = i18n.get("label.filter.tags");
final String text = i18n.get("label.filter.text");
@@ -152,13 +150,12 @@ public class CountMessageLabel extends Label {
filterMesgBuf.append(getStatusMsg(targFilParams.getClickedStatusTargetTags(), status));
filterMesgBuf
.append(getTagsMsg(targFilParams.isNoTagSelected(), targFilParams.getClickedTargetTags(), tags));
filterMesgBuf.append(getSerachMsg(
targFilParams.getSearchText().isPresent() ? targFilParams.getSearchText().get() : null, text));
filterMesgBuf.append(getDistMsg(
targFilParams.getDistributionSet().isPresent() ? targFilParams.getDistributionSet().get() : null,
dists));
filterMesgBuf.append(getCustomFilterMsg(targFilParams.getTargetFilterQuery().isPresent()
? targFilParams.getTargetFilterQuery().get() : null, custom));
filterMesgBuf.append(
targFilParams.getSearchText().map(search -> text).orElse(HawkbitCommonUtil.SP_STRING_SPACE));
filterMesgBuf.append(
targFilParams.getDistributionSet().map(set -> dists).orElse(HawkbitCommonUtil.SP_STRING_SPACE));
filterMesgBuf.append(targFilParams.getTargetFilterQuery().map(query -> custom)
.orElse(HawkbitCommonUtil.SP_STRING_SPACE));
final String filterMesageChk = filterMesgBuf.toString().trim();
String filterMesage = filterMesageChk;
if (filterMesage.endsWith(",")) {
@@ -166,17 +163,23 @@ public class CountMessageLabel extends Label {
}
message.append(filterMesage);
}
if ((targetTable.size() + Optional.fromNullable(managementUIState.getTargetsTruncated())
.or(0L)) > SPUIDefinitions.MAX_TABLE_ENTRIES) {
message.append(HawkbitCommonUtil.SP_STRING_PIPE);
message.append(i18n.get("label.filter.shown"));
message.append(SPUIDefinitions.MAX_TABLE_ENTRIES);
}
setCaption(message.toString());
}
private StringBuilder getTotalTargetMessage(final TargetTableFilters targFilParams) {
long totalTargetTableEnteries = targetTable.size();
private StringBuilder getTotalTargetMessage() {
if (managementUIState.getTargetsTruncated() != null) {
// set the icon
setIcon(FontAwesome.INFO_CIRCLE);
setDescription(i18n.get("label.target.filter.truncated", managementUIState.getTargetsTruncated(),
SPUIDefinitions.MAX_TABLE_ENTRIES));
totalTargetTableEnteries += managementUIState.getTargetsTruncated();
} else {
setIcon(null);
setDescription(null);
@@ -184,20 +187,7 @@ public class CountMessageLabel extends Label {
final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count"));
message.append(managementUIState.getTargetsCountAll());
message.append(HawkbitCommonUtil.SP_STRING_SPACE);
if (totalTargetTableEnteries > SPUIDefinitions.MAX_TABLE_ENTRIES) {
message.append(i18n.get("label.filter.shown"));
message.append(SPUIDefinitions.MAX_TABLE_ENTRIES);
} else {
if (!targFilParams.hasFilter()) {
message.append(i18n.get("label.filter.shown"));
message.append(targetTable.size());
}
message.append(HawkbitCommonUtil.SP_STRING_SPACE);
}
message.append(HawkbitCommonUtil.SP_STRING_SPACE);
return message;
}
@@ -242,37 +232,4 @@ public class CountMessageLabel extends Label {
return tags.isEmpty() && (noTargetTagSelected == null || !noTargetTagSelected.booleanValue())
? HawkbitCommonUtil.SP_STRING_SPACE : param;
}
/**
* Get Search Text Message.
*
* @param searchTxt
* as search text
* @return String as msg.
*/
private static String getSerachMsg(final String searchTxt, final String param) {
return Strings.isNullOrEmpty(searchTxt) ? HawkbitCommonUtil.SP_STRING_SPACE : param;
}
/**
* Get Dist set Message.
*
* @param distId
* as serach
* @return String as msg.
*/
private static String getDistMsg(final DistributionSetIdName distributionSetIdName, final String param) {
return distributionSetIdName != null ? param : HawkbitCommonUtil.SP_STRING_SPACE;
}
/**
* Get the custom target filter message.
*
* @param targetFilterQuery
* @param param
* @return
*/
private static String getCustomFilterMsg(final TargetFilterQuery targetFilterQuery, final String param) {
return targetFilterQuery != null ? param : HawkbitCommonUtil.SP_STRING_SPACE;
}
}

View File

@@ -25,16 +25,17 @@ import org.eclipse.hawkbit.ui.management.event.DragEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.TextArea;
@@ -45,7 +46,7 @@ import com.vaadin.ui.Window;
* Add and Update Target.
*/
@SpringComponent
@VaadinSessionScope
@ViewScope
public class TargetAddUpdateWindowLayout extends CustomComponent {
private static final long serialVersionUID = -6659290471705262389L;

View File

@@ -19,6 +19,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -50,14 +51,14 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
private static final long serialVersionUID = -5645680058303167558L;
private Sort sort = new Sort(TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
private transient Collection<TargetUpdateStatus> status = null;
private String[] targetTags = null;
private Long distributionId = null;
private String searchText = null;
private Boolean noTagClicked = Boolean.FALSE;
private transient Collection<TargetUpdateStatus> status;
private String[] targetTags;
private Long distributionId;
private String searchText;
private Boolean noTagClicked;
private transient TargetManagement targetManagement;
private transient I18N i18N;
private Long pinnedDistId = null;
private Long pinnedDistId;
private TargetFilterQuery targetFilterQuery;
private ManagementUIState managementUIState;
@@ -176,7 +177,8 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
}
private Boolean anyFilterSelected() {
if (status == null && distributionId == null && Strings.isNullOrEmpty(searchText) && !isTagSelected()) {
if (CollectionUtils.isEmpty(status) && distributionId == null && Strings.isNullOrEmpty(searchText)
&& !isTagSelected()) {
return false;
}
return true;

View File

@@ -22,16 +22,15 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
import org.eclipse.hawkbit.repository.model.NamedEntity;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetIdName;
@@ -54,14 +53,19 @@ import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.management.state.TargetTableFilters;
import org.eclipse.hawkbit.ui.push.CancelTargetAssignmentEventContainer;
import org.eclipse.hawkbit.ui.push.TargetCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetInfoUpdateEventContainer;
import org.eclipse.hawkbit.ui.push.TargetUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.AssignInstalledDSTooltipGenerator;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -73,6 +77,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent;
@@ -122,28 +127,86 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator());
}
/**
* EventListener method which is called when a list of events is published.
* Event types should not be mixed up.
*
* @param events
* list of events
*/
@EventBusListenerMethod(scope = EventScope.SESSION)
public void onEvents(final List<?> events) {
final Object firstEvent = events.get(0);
if (TargetCreatedEvent.class.isInstance(firstEvent)) {
onTargetCreatedEvents();
} else if (TargetInfoUpdateEvent.class.isInstance(firstEvent)) {
onTargetUpdateEvents(((List<TargetInfoUpdateEvent>) events).stream()
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity().getTarget())
.collect(Collectors.toList()));
} else if (TargetDeletedEvent.class.isInstance(firstEvent)) {
onTargetDeletedEvent((List<TargetDeletedEvent>) events);
} else if (TargetUpdatedEvent.class.isInstance(firstEvent)) {
onTargetUpdateEvents(((List<TargetUpdatedEvent>) events).stream()
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity()).collect(Collectors.toList()));
void onTargetDeletedEvents(final TargetDeletedEventContainer eventContainer) {
final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource();
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shouldRefreshTargets = false;
for (final TargetDeletedEvent deletedEvent : eventContainer.getEvents()) {
final TargetIdName targetIdName = new TargetIdName(deletedEvent.getTargetId(), null, null);
if (visibleItemIds.contains(targetIdName)) {
targetContainer.removeItem(targetIdName);
} else {
shouldRefreshTargets = true;
break;
}
}
if (shouldRefreshTargets) {
refreshOnDelete();
} else {
targetContainer.commit();
eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.REFRESH_TARGETS));
}
reSelectItemsAfterDeletionEvent();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onCancelTargetAssignmentEvents(final CancelTargetAssignmentEventContainer eventContainer) {
// workaround until push is available for action
// history, re-select
// the updated target so the action history gets
// refreshed.
reselectTargetIfSelectedInStream(eventContainer.getEvents().stream().map(event -> event.getTarget()));
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetUpdatedEvents(final TargetUpdatedEventContainer eventContainer) {
onTargetUpdateEvents(eventContainer.getEvents().stream()
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity()).collect(Collectors.toList()));
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetInfoUpdateEvents(final TargetInfoUpdateEventContainer eventContainer) {
onTargetUpdateEvents(eventContainer.getEvents().stream()
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity().getTarget())
.collect(Collectors.toList()));
}
/**
* EventListener method which is called by the event bus to notify about a
* list of {@link TargetInfoUpdateEvent}.
*
* @param updatedTargets
* list of updated targets
*/
private void onTargetUpdateEvents(final List<Target> updatedTargets) {
final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource();
@SuppressWarnings("unchecked")
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
if (isFilterEnabled()) {
refreshTargets();
} else {
updatedTargets.stream().filter(target -> visibleItemIds.contains(target.getTargetIdName()))
.forEach(target -> updateVisibleItemOnEvent(target.getTargetInfo()));
targetContainer.commit();
}
// workaround until push is available for action
// history, re-select
// the updated target so the action history gets
// refreshed.
reselectTargetIfSelectedInStream(updatedTargets.stream());
}
private void reselectTargetIfSelectedInStream(final Stream<Target> targets) {
targets.filter(target -> isLastSelectedTarget(target.getTargetIdName())).findAny().ifPresent(
target -> eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, target)));
}
@EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetCreatedEvents(final TargetCreatedEventContainer holder) {
refreshTargets();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
@@ -299,31 +362,12 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
return managementViewAcceptCriteria;
}
private void onTargetDeletedEvent(final List<TargetDeletedEvent> events) {
final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource();
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
boolean shouldRefreshTargets = false;
for (final TargetDeletedEvent deletedEvent : events) {
final TargetIdName targetIdName = new TargetIdName(deletedEvent.getTargetId(), null, null);
if (visibleItemIds.contains(targetIdName)) {
targetContainer.removeItem(targetIdName);
} else {
shouldRefreshTargets = true;
}
}
if (shouldRefreshTargets) {
refreshOnDelete();
} else {
targetContainer.commit();
}
reSelectItemsAfterDeletionEvent();
}
private void reSelectItemsAfterDeletionEvent() {
Set<Object> values = new HashSet<>();
Set<Object> values;
if (isMultiSelect()) {
values = new HashSet<>((Set<?>) getValue());
} else {
values = Sets.newHashSetWithExpectedSize(1);
values.add(getValue());
}
unSelectAll();
@@ -762,41 +806,6 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
&& managementUIState.getLastSelectedTargetIdName().equals(targetIdName);
}
/**
* EventListener method which is called by the event bus to notify about a
* list of {@link TargetInfoUpdateEvent}.
*
* @param updatedTargets
* list of updated targets
*/
private void onTargetUpdateEvents(final List<Target> updatedTargets) {
@SuppressWarnings("unchecked")
final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
if (isFilterEnabled()) {
LOG.debug("Filter enabled on UI {}. Refresh targets from database.", getUI().getUIId());
refreshTargets();
} else {
updatedTargets.stream().filter(target -> visibleItemIds.contains(target.getTargetIdName()))
.forEach(target -> updateVisibleItemOnEvent(target.getTargetInfo()));
}
// workaround until push is available for action
// history, re-select
// the updated target so the action history gets
// refreshed.
final Optional<Target> selected = updatedTargets.stream()
.filter(target -> isLastSelectedTarget(target.getTargetIdName())).findAny();
if (selected.isPresent()) {
LOG.debug("Selected element has changed on UI {}. Reselect to update action history.", getUI().getUIId());
eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, selected.get()));
}
}
private void onTargetCreatedEvents() {
refreshTargets();
}
private boolean isFilterEnabled() {
final TargetTableFilters targetTableFilters = managementUIState.getTargetTableFilters();
return targetTableFilters.getSearchText().isPresent() || !targetTableFilters.getClickedTargetTags().isEmpty()
@@ -871,7 +880,7 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
if (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) {
size = targetManagement.countTargetByTargetFilterQuery(
managementUIState.getTargetTableFilters().getTargetFilterQuery().get());
} else if (!anyFilterSelected(status, pinnedDistId, noTagClicked, targetTags, searchText)) {
} else if (noFilterSelected(status, pinnedDistId, noTagClicked, targetTags, searchText)) {
size = totalTargetsCount;
} else {
size = targetManagement.countTargetByFilters(status, searchText, distributionId, noTagClicked, targetTags);
@@ -884,9 +893,9 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
&& !Strings.isNullOrEmpty(managementUIState.getTargetTableFilters().getSearchText().get());
}
private static Boolean anyFilterSelected(final Collection<TargetUpdateStatus> status, final Long distributionId,
private static boolean noFilterSelected(final Collection<TargetUpdateStatus> status, final Long distributionId,
final Boolean noTagClicked, final String[] targetTags, final String searchText) {
return status == null && distributionId == null && Strings.isNullOrEmpty(searchText)
return CollectionUtils.isEmpty(status) && distributionId == null && Strings.isNullOrEmpty(searchText)
&& !isTagSelected(targetTags, noTagClicked);
}

View File

@@ -13,13 +13,13 @@ import static org.apache.commons.lang3.StringUtils.isNotEmpty;
import java.util.List;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerConstants;
import org.eclipse.hawkbit.ui.colorpicker.ColorPickerHelper;
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
import org.eclipse.hawkbit.ui.push.TargetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetTagDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetTagUpdatedEventContainer;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
@@ -43,21 +43,21 @@ public class CreateUpdateTargetTagLayoutWindow extends AbstractCreateUpdateTagLa
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
void onEventTargetTagCreated(final TargetTagCreatedEventContainer eventContainer) {
populateTagNameCombo();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) {
void onEventTargetDeletedEvent(final TargetTagDeletedEventContainer eventContainer) {
populateTagNameCombo();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onEventTargetTagUpdateEvent(final TargetTagUpdateEvent event) {
void onEventTargetTagUpdateEvent(final TargetTagUpdatedEventContainer eventContainer) {
populateTagNameCombo();
}

View File

@@ -28,7 +28,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
@@ -41,7 +41,7 @@ import com.vaadin.ui.VerticalLayout;
*
*/
@SpringComponent
@VaadinSessionScope
@ViewScope
public class FilterByStatusLayout extends VerticalLayout implements Button.ClickListener {
private static final long serialVersionUID = -6930348859189929850L;

View File

@@ -15,9 +15,6 @@ import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.model.TargetIdName;
import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
@@ -28,11 +25,14 @@ import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.ManagementViewAcceptCriteria;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.management.tag.TagIdName;
import org.eclipse.hawkbit.ui.push.TargetTagCreatedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetTagDeletedEventContainer;
import org.eclipse.hawkbit.ui.push.TargetTagUpdatedEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -286,21 +286,21 @@ public class TargetTagFilterButtons extends AbstractFilterButtons {
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onEvent(final TargetTagUpdateEvent event) {
void onEvent(final TargetTagUpdatedEventContainer eventContainer) {
refreshContainer();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) {
void onEventTargetTagCreated(final TargetTagCreatedEventContainer eventContainer) {
refreshContainer();
}
@EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" })
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) {
void onEventTargetDeletedEvent(final TargetTagDeletedEventContainer eventContainer) {
refreshContainer();
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
/**
* EventHolder for {@link CancelTargetAssignmentEvent}s.
*
*/
public class CancelTargetAssignmentEventContainer implements EventContainer<CancelTargetAssignmentEvent> {
private final List<CancelTargetAssignmentEvent> events;
CancelTargetAssignmentEventContainer(final List<CancelTargetAssignmentEvent> events) {
this.events = events;
}
@Override
public List<CancelTargetAssignmentEvent> getEvents() {
return events;
}
}

View File

@@ -8,9 +8,9 @@
*/
package org.eclipse.hawkbit.ui.push;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingDeque;
@@ -22,7 +22,6 @@ import java.util.stream.Collectors;
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.ui.UIEventProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContext;
@@ -113,8 +112,7 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
}
private boolean isEventProvided(final Event event) {
return eventProvider.getSingleEvents().contains(event.getClass())
|| eventProvider.getBulkEvents().contains(event.getClass());
return eventProvider.getEvents().containsKey(event.getClass());
}
@Override
@@ -125,8 +123,8 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
LOG.error("Vaadin session of UI {} is null! Event push disabled!", uiid);
}
jobHandle = executorService.scheduleWithFixedDelay(new DispatchRunnable(vaadinUI, vaadinUI.getSession()), 500,
2000, TimeUnit.MILLISECONDS);
jobHandle = executorService.scheduleWithFixedDelay(new DispatchRunnable(vaadinUI, vaadinUI.getSession()),
10_000, 1_000, TimeUnit.MILLISECONDS);
systemEventBus.register(this);
}
@@ -212,13 +210,13 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
try {
SecurityContextHolder.setContext(userContext);
final List<EventContainer<Event>> groupedEvents = groupEvents(events, userContext, eventProvider);
vaadinUI.access(() -> {
if (vaadinSession.getState() != State.OPEN) {
return;
}
LOG.debug("UI EventBus aggregator of UI {} got lock on session.", vaadinUI.getUIId());
fowardSingleEvents(events, userContext);
fowardBulkEvents(events, userContext);
groupedEvents.forEach(holder -> eventBus.publish(vaadinUI, holder));
LOG.debug("UI EventBus aggregator of UI {} left lock on session.", vaadinUI.getUIId());
}).get();
} catch (InterruptedException | ExecutionException e) {
@@ -228,25 +226,25 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
}
}
private void fowardBulkEvents(final List<Event> events, final SecurityContext userContext) {
final Set<Class<?>> filterBulkEvenTypes = eventProvider.getFilteredBulkEventsType(events);
@SuppressWarnings("unchecked")
private List<EventContainer<Event>> groupEvents(final List<Event> events, final SecurityContext userContext,
final UIEventProvider eventProvider) {
for (final Class<?> bulkType : filterBulkEvenTypes) {
final List<Event> listBulkEvents = events.stream()
.filter(event -> DelayedEventBusPushStrategy.eventSecurityCheck(userContext, event)
&& bulkType.isInstance(event))
.collect(Collectors.toList());
if (!listBulkEvents.isEmpty()) {
eventBus.publish(vaadinUI, listBulkEvents);
}
}
}
return events.stream().filter(event -> eventSecurityCheck(userContext, event))
.collect(Collectors.groupingBy(Event::getClass)).entrySet().stream().map(entry -> {
EventContainer<Event> holder = null;
try {
final Constructor<Event> declaredConstructor = (Constructor<Event>) eventProvider
.getEvents().get(entry.getKey()).getDeclaredConstructor(List.class);
declaredConstructor.setAccessible(true);
private void fowardSingleEvents(final List<Event> events, final SecurityContext userContext) {
events.stream()
.filter(event -> DelayedEventBusPushStrategy.eventSecurityCheck(userContext, event)
&& eventProvider.getSingleEvents().contains(event.getClass()))
.forEach(event -> eventBus.publish(vaadinUI, event));
holder = (EventContainer<Event>) declaredConstructor.newInstance(entry.getValue());
} catch (final ReflectiveOperationException e) {
LOG.error("Failed to create EventHolder!", e);
}
return holder;
}).collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
/**
* EventHolder for {@link DistributionCreatedEvent}s.
*
*/
public class DistributionCreatedEventContainer implements EventContainer<DistributionCreatedEvent> {
private final List<DistributionCreatedEvent> events;
DistributionCreatedEventContainer(final List<DistributionCreatedEvent> events) {
this.events = events;
}
@Override
public List<DistributionCreatedEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
/**
* EventHolder for {@link DistributionDeletedEvent}s.
*
*/
public class DistributionDeletedEventContainer implements EventContainer<DistributionDeletedEvent> {
private final List<DistributionDeletedEvent> events;
DistributionDeletedEventContainer(final List<DistributionDeletedEvent> events) {
this.events = events;
}
@Override
public List<DistributionDeletedEvent> getEvents() {
return events;
}
}

View File

@@ -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
*/
package org.eclipse.hawkbit.ui.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent;
/**
* EventHolder for {@link DistributionSetTagAssigmentResultEvent}s.
*
*/
public class DistributionSetTagAssignmentResultEventContainer
implements EventContainer<DistributionSetTagAssigmentResultEvent> {
private final List<DistributionSetTagAssigmentResultEvent> events;
DistributionSetTagAssignmentResultEventContainer(final List<DistributionSetTagAssigmentResultEvent> events) {
this.events = events;
}
@Override
public List<DistributionSetTagAssigmentResultEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedEvent;
/**
* EventHolder for {@link DistributionSetTagCreatedEvent}s.
*
*/
public class DistributionSetTagCreatedEventContainer implements EventContainer<DistributionSetTagCreatedEvent> {
private final List<DistributionSetTagCreatedEvent> events;
DistributionSetTagCreatedEventContainer(final List<DistributionSetTagCreatedEvent> events) {
this.events = events;
}
@Override
public List<DistributionSetTagCreatedEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
/**
* EventHolder for {@link DistributionSetTagDeletedEvent}s.
*
*/
public class DistributionSetTagDeletedEventContainer implements EventContainer<DistributionSetTagDeletedEvent> {
private final List<DistributionSetTagDeletedEvent> events;
DistributionSetTagDeletedEventContainer(final List<DistributionSetTagDeletedEvent> events) {
this.events = events;
}
@Override
public List<DistributionSetTagDeletedEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
/**
* EventHolder for {@link DistributionSetTagUpdateEvent}s.
*
*/
public class DistributionSetTagUpdatedEventContainer implements EventContainer<DistributionSetTagUpdateEvent> {
private final List<DistributionSetTagUpdateEvent> events;
DistributionSetTagUpdatedEventContainer(final List<DistributionSetTagUpdateEvent> events) {
this.events = events;
}
@Override
public List<DistributionSetTagUpdateEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
/**
* EventHolder for {@link DistributionSetUpdateEvent}s.
*
*/
public class DistributionSetUpdatedEventContainer implements EventContainer<DistributionSetUpdateEvent> {
private final List<DistributionSetUpdateEvent> events;
DistributionSetUpdatedEventContainer(final List<DistributionSetUpdateEvent> events) {
this.events = events;
}
@Override
public List<DistributionSetUpdateEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.eventbus.event.Event;
/**
* EventHolder beans contains a list of events that can be process by the UI in
* batch like fashion.
*
* @param <T>
* event type
*
*/
@FunctionalInterface
public interface EventContainer<T extends Event> {
/**
* @return list of contained events
*/
List<T> getEvents();
}

View File

@@ -0,0 +1,75 @@
/**
* 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.push;
import java.util.Map;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent;
import com.google.common.collect.Maps;
/**
* The default hawkbit event provider.
*/
public class HawkbitEventProvider implements UIEventProvider {
private static final Map<Class<? extends Event>, Class<?>> EVENTS = Maps.newHashMapWithExpectedSize(18);
static {
EVENTS.put(TargetTagDeletedEvent.class, TargetTagDeletedEventContainer.class);
EVENTS.put(TargetTagCreatedEvent.class, TargetTagCreatedEventContainer.class);
EVENTS.put(TargetTagUpdateEvent.class, TargetTagUpdatedEventContainer.class);
EVENTS.put(TargetTagAssigmentResultEvent.class, TargetTagAssigmentResultEventContainer.class);
EVENTS.put(DistributionSetTagCreatedEvent.class, DistributionSetTagCreatedEventContainer.class);
EVENTS.put(DistributionSetTagDeletedEvent.class, DistributionSetTagDeletedEventContainer.class);
EVENTS.put(DistributionSetTagUpdateEvent.class, DistributionSetTagUpdatedEventContainer.class);
EVENTS.put(DistributionSetTagAssigmentResultEvent.class,
DistributionSetTagAssignmentResultEventContainer.class);
EVENTS.put(TargetCreatedEvent.class, TargetCreatedEventContainer.class);
EVENTS.put(TargetInfoUpdateEvent.class, TargetInfoUpdateEventContainer.class);
EVENTS.put(TargetDeletedEvent.class, TargetDeletedEventContainer.class);
EVENTS.put(TargetUpdatedEvent.class, TargetUpdatedEventContainer.class);
EVENTS.put(CancelTargetAssignmentEvent.class, CancelTargetAssignmentEventContainer.class);
EVENTS.put(DistributionSetUpdateEvent.class, DistributionSetUpdatedEventContainer.class);
EVENTS.put(DistributionDeletedEvent.class, DistributionDeletedEventContainer.class);
EVENTS.put(DistributionCreatedEvent.class, DistributionCreatedEventContainer.class);
EVENTS.put(RolloutGroupChangeEvent.class, RolloutGroupChangeEventContainer.class);
EVENTS.put(RolloutChangeEvent.class, RolloutChangeEventContainer.class);
}
@Override
public Map<Class<? extends Event>, Class<?>> getEvents() {
return EVENTS;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent;
/**
* EventHolder for {@link RolloutChangeEvent}s.
*
*/
public class RolloutChangeEventContainer implements EventContainer<RolloutChangeEvent> {
private final List<RolloutChangeEvent> events;
RolloutChangeEventContainer(final List<RolloutChangeEvent> events) {
this.events = events;
}
@Override
public List<RolloutChangeEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent;
/**
* EventHolder for {@link RolloutGroupChangeEvent}s.
*
*/
public class RolloutGroupChangeEventContainer implements EventContainer<RolloutGroupChangeEvent> {
private final List<RolloutGroupChangeEvent> events;
RolloutGroupChangeEventContainer(final List<RolloutGroupChangeEvent> events) {
this.events = events;
}
@Override
public List<RolloutGroupChangeEvent> getEvents() {
return events;
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.push;
import java.util.List;
import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent;
/**
* EventHolder for {@link TargetCreatedEvent}s.
*
*/
public class TargetCreatedEventContainer implements EventContainer<TargetCreatedEvent> {
private final List<TargetCreatedEvent> events;
TargetCreatedEventContainer(final List<TargetCreatedEvent> events) {
this.events = events;
}
@Override
public List<TargetCreatedEvent> getEvents() {
return events;
}
}

Some files were not shown because too many files have changed in this diff Show More