Merge branch 'master' into feature_target_filtering_supports_overdue

Conflicts:
	hawkbit-repository\hawkbit-repository-jpa\src\main\java\org\eclipse\hawkbit\repository\jpa\JpaDeploymentManagement.java
	hawkbit-repository\hawkbit-repository-jpa\src\main\java\org\eclipse\hawkbit\repository\jpa\JpaTargetManagement.java
	hawkbit-ui\src\main\java\org\eclipse\hawkbit\ui\management\targettable\TargetBeanQuery.java
	hawkbit-ui\src\main\java\org\eclipse\hawkbit\ui\management\targettable\TargetTable.java


Signed-off-by: Marcel Mager (INST-IOT/ESB) <Marcel.Mager@bosch-si.com>
This commit is contained in:
Marcel Mager (INST-IOT/ESB)
2016-10-18 12:57:10 +02:00
114 changed files with 1741 additions and 1133 deletions

View File

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

View File

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

View File

@@ -32,22 +32,6 @@ public class SimulatedDeviceFactory {
@Autowired @Autowired
private SpSenderService spSenderService; 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. * Creating a simulated device.
* *
@@ -70,10 +54,19 @@ public class SimulatedDeviceFactory {
*/ */
public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol, public AbstractSimulatedDevice createSimulatedDevice(final String id, final String tenant, final Protocol protocol,
final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) { 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) { switch (protocol) {
case DMF_AMQP: case DMF_AMQP:
spSenderService.createOrUpdateThing(tenant, id); final AbstractSimulatedDevice device = new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec);
return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec); device.setNextPollCounterSec(pollDelaySec);
if (pollImmediatly) {
spSenderService.createOrUpdateThing(tenant, id);
}
return device;
case DDI_HTTP: case DDI_HTTP:
final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger()) final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger())
.requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC) .requestInterceptor(new GatewayTokenInterceptor(gatewayToken)).logLevel(Logger.Level.BASIC)
@@ -83,4 +76,30 @@ public class SimulatedDeviceFactory {
throw new IllegalArgumentException("Protocol " + protocol + " unknown"); 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++) { for (int i = 0; i < amount; i++) {
final String deviceId = name + i; final String deviceId = name + i;
repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint), repository.add(deviceFactory.createSimulatedDeviceWithImmediatePoll(deviceId, tenant, protocol, pollDelay,
gatewayToken)); new URL(endpoint), gatewayToken));
} }
return ResponseEntity.ok("Updated " + amount + " " + protocol + " connected targets!"); 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; final String deviceId = autostart.getName() + i;
try { try {
if (amqpProperties.isEnabled()) { if (amqpProperties.isEnabled()) {
repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(), repository.add(deviceFactory.createSimulatedDeviceWithImmediatePoll(deviceId,
autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()), autostart.getTenant(), autostart.getApi(), autostart.getPollDelay(),
autostart.getGatewayToken())); new URL(autostart.getEndpoint()), autostart.getGatewayToken()));
} }
} catch (final MalformedURLException e) { } 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) -> { new GenerateDialog((namePrefix, tenant, amount, pollDelay, basePollUrl, gatewayToken, protocol) -> {
for (int index = 0; index < amount; index++) { for (int index = 0; index < amount; index++) {
final String deviceId = namePrefix + index; final String deviceId = namePrefix + index;
beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId, beanContainer
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); .addBean(repository.add(deviceFactory.createSimulatedDeviceWithImmediatePoll(deviceId,
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
} }
}, amqpProperties.isEnabled())); }, amqpProperties.isEnabled()));
} }

View File

@@ -11,8 +11,8 @@ package org.eclipse.hawkbit.app;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.hawkbit.ui.HawkbitUI; 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.DelayedEventBusPushStrategy;
import org.eclipse.hawkbit.ui.push.UIEventProvider;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.eventbus.EventBus; 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.FeignClientConfiguration;
import org.eclipse.hawkbit.feign.core.client.IgnoreMultipleConsumersProducersSpringMvcContract; import org.eclipse.hawkbit.feign.core.client.IgnoreMultipleConsumersProducersSpringMvcContract;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; 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.MgmtRolloutClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource; 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.ConfigurableScenario;
import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample; import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample;
import org.eclipse.hawkbit.mgmt.client.scenarios.upload.FeignMultipartEncoder; 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.EnableFeignClients;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder; import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.hateoas.hal.Jackson2HalModule; import org.springframework.hateoas.hal.Jackson2HalModule;
@@ -43,7 +44,6 @@ import feign.slf4j.Slf4jLogger;
@SpringBootApplication @SpringBootApplication
@EnableFeignClients("org.eclipse.hawkbit.mgmt.client.resource") @EnableFeignClients("org.eclipse.hawkbit.mgmt.client.resource")
@EnableConfigurationProperties(ClientConfigurationProperties.class) @EnableConfigurationProperties(ClientConfigurationProperties.class)
@Configuration
@AutoConfigureAfter(FeignClientConfiguration.class) @AutoConfigureAfter(FeignClientConfiguration.class)
@Import(FeignClientConfiguration.class) @Import(FeignClientConfiguration.class)
public class Application implements CommandLineRunner { public class Application implements CommandLineRunner {
@@ -78,10 +78,12 @@ public class Application implements CommandLineRunner {
public ConfigurableScenario configurableScenario(final MgmtDistributionSetClientResource distributionSetResource, public ConfigurableScenario configurableScenario(final MgmtDistributionSetClientResource distributionSetResource,
final MgmtSoftwareModuleClientResource softwareModuleResource, final MgmtSoftwareModuleClientResource softwareModuleResource,
final MgmtTargetClientResource targetResource, final MgmtRolloutClientResource rolloutResource, final MgmtTargetClientResource targetResource, final MgmtRolloutClientResource rolloutResource,
final MgmtTargetTagClientResource targetTagResource,
final MgmtDistributionSetTagClientResource distributionSetTagResource,
final ClientConfigurationProperties clientConfigurationProperties) { final ClientConfigurationProperties clientConfigurationProperties) {
return new ConfigurableScenario(distributionSetResource, softwareModuleResource, return new ConfigurableScenario(distributionSetResource, softwareModuleResource,
uploadSoftwareModule(clientConfigurationProperties), targetResource, rolloutResource, uploadSoftwareModule(clientConfigurationProperties), targetResource, rolloutResource, targetTagResource,
clientConfigurationProperties); distributionSetTagResource, clientConfigurationProperties);
} }
@Bean @Bean
@@ -89,8 +91,8 @@ public class Application implements CommandLineRunner {
return new CreateStartedRolloutExample(); return new CreateStartedRolloutExample();
} }
@Bean private static MgmtSoftwareModuleClientResource uploadSoftwareModule(
public MgmtSoftwareModuleClientResource uploadSoftwareModule(final ClientConfigurationProperties configuration) { final ClientConfigurationProperties configuration) {
final ObjectMapper mapper = new ObjectMapper() final ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new Jackson2HalModule()); .registerModule(new Jackson2HalModule());

View File

@@ -55,8 +55,19 @@ public class ClientConfigurationProperties {
private int artifactsPerSM = 1; private int artifactsPerSM = 1;
private String targetAddress = "amqp:/simulator.replyTo"; private String targetAddress = "amqp:/simulator.replyTo";
private boolean runRollouts = true; private boolean runRollouts = true;
private short rolloutSuccessThreshold = 80;
private int rolloutDeploymentGroups = 4; 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 * Artifact size. Values can use the suffixed "MB" or "KB" to indicate a
* Megabyte or Kilobyte size. * Megabyte or Kilobyte size.
@@ -167,6 +178,30 @@ public class ClientConfigurationProperties {
this.appModulesPerDistributionSet = appModulesPerDistributionSet; 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() { public List<Scenario> getScenarios() {

View File

@@ -11,23 +11,31 @@ package org.eclipse.hawkbit.mgmt.client.scenarios;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit; 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;
import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario; import org.eclipse.hawkbit.mgmt.client.ClientConfigurationProperties.Scenario;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtDistributionSetClientResource; 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.MgmtRolloutClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource; import org.eclipse.hawkbit.mgmt.client.resource.MgmtSoftwareModuleClientResource;
import org.eclipse.hawkbit.mgmt.client.resource.MgmtTargetClientResource; 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.DistributionSetBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.RolloutBuilder; 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.SoftwareModuleAssigmentBuilder;
import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; 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.resource.builder.TargetBuilder;
import org.eclipse.hawkbit.mgmt.client.scenarios.upload.ArtifactFile; import org.eclipse.hawkbit.mgmt.client.scenarios.upload.ArtifactFile;
import org.eclipse.hawkbit.mgmt.json.model.PagedList; import org.eclipse.hawkbit.mgmt.json.model.PagedList;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; 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.rollout.MgmtRolloutResponseBody;
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule; 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.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -41,7 +49,7 @@ import org.slf4j.LoggerFactory;
*/ */
public class ConfigurableScenario { 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); private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurableScenario.class);
@@ -51,22 +59,32 @@ public class ConfigurableScenario {
private final MgmtTargetClientResource targetResource; private final MgmtTargetClientResource targetResource;
private final MgmtTargetTagClientResource targetTagResource;
private final MgmtDistributionSetTagClientResource distributionSetTagResource;
private final MgmtRolloutClientResource rolloutResource; private final MgmtRolloutClientResource rolloutResource;
private final ClientConfigurationProperties clientConfigurationProperties; private final ClientConfigurationProperties clientConfigurationProperties;
private final MgmtSoftwareModuleClientResource uploadSoftwareModule; 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, public ConfigurableScenario(final MgmtDistributionSetClientResource distributionSetResource,
final MgmtSoftwareModuleClientResource softwareModuleResource, final MgmtSoftwareModuleClientResource softwareModuleResource,
final MgmtSoftwareModuleClientResource uploadSoftwareModule, final MgmtTargetClientResource targetResource, final MgmtSoftwareModuleClientResource uploadSoftwareModule, final MgmtTargetClientResource targetResource,
final MgmtRolloutClientResource rolloutResource, final MgmtRolloutClientResource rolloutResource, final MgmtTargetTagClientResource targetTagResource,
final MgmtDistributionSetTagClientResource distributionSetTagResource,
final ClientConfigurationProperties clientConfigurationProperties) { final ClientConfigurationProperties clientConfigurationProperties) {
this.targetTagResource = targetTagResource;
this.distributionSetResource = distributionSetResource; this.distributionSetResource = distributionSetResource;
this.softwareModuleResource = softwareModuleResource; this.softwareModuleResource = softwareModuleResource;
this.uploadSoftwareModule = uploadSoftwareModule; this.uploadSoftwareModule = uploadSoftwareModule;
this.targetResource = targetResource; this.targetResource = targetResource;
this.rolloutResource = rolloutResource; this.rolloutResource = rolloutResource;
this.distributionSetTagResource = distributionSetTagResource;
this.clientConfigurationProperties = clientConfigurationProperties; this.clientConfigurationProperties = clientConfigurationProperties;
} }
@@ -111,7 +129,8 @@ public class ConfigurableScenario {
PagedList<MgmtSoftwareModule> modules; PagedList<MgmtSoftwareModule> modules;
do { do {
modules = softwareModuleResource.getSoftwareModules(0, PAGE_SIZE, null, null).getBody(); 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); } while (modules.getTotal() > PAGE_SIZE);
} }
@@ -119,16 +138,40 @@ public class ConfigurableScenario {
PagedList<MgmtDistributionSet> distributionSets; PagedList<MgmtDistributionSet> distributionSets;
do { do {
distributionSets = distributionSetResource.getDistributionSets(0, PAGE_SIZE, null, null).getBody(); 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); } 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() { private void deleteTargets() {
PagedList<MgmtTarget> targets; PagedList<MgmtTarget> targets;
do { do {
targets = targetResource.getTargets(0, PAGE_SIZE, null, null).getBody(); 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); } 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) { private void runRollouts(final Scenario scenario) {
@@ -140,10 +183,10 @@ public class ConfigurableScenario {
private void runRollout(final MgmtDistributionSet set, final Scenario scenario) { private void runRollout(final MgmtDistributionSet set, final Scenario scenario) {
LOGGER.info("Run rollout for set {}", set.getDsId()); LOGGER.info("Run rollout for set {}", set.getDsId());
// create a Rollout // create a Rollout
final MgmtRolloutResponseBody rolloutResponseBody = rolloutResource final MgmtRolloutResponseBody rolloutResponseBody = rolloutResource.create(new RolloutBuilder()
.create(new RolloutBuilder().name("Rollout" + set.getName() + set.getVersion()) .name("Rollout" + set.getName() + set.getVersion()).groupSize(scenario.getRolloutDeploymentGroups())
.groupSize(scenario.getRolloutDeploymentGroups()).targetFilterQuery("name==*") .targetFilterQuery("name==*").distributionSetId(set.getDsId())
.distributionSetId(set.getDsId()).successThreshold("80").errorThreshold("5").build()) .successThreshold(String.valueOf(scenario.getRolloutSuccessThreshold())).errorThreshold("5").build())
.getBody(); .getBody();
// start the created Rollout // start the created Rollout
@@ -164,21 +207,44 @@ public class ConfigurableScenario {
private void createDistributionSets(final Scenario scenario) { private void createDistributionSets(final Scenario scenario) {
LOGGER.info("Creating {} distribution sets", scenario.getDistributionSets()); LOGGER.info("Creating {} distribution sets", scenario.getDistributionSets());
final byte[] artifact = generateArtifact(scenario);
distributionSetResource.createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()) final List<MgmtDistributionSet> sets = distributionSetResource
.type("os_app").version("1.0.").buildAsList(scenario.getDistributionSets())).getBody() .createDistributionSets(new DistributionSetBuilder().name(scenario.getDsName()).type("os_app")
.forEach(dsSet -> { .version("1.0.").buildAsList(scenario.getDistributionSets()))
final List<MgmtSoftwareModule> modules = addModules(scenario, dsSet, artifact); .getBody();
final SoftwareModuleAssigmentBuilder assign = new SoftwareModuleAssigmentBuilder(); assignSoftwareModulesTo(scenario, sets);
modules.forEach(module -> assign.id(module.getModuleId()));
distributionSetResource.assignSoftwareModules(dsSet.getDsId(), assign.build()); tagDistributionSets(scenario, sets);
});
LOGGER.info("Creating {} distribution sets -> Done", scenario.getDistributionSets()); 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, private List<MgmtSoftwareModule> addModules(final Scenario scenario, final MgmtDistributionSet dsSet,
final byte[] artifact) { final byte[] artifact) {
final List<MgmtSoftwareModule> modules = softwareModuleResource final List<MgmtSoftwareModule> modules = softwareModuleResource
@@ -191,8 +257,10 @@ public class ConfigurableScenario {
.getBody()); .getBody());
for (int iArtifact = 0; iArtifact < scenario.getArtifactsPerSM(); iArtifact++) { for (int iArtifact = 0; iArtifact < scenario.getArtifactsPerSM(); iArtifact++) {
final int count = iArtifact;
modules.forEach(module -> { 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); uploadSoftwareModule.uploadArtifact(module.getModuleId(), file, null, null, null);
}); });
} }
@@ -202,17 +270,44 @@ public class ConfigurableScenario {
private void createTargets(final Scenario scenario) { private void createTargets(final Scenario scenario) {
LOGGER.info("Creating {} targets", scenario.getTargets()); LOGGER.info("Creating {} targets", scenario.getTargets());
IntStream.range(0, scenario.getTargets() / PAGE_SIZE).parallel().forEach(i -> createTargetPage(scenario, i));
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));
}
LOGGER.info("Creating {} targets -> Done", scenario.getTargets()); 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) { private static int parseSize(final String s) {
final String size = s.toUpperCase(); final String size = s.toUpperCase();
if (size.endsWith("KB")) { if (size.endsWith("KB")) {

View File

@@ -11,7 +11,9 @@ hawkbit.url=http://localhost:8080
hawkbit.username=admin hawkbit.username=admin
hawkbit.password=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].cleanRepository=false
hawkbit.scenarios.[0].targets=0 hawkbit.scenarios.[0].targets=0

View File

@@ -12,7 +12,7 @@
<configuration> <configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" /> <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"> <Root level="INFO">
<appender-ref ref="CONSOLE" /> <appender-ref ref="CONSOLE" />

View File

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

View File

@@ -14,11 +14,17 @@ security.basic.realm=HawkBit
security.user.name=admin security.user.name=admin
security.user.password=admin security.user.password=admin
# JPA / Datasource ### JPA / Datasource - START
spring.jpa.eclipselink.eclipselink.weaving=false
spring.jpa.database=H2 spring.jpa.database=H2
spring.jpa.show-sql=false spring.jpa.show-sql=false
spring.datasource.driverClassName=org.h2.Driver 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 # MongoDB for artifact-repository
spring.data.mongodb.uri=mongodb://localhost/artifactrepo 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.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target; 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.RequestResponseContextHolder;
import org.eclipse.hawkbit.rest.util.RestResourceConversionHelper; import org.eclipse.hawkbit.rest.util.RestResourceConversionHelper;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties; import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
@@ -130,14 +129,6 @@ public class DdiRootController implements DdiRootControllerRestApi {
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(controllerId, IpUtil final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(controllerId, IpUtil
.getClientIpFromRequest(requestResponseContextHolder.getHttpServletRequest(), securityProperties)); .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<>( return new ResponseEntity<>(
DataConversionHelper.fromTarget(target, controllerManagement.findOldestActiveActionByTarget(target), DataConversionHelper.fromTarget(target, controllerManagement.findOldestActiveActionByTarget(target),
controllerManagement.getPollingTime(), tenantAware), controllerManagement.getPollingTime(), tenantAware),

View File

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

View File

@@ -12,7 +12,7 @@
<configuration> <configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" /> <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"> <Root level="INFO">
<appender-ref ref="CONSOLE" /> <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.DownloadAndUpdateRequest;
import org.eclipse.hawkbit.dmf.json.model.SoftwareModule; import org.eclipse.hawkbit.dmf.json.model.SoftwareModule;
import org.eclipse.hawkbit.eventbus.EventSubscriber; import org.eclipse.hawkbit.eventbus.EventSubscriber;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.SystemManagement; 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.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
@@ -125,12 +125,13 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
@Subscribe @Subscribe
public void targetCancelAssignmentToDistributionSet( public void targetCancelAssignmentToDistributionSet(
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent) { final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent) {
final String controllerId = cancelTargetAssignmentDistributionSetEvent.getControllerId(); final String controllerId = cancelTargetAssignmentDistributionSetEvent.getTarget().getControllerId();
final Long actionId = cancelTargetAssignmentDistributionSetEvent.getActionId(); final Long actionId = cancelTargetAssignmentDistributionSetEvent.getActionId();
final Message message = getMessageConverter().toMessage(actionId, createConnectorMessageProperties( final Message message = getMessageConverter().toMessage(actionId, createConnectorMessageProperties(
cancelTargetAssignmentDistributionSetEvent.getTenant(), controllerId, EventTopic.CANCEL_DOWNLOAD)); 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.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType; import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus; 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.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.RepositoryConstants; 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.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.TenantNotExistException; import org.eclipse.hawkbit.repository.exception.TenantNotExistException;
import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException; import org.eclipse.hawkbit.repository.exception.TooManyStatusEntriesException;
@@ -194,8 +194,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
if (action.get().isCancelingOrCanceled()) { if (action.get().isCancelingOrCanceled()) {
amqpMessageDispatcherService.targetCancelAssignmentToDistributionSet( amqpMessageDispatcherService.targetCancelAssignmentToDistributionSet(
new CancelTargetAssignmentEvent(target.getOptLockRevision(), target.getTenant(), new CancelTargetAssignmentEvent(target, action.get().getId()));
target.getControllerId(), action.get().getId(), target.getTargetInfo().getAddress()));
return; return;
} }
@@ -328,7 +327,6 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
// cancel action rejected, write warning status message and fall // cancel action rejected, write warning status message and fall
// back to running action status // back to running action status
} else { } else {
logAndThrowMessageError(message, logAndThrowMessageError(message,
"Cancel recjected message is not allowed, if action is on state: " + action.getStatus()); "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.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType; import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DownloadAndUpdateRequest; 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.SystemManagement;
import org.eclipse.hawkbit.repository.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -202,10 +202,11 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
@Description("Verfies that send cancel event works") @Description("Verfies that send cancel event works")
public void testSendCancelRequest() { public void testSendCancelRequest() {
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent( final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
1L, TENANT, CONTROLLER_ID, 1L, AMQP_URI); testTarget, 1L);
amqpMessageDispatcherService amqpMessageDispatcherService
.targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent); .targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent);
final Message sendMessage = createArgumentCapture(cancelTargetAssignmentDistributionSetEvent.getTargetAdress()); final Message sendMessage = createArgumentCapture(
cancelTargetAssignmentDistributionSetEvent.getTarget().getTargetInfo().getAddress());
assertCancelMessage(sendMessage); assertCancelMessage(sendMessage);
} }

View File

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

View File

@@ -127,7 +127,7 @@ public interface MgmtTargetTagRestApi {
* @param targetTagId * @param targetTagId
* the ID of the target tag to retrieve * the ID of the target tag to retrieve
* @param assignedTargetRequestBodies * @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. * @return the list of assigned targets and unassigned targets.
*/ */
@@ -143,7 +143,7 @@ public interface MgmtTargetTagRestApi {
* @param targetTagId * @param targetTagId
* the ID of the target tag to retrieve * the ID of the target tag to retrieve
* @param assignedTargetRequestBodies * @param assignedTargetRequestBodies
* list of target ids to be assigned * list of controller ids to be assigned
* *
* @return the list of assigned targets. * @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 + ")].description", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].controllerId", contains(idA))) .andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].controllerId", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].createdBy", contains("bumlux"))) .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())) .andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].lastControllerRequestAt", notNullValue()))
// idB // idB
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")]._links.self.href", .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 + ")].description", contains(idB)))
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].controllerId", contains(idB))) .andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].controllerId", contains(idB)))
.andExpect(jsonPath("$.content.[?(@.name==" + idB + ")].createdBy", contains("bumlux"))) .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())) .andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].lastControllerRequestAt", notNullValue()))
// idC // idC
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")]._links.self.href", .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 + ")].description", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].controllerId", contains(idC))) .andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].controllerId", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].createdBy", contains("bumlux"))) .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())); .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 + ")].description", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].controllerId", contains(idA))) .andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].controllerId", contains(idA)))
.andExpect(jsonPath("$.content.[?(@.name==" + idA + ")].createdBy", contains("bumlux"))) .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 @Test
@@ -500,7 +500,7 @@ public class MgmtTargetResourceTest extends AbstractRestIntegrationTest {
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].description", contains(idC))) .andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].description", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].controllerId", contains(idC))) .andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].controllerId", contains(idC)))
.andExpect(jsonPath("$.content.[?(@.name==" + idC + ")].createdBy", contains("bumlux"))) .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 // idB
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")]._links.self.href", .andExpect(jsonPath("$.content.[?(@.name==" + idD + ")]._links.self.href",
contains(linksHrefPrefix + idD))) 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 + ")].description", contains(idD)))
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].controllerId", contains(idD))) .andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].controllerId", contains(idD)))
.andExpect(jsonPath("$.content.[?(@.name==" + idD + ")].createdBy", contains("bumlux"))) .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 // idC
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")]._links.self.href", .andExpect(jsonPath("$.content.[?(@.name==" + idE + ")]._links.self.href",
contains(linksHrefPrefix + idE))) 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 + ")].description", contains(idE)))
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].controllerId", contains(idE))) .andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].controllerId", contains(idE)))
.andExpect(jsonPath("$.content.[?(@.name==" + idE + ")].createdBy", contains("bumlux"))) .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 @Test

View File

@@ -23,7 +23,7 @@
<Logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR" /> <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 --> <!-- Security Log with hints on potential attacks -->
<logger name="server-security" level="INFO" /> <logger name="server-security" level="INFO" />

View File

@@ -187,13 +187,16 @@ public interface ArtifactManagement {
void deleteExternalArtifact(@NotNull Long id); 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 * the related local artifact
*
* @return <code>true</code> if an binary was actually garbage collected
*/ */
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY)
void deleteLocalArtifact(@NotNull LocalArtifact existing); boolean clearLocalArtifactBinary(@NotNull LocalArtifact onlyByThisReferenced);
/** /**
* Deletes {@link Artifact} based on given id. * 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 * 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 * @param controllerId
* of the target to to update * of the target to to update

View File

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

View File

@@ -192,6 +192,15 @@ public interface TargetManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_TARGET)
void deleteTargets(@NotEmpty Long... targetIDs); 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 * finds all {@link Target#getControllerId()} which are currently in the
* database. * 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; package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
/** /**
* A event for assignment target tag. * A event for assignment target tag.
*/ */
public class DistributionSetTagAssigmentResultEvent { public class DistributionSetTagAssigmentResultEvent implements Event {
private final DistributionSetTagAssignmentResult assigmentResult; private final DistributionSetTagAssignmentResult assigmentResult;
private final String tenant;
/** /**
* Constructor. * Constructor.
* *
* @param assigmentResult * @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.assigmentResult = assigmentResult;
this.tenant = tenant;
} }
public DistributionSetTagAssignmentResult getAssigmentResult() { public DistributionSetTagAssignmentResult getAssigmentResult() {
return assigmentResult; 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; package org.eclipse.hawkbit.repository.eventbus.event;
import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
/** /**
* A event for assignment target tag. * A event for assignment target tag.
*/ */
public class TargetTagAssigmentResultEvent { public class TargetTagAssigmentResultEvent implements Event {
private final TargetTagAssignmentResult assigmentResult; private final TargetTagAssignmentResult assigmentResult;
private final String tenant;
/** /**
* Constructor. * Constructor.
* *
* @param assigmentResult * @param assigmentResult
* the assignment result- * 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; this.assigmentResult = assigmentResult;
} }
@@ -31,4 +36,14 @@ public class TargetTagAssigmentResultEvent {
return assigmentResult; 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 java.util.List;
import org.eclipse.hawkbit.eventbus.event.Event;
/** /**
* Result object for {@link DistributionSetTag} assignments. * 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 DistributionSetTag distributionSetTag;
private final String tenant;
/** /**
* Constructor. * Constructor.
@@ -36,14 +39,24 @@ public class DistributionSetTagAssignmentResult extends AssignmentResult<Distrib
*/ */
public DistributionSetTagAssignmentResult(final int alreadyAssigned, final int assigned, final int unassigned, public DistributionSetTagAssignmentResult(final int alreadyAssigned, final int assigned, final int unassigned,
final List<DistributionSet> assignedDs, final List<DistributionSet> unassignedDs, final List<DistributionSet> assignedDs, final List<DistributionSet> unassignedDs,
final DistributionSetTag distributionSetTag) { final DistributionSetTag distributionSetTag, final String tenant) {
super(assigned, alreadyAssigned,unassigned, assignedDs, unassignedDs); super(assigned, alreadyAssigned, unassigned, assignedDs, unassignedDs);
this.distributionSetTag = distributionSetTag; this.distributionSetTag = distributionSetTag;
this.tenant = tenant;
} }
public DistributionSetTag getDistributionSetTag() { public DistributionSetTag getDistributionSetTag() {
return distributionSetTag; 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 * @return <code>true</code> if tag could be added sucessfully (i.e. was not
* already in the list). * already in the list).
*/ */
public boolean addTag(TargetTag tag); boolean addTag(TargetTag tag);
/** /**
* @param tag * @param tag
* to remove * to remove
* @return <code>true</code> if tag was in the list and removed * @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 @Override
protected Map<String, Object> getVendorProperties() { 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 // Turn off dynamic weaving to disable LTW lookup in static weaving mode
properties.put("eclipselink.weaving", "false"); properties.put("eclipselink.weaving", "false");
// needed for reports // needed for reports
properties.put("eclipselink.jdbc.allow-native-sql-queries", "true"); properties.put("eclipselink.jdbc.allow-native-sql-queries", "true");
// flyway // flyway
properties.put("eclipselink.ddl-generation", "none"); properties.put("eclipselink.ddl-generation", "none");
// Embeed into hawkBit logging
properties.put("eclipselink.persistence-context.flush-mode", "auto");
properties.put("eclipselink.logging.logger", "JavaLogger"); properties.put("eclipselink.logging.logger", "JavaLogger");
return properties; return properties;

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager; 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 @Override
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteLocalArtifact(final LocalArtifact existing) { public boolean clearLocalArtifactBinary(final LocalArtifact existing) {
if (existing == null) {
return;
}
boolean artifactIsOnlyUsedByOneSoftwareModule = true;
for (final LocalArtifact lArtifact : localArtifactRepository for (final LocalArtifact lArtifact : localArtifactRepository
.findByGridFsFileName(((JpaLocalArtifact) existing).getGridFsFileName())) { .findByGridFsFileName(((JpaLocalArtifact) existing).getGridFsFileName())) {
if (!lArtifact.getSoftwareModule().isDeleted() if (!lArtifact.getSoftwareModule().isDeleted()
&& Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) { && Long.compare(lArtifact.getSoftwareModule().getId(), existing.getSoftwareModule().getId()) != 0) {
artifactIsOnlyUsedByOneSoftwareModule = false; return false;
break;
} }
} }
if (artifactIsOnlyUsedByOneSoftwareModule) { try {
try { LOG.debug("deleting artifact from repository {}", ((JpaLocalArtifact) existing).getGridFsFileName());
LOG.debug("deleting artifact from repository {}", ((JpaLocalArtifact) existing).getGridFsFileName()); artifactRepository.deleteBySha1(((JpaLocalArtifact) existing).getGridFsFileName());
artifactRepository.deleteBySha1(((JpaLocalArtifact) existing).getGridFsFileName()); return true;
} catch (final ArtifactStoreException e) { } catch (final ArtifactStoreException e) {
throw new ArtifactDeleteFailedException(e); throw new ArtifactDeleteFailedException(e);
}
} }
} }
@@ -185,7 +179,7 @@ public class JpaArtifactManagement implements ArtifactManagement {
return; return;
} }
deleteLocalArtifact(existing); clearLocalArtifactBinary(existing);
existing.getSoftwareModule().removeArtifact(existing); existing.getSoftwareModule().removeArtifact(existing);
softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule()); softwareModuleRepository.save((JpaSoftwareModule) existing.getSoftwareModule());

View File

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

View File

@@ -28,11 +28,11 @@ import javax.persistence.criteria.ListJoin;
import javax.persistence.criteria.Root; import javax.persistence.criteria.Root;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.ActionFields; import org.eclipse.hawkbit.repository.ActionFields;
import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.DeploymentManagement;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult; import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult;
import org.eclipse.hawkbit.repository.TargetManagement; 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.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent;
import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException;
@@ -84,6 +84,7 @@ import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Modifying;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -357,17 +358,6 @@ public class JpaDeploymentManagement implements DeploymentManagement {
return actionForTarget; 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, private void assignDistributionSetEvent(final JpaTarget target, final Long actionId,
final List<JpaSoftwareModule> modules) { final List<JpaSoftwareModule> modules) {
((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING); ((JpaTargetInfo) target.getTargetInfo()).setUpdateStatus(TargetUpdateStatus.PENDING);
@@ -461,8 +451,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
* the action id of the assignment * the action id of the assignment
*/ */
private void cancelAssignDistributionSetEvent(final Target target, final Long actionId) { private void cancelAssignDistributionSetEvent(final Target target, final Long actionId) {
afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target.getOptLockRevision(), afterCommit.afterCommit(() -> eventBus.post(new CancelTargetAssignmentEvent(target, actionId)));
target.getTenant(), target.getControllerId(), actionId, target.getTargetInfo().getAddress())));
} }
@Override @Override
@@ -521,7 +510,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
@Override @Override
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_COMMITTED) @Transactional(propagation = Propagation.REQUIRES_NEW, isolation = Isolation.READ_COMMITTED)
public Action startScheduledAction(final Action action) { public Action startScheduledAction(final Action action) {
final JpaAction mergedAction = (JpaAction) entityManager.merge(action); final JpaAction mergedAction = (JpaAction) entityManager.merge(action);

View File

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

View File

@@ -247,7 +247,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) {
for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { 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.TagFields;
import org.eclipse.hawkbit.repository.TagManagement; 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.DistributionSetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent; 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.TargetTagDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent;
import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException;
@@ -96,8 +96,7 @@ public class JpaTagManagement implements TagManagement {
final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag); final TargetTag save = targetTagRepository.save((JpaTargetTag) targetTag);
afterCommit afterCommit.afterCommit(() -> eventBus.post(new TargetTagCreatedEvent(save)));
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
return save; return save;
} }
@@ -116,8 +115,7 @@ public class JpaTagManagement implements TagManagement {
}); });
final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags)); final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags));
afterCommit afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new TargetTagCreatedEvent(tag))));
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
return save; return save;
} }
@@ -199,8 +197,7 @@ public class JpaTagManagement implements TagManagement {
final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag); final DistributionSetTag save = distributionSetTagRepository.save((JpaDistributionSetTag) distributionSetTag);
afterCommit.afterCommit( afterCommit.afterCommit(() -> eventBus.post(new DistributionSetTagCreatedEvent(save)));
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
return save; return save;
} }
@@ -219,8 +216,7 @@ public class JpaTagManagement implements TagManagement {
} }
final List<DistributionSetTag> save = Collections final List<DistributionSetTag> save = Collections
.unmodifiableList(distributionSetTagRepository.save(distributionSetTags)); .unmodifiableList(distributionSetTagRepository.save(distributionSetTags));
afterCommit.afterCommit( afterCommit.afterCommit(() -> save.forEach(tag -> eventBus.post(new DistributionSetTagCreatedEvent(tag))));
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
return save; return save;
} }

View File

@@ -209,19 +209,16 @@ public class JpaTargetManagement implements TargetManagement {
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteTargets(final Long... targetIDs) { public void deleteTargets(final Long... targetIDs) {
// we need to select the target IDs first to check the if the targetIDs deleteTargets(Lists.newArrayList(targetIDs));
// belonging to the }
// tenant! Delete statement are not automatically enhanced with the
// @FilterDef of the @Override
// hibernate session. @Modifying
final List<Long> targetsForCurrentTenant = targetRepository.findAll(Lists.newArrayList(targetIDs)).stream() @Transactional(isolation = Isolation.READ_UNCOMMITTED)
.map(Target::getId).collect(Collectors.toList()); public void deleteTargets(final Collection<Long> targetIDs) {
if (!targetsForCurrentTenant.isEmpty()) { targetRepository.deleteByIdIn(targetIDs);
targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant);
targetRepository.deleteByIdIn(targetsForCurrentTenant); targetIDs.forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId)));
}
targetsForCurrentTenant
.forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId)));
} }
@Override @Override
@@ -371,7 +368,8 @@ public class JpaTargetManagement implements TargetManagement {
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(0, 0, alreadyAssignedTargets.size(), final TargetTagAssignmentResult result = new TargetTagAssignmentResult(0, 0, alreadyAssignedTargets.size(),
Collections.emptyList(), alreadyAssignedTargets, tag); Collections.emptyList(), alreadyAssignedTargets, tag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result))); afterCommit.afterCommit(
() -> eventBus.post(new TargetTagAssigmentResultEvent(result, tenantAware.getCurrentTenant())));
return result; return result;
} }
@@ -382,7 +380,8 @@ public class JpaTargetManagement implements TargetManagement {
allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)), allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)),
Collections.emptyList(), tag); 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 // no reason to persist the tag
entityManager.detach(tag); entityManager.detach(tag);
@@ -392,9 +391,9 @@ public class JpaTargetManagement implements TargetManagement {
@Override @Override
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @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 final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds)); .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(controllerIds));
allTargets.forEach(target -> target.addTag(tag)); allTargets.forEach(target -> target.addTag(tag));
final List<Target> save = Collections.unmodifiableList(targetRepository.save(allTargets)); final List<Target> save = Collections.unmodifiableList(targetRepository.save(allTargets));
@@ -402,7 +401,7 @@ public class JpaTargetManagement implements TargetManagement {
afterCommit.afterCommit(() -> { afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save, final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save,
Collections.emptyList(), tag); Collections.emptyList(), tag);
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult)); eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
}); });
return save; return save;
@@ -418,7 +417,7 @@ public class JpaTargetManagement implements TargetManagement {
afterCommit.afterCommit(() -> { afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(), final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, 0, save.size(),
Collections.emptyList(), save, tag); Collections.emptyList(), save, tag);
eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult)); eventBus.post(new TargetTagAssigmentResultEvent(assigmentResult, tenantAware.getCurrentTenant()));
}); });
return save; return save;
} }
@@ -587,8 +586,8 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull Pageable pageRequest, Long distributionSetId, public Page<Target> findAllTargetsByTargetFilterQueryAndNonDS(@NotNull final Pageable pageRequest,
@NotNull TargetFilterQuery targetFilterQuery) { final Long distributionSetId, @NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
virtualPropertyReplacer); virtualPropertyReplacer);
@@ -602,10 +601,10 @@ public class JpaTargetManagement implements TargetManagement {
} }
@Override @Override
public Long countTargetsByTargetFilterQueryAndNonDS(Long distributionSetId, public Long countTargetsByTargetFilterQueryAndNonDS(final Long distributionSetId,
@NotNull TargetFilterQuery targetFilterQuery) { @NotNull final TargetFilterQuery targetFilterQuery) {
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class,
virtualPropertyReplacer); virtualPropertyReplacer);
final List<Specification<JpaTarget>> specList = new ArrayList<>(2); final List<Specification<JpaTarget>> specList = new ArrayList<>(2);
specList.add(spec); specList.add(spec);
specList.add(TargetSpecifications.hasNotDistributionSetInActions(distributionSetId)); specList.add(TargetSpecifications.hasNotDistributionSetInActions(distributionSetId));

View File

@@ -8,8 +8,6 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.util.Optional;
import org.eclipse.hawkbit.repository.TenantStatsManagement; import org.eclipse.hawkbit.repository.TenantStatsManagement;
import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.eclipse.hawkbit.repository.report.model.TenantUsage;
import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -46,15 +44,8 @@ public class JpaTenantStatsManagement implements TenantStatsManagement {
final TenantUsage result = new TenantUsage(tenant); final TenantUsage result = new TenantUsage(tenant);
result.setTargets(targetRepository.count()); result.setTargets(targetRepository.count());
result.setArtifacts(artifactRepository.countBySoftwareModuleDeleted(false));
final Long artifacts = artifactRepository.countBySoftwareModuleDeleted(false); artifactRepository.getSumOfUndeletedArtifactSize().map(result::setOverallArtifactVolumeInBytes);
result.setArtifacts(artifacts);
final Optional<Long> artifactsSize = artifactRepository.getSumOfUndeletedArtifactSize();
if (artifactsSize.isPresent()) {
result.setOverallArtifactVolumeInBytes(artifactsSize.get());
}
result.setActions(actionRepository.count()); result.setActions(actionRepository.count());
return result; 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.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; 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.jpa.repository.Query;
import org.springframework.data.repository.query.Param; import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Isolation;
@@ -107,6 +108,20 @@ public interface RolloutGroupRepository
*/ */
List<JpaRolloutGroup> findByParentAndStatus(JpaRolloutGroup rolloutGroup, RolloutGroupStatus status); 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 * Retrieves all {@link RolloutGroup} for a specific rollout and status not
* having ordered by ID DESC, latest top. * having ordered by ID DESC, latest top.

View File

@@ -62,7 +62,10 @@ public interface RolloutRepository
List<JpaRollout> findByLastCheckAndStatus(long lastCheck, RolloutStatus status); 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 * @param name
* the rollout name * the rollout name

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.persistence.Entity; import javax.persistence.Entity;
@@ -56,15 +55,4 @@ public interface TargetInfoRepository {
*/ */
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true) @CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
<S extends JpaTargetInfo> S save(S entity); <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) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
// Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477 // Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=349477
@Query("DELETE FROM JpaTarget t WHERE t.id IN ?1") @Query("DELETE FROM JpaTarget t WHERE t.id IN ?1")
@CacheEvict(value = { "targetStatus", "distributionUsageInstalled", "targetsLastPoll" }, allEntries = true)
void deleteByIdIn(final Collection<Long> targetIDs); void deleteByIdIn(final Collection<Long> targetIDs);
/** /**

View File

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

View File

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

View File

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

View File

@@ -82,6 +82,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@Transient @Transient
private boolean entityNew; private boolean entityNew;
@CascadeOnDelete
@ManyToMany(targetEntity = JpaTargetTag.class) @ManyToMany(targetEntity = JpaTargetTag.class)
@JoinTable(name = "sp_target_target_tag", joinColumns = { @JoinTable(name = "sp_target_target_tag", joinColumns = {
@JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { @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. * Read only on management API. Are commited by controller.
*/ */
@CascadeOnDelete
@ElementCollection @ElementCollection
@Column(name = "attribute_value", length = 128) @Column(name = "attribute_value", length = 128)
@MapKeyColumn(name = "attribute_key", nullable = false, length = 32) @MapKeyColumn(name = "attribute_key", nullable = false, length = 32)
@CollectionTable(name = "sp_target_attributes", joinColumns = { @CollectionTable(name = "sp_target_attributes", joinColumns = {
@JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) @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>()); private final Map<String, String> controllerAttributes = Collections.synchronizedMap(new HashMap<String, String>());
// set default request controller attributes to true, because we want to // 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); rolloutGroup, Action.Status.SCHEDULED);
logger.debug("{} Next actions to start for rollout {} and parent group {}", rolloutGroupActions.size(), rollout, logger.debug("{} Next actions to start for rollout {} and parent group {}", rolloutGroupActions.size(), rollout,
rolloutGroup); 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()) { if (!rolloutGroupActions.isEmpty()) {
// get all next scheduled groups based on the found actions and set // get all next scheduled groups based on the found actions and set
// them in state running // 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.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.repository.ActionStatusFields; import org.eclipse.hawkbit.repository.ActionStatusFields;
import org.eclipse.hawkbit.repository.DistributionSetAssignmentResult; 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.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException;
import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; 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.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -146,11 +146,10 @@ public class ArtifactDetailsLayout extends VerticalLayout {
} }
private void createComponents() { private void createComponents() {
String labelStr = ""; final String labelStr = artifactUploadState.getSelectedBaseSoftwareModule()
if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) { .map(softwareModule -> HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(),
final SoftwareModule softwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get(); softwareModule.getVersion()))
labelStr = HawkbitCommonUtil.getFormattedNameVersion(softwareModule.getName(), softwareModule.getVersion()); .orElse("");
}
titleOfArtifactDetails = new LabelBuilder().name(HawkbitCommonUtil.getArtifactoryDetailsLabelId(labelStr)) titleOfArtifactDetails = new LabelBuilder().name(HawkbitCommonUtil.getArtifactoryDetailsLabelId(labelStr))
.buildCaptionLabel(); .buildCaptionLabel();
titleOfArtifactDetails.setContentMode(ContentMode.HTML); 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.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout; import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout;
import org.eclipse.hawkbit.ui.utils.I18N; 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.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import com.vaadin.data.Item; import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer; import com.vaadin.data.util.IndexedContainer;
import com.vaadin.spring.annotation.SpringComponent; 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.Button;
import com.vaadin.ui.Label; import com.vaadin.ui.Label;
import com.vaadin.ui.Table; import com.vaadin.ui.Table;
@@ -39,7 +39,7 @@ import com.vaadin.ui.themes.ValoTheme;
*/ */
@SpringComponent @SpringComponent
@VaadinSessionScope @ViewScope
public class DistributionSetMetadatadetailslayout extends Table { public class DistributionSetMetadatadetailslayout extends Table {
private static final long serialVersionUID = 2913758299611837718L; private static final long serialVersionUID = 2913758299611837718L;

View File

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

View File

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

View File

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

View File

@@ -9,24 +9,20 @@
package org.eclipse.hawkbit.ui.common.tagdetails; package org.eclipse.hawkbit.ui.common.tagdetails;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.TargetManagement; 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.Target;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.push.TargetTagAssigmentResultEventContainer;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod; import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.data.Item;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope; import com.vaadin.spring.annotation.ViewScope;
@@ -110,44 +106,32 @@ public class TargetTagToken extends AbstractTargetTagToken<Target> {
} }
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onTargetTagUpdateEvent(final TargetTagUpdateEvent event) { void onTargetTagAssigmentResultEvent(final TargetTagAssigmentResultEventContainer holder) {
final TargetTag entity = event.getEntity(); holder.getEvents().stream().map(event -> event.getAssigmentResult()).forEach(assignmentResult -> {
final Item item = container.getItem(entity.getId()); final TargetTag targetTag = assignmentResult.getTargetTag();
if (item != null) { if (isAssign(assignmentResult)) {
updateItem(entity.getName(), entity.getColour(), item); addNewToken(targetTag.getId());
} } else if (isUnassign(assignmentResult)) {
} removeTokenItem(targetTag.getId(), targetTag.getName());
}
@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());
}
} }
protected boolean isAssign(final TargetTagAssignmentResult assignmentResult) { protected boolean isAssign(final TargetTagAssignmentResult assignmentResult) {
if (assignmentResult.getAssigned() > 0) { if (assignmentResult.getAssigned() > 0 && managementUIState.getLastSelectedTargetIdName() != null) {
final List<String> assignedTargetNames = assignmentResult.getAssignedEntity().stream() return assignmentResult.getAssignedEntity().stream().map(t -> t.getControllerId())
.map(t -> t.getControllerId()).collect(Collectors.toList()); .anyMatch(controllerId -> controllerId
if (assignedTargetNames.contains(managementUIState.getLastSelectedTargetIdName().getControllerId())) { .equals(managementUIState.getLastSelectedTargetIdName().getControllerId()));
return true;
}
} }
return false; return false;
} }
protected boolean isUnassign(final TargetTagAssignmentResult assignmentResult) { protected boolean isUnassign(final TargetTagAssignmentResult assignmentResult) {
if (assignmentResult.getUnassigned() > 0) { if (assignmentResult.getUnassigned() > 0 && managementUIState.getLastSelectedTargetIdName() != null) {
final List<String> unassignedTargetNamesList = assignmentResult.getUnassignedEntity().stream() return assignmentResult.getUnassignedEntity().stream().map(t -> t.getControllerId())
.map(t -> t.getControllerId()).collect(Collectors.toList()); .anyMatch(controllerId -> controllerId
if (unassignedTargetNamesList.contains(managementUIState.getLastSelectedTargetIdName().getControllerId())) { .equals(managementUIState.getLastSelectedTargetIdName().getControllerId()));
return true;
}
} }
return false; 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.distributions.event.DistributionSetTypeEvent.DistributionSetTypeEnum;
import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; 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.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -405,7 +405,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout<Distri
eventBus.publish(this, eventBus.publish(this,
new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType)); new DistributionSetTypeEvent(DistributionSetTypeEnum.UPDATE_DIST_SET_TYPE, updateDistSetType));
} else { } else {
uiNotification.displayValidationError(i18n.get("message.tag.update.mandatory")); uiNotification.displayValidationError(i18n.get("message.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.SoftwareManagement;
import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement; 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.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet; 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.distributions.state.ManageDistUIState;
import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent;
import org.eclipse.hawkbit.ui.management.event.DistributionTableFilterEvent; 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.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.TableColumn; import org.eclipse.hawkbit.ui.utils.TableColumn;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -124,30 +126,56 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
} }
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final DistributionSetUpdateEvent event) { void onDistributionSetUpdateEvents(final DistributionSetUpdatedEventContainer eventContainer) {
final DistributionSet ds = event.getEntity();
final DistributionSetIdName lastSelectedDsIdName = manageDistUIState.getLastSelectedDistribution().isPresent()
? manageDistUIState.getLastSelectedDistribution().get() : null;
final List<DistributionSetIdName> visibleItemIds = (List<DistributionSetIdName>) getVisibleItemIds(); final List<DistributionSetIdName> visibleItemIds = (List<DistributionSetIdName>) getVisibleItemIds();
// refresh the details tabs only if selected ds is updated handleSelectedAndUpdatedDs(eventContainer.getEvents());
if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) {
// update table row+details layout updateVisableTableEntries(eventContainer.getEvents(), visibleItemIds);
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 private void handleSelectedAndUpdatedDs(final List<DistributionSetUpdateEvent> events) {
UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); 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) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final List<?> events) { void onDistributionCreatedEvents(final DistributionCreatedEventContainer eventContainer) {
final Object firstEvent = events.get(0); refreshDistributions();
if (DistributionCreatedEvent.class.isInstance(firstEvent)) { }
refreshDistributions();
} else if (DistributionDeletedEvent.class.isInstance(firstEvent)) { @EventBusListenerMethod(scope = EventScope.SESSION)
onDistributionDeleteEvent((List<DistributionDeletedEvent>) events); 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 @Override
@@ -454,7 +482,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final SaveActionWindowEvent event) { void onEvent(final SaveActionWindowEvent event) {
if (event == SaveActionWindowEvent.DELETED_DISTRIBUTIONS || event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) { 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 if (event == DistributionTableFilterEvent.FILTER_BY_TEXT
|| event == DistributionTableFilterEvent.REMOVE_FILTER_BY_TEXT || event == DistributionTableFilterEvent.REMOVE_FILTER_BY_TEXT
|| event == DistributionTableFilterEvent.FILTER_BY_TAG) { || 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); 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() { private void refreshOnDelete() {
final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource();
final int size = dsContainer.size(); 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.filtermanagement.state.FilterManagementUIState;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.EventScope;
@@ -100,13 +100,11 @@ public class TargetFilterCountMessageLabel extends Label {
setDescription(null); setDescription(null);
} }
targetMessage.append(totalTargets); targetMessage.append(totalTargets);
targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE);
targetMessage.append(i18n.get("label.filter.shown"));
if (totalTargets > SPUIDefinitions.MAX_TABLE_ENTRIES) { 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); targetMessage.append(SPUIDefinitions.MAX_TABLE_ENTRIES);
} else {
targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE);
targetMessage.append(totalTargets);
} }
setCaption(targetMessage.toString()); setCaption(targetMessage.toString());

View File

@@ -12,6 +12,7 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; 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.DistributionSetManagement;
import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement; 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.DistributionDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent;
import org.eclipse.hawkbit.repository.model.DistributionSet; 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.PinUnpinEvent;
import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.management.event.SaveActionWindowEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState; 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.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
@@ -113,44 +116,95 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
} }
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final List<?> events) { void onDistributionCreatedEvents(final DistributionCreatedEventContainer eventContainer) {
final Object firstEvent = events.get(0); if (eventContainer.getEvents().stream().anyMatch(event -> event.getEntity().isComplete())) {
if (DistributionDeletedEvent.class.isInstance(firstEvent)) {
onDistributionDeleteEvent((List<DistributionDeletedEvent>) events);
} else if (DistributionCreatedEvent.class.isInstance(firstEvent)
&& ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) {
refreshDistributions(); refreshDistributions();
} }
} }
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
void onEvents(final DistributionSetUpdateEvent event) { void onDistributionDeleteEvents(final DistributionDeletedEventContainer eventContainer) {
final DistributionSet ds = event.getEntity(); 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 List<DistributionSetIdName> visibleItemIds = (List<DistributionSetIdName>) getVisibleItemIds();
final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst() if (allOfThemAffectCompletedSetsThatAreNotVisible(eventContainer.getEvents(), visibleItemIds)) {
.isPresent(); 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(); refreshDistributions();
} else if (!ds.isComplete() && dsVisible) {
refreshDistributions(); if (setsThatAreVisibleButNotCompleteAnymore.stream()
if (ds.getId().equals(managementUIState.getLastSelectedDsIdName().getId())) { .anyMatch(set -> set.getId().equals(managementUIState.getLastSelectedDsIdName().getId()))) {
managementUIState.setLastSelectedDistribution(null); managementUIState.setLastSelectedDistribution(null);
managementUIState.setLastSelectedEntity(null); managementUIState.setLastSelectedEntity(null);
} }
} else if (dsVisible) { return true;
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 false;
} }
/** /**
@@ -717,28 +771,6 @@ public class DistributionTable extends AbstractNamedVersionTable<DistributionSet
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); 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() { private void reSelectItemsAfterDeletionEvent() {
Set<Object> values = new HashSet<>(); Set<Object> values = new HashSet<>();
if (isMultiSelect()) { if (isMultiSelect()) {

View File

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

View File

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

View File

@@ -14,9 +14,7 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.ui.common.DistributionSetIdName;
import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent;
import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent; import org.eclipse.hawkbit.ui.management.event.PinUnpinEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
@@ -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.management.targettable.TargetTable;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod; import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings; import com.google.common.base.Optional;
import com.vaadin.server.FontAwesome; import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
@@ -131,17 +129,17 @@ public class CountMessageLabel extends Label {
private void displayTargetCountStatus() { private void displayTargetCountStatus() {
final TargetTableFilters targFilParams = managementUIState.getTargetTableFilters(); final TargetTableFilters targFilParams = managementUIState.getTargetTableFilters();
final StringBuilder message = getTotalTargetMessage(targFilParams); final StringBuilder message = getTotalTargetMessage();
final String filteredTargets = i18n.get("label.filter.targets");
if (targFilParams.hasFilter()) { if (targFilParams.hasFilter()) {
message.append(filteredTargets); message.append(HawkbitCommonUtil.SP_STRING_PIPE);
message.append(i18n.get("label.filter.targets"));
if (managementUIState.getTargetsTruncated() != null) { if (managementUIState.getTargetsTruncated() != null) {
message.append(targetTable.size() + managementUIState.getTargetsTruncated()); message.append(targetTable.size() + managementUIState.getTargetsTruncated());
} else { } else {
message.append(targetTable.size()); 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 status = i18n.get("label.filter.status");
final String overdue = i18n.get("label.filter.overdue"); final String overdue = i18n.get("label.filter.overdue");
final String tags = i18n.get("label.filter.tags"); final String tags = i18n.get("label.filter.tags");
@@ -154,13 +152,12 @@ public class CountMessageLabel extends Label {
filterMesgBuf.append(getOverdueStateMsg(targFilParams.isOverdueFilterEnabled(), overdue)); filterMesgBuf.append(getOverdueStateMsg(targFilParams.isOverdueFilterEnabled(), overdue));
filterMesgBuf filterMesgBuf
.append(getTagsMsg(targFilParams.isNoTagSelected(), targFilParams.getClickedTargetTags(), tags)); .append(getTagsMsg(targFilParams.isNoTagSelected(), targFilParams.getClickedTargetTags(), tags));
filterMesgBuf.append(getSerachMsg( filterMesgBuf.append(
targFilParams.getSearchText().isPresent() ? targFilParams.getSearchText().get() : null, text)); targFilParams.getSearchText().map(search -> text).orElse(HawkbitCommonUtil.SP_STRING_SPACE));
filterMesgBuf.append(getDistMsg( filterMesgBuf.append(
targFilParams.getDistributionSet().isPresent() ? targFilParams.getDistributionSet().get() : null, targFilParams.getDistributionSet().map(set -> dists).orElse(HawkbitCommonUtil.SP_STRING_SPACE));
dists)); filterMesgBuf.append(targFilParams.getTargetFilterQuery().map(query -> custom)
filterMesgBuf.append(getCustomFilterMsg(targFilParams.getTargetFilterQuery().isPresent() .orElse(HawkbitCommonUtil.SP_STRING_SPACE));
? targFilParams.getTargetFilterQuery().get() : null, custom));
final String filterMesageChk = filterMesgBuf.toString().trim(); final String filterMesageChk = filterMesgBuf.toString().trim();
String filterMesage = filterMesageChk; String filterMesage = filterMesageChk;
if (filterMesage.endsWith(",")) { if (filterMesage.endsWith(",")) {
@@ -168,17 +165,23 @@ public class CountMessageLabel extends Label {
} }
message.append(filterMesage); 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()); setCaption(message.toString());
} }
private StringBuilder getTotalTargetMessage(final TargetTableFilters targFilParams) { private StringBuilder getTotalTargetMessage() {
long totalTargetTableEnteries = targetTable.size();
if (managementUIState.getTargetsTruncated() != null) { if (managementUIState.getTargetsTruncated() != null) {
// set the icon // set the icon
setIcon(FontAwesome.INFO_CIRCLE); setIcon(FontAwesome.INFO_CIRCLE);
setDescription(i18n.get("label.target.filter.truncated", managementUIState.getTargetsTruncated(), setDescription(i18n.get("label.target.filter.truncated", managementUIState.getTargetsTruncated(),
SPUIDefinitions.MAX_TABLE_ENTRIES)); SPUIDefinitions.MAX_TABLE_ENTRIES));
totalTargetTableEnteries += managementUIState.getTargetsTruncated();
} else { } else {
setIcon(null); setIcon(null);
setDescription(null); setDescription(null);
@@ -186,20 +189,7 @@ public class CountMessageLabel extends Label {
final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count")); final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count"));
message.append(managementUIState.getTargetsCountAll()); 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; return message;
} }
@@ -255,37 +245,4 @@ public class CountMessageLabel extends Label {
return tags.isEmpty() && (noTargetTagSelected == null || !noTargetTagSelected.booleanValue()) return tags.isEmpty() && (noTargetTagSelected == null || !noTargetTagSelected.booleanValue())
? HawkbitCommonUtil.SP_STRING_SPACE : param; ? 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.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope; import com.vaadin.spring.annotation.VaadinSessionScope;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.CustomComponent; import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.FormLayout; import com.vaadin.ui.FormLayout;
import com.vaadin.ui.TextArea; import com.vaadin.ui.TextArea;
@@ -45,7 +46,7 @@ import com.vaadin.ui.Window;
* Add and Update Target. * Add and Update Target.
*/ */
@SpringComponent @SpringComponent
@VaadinSessionScope @ViewScope
public class TargetAddUpdateWindowLayout extends CustomComponent { public class TargetAddUpdateWindowLayout extends CustomComponent {
private static final long serialVersionUID = -6659290471705262389L; private static final long serialVersionUID = -6659290471705262389L;

View File

@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.FilterParams;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest; import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.TargetManagement;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
@@ -52,15 +53,15 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
private static final long serialVersionUID = -5645680058303167558L; private static final long serialVersionUID = -5645680058303167558L;
private Sort sort = new Sort(TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt"); private Sort sort = new Sort(TARGET_TABLE_CREATE_AT_SORT_ORDER, "createdAt");
private transient Collection<TargetUpdateStatus> status = null; private transient Collection<TargetUpdateStatus> status;
private transient Boolean overdueState; private transient Boolean overdueState;
private String[] targetTags = null; private String[] targetTags;
private Long distributionId = null; private Long distributionId;
private String searchText = null; private String searchText;
private Boolean noTagClicked = Boolean.FALSE; private Boolean noTagClicked;
private transient TargetManagement targetManagement; private transient TargetManagement targetManagement;
private transient I18N i18N; private transient I18N i18N;
private Long pinnedDistId = null; private Long pinnedDistId;
private TargetFilterQuery targetFilterQuery; private TargetFilterQuery targetFilterQuery;
private ManagementUIState managementUIState; private ManagementUIState managementUIState;
@@ -210,7 +211,7 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
private boolean isAnyFilterSelected() { private boolean isAnyFilterSelected() {
final boolean isFilterSelected = isTagSelected() || isOverdueFilterEnabled(); final boolean isFilterSelected = isTagSelected() || isOverdueFilterEnabled();
return isFilterSelected || status != null || distributionId != null || !isNullOrEmpty(searchText); return isFilterSelected || CollectionUtils.isNotEmpty(status) || distributionId != null || !isNullOrEmpty(searchText);
} }
private TargetManagement getTargetManagement() { private TargetManagement getTargetManagement() {

View File

@@ -22,17 +22,16 @@ import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.FilterParams; import org.eclipse.hawkbit.repository.FilterParams;
import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement; 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.TargetDeletedEvent;
import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; 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.NamedEntity;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetIdName;
@@ -55,6 +54,11 @@ import org.eclipse.hawkbit.ui.management.event.TargetTableEvent;
import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.management.state.TargetTableFilters; import org.eclipse.hawkbit.ui.management.state.TargetTableFilters;
import org.eclipse.hawkbit.ui.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.AssignInstalledDSTooltipGenerator;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil;
@@ -74,6 +78,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.vaadin.data.Container; import com.vaadin.data.Container;
import com.vaadin.data.Item; import com.vaadin.data.Item;
import com.vaadin.event.dd.DragAndDropEvent; import com.vaadin.event.dd.DragAndDropEvent;
@@ -123,28 +128,86 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
setItemDescriptionGenerator(new AssignInstalledDSTooltipGenerator()); 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) @EventBusListenerMethod(scope = EventScope.SESSION)
public void onEvents(final List<?> events) { void onTargetDeletedEvents(final TargetDeletedEventContainer eventContainer) {
final Object firstEvent = events.get(0); final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource();
if (TargetCreatedEvent.class.isInstance(firstEvent)) { final List<Object> visibleItemIds = (List<Object>) getVisibleItemIds();
onTargetCreatedEvents(); boolean shouldRefreshTargets = false;
} else if (TargetInfoUpdateEvent.class.isInstance(firstEvent)) { for (final TargetDeletedEvent deletedEvent : eventContainer.getEvents()) {
onTargetUpdateEvents(((List<TargetInfoUpdateEvent>) events).stream() final TargetIdName targetIdName = new TargetIdName(deletedEvent.getTargetId(), null, null);
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity().getTarget()) if (visibleItemIds.contains(targetIdName)) {
.collect(Collectors.toList())); targetContainer.removeItem(targetIdName);
} else if (TargetDeletedEvent.class.isInstance(firstEvent)) { } else {
onTargetDeletedEvent((List<TargetDeletedEvent>) events); shouldRefreshTargets = true;
} else if (TargetUpdatedEvent.class.isInstance(firstEvent)) { break;
onTargetUpdateEvents(((List<TargetUpdatedEvent>) events).stream() }
.map(targetInfoUpdateEvent -> targetInfoUpdateEvent.getEntity()).collect(Collectors.toList()));
} }
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) @EventBusListenerMethod(scope = EventScope.SESSION)
@@ -300,31 +363,12 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
return managementViewAcceptCriteria; 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() { private void reSelectItemsAfterDeletionEvent() {
Set<Object> values = new HashSet<>(); Set<Object> values;
if (isMultiSelect()) { if (isMultiSelect()) {
values = new HashSet<>((Set<?>) getValue()); values = new HashSet<>((Set<?>) getValue());
} else { } else {
values = Sets.newHashSetWithExpectedSize(1);
values.add(getValue()); values.add(getValue());
} }
unSelectAll(); unSelectAll();
@@ -766,41 +810,6 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
&& managementUIState.getLastSelectedTargetIdName().equals(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() { private boolean isFilterEnabled() {
final TargetTableFilters targetTableFilters = managementUIState.getTargetTableFilters(); final TargetTableFilters targetTableFilters = managementUIState.getTargetTableFilters();
return targetTableFilters.getSearchText().isPresent() || !targetTableFilters.getClickedTargetTags().isEmpty() return targetTableFilters.getSearchText().isPresent() || !targetTableFilters.getClickedTargetTags().isEmpty()
@@ -873,16 +882,12 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
} }
private long getTargetsCountWithFilter(final long totalTargetsCount, private long getTargetsCountWithFilter(final long totalTargetsCount,
// final Collection<TargetUpdateStatus> status,
// final Boolean overdueState, final String[] targetTags, final Long
// distributionId, final String searchText,
// final Boolean noTagClicked
final Long pinnedDistId, final FilterParams filterParams) { final Long pinnedDistId, final FilterParams filterParams) {
final long size; final long size;
if (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) { if (managementUIState.getTargetTableFilters().getTargetFilterQuery().isPresent()) {
size = targetManagement.countTargetByTargetFilterQuery( size = targetManagement.countTargetByTargetFilterQuery(
managementUIState.getTargetTableFilters().getTargetFilterQuery().get()); managementUIState.getTargetTableFilters().getTargetFilterQuery().get());
} else if (!anyFilterSelected(filterParams.getFilterByStatus(), pinnedDistId, } else if (noFilterSelected(filterParams.getFilterByStatus(), pinnedDistId,
filterParams.getSelectTargetWithNoTag(), filterParams.getFilterByTagNames(), filterParams.getSelectTargetWithNoTag(), filterParams.getFilterByTagNames(),
filterParams.getFilterBySearchText())) { filterParams.getFilterBySearchText())) {
size = totalTargetsCount; size = totalTargetsCount;
@@ -900,9 +905,9 @@ public class TargetTable extends AbstractTable<Target, TargetIdName> {
&& !Strings.isNullOrEmpty(managementUIState.getTargetTableFilters().getSearchText().get()); && !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) { 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); && !isTagSelected(targetTags, noTagClicked);
} }

View File

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

View File

@@ -28,7 +28,7 @@ import org.vaadin.spring.events.annotation.EventBusListenerMethod;
import com.vaadin.server.FontAwesome; import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.VaadinSessionScope; import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Alignment; import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button; import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickEvent;
@@ -41,7 +41,7 @@ import com.vaadin.ui.VerticalLayout;
* *
*/ */
@SpringComponent @SpringComponent
@VaadinSessionScope @ViewScope
public class FilterByStatusLayout extends VerticalLayout implements Button.ClickListener { public class FilterByStatusLayout extends VerticalLayout implements Button.ClickListener {
private static final long serialVersionUID = -6930348859189929850L; 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.EntityFactory;
import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.repository.TargetManagement; 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.TargetIdName;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; 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.event.ManagementViewAcceptCriteria;
import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.state.ManagementUIState;
import org.eclipse.hawkbit.ui.management.tag.TagIdName; 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.HawkbitCommonUtil;
import org.eclipse.hawkbit.ui.utils.I18N; 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.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
@@ -286,21 +286,21 @@ public class TargetTagFilterButtons extends AbstractFilterButtons {
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed // Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" }) @SuppressWarnings({ "squid:S1172" })
void onEvent(final TargetTagUpdateEvent event) { void onEvent(final TargetTagUpdatedEventContainer eventContainer) {
refreshContainer(); refreshContainer();
} }
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed // Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" }) @SuppressWarnings({ "squid:S1172" })
void onEventTargetTagCreated(final TargetTagCreatedBulkEvent event) { void onEventTargetTagCreated(final TargetTagCreatedEventContainer eventContainer) {
refreshContainer(); refreshContainer();
} }
@EventBusListenerMethod(scope = EventScope.SESSION) @EventBusListenerMethod(scope = EventScope.SESSION)
// Exception squid:S1172 - event not needed // Exception squid:S1172 - event not needed
@SuppressWarnings({ "squid:S1172" }) @SuppressWarnings({ "squid:S1172" })
void onEventTargetDeletedEvent(final TargetTagDeletedEvent event) { void onEventTargetDeletedEvent(final TargetTagDeletedEventContainer eventContainer) {
refreshContainer(); 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; package org.eclipse.hawkbit.ui.push;
import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.concurrent.BlockingDeque; import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingDeque; 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.EntityEvent;
import org.eclipse.hawkbit.eventbus.event.Event; import org.eclipse.hawkbit.eventbus.event.Event;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.ui.UIEventProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
@@ -113,8 +112,7 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
} }
private boolean isEventProvided(final Event event) { private boolean isEventProvided(final Event event) {
return eventProvider.getSingleEvents().contains(event.getClass()) return eventProvider.getEvents().containsKey(event.getClass());
|| eventProvider.getBulkEvents().contains(event.getClass());
} }
@Override @Override
@@ -125,8 +123,8 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
LOG.error("Vaadin session of UI {} is null! Event push disabled!", uiid); LOG.error("Vaadin session of UI {} is null! Event push disabled!", uiid);
} }
jobHandle = executorService.scheduleWithFixedDelay(new DispatchRunnable(vaadinUI, vaadinUI.getSession()), 500, jobHandle = executorService.scheduleWithFixedDelay(new DispatchRunnable(vaadinUI, vaadinUI.getSession()),
2000, TimeUnit.MILLISECONDS); 10_000, 1_000, TimeUnit.MILLISECONDS);
systemEventBus.register(this); systemEventBus.register(this);
} }
@@ -212,13 +210,13 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
try { try {
SecurityContextHolder.setContext(userContext); SecurityContextHolder.setContext(userContext);
final List<EventContainer<Event>> groupedEvents = groupEvents(events, userContext, eventProvider);
vaadinUI.access(() -> { vaadinUI.access(() -> {
if (vaadinSession.getState() != State.OPEN) { if (vaadinSession.getState() != State.OPEN) {
return; return;
} }
LOG.debug("UI EventBus aggregator of UI {} got lock on session.", vaadinUI.getUIId()); LOG.debug("UI EventBus aggregator of UI {} got lock on session.", vaadinUI.getUIId());
fowardSingleEvents(events, userContext); groupedEvents.forEach(holder -> eventBus.publish(vaadinUI, holder));
fowardBulkEvents(events, userContext);
LOG.debug("UI EventBus aggregator of UI {} left lock on session.", vaadinUI.getUIId()); LOG.debug("UI EventBus aggregator of UI {} left lock on session.", vaadinUI.getUIId());
}).get(); }).get();
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
@@ -228,25 +226,25 @@ public class DelayedEventBusPushStrategy implements EventPushStrategy {
} }
} }
private void fowardBulkEvents(final List<Event> events, final SecurityContext userContext) { @SuppressWarnings("unchecked")
final Set<Class<?>> filterBulkEvenTypes = eventProvider.getFilteredBulkEventsType(events); private List<EventContainer<Event>> groupEvents(final List<Event> events, final SecurityContext userContext,
final UIEventProvider eventProvider) {
for (final Class<?> bulkType : filterBulkEvenTypes) { return events.stream().filter(event -> eventSecurityCheck(userContext, event))
final List<Event> listBulkEvents = events.stream() .collect(Collectors.groupingBy(Event::getClass)).entrySet().stream().map(entry -> {
.filter(event -> DelayedEventBusPushStrategy.eventSecurityCheck(userContext, event) EventContainer<Event> holder = null;
&& bulkType.isInstance(event)) try {
.collect(Collectors.toList()); final Constructor<Event> declaredConstructor = (Constructor<Event>) eventProvider
if (!listBulkEvents.isEmpty()) { .getEvents().get(entry.getKey()).getDeclaredConstructor(List.class);
eventBus.publish(vaadinUI, listBulkEvents); declaredConstructor.setAccessible(true);
}
}
}
private void fowardSingleEvents(final List<Event> events, final SecurityContext userContext) { holder = (EventContainer<Event>) declaredConstructor.newInstance(entry.getValue());
events.stream() } catch (final ReflectiveOperationException e) {
.filter(event -> DelayedEventBusPushStrategy.eventSecurityCheck(userContext, event) LOG.error("Failed to create EventHolder!", e);
&& eventProvider.getSingleEvents().contains(event.getClass())) }
.forEach(event -> eventBus.publish(vaadinUI, event));
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