Merge branch 'master' into feature_target_filtering_supports_overdue

Conflicts:
	hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java
This commit is contained in:
Dominik Herbst
2016-09-27 13:38:55 +02:00
118 changed files with 995 additions and 1156 deletions

View File

@@ -1,11 +1,12 @@
Build: [![Circle CI](https://circleci.com/gh/eclipse/hawkbit.svg?style=svg)](https://circleci.com/gh/eclipse/hawkbit)
<img src=hawkbit_logo.png width=533 height=246 /> <img src=hawkbit_logo.png width=533 height=246 />
# Eclipse.IoT hawkBit - Update Server # Eclipse.IoT hawkBit - Update Server
[hawkBit](https://projects.eclipse.org/projects/iot.hawkbit) is an domain independent back end solution for rolling out software updates to constrained edge devices as well as more powerful controllers and gateways connected to IP based networking infrastructure. [hawkBit](https://projects.eclipse.org/projects/iot.hawkbit) is an domain independent back end solution for rolling out software updates to constrained edge devices as well as more powerful controllers and gateways connected to IP based networking infrastructure.
Build: [![Circle CI](https://circleci.com/gh/eclipse/hawkbit.svg?style=shield)](https://circleci.com/gh/eclipse/hawkbit)
[![SonarQuality](https://sonar.eu-gb.mybluemix.net/api/badges/gate?key=org.eclipse.hawkbit:hawkbit-parent)](https://sonar.eu-gb.mybluemix.net)
# Documentation # Documentation
see [hawkBit Wiki](https://github.com/eclipse/hawkbit/wiki) see [hawkBit Wiki](https://github.com/eclipse/hawkbit/wiki)

View File

@@ -8,6 +8,8 @@ package org.eclipse.hawkbit.app;
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
*/ */
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.UIEventProvider;
import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy; import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy;
@@ -38,8 +40,8 @@ public class MyUI extends HawkbitUI {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Autowired @Autowired
public MyUI(final EventBus systemEventBus, final org.vaadin.spring.events.EventBus.SessionEventBus eventBus, public MyUI(final ScheduledExecutorService executorService, final EventBus systemEventBus,
final UIEventProvider provider) { final org.vaadin.spring.events.EventBus.SessionEventBus eventBus, final UIEventProvider provider) {
super(new DelayedEventBusPushStrategy(eventBus, systemEventBus, provider)); super(new DelayedEventBusPushStrategy(executorService, eventBus, systemEventBus, provider));
} }
} }

View File

@@ -11,7 +11,6 @@ package org.eclipse.hawkbit.simulator.amqp;
import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX;
import java.time.Duration; import java.time.Duration;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -36,6 +35,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.support.RetryTemplate; import org.springframework.retry.support.RetryTemplate;
import com.google.common.collect.Maps;
/** /**
* The spring AMQP configuration to use a AMQP for communication with SP update * The spring AMQP configuration to use a AMQP for communication with SP update
* server. * server.
@@ -200,13 +201,13 @@ public class AmqpConfiguration {
} }
private Map<String, Object> getDeadLetterExchangeArgs() { private Map<String, Object> getDeadLetterExchangeArgs() {
final Map<String, Object> args = new HashMap<>(); final Map<String, Object> args = Maps.newHashMapWithExpectedSize(1);
args.put("x-dead-letter-exchange", amqpProperties.getDeadLetterExchange()); args.put("x-dead-letter-exchange", amqpProperties.getDeadLetterExchange());
return args; return args;
} }
private static Map<String, Object> getTTLMaxArgs() { private static Map<String, Object> getTTLMaxArgs() {
final Map<String, Object> args = new HashMap<>(); final Map<String, Object> args = Maps.newHashMapWithExpectedSize(2);
args.put("x-message-ttl", Duration.ofDays(1).toMillis()); args.put("x-message-ttl", Duration.ofDays(1).toMillis());
args.put("x-max-length", 100_000); args.put("x-max-length", 100_000);
return args; return args;

View File

@@ -8,6 +8,8 @@
*/ */
package org.eclipse.hawkbit.app; package org.eclipse.hawkbit.app;
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.UIEventProvider;
import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy; import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy;
@@ -37,8 +39,8 @@ public class MyUI extends HawkbitUI {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Autowired @Autowired
public MyUI(final EventBus systemEventBus, final org.vaadin.spring.events.EventBus.SessionEventBus eventBus, public MyUI(final ScheduledExecutorService scheduledExecutorService, final EventBus systemEventBus,
final UIEventProvider provider) { final org.vaadin.spring.events.EventBus.SessionEventBus eventBus, final UIEventProvider provider) {
super(new DelayedEventBusPushStrategy(eventBus, systemEventBus, provider)); super(new DelayedEventBusPushStrategy(scheduledExecutorService, eventBus, systemEventBus, provider));
} }
} }

View File

@@ -41,14 +41,11 @@ public class PropertyHostnameResolverAutoConfiguration {
@Bean @Bean
@ConditionalOnMissingBean(value = HostnameResolver.class) @ConditionalOnMissingBean(value = HostnameResolver.class)
public HostnameResolver hostnameResolver() { public HostnameResolver hostnameResolver() {
return new HostnameResolver() { return () -> {
@Override try {
public URL resolveHostname() { return new URL(serverProperties.getUrl());
try { } catch (final MalformedURLException e) {
return new URL(serverProperties.getUrl()); throw Throwables.propagate(e);
} catch (final MalformedURLException e) {
throw Throwables.propagate(e);
}
} }
}; };
} }

View File

@@ -37,7 +37,9 @@ public interface DdiRootControllerRestApi {
/** /**
* Returns all artifacts of a given software module and target. * Returns all artifacts of a given software module and target.
* *
* @param tenant
* of the request
* @param targetid * @param targetid
* of the target that matches to controller id * of the target that matches to controller id
* @param softwareModuleId * @param softwareModuleId
@@ -53,6 +55,8 @@ public interface DdiRootControllerRestApi {
/** /**
* Root resource for an individual {@link Target}. * Root resource for an individual {@link Target}.
* *
* @param tenant
* of the request
* @param targetid * @param targetid
* of the target that matches to controller id * of the target that matches to controller id
* @param request * @param request
@@ -68,6 +72,8 @@ public interface DdiRootControllerRestApi {
* Handles GET {@link DdiArtifact} download request. This could be full or * Handles GET {@link DdiArtifact} download request. This could be full or
* partial (as specified by RFC7233 (Range Requests)) download request. * partial (as specified by RFC7233 (Range Requests)) download request.
* *
* @param tenant
* of the request
* @param targetid * @param targetid
* of the related target * of the related target
* @param softwareModuleId * @param softwareModuleId
@@ -92,6 +98,8 @@ public interface DdiRootControllerRestApi {
/** /**
* Handles GET {@link DdiArtifact} MD5 checksum file download request. * Handles GET {@link DdiArtifact} MD5 checksum file download request.
* *
* @param tenant
* of the request
* @param targetid * @param targetid
* of the related target * of the related target
* @param softwareModuleId * @param softwareModuleId
@@ -116,6 +124,8 @@ public interface DdiRootControllerRestApi {
/** /**
* Resource for software module. * Resource for software module.
* *
* @param tenant
* of the request
* @param targetid * @param targetid
* of the target that matches to controller id * of the target that matches to controller id
* @param actionId * @param actionId
@@ -139,6 +149,8 @@ public interface DdiRootControllerRestApi {
/** /**
* This is the feedback channel for the {@link DdiDeploymentBase} action. * This is the feedback channel for the {@link DdiDeploymentBase} action.
* *
* @param tenant
* of the request
* @param feedback * @param feedback
* to provide * to provide
* @param targetid * @param targetid
@@ -159,6 +171,8 @@ public interface DdiRootControllerRestApi {
/** /**
* This is the feedback channel for the config data action. * This is the feedback channel for the config data action.
* *
* @param tenant
* of the request
* @param configData * @param configData
* as body * as body
* @param targetid * @param targetid
@@ -176,6 +190,8 @@ public interface DdiRootControllerRestApi {
/** /**
* RequestMethod.GET method for the {@link DdiCancel} action. * RequestMethod.GET method for the {@link DdiCancel} action.
* *
* @param tenant
* of the request
* @param targetid * @param targetid
* ID of the calling target * ID of the calling target
* @param actionId * @param actionId
@@ -195,6 +211,8 @@ public interface DdiRootControllerRestApi {
* RequestMethod.POST method receiving the {@link DdiActionFeedback} from * RequestMethod.POST method receiving the {@link DdiActionFeedback} from
* the target. * the target.
* *
* @param tenant
* of the request
* @param feedback * @param feedback
* the {@link DdiActionFeedback} from the target. * the {@link DdiActionFeedback} from the target.
* @param targetid * @param targetid

View File

@@ -12,7 +12,6 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -73,16 +72,16 @@ public final class DataConversionHelper {
* of the target * of the target
* @param module * @param module
* the software module * the software module
* @param artifactUrlHandler
* for creating download URLs
* @return a list of artifacts or a empty list. Cannot be <null>. * @return a list of artifacts or a empty list. Cannot be <null>.
*/ */
public static List<DdiArtifact> createArtifacts(final String targetid, public static List<DdiArtifact> createArtifacts(final String targetid,
final org.eclipse.hawkbit.repository.model.SoftwareModule module, final org.eclipse.hawkbit.repository.model.SoftwareModule module,
final ArtifactUrlHandler artifactUrlHandler) { final ArtifactUrlHandler artifactUrlHandler) {
final List<DdiArtifact> files = new ArrayList<>();
module.getLocalArtifacts() return module.getLocalArtifacts().stream()
.forEach(artifact -> files.add(createArtifact(targetid, artifactUrlHandler, artifact))); .map(artifact -> createArtifact(targetid, artifactUrlHandler, artifact)).collect(Collectors.toList());
return files;
} }
private static DdiArtifact createArtifact(final String targetid, final ArtifactUrlHandler artifactUrlHandler, private static DdiArtifact createArtifact(final String targetid, final ArtifactUrlHandler artifactUrlHandler,

View File

@@ -35,7 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;

View File

@@ -151,7 +151,12 @@ public class DdiRootController implements DdiRootControllerRestApi {
LOG.warn("Softare module with id {} could not be found.", softwareModuleId); LOG.warn("Softare module with id {} could not be found.", softwareModuleId);
result = new ResponseEntity<>(HttpStatus.NOT_FOUND); result = new ResponseEntity<>(HttpStatus.NOT_FOUND);
} else { } else {
// Exception squid:S3655 - Optional access is checked in checkModule
// subroutine
@SuppressWarnings("squid:S3655")
final LocalArtifact artifact = module.getLocalArtifactByFilename(fileName).get(); final LocalArtifact artifact = module.getLocalArtifactByFilename(fileName).get();
final DbArtifact file = artifactManagement.loadLocalArtifactBinary(artifact); final DbArtifact file = artifactManagement.loadLocalArtifactBinary(artifact);
final String ifMatch = requestResponseContextHolder.getHttpServletRequest().getHeader("If-Match"); final String ifMatch = requestResponseContextHolder.getHttpServletRequest().getHeader("If-Match");
@@ -196,6 +201,9 @@ public class DdiRootController implements DdiRootControllerRestApi {
} }
@Override @Override
// Exception squid:S3655 - Optional access is checked in checkModule
// subroutine
@SuppressWarnings("squid:S3655")
public ResponseEntity<Void> downloadArtifactMd5(@PathVariable("tenant") final String tenant, public ResponseEntity<Void> downloadArtifactMd5(@PathVariable("tenant") final String tenant,
@PathVariable("targetid") final String targetid, @PathVariable("targetid") final String targetid,
@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("softwareModuleId") final Long softwareModuleId,

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.amqp; package org.eclipse.hawkbit.amqp;
import java.time.Duration; import java.time.Duration;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
@@ -47,6 +46,8 @@ import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.support.RetryTemplate; import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.ErrorHandler; import org.springframework.util.ErrorHandler;
import com.google.common.collect.Maps;
/** /**
* Spring configuration for AMQP 0.9 based DMF communication for indirect device * Spring configuration for AMQP 0.9 based DMF communication for indirect device
* integration. * integration.
@@ -306,7 +307,7 @@ public class AmqpConfiguration {
} }
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() { private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
final Map<String, Object> args = new HashMap<>(); final Map<String, Object> args = Maps.newHashMapWithExpectedSize(2);
args.put("x-message-ttl", Duration.ofSeconds(30).toMillis()); args.put("x-message-ttl", Duration.ofSeconds(30).toMillis());
args.put("x-max-length", 1_000); args.put("x-max-length", 1_000);
return args; return args;

View File

@@ -9,24 +9,26 @@
package org.eclipse.hawkbit.amqp; package org.eclipse.hawkbit.amqp;
import java.time.Duration; import java.time.Duration;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.Queue;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import com.google.common.collect.Maps;
/** /**
* Bean which holds the necessary properties for configuring the AMQP deadletter * Bean which holds the necessary properties for configuring the AMQP deadletter
* queue. * queue.
*/ */
@ConfigurationProperties("hawkbit.dmf.rabbitmq.deadLetter") @ConfigurationProperties("hawkbit.dmf.rabbitmq.deadLetter")
public class AmqpDeadletterProperties { public class AmqpDeadletterProperties {
private static final int THREE_WEEKS = 21;
/** /**
* Message time to live (ttl) for the deadletter queue. Default ttl is 3 * Message time to live (ttl) for the deadletter queue. Default ttl is 3
* weeks. * weeks.
*/ */
private long ttl = Duration.ofDays(21).toMillis(); private long ttl = Duration.ofDays(THREE_WEEKS).toMillis();
/** /**
* Return the deadletter arguments. * Return the deadletter arguments.
@@ -36,7 +38,7 @@ public class AmqpDeadletterProperties {
* @return map which holds the properties * @return map which holds the properties
*/ */
public Map<String, Object> getDeadLetterExchangeArgs(final String exchange) { public Map<String, Object> getDeadLetterExchangeArgs(final String exchange) {
final Map<String, Object> args = new HashMap<>(); final Map<String, Object> args = Maps.newHashMapWithExpectedSize(1);
args.put("x-dead-letter-exchange", exchange); args.put("x-dead-letter-exchange", exchange);
return args; return args;
} }
@@ -53,7 +55,7 @@ public class AmqpDeadletterProperties {
} }
private Map<String, Object> getTTLArgs() { private Map<String, Object> getTTLArgs() {
final Map<String, Object> args = new HashMap<>(); final Map<String, Object> args = Maps.newHashMapWithExpectedSize(1);
args.put("x-message-ttl", getTtl()); args.put("x-message-ttl", getTtl());
return args; return args;
} }

View File

@@ -20,6 +20,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("hawkbit.dmf.rabbitmq") @ConfigurationProperties("hawkbit.dmf.rabbitmq")
public class AmqpProperties { public class AmqpProperties {
private static final int ONE_MINUTE = 60;
private static final int DEFAULT_QUEUE_DECLARATION_RETRIES = 50;
private static final int DEFAULT_INITIAL_CONSUMERS = 3;
private static final int DEFAULT_PREFETCH_COUNT = 10;
private static final int DEFAULT_MAX_CONSUMERS = 10;
/** /**
* Enable DMF API based on AMQP 0.9 * Enable DMF API based on AMQP 0.9
*/ */
@@ -54,24 +64,24 @@ public class AmqpProperties {
/** /**
* Requested heartbeat interval from broker in {@link TimeUnit#SECONDS}. * Requested heartbeat interval from broker in {@link TimeUnit#SECONDS}.
*/ */
private int requestedHeartBeat = (int) TimeUnit.SECONDS.toSeconds(60); private int requestedHeartBeat = (int) TimeUnit.SECONDS.toSeconds(ONE_MINUTE);
/** /**
* Sets an upper limit to the number of consumers. * Sets an upper limit to the number of consumers.
*/ */
private int maxConcurrentConsumers = 10; private int maxConcurrentConsumers = DEFAULT_MAX_CONSUMERS;
/** /**
* Tells the broker how many messages to send to each consumer in a single * Tells the broker how many messages to send to each consumer in a single
* request. Often this can be set quite high to improve throughput. * request. Often this can be set quite high to improve throughput.
*/ */
private int prefetchCount = 10; private int prefetchCount = DEFAULT_PREFETCH_COUNT;
/** /**
* Initial number of consumers. Is scaled up if necessary up to * Initial number of consumers. Is scaled up if necessary up to
* {@link #maxConcurrentConsumers}. * {@link #maxConcurrentConsumers}.
*/ */
private int initialConcurrentConsumers = 3; private int initialConcurrentConsumers = DEFAULT_INITIAL_CONSUMERS;
/** /**
* The number of retry attempts when passive queue declaration fails. * The number of retry attempts when passive queue declaration fails.
@@ -79,7 +89,7 @@ public class AmqpProperties {
* consuming from multiple queues, when not all queues were available during * consuming from multiple queues, when not all queues were available during
* initialization. * initialization.
*/ */
private int declarationRetries = 50; private int declarationRetries = DEFAULT_QUEUE_DECLARATION_RETRIES;
public int getDeclarationRetries() { public int getDeclarationRetries() {
return declarationRetries; return declarationRetries;

View File

@@ -12,7 +12,10 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata; import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet; import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
@@ -34,10 +37,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
/** /**
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
*
*
*
*
*/ */
public final class MgmtDistributionSetMapper { public final class MgmtDistributionSetMapper {
private MgmtDistributionSetMapper() { private MgmtDistributionSetMapper() {
@@ -75,15 +74,13 @@ public final class MgmtDistributionSetMapper {
* to use for conversion * to use for conversion
* @return converted list of {@link DistributionSet}s * @return converted list of {@link DistributionSet}s
*/ */
static List<DistributionSet> dsFromRequest(final Iterable<MgmtDistributionSetRequestBodyPost> sets, static List<DistributionSet> dsFromRequest(final Collection<MgmtDistributionSetRequestBodyPost> sets,
final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement, final SoftwareManagement softwareManagement, final DistributionSetManagement distributionSetManagement,
final EntityFactory entityFactory) { final EntityFactory entityFactory) {
final List<DistributionSet> mappedList = new ArrayList<>(); return sets.stream()
for (final MgmtDistributionSetRequestBodyPost dsRest : sets) { .map(dsRest -> fromRequest(dsRest, softwareManagement, distributionSetManagement, entityFactory))
mappedList.add(fromRequest(dsRest, softwareManagement, distributionSetManagement, entityFactory)); .collect(Collectors.toList());
}
return mappedList;
} }
@@ -139,15 +136,12 @@ public final class MgmtDistributionSetMapper {
*/ */
static List<DistributionSetMetadata> fromRequestDsMetadata(final DistributionSet ds, static List<DistributionSetMetadata> fromRequestDsMetadata(final DistributionSet ds,
final List<MgmtMetadata> metadata, final EntityFactory entityFactory) { final List<MgmtMetadata> metadata, final EntityFactory entityFactory) {
final List<DistributionSetMetadata> mappedList = new ArrayList<>(metadata.size()); if (metadata == null) {
for (final MgmtMetadata metadataRest : metadata) { return Collections.emptyList();
if (metadataRest.getKey() == null) {
throw new IllegalArgumentException("the key of the metadata must be present");
}
mappedList.add(
entityFactory.generateDistributionSetMetadata(ds, metadataRest.getKey(), metadataRest.getValue()));
} }
return mappedList;
return metadata.stream().map(metadataRest -> entityFactory.generateDistributionSetMetadata(ds,
metadataRest.getKey(), metadataRest.getValue())).collect(Collectors.toList());
} }
/** /**
@@ -196,15 +190,12 @@ public final class MgmtDistributionSetMapper {
return result; return result;
} }
static List<MgmtDistributionSet> toResponseDistributionSets(final Iterable<DistributionSet> sets) { static List<MgmtDistributionSet> toResponseDistributionSets(final Collection<DistributionSet> sets) {
final List<MgmtDistributionSet> response = new ArrayList<>(); if (sets == null) {
if (sets != null) { return Collections.emptyList();
for (final DistributionSet set : sets) {
response.add(toResponse(set));
}
} }
return response;
return sets.stream().map(MgmtDistributionSetMapper::toResponse).collect(Collectors.toList());
} }
static MgmtMetadata toResponseDsMetadata(final DistributionSetMetadata metadata) { static MgmtMetadata toResponseDsMetadata(final DistributionSetMetadata metadata) {
@@ -224,14 +215,10 @@ public final class MgmtDistributionSetMapper {
} }
static List<MgmtDistributionSet> toResponseFromDsList(final List<DistributionSet> sets) { static List<MgmtDistributionSet> toResponseFromDsList(final List<DistributionSet> sets) {
final List<MgmtDistributionSet> mappedList = new ArrayList<>(); if (sets == null) {
if (sets != null) { return Collections.emptyList();
for (final DistributionSet set : sets) {
final MgmtDistributionSet response = toResponse(set);
mappedList.add(response);
}
} }
return mappedList;
return sets.stream().map(MgmtDistributionSetMapper::toResponse).collect(Collectors.toList());
} }
} }

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; package org.eclipse.hawkbit.mgmt.rest.resource;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -123,7 +124,7 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
.runAsSystem(() -> this.systemManagement.getTenantMetadata().getDefaultDsType().getKey()); .runAsSystem(() -> this.systemManagement.getTenantMetadata().getDefaultDsType().getKey());
sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey)); sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey));
final Iterable<DistributionSet> createdDSets = this.distributionSetManagement final Collection<DistributionSet> createdDSets = this.distributionSetManagement
.createDistributionSets(MgmtDistributionSetMapper.dsFromRequest(sets, this.softwareManagement, .createDistributionSets(MgmtDistributionSetMapper.dsFromRequest(sets, this.softwareManagement,
this.distributionSetManagement, entityFactory)); this.distributionSetManagement, entityFactory));

View File

@@ -11,8 +11,10 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.ArrayList; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetType; import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetType;
import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetTypeRequestBodyPost; import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetTypeRequestBodyPost;
@@ -39,13 +41,13 @@ final class MgmtDistributionSetTypeMapper {
static List<DistributionSetType> smFromRequest(final EntityFactory entityFactory, static List<DistributionSetType> smFromRequest(final EntityFactory entityFactory,
final SoftwareManagement softwareManagement, final SoftwareManagement softwareManagement,
final Iterable<MgmtDistributionSetTypeRequestBodyPost> smTypesRest) { final Collection<MgmtDistributionSetTypeRequestBodyPost> smTypesRest) {
final List<DistributionSetType> mappedList = new ArrayList<>(); if (smTypesRest == null) {
return Collections.emptyList();
for (final MgmtDistributionSetTypeRequestBodyPost smRest : smTypesRest) {
mappedList.add(fromRequest(entityFactory, softwareManagement, smRest));
} }
return mappedList;
return smTypesRest.stream().map(smRest -> fromRequest(entityFactory, softwareManagement, smRest))
.collect(Collectors.toList());
} }
static DistributionSetType fromRequest(final EntityFactory entityFactory, static DistributionSetType fromRequest(final EntityFactory entityFactory,
@@ -91,19 +93,19 @@ final class MgmtDistributionSetTypeMapper {
} }
static List<MgmtDistributionSetType> toTypesResponse(final List<DistributionSetType> types) { static List<MgmtDistributionSetType> toTypesResponse(final List<DistributionSetType> types) {
final List<MgmtDistributionSetType> response = new ArrayList<>(); if (types == null) {
for (final DistributionSetType dsType : types) { return Collections.emptyList();
response.add(toResponse(dsType));
} }
return response;
return types.stream().map(MgmtDistributionSetTypeMapper::toResponse).collect(Collectors.toList());
} }
static List<MgmtDistributionSetType> toListResponse(final List<DistributionSetType> types) { static List<MgmtDistributionSetType> toListResponse(final List<DistributionSetType> types) {
final List<MgmtDistributionSetType> response = new ArrayList<>(); if (types == null) {
for (final DistributionSetType dsType : types) { return Collections.emptyList();
response.add(toResponse(dsType));
} }
return response;
return types.stream().map(MgmtDistributionSetTypeMapper::toResponse).collect(Collectors.toList());
} }
static MgmtDistributionSetType toResponse(final DistributionSetType type) { static MgmtDistributionSetType toResponse(final DistributionSetType type) {

View File

@@ -8,6 +8,12 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtDistributionSetTypeMapper.toResponse;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtDistributionSetTypeMapper.toTypesResponse;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleTypeMapper.toResponse;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleTypeMapper.toTypesResponse;
import static org.springframework.http.HttpStatus.CREATED;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.mgmt.json.model.MgmtId; import org.eclipse.hawkbit.mgmt.json.model.MgmtId;
@@ -32,7 +38,6 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@@ -42,8 +47,6 @@ import org.springframework.web.bind.annotation.RestController;
/** /**
* REST Resource handling for {@link SoftwareModule} and related * REST Resource handling for {@link SoftwareModule} and related
* {@link Artifact} CRUD operations. * {@link Artifact} CRUD operations.
*
*
*/ */
@RestController @RestController
public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeRestApi { public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeRestApi {
@@ -67,7 +70,6 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam);
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
final Sort sorting = PagingUtility.sanitizeDistributionSetTypeSortParam(sortParam); final Sort sorting = PagingUtility.sanitizeDistributionSetTypeSortParam(sortParam);
final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting);
final Slice<DistributionSetType> findModuleTypessAll; final Slice<DistributionSetType> findModuleTypessAll;
@@ -82,31 +84,32 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
final List<MgmtDistributionSetType> rest = MgmtDistributionSetTypeMapper final List<MgmtDistributionSetType> rest = MgmtDistributionSetTypeMapper
.toListResponse(findModuleTypessAll.getContent()); .toListResponse(findModuleTypessAll.getContent());
return new ResponseEntity<>(new PagedList<>(rest, countModulesAll), HttpStatus.OK); return ResponseEntity.ok(new PagedList<>(rest, countModulesAll));
} }
@Override @Override
public ResponseEntity<MgmtDistributionSetType> getDistributionSetType( public ResponseEntity<MgmtDistributionSetType> getDistributionSetType(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
return new ResponseEntity<>(MgmtDistributionSetTypeMapper.toResponse(foundType), HttpStatus.OK); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
return ResponseEntity.ok(toResponse(foundType));
} }
@Override @Override
public ResponseEntity<Void> deleteDistributionSetType( public ResponseEntity<Void> deleteDistributionSetType(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId) {
final DistributionSetType module = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final DistributionSetType module = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
distributionSetManagement.deleteDistributionSetType(module); distributionSetManagement.deleteDistributionSetType(module);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
@Override @Override
public ResponseEntity<MgmtDistributionSetType> updateDistributionSetType( public ResponseEntity<MgmtDistributionSetType> updateDistributionSetType(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@RequestBody final MgmtDistributionSetTypeRequestBodyPut restDistributionSetType) { @RequestBody final MgmtDistributionSetTypeRequestBodyPut restDistributionSetType) {
final DistributionSetType type = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType type = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
// only description can be modified // only description can be modified
@@ -117,8 +120,7 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
final DistributionSetType updatedDistributionSetType = distributionSetManagement final DistributionSetType updatedDistributionSetType = distributionSetManagement
.updateDistributionSetType(type); .updateDistributionSetType(type);
return new ResponseEntity<>(MgmtDistributionSetTypeMapper.toResponse(updatedDistributionSetType), return ResponseEntity.ok(toResponse(updatedDistributionSetType));
HttpStatus.OK);
} }
@Override @Override
@@ -128,16 +130,17 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
final List<DistributionSetType> createdSoftwareModules = distributionSetManagement.createDistributionSetTypes( final List<DistributionSetType> createdSoftwareModules = distributionSetManagement.createDistributionSetTypes(
MgmtDistributionSetTypeMapper.smFromRequest(entityFactory, softwareManagement, distributionSetTypes)); MgmtDistributionSetTypeMapper.smFromRequest(entityFactory, softwareManagement, distributionSetTypes));
return new ResponseEntity<>(MgmtDistributionSetTypeMapper.toTypesResponse(createdSoftwareModules), return ResponseEntity.status(CREATED).body(toTypesResponse(createdSoftwareModules));
HttpStatus.CREATED);
} }
private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final Long distributionSetTypeId) { private DistributionSetType findDistributionSetTypeWithExceptionIfNotFound(final Long distributionSetTypeId) {
final DistributionSetType module = distributionSetManagement.findDistributionSetTypeById(distributionSetTypeId); final DistributionSetType module = distributionSetManagement.findDistributionSetTypeById(distributionSetTypeId);
if (module == null) { if (module == null) {
throw new EntityNotFoundException( throw new EntityNotFoundException(
"DistributionSetType with Id {" + distributionSetTypeId + "} does not exist"); "DistributionSetType with Id {" + distributionSetTypeId + "} does not exist");
} }
return module; return module;
} }
@@ -146,8 +149,7 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
return new ResponseEntity<>(MgmtSoftwareModuleTypeMapper.toListResponse(foundType.getMandatoryModuleTypes()), return ResponseEntity.ok(toTypesResponse(foundType.getMandatoryModuleTypes()));
HttpStatus.OK);
} }
@Override @Override
@@ -156,7 +158,6 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) { @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
if (!foundType.containsMandatoryModuleType(foundSmType)) { if (!foundType.containsMandatoryModuleType(foundSmType)) {
@@ -164,7 +165,7 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
"Software module with given ID is not part of this distribution set type!"); "Software module with given ID is not part of this distribution set type!");
} }
return new ResponseEntity<>(MgmtSoftwareModuleTypeMapper.toResponse(foundSmType), HttpStatus.OK); return ResponseEntity.ok(toResponse(foundSmType));
} }
@Override @Override
@@ -173,7 +174,6 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) { @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
if (!foundType.containsOptionalModuleType(foundSmType)) { if (!foundType.containsOptionalModuleType(foundSmType)) {
@@ -181,7 +181,7 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
"Software module with given ID is not part of this distribution set type!"); "Software module with given ID is not part of this distribution set type!");
} }
return new ResponseEntity<>(MgmtSoftwareModuleTypeMapper.toResponse(foundSmType), HttpStatus.OK); return ResponseEntity.ok(toResponse(foundSmType));
} }
@Override @Override
@@ -189,9 +189,7 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
return ResponseEntity.ok(toTypesResponse(foundType.getOptionalModuleTypes()));
return new ResponseEntity<>(MgmtSoftwareModuleTypeMapper.toListResponse(foundType.getOptionalModuleTypes()),
HttpStatus.OK);
} }
@Override @Override
@@ -200,7 +198,6 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) { @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
if (!foundType.containsMandatoryModuleType(foundSmType)) { if (!foundType.containsMandatoryModuleType(foundSmType)) {
@@ -209,18 +206,17 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
} }
foundType.removeModuleType(softwareModuleTypeId); foundType.removeModuleType(softwareModuleTypeId);
distributionSetManagement.updateDistributionSetType(foundType); distributionSetManagement.updateDistributionSetType(foundType);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
@Override @Override
public ResponseEntity<Void> removeOptionalModule( public ResponseEntity<Void> removeOptionalModule(
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @PathVariable("distributionSetTypeId") final Long distributionSetTypeId,
@PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) { @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); final SoftwareModuleType foundSmType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId);
if (!foundType.containsOptionalModuleType(foundSmType)) { if (!foundType.containsOptionalModuleType(foundSmType)) {
@@ -229,10 +225,9 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
} }
foundType.removeModuleType(softwareModuleTypeId); foundType.removeModuleType(softwareModuleTypeId);
distributionSetManagement.updateDistributionSetType(foundType); distributionSetManagement.updateDistributionSetType(foundType);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
@Override @Override
@@ -240,14 +235,11 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final MgmtId smtId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final MgmtId smtId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final SoftwareModuleType smType = findSoftwareModuleTypeWithExceptionIfNotFound(smtId.getId()); final SoftwareModuleType smType = findSoftwareModuleTypeWithExceptionIfNotFound(smtId.getId());
foundType.addMandatoryModuleType(smType); foundType.addMandatoryModuleType(smType);
distributionSetManagement.updateDistributionSetType(foundType); distributionSetManagement.updateDistributionSetType(foundType);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
@Override @Override
@@ -255,23 +247,22 @@ public class MgmtDistributionSetTypeResource implements MgmtDistributionSetTypeR
@PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final MgmtId smtId) { @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final MgmtId smtId) {
final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId);
final SoftwareModuleType smType = findSoftwareModuleTypeWithExceptionIfNotFound(smtId.getId()); final SoftwareModuleType smType = findSoftwareModuleTypeWithExceptionIfNotFound(smtId.getId());
foundType.addOptionalModuleType(smType); foundType.addOptionalModuleType(smType);
distributionSetManagement.updateDistributionSetType(foundType); distributionSetManagement.updateDistributionSetType(foundType);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
private SoftwareModuleType findSoftwareModuleTypeWithExceptionIfNotFound(final Long softwareModuleTypeId) { private SoftwareModuleType findSoftwareModuleTypeWithExceptionIfNotFound(final Long softwareModuleTypeId) {
final SoftwareModuleType module = softwareManagement.findSoftwareModuleTypeById(softwareModuleTypeId); final SoftwareModuleType module = softwareManagement.findSoftwareModuleTypeById(softwareModuleTypeId);
if (module == null) { if (module == null) {
throw new EntityNotFoundException( throw new EntityNotFoundException(
"SoftwareModuleType with Id {" + softwareModuleTypeId + "} does not exist"); "SoftwareModuleType with Id {" + softwareModuleTypeId + "} does not exist");
} }
return module; return module;
} }
} }

View File

@@ -11,8 +11,9 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutCondition.Condition; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutCondition.Condition;
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutErrorAction.ErrorAction; import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutErrorAction.ErrorAction;
@@ -48,9 +49,11 @@ final class MgmtRolloutMapper {
} }
static List<MgmtRolloutResponseBody> toResponseRollout(final List<Rollout> rollouts) { static List<MgmtRolloutResponseBody> toResponseRollout(final List<Rollout> rollouts) {
final List<MgmtRolloutResponseBody> result = new ArrayList<>(rollouts.size()); if (rollouts == null) {
rollouts.forEach(r -> result.add(toResponseRollout(r))); return Collections.emptyList();
return result; }
return rollouts.stream().map(MgmtRolloutMapper::toResponseRollout).collect(Collectors.toList());
} }
static MgmtRolloutResponseBody toResponseRollout(final Rollout rollout) { static MgmtRolloutResponseBody toResponseRollout(final Rollout rollout) {
@@ -103,9 +106,11 @@ final class MgmtRolloutMapper {
} }
static List<MgmtRolloutGroupResponseBody> toResponseRolloutGroup(final List<RolloutGroup> rollouts) { static List<MgmtRolloutGroupResponseBody> toResponseRolloutGroup(final List<RolloutGroup> rollouts) {
final List<MgmtRolloutGroupResponseBody> result = new ArrayList<>(rollouts.size()); if (rollouts == null) {
rollouts.forEach(r -> result.add(toResponseRolloutGroup(r))); return Collections.emptyList();
return result; }
return rollouts.stream().map(MgmtRolloutMapper::toResponseRolloutGroup).collect(Collectors.toList());
} }
static MgmtRolloutGroupResponseBody toResponseRolloutGroup(final RolloutGroup rolloutGroup) { static MgmtRolloutGroupResponseBody toResponseRolloutGroup(final RolloutGroup rolloutGroup) {

View File

@@ -11,8 +11,10 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.ArrayList; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata; import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact; import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
@@ -65,60 +67,46 @@ public final class MgmtSoftwareModuleMapper {
} }
static List<SoftwareModuleMetadata> fromRequestSwMetadata(final EntityFactory entityFactory, static List<SoftwareModuleMetadata> fromRequestSwMetadata(final EntityFactory entityFactory,
final SoftwareModule sw, final List<MgmtMetadata> metadata) { final SoftwareModule sw, final Collection<MgmtMetadata> metadata) {
final List<SoftwareModuleMetadata> mappedList = new ArrayList<>(metadata.size()); if (metadata == null) {
for (final MgmtMetadata metadataRest : metadata) { return Collections.emptyList();
if (metadataRest.getKey() == null) {
throw new IllegalArgumentException("the key of the metadata must be present");
}
mappedList.add(
entityFactory.generateSoftwareModuleMetadata(sw, metadataRest.getKey(), metadataRest.getValue()));
} }
return mappedList;
return metadata.stream().map(metadataRest -> entityFactory.generateSoftwareModuleMetadata(sw,
metadataRest.getKey(), metadataRest.getValue())).collect(Collectors.toList());
} }
static List<SoftwareModule> smFromRequest(final EntityFactory entityFactory, static List<SoftwareModule> smFromRequest(final EntityFactory entityFactory,
final Iterable<MgmtSoftwareModuleRequestBodyPost> smsRest, final SoftwareManagement softwareManagement) { final Collection<MgmtSoftwareModuleRequestBodyPost> smsRest, final SoftwareManagement softwareManagement) {
final List<SoftwareModule> mappedList = new ArrayList<>(); if (smsRest == null) {
for (final MgmtSoftwareModuleRequestBodyPost smRest : smsRest) { return Collections.emptyList();
mappedList.add(fromRequest(entityFactory, smRest, softwareManagement));
} }
return mappedList;
return smsRest.stream().map(smRest -> fromRequest(entityFactory, smRest, softwareManagement))
.collect(Collectors.toList());
} }
/** /**
* Create response for sw modules. * Create response for sw modules.
* *
* @param baseSoftareModules * @param softwareModules
* the modules * the modules
* @return the response * @return the response
*/ */
public static List<MgmtSoftwareModule> toResponse(final List<SoftwareModule> baseSoftareModules) { public static List<MgmtSoftwareModule> toResponse(final Collection<SoftwareModule> softwareModules) {
final List<MgmtSoftwareModule> mappedList = new ArrayList<>(); if (softwareModules == null) {
if (baseSoftareModules != null) { return Collections.emptyList();
for (final SoftwareModule target : baseSoftareModules) {
final MgmtSoftwareModule response = toResponse(target);
mappedList.add(response);
}
} }
return mappedList;
return softwareModules.stream().map(MgmtSoftwareModuleMapper::toResponse).collect(Collectors.toList());
} }
static List<MgmtSoftwareModule> toResponseSoftwareModules(final Iterable<SoftwareModule> softwareModules) { static List<MgmtMetadata> toResponseSwMetadata(final Collection<SoftwareModuleMetadata> metadata) {
final List<MgmtSoftwareModule> response = new ArrayList<>(); if (metadata == null) {
for (final SoftwareModule softwareModule : softwareModules) { return Collections.emptyList();
response.add(toResponse(softwareModule));
} }
return response;
}
static List<MgmtMetadata> toResponseSwMetadata(final List<SoftwareModuleMetadata> metadata) { return metadata.stream().map(MgmtSoftwareModuleMapper::toResponseSwMetadata).collect(Collectors.toList());
final List<MgmtMetadata> mappedList = new ArrayList<>(metadata.size());
for (final SoftwareModuleMetadata distributionSetMetadata : metadata) {
mappedList.add(toResponseSwMetadata(distributionSetMetadata));
}
return mappedList;
} }
static MgmtMetadata toResponseSwMetadata(final SoftwareModuleMetadata metadata) { static MgmtMetadata toResponseSwMetadata(final SoftwareModuleMetadata metadata) {
@@ -194,15 +182,11 @@ public final class MgmtSoftwareModuleMapper {
return artifactRest; return artifactRest;
} }
static List<MgmtArtifact> artifactsToResponse(final List<Artifact> artifacts) { static List<MgmtArtifact> artifactsToResponse(final Collection<Artifact> artifacts) {
final List<MgmtArtifact> mappedList = new ArrayList<>(); if (artifacts == null) {
return Collections.emptyList();
if (artifacts != null) {
for (final Artifact artifact : artifacts) {
final MgmtArtifact response = toResponse(artifact);
mappedList.add(response);
}
} }
return mappedList;
return artifacts.stream().map(MgmtSoftwareModuleMapper::toResponse).collect(Collectors.toList());
} }
} }

View File

@@ -8,7 +8,15 @@
*/ */
package org.eclipse.hawkbit.mgmt.rest.resource; package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleMapper.artifactsToResponse;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleMapper.toResponse;
import static org.eclipse.hawkbit.mgmt.rest.resource.MgmtSoftwareModuleMapper.toResponseSwMetadata;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.CREATED;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata; import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
@@ -46,10 +54,10 @@ import org.springframework.web.multipart.MultipartFile;
/** /**
* REST Resource handling for {@link SoftwareModule} and related * REST Resource handling for {@link SoftwareModule} and related
* {@link Artifact} CRUD operations. * {@link Artifact} CRUD operations.
*
*/ */
@RestController @RestController
public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi { public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
private static final Logger LOG = LoggerFactory.getLogger(MgmtSoftwareModuleResource.class); private static final Logger LOG = LoggerFactory.getLogger(MgmtSoftwareModuleResource.class);
@Autowired @Autowired
@@ -69,7 +77,7 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
@RequestParam(value = "sha1sum", required = false) final String sha1Sum) { @RequestParam(value = "sha1sum", required = false) final String sha1Sum) {
if (file.isEmpty()) { if (file.isEmpty()) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST); return new ResponseEntity<>(BAD_REQUEST);
} }
String fileName = optionalFileName; String fileName = optionalFileName;
@@ -81,10 +89,10 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
final Artifact result = artifactManagement.createLocalArtifact(file.getInputStream(), softwareModuleId, final Artifact result = artifactManagement.createLocalArtifact(file.getInputStream(), softwareModuleId,
fileName, md5Sum == null ? null : md5Sum.toLowerCase(), fileName, md5Sum == null ? null : md5Sum.toLowerCase(),
sha1Sum == null ? null : sha1Sum.toLowerCase(), false, file.getContentType()); sha1Sum == null ? null : sha1Sum.toLowerCase(), false, file.getContentType());
return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponse(result), HttpStatus.CREATED); return ResponseEntity.status(CREATED).body(toResponse(result));
} catch (final IOException e) { } catch (final IOException e) {
LOG.error("Failed to store artifact", e); LOG.error("Failed to store artifact", e);
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); return new ResponseEntity<>(INTERNAL_SERVER_ERROR);
} }
} }
@@ -92,31 +100,34 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
@ResponseBody @ResponseBody
public ResponseEntity<List<MgmtArtifact>> getArtifacts( public ResponseEntity<List<MgmtArtifact>> getArtifacts(
@PathVariable("softwareModuleId") final Long softwareModuleId) { @PathVariable("softwareModuleId") final Long softwareModuleId) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
return new ResponseEntity<>(MgmtSoftwareModuleMapper.artifactsToResponse(module.getArtifacts()), HttpStatus.OK); final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
return ResponseEntity.ok(artifactsToResponse(module.getArtifacts()));
} }
@Override @Override
@ResponseBody @ResponseBody
// Exception squid:S3655 - Optional access is checked in
// findSoftwareModuleWithExceptionIfNotFound
// subroutine
@SuppressWarnings("squid:S3655")
public ResponseEntity<MgmtArtifact> getArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, public ResponseEntity<MgmtArtifact> getArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("artifactId") final Long artifactId) { @PathVariable("artifactId") final Long artifactId) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponse(module.getLocalArtifact(artifactId).get()), return ResponseEntity.ok(toResponse(module.getLocalArtifact(artifactId).get()));
HttpStatus.OK);
} }
@Override @Override
@ResponseBody @ResponseBody
public ResponseEntity<Void> deleteArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, public ResponseEntity<Void> deleteArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("artifactId") final Long artifactId) { @PathVariable("artifactId") final Long artifactId) {
findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId);
artifactManagement.deleteLocalArtifact(artifactId); artifactManagement.deleteLocalArtifact(artifactId);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
@Override @Override
@@ -143,33 +154,34 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
} }
final List<MgmtSoftwareModule> rest = MgmtSoftwareModuleMapper.toResponse(findModulesAll.getContent()); final List<MgmtSoftwareModule> rest = MgmtSoftwareModuleMapper.toResponse(findModulesAll.getContent());
return new ResponseEntity<>(new PagedList<>(rest, countModulesAll), HttpStatus.OK); return ResponseEntity.ok(new PagedList<>(rest, countModulesAll));
} }
@Override @Override
public ResponseEntity<MgmtSoftwareModule> getSoftwareModule( public ResponseEntity<MgmtSoftwareModule> getSoftwareModule(
@PathVariable("softwareModuleId") final Long softwareModuleId) { @PathVariable("softwareModuleId") final Long softwareModuleId) {
final SoftwareModule findBaseSoftareModule = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponse(findBaseSoftareModule), HttpStatus.OK); final SoftwareModule findBaseSoftareModule = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
return ResponseEntity.ok(toResponse(findBaseSoftareModule));
} }
@Override @Override
public ResponseEntity<List<MgmtSoftwareModule>> createSoftwareModules( public ResponseEntity<List<MgmtSoftwareModule>> createSoftwareModules(
@RequestBody final List<MgmtSoftwareModuleRequestBodyPost> softwareModules) { @RequestBody final List<MgmtSoftwareModuleRequestBodyPost> softwareModules) {
LOG.debug("creating {} softwareModules", softwareModules.size()); LOG.debug("creating {} softwareModules", softwareModules.size());
final Iterable<SoftwareModule> createdSoftwareModules = softwareManagement.createSoftwareModule( final Collection<SoftwareModule> createdSoftwareModules = softwareManagement.createSoftwareModule(
MgmtSoftwareModuleMapper.smFromRequest(entityFactory, softwareModules, softwareManagement)); MgmtSoftwareModuleMapper.smFromRequest(entityFactory, softwareModules, softwareManagement));
LOG.debug("{} softwareModules created, return status {}", softwareModules.size(), HttpStatus.CREATED); LOG.debug("{} softwareModules created, return status {}", softwareModules.size(), HttpStatus.CREATED);
return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponseSoftwareModules(createdSoftwareModules), return ResponseEntity.status(CREATED).body(toResponse(createdSoftwareModules));
HttpStatus.CREATED);
} }
@Override @Override
public ResponseEntity<MgmtSoftwareModule> updateSoftwareModule( public ResponseEntity<MgmtSoftwareModule> updateSoftwareModule(
@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("softwareModuleId") final Long softwareModuleId,
@RequestBody final MgmtSoftwareModuleRequestBodyPut restSoftwareModule) { @RequestBody final MgmtSoftwareModuleRequestBodyPut restSoftwareModule) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
// only description and vendor can be modified // only description and vendor can be modified
@@ -181,16 +193,16 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
} }
final SoftwareModule updateSoftwareModule = softwareManagement.updateSoftwareModule(module); final SoftwareModule updateSoftwareModule = softwareManagement.updateSoftwareModule(module);
return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponse(updateSoftwareModule), HttpStatus.OK); return ResponseEntity.ok(toResponse(updateSoftwareModule));
} }
@Override @Override
public ResponseEntity<Void> deleteSoftwareModule(@PathVariable("softwareModuleId") final Long softwareModuleId) { public ResponseEntity<Void> deleteSoftwareModule(@PathVariable("softwareModuleId") final Long softwareModuleId) {
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
softwareManagement.deleteSoftwareModule(module); softwareManagement.deleteSoftwareModule(module);
return new ResponseEntity<>(HttpStatus.OK); return ResponseEntity.ok().build();
} }
@Override @Override
@@ -218,34 +230,38 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
metaDataPage = softwareManagement.findSoftwareModuleMetadataBySoftwareModuleId(softwareModuleId, pageable); metaDataPage = softwareManagement.findSoftwareModuleMetadataBySoftwareModuleId(softwareModuleId, pageable);
} }
return new ResponseEntity<>( return ResponseEntity
new PagedList<>(MgmtSoftwareModuleMapper.toResponseSwMetadata(metaDataPage.getContent()), .ok(new PagedList<>(toResponseSwMetadata(metaDataPage.getContent()), metaDataPage.getTotalElements()));
metaDataPage.getTotalElements()),
HttpStatus.OK);
} }
@Override @Override
public ResponseEntity<MgmtMetadata> getMetadataValue(@PathVariable("softwareModuleId") final Long softwareModuleId, public ResponseEntity<MgmtMetadata> getMetadataValue(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("metadataKey") final String metadataKey) { @PathVariable("metadataKey") final String metadataKey) {
final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
final SoftwareModuleMetadata findOne = softwareManagement.findSoftwareModuleMetadata(sw, metadataKey); final SoftwareModuleMetadata findOne = softwareManagement.findSoftwareModuleMetadata(sw, metadataKey);
return ResponseEntity.<MgmtMetadata> ok(MgmtSoftwareModuleMapper.toResponseSwMetadata(findOne));
return ResponseEntity.ok(toResponseSwMetadata(findOne));
} }
@Override @Override
public ResponseEntity<MgmtMetadata> updateMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId, public ResponseEntity<MgmtMetadata> updateMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("metadataKey") final String metadataKey, @RequestBody final MgmtMetadata metadata) { @PathVariable("metadataKey") final String metadataKey, @RequestBody final MgmtMetadata metadata) {
final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
final SoftwareModuleMetadata updated = softwareManagement.updateSoftwareModuleMetadata( final SoftwareModuleMetadata updated = softwareManagement.updateSoftwareModuleMetadata(
entityFactory.generateSoftwareModuleMetadata(sw, metadataKey, metadata.getValue())); entityFactory.generateSoftwareModuleMetadata(sw, metadataKey, metadata.getValue()));
return ResponseEntity.ok(MgmtSoftwareModuleMapper.toResponseSwMetadata(updated));
return ResponseEntity.ok(toResponseSwMetadata(updated));
} }
@Override @Override
public ResponseEntity<Void> deleteMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId, public ResponseEntity<Void> deleteMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId,
@PathVariable("metadataKey") final String metadataKey) { @PathVariable("metadataKey") final String metadataKey) {
final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
softwareManagement.deleteSoftwareModuleMetadata(sw, metadataKey); softwareManagement.deleteSoftwareModuleMetadata(sw, metadataKey);
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@@ -253,24 +269,25 @@ public class MgmtSoftwareModuleResource implements MgmtSoftwareModuleRestApi {
public ResponseEntity<List<MgmtMetadata>> createMetadata( public ResponseEntity<List<MgmtMetadata>> createMetadata(
@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("softwareModuleId") final Long softwareModuleId,
@RequestBody final List<MgmtMetadata> metadataRest) { @RequestBody final List<MgmtMetadata> metadataRest) {
final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
final SoftwareModule sw = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null);
final List<SoftwareModuleMetadata> created = softwareManagement.createSoftwareModuleMetadata( final List<SoftwareModuleMetadata> created = softwareManagement.createSoftwareModuleMetadata(
MgmtSoftwareModuleMapper.fromRequestSwMetadata(entityFactory, sw, metadataRest)); MgmtSoftwareModuleMapper.fromRequestSwMetadata(entityFactory, sw, metadataRest));
return new ResponseEntity<>(MgmtSoftwareModuleMapper.toResponseSwMetadata(created), HttpStatus.CREATED); return ResponseEntity.status(CREATED).body(toResponseSwMetadata(created));
} }
private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId, private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId,
final Long artifactId) { final Long artifactId) {
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId); final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
if (module == null) { if (module == null) {
throw new EntityNotFoundException("SoftwareModule with Id {" + softwareModuleId + "} does not exist"); throw new EntityNotFoundException("SoftwareModule with Id {" + softwareModuleId + "} does not exist");
} else if (artifactId != null && !module.getLocalArtifact(artifactId).isPresent()) { }
if (artifactId != null && !module.getLocalArtifact(artifactId).isPresent()) {
throw new EntityNotFoundException("Artifact with Id {" + artifactId + "} does not exist"); throw new EntityNotFoundException("Artifact with Id {" + artifactId + "} does not exist");
} }
return module; return module;
} }
} }

View File

@@ -11,9 +11,10 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType; import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType;
import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleTypeRequestBodyPost; import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleTypeRequestBodyPost;
@@ -25,9 +26,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
* A mapper which maps repository model to RESTful model representation and * A mapper which maps repository model to RESTful model representation and
* back. * back.
* *
*
*
*
*/ */
final class MgmtSoftwareModuleTypeMapper { final class MgmtSoftwareModuleTypeMapper {
@@ -37,13 +35,12 @@ final class MgmtSoftwareModuleTypeMapper {
} }
static List<SoftwareModuleType> smFromRequest(final EntityFactory entityFactory, static List<SoftwareModuleType> smFromRequest(final EntityFactory entityFactory,
final Iterable<MgmtSoftwareModuleTypeRequestBodyPost> smTypesRest) { final Collection<MgmtSoftwareModuleTypeRequestBodyPost> smTypesRest) {
final List<SoftwareModuleType> mappedList = new ArrayList<>(); if (smTypesRest == null) {
return Collections.emptyList();
for (final MgmtSoftwareModuleTypeRequestBodyPost smRest : smTypesRest) {
mappedList.add(fromRequest(entityFactory, smRest));
} }
return mappedList;
return smTypesRest.stream().map(smRest -> fromRequest(entityFactory, smRest)).collect(Collectors.toList());
} }
static SoftwareModuleType fromRequest(final EntityFactory entityFactory, static SoftwareModuleType fromRequest(final EntityFactory entityFactory,
@@ -57,20 +54,12 @@ final class MgmtSoftwareModuleTypeMapper {
return result; return result;
} }
static List<MgmtSoftwareModuleType> toTypesResponse(final List<SoftwareModuleType> types) { static List<MgmtSoftwareModuleType> toTypesResponse(final Collection<SoftwareModuleType> types) {
final List<MgmtSoftwareModuleType> response = new ArrayList<>(); if (types == null) {
for (final SoftwareModuleType softwareModule : types) { return Collections.emptyList();
response.add(toResponse(softwareModule));
} }
return response;
}
static List<MgmtSoftwareModuleType> toListResponse(final Collection<SoftwareModuleType> types) { return types.stream().map(MgmtSoftwareModuleTypeMapper::toResponse).collect(Collectors.toList());
final List<MgmtSoftwareModuleType> response = new ArrayList<>();
for (final SoftwareModuleType softwareModule : types) {
response.add(toResponse(softwareModule));
}
return response;
} }
static MgmtSoftwareModuleType toResponse(final SoftwareModuleType type) { static MgmtSoftwareModuleType toResponse(final SoftwareModuleType type) {

View File

@@ -72,7 +72,7 @@ public class MgmtSoftwareModuleTypeResource implements MgmtSoftwareModuleTypeRes
} }
final List<MgmtSoftwareModuleType> rest = MgmtSoftwareModuleTypeMapper final List<MgmtSoftwareModuleType> rest = MgmtSoftwareModuleTypeMapper
.toListResponse(findModuleTypessAll.getContent()); .toTypesResponse(findModuleTypessAll.getContent());
return new ResponseEntity<>(new PagedList<>(rest, countModulesAll), HttpStatus.OK); return new ResponseEntity<>(new PagedList<>(rest, countModulesAll), HttpStatus.OK);
} }

View File

@@ -13,9 +13,11 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.net.URI; import java.net.URI;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.Collection;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.mgmt.json.model.MgmtPollStatus; import org.eclipse.hawkbit.mgmt.json.model.MgmtPollStatus;
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtAction; import org.eclipse.hawkbit.mgmt.json.model.action.MgmtAction;
@@ -92,17 +94,17 @@ public final class MgmtTargetMapper {
* the targets * the targets
* @return the response * @return the response
*/ */
public static List<MgmtTarget> toResponseWithLinksAndPollStatus(final Iterable<Target> targets) { public static List<MgmtTarget> toResponseWithLinksAndPollStatus(final Collection<Target> targets) {
final List<MgmtTarget> mappedList = new ArrayList<>(); if (targets == null) {
if (targets != null) { return Collections.emptyList();
for (final Target target : targets) {
final MgmtTarget response = toResponse(target);
addPollStatus(target, response);
addTargetLinks(response);
mappedList.add(response);
}
} }
return mappedList;
return targets.stream().map(target -> {
final MgmtTarget response = toResponse(target);
addPollStatus(target, response);
addTargetLinks(response);
return response;
}).collect(Collectors.toList());
} }
/** /**
@@ -112,15 +114,12 @@ public final class MgmtTargetMapper {
* list of targets * list of targets
* @return the response * @return the response
*/ */
public static List<MgmtTarget> toResponse(final Iterable<Target> targets) { public static List<MgmtTarget> toResponse(final Collection<Target> targets) {
final List<MgmtTarget> mappedList = new ArrayList<>(); if (targets == null) {
if (targets != null) { return Collections.emptyList();
for (final Target target : targets) {
final MgmtTarget response = toResponse(target);
mappedList.add(response);
}
} }
return mappedList;
return targets.stream().map(MgmtTargetMapper::toResponse).collect(Collectors.toList());
} }
/** /**
@@ -173,12 +172,13 @@ public final class MgmtTargetMapper {
} }
static List<Target> fromRequest(final EntityFactory entityFactory, static List<Target> fromRequest(final EntityFactory entityFactory,
final Iterable<MgmtTargetRequestBody> targetsRest) { final Collection<MgmtTargetRequestBody> targetsRest) {
final List<Target> mappedList = new ArrayList<>(); if (targetsRest == null) {
for (final MgmtTargetRequestBody targetRest : targetsRest) { return Collections.emptyList();
mappedList.add(fromRequest(entityFactory, targetRest));
} }
return mappedList;
return targetsRest.stream().map(targetRest -> fromRequest(entityFactory, targetRest))
.collect(Collectors.toList());
} }
static Target fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) { static Target fromRequest(final EntityFactory entityFactory, final MgmtTargetRequestBody targetRest) {
@@ -190,17 +190,12 @@ public final class MgmtTargetMapper {
return target; return target;
} }
static List<MgmtActionStatus> toActionStatusRestResponse(final List<ActionStatus> actionStatus) { static List<MgmtActionStatus> toActionStatusRestResponse(final Collection<ActionStatus> actionStatus) {
final List<MgmtActionStatus> mappedList = new ArrayList<>(); if (actionStatus == null) {
return Collections.emptyList();
if (actionStatus != null) {
for (final ActionStatus status : actionStatus) {
final MgmtActionStatus response = toResponse(status);
mappedList.add(response);
}
} }
return mappedList; return actionStatus.stream().map(MgmtTargetMapper::toResponse).collect(Collectors.toList());
} }
static MgmtAction toResponse(final String targetId, final Action action, final boolean isActive) { static MgmtAction toResponse(final String targetId, final Action action, final boolean isActive) {
@@ -222,14 +217,13 @@ public final class MgmtTargetMapper {
return result; return result;
} }
static List<MgmtAction> toResponse(final String targetId, final List<Action> actions) { static List<MgmtAction> toResponse(final String targetId, final Collection<Action> actions) {
final List<MgmtAction> mappedList = new ArrayList<>(); if (actions == null) {
return Collections.emptyList();
for (final Action action : actions) {
final MgmtAction response = toResponse(targetId, action, action.isActive());
mappedList.add(response);
} }
return mappedList;
return actions.stream().map(action -> toResponse(targetId, action, action.isActive()))
.collect(Collectors.toList());
} }
private static String getNameOfActionStatusType(final Action.Status type) { private static String getNameOfActionStatusType(final Action.Status type) {

View File

@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.mgmt.rest.resource;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn; import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -108,7 +109,7 @@ public class MgmtTargetResource implements MgmtTargetRestApi {
@Override @Override
public ResponseEntity<List<MgmtTarget>> createTargets(@RequestBody final List<MgmtTargetRequestBody> targets) { public ResponseEntity<List<MgmtTarget>> createTargets(@RequestBody final List<MgmtTargetRequestBody> targets) {
LOG.debug("creating {} targets", targets.size()); LOG.debug("creating {} targets", targets.size());
final Iterable<Target> createdTargets = this.targetManagement final Collection<Target> createdTargets = this.targetManagement
.createTargets(MgmtTargetMapper.fromRequest(entityFactory, targets)); .createTargets(MgmtTargetMapper.fromRequest(entityFactory, targets));
LOG.debug("{} targets created, return status {}", targets.size(), HttpStatus.CREATED); LOG.debug("{} targets created, return status {}", targets.size(), HttpStatus.CREATED);
return new ResponseEntity<>(MgmtTargetMapper.toResponse(createdTargets), HttpStatus.CREATED); return new ResponseEntity<>(MgmtTargetMapper.toResponse(createdTargets), HttpStatus.CREATED);

View File

@@ -494,9 +494,6 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractRestIntegration
final SoftwareModuleType testSmType = softwareManagement.createSoftwareModuleType( final SoftwareModuleType testSmType = softwareManagement.createSoftwareModuleType(
entityFactory.generateSoftwareModuleType("test123", "TestName123", "Desc123", 5)); entityFactory.generateSoftwareModuleType("test123", "TestName123", "Desc123", 5));
final List<DistributionSetType> types = new ArrayList<>();
types.add(testType);
// DST does not exist // DST does not exist
mvc.perform(get("/rest/v1/distributionsettypes/12345678")).andDo(MockMvcResultPrinter.print()) mvc.perform(get("/rest/v1/distributionsettypes/12345678")).andDo(MockMvcResultPrinter.print())
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
@@ -554,9 +551,8 @@ public class MgmtDistributionSetTypeResourceTest extends AbstractRestIntegration
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
final DistributionSetType missingName = entityFactory.generateDistributionSetType("test123", null, "Desc123"); // Missing mandatory field name
mvc.perform(post("/rest/v1/distributionsettypes") mvc.perform(post("/rest/v1/distributionsettypes").content("[{\"description\":\"Desc123\",\"key\":\"test123\"}]")
.content(JsonBuilder.distributionSetTypes(Lists.newArrayList(missingName)))
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());

View File

@@ -438,8 +438,7 @@ public class MgmtSoftwareModuleResourceTest extends AbstractRestIntegrationTestW
SoftwareModule sm = entityFactory.generateSoftwareModule(osType, "name 1", "version 1", null, null); SoftwareModule sm = entityFactory.generateSoftwareModule(osType, "name 1", "version 1", null, null);
sm = softwareManagement.createSoftwareModule(sm); sm = softwareManagement.createSoftwareModule(sm);
final List<SoftwareModule> modules = new ArrayList<>(); final List<SoftwareModule> modules = Lists.newArrayList(sm);
modules.add(sm);
// SM does not exist // SM does not exist
mvc.perform(get("/rest/v1/softwaremodules/12345678")).andDo(MockMvcResultPrinter.print()) mvc.perform(get("/rest/v1/softwaremodules/12345678")).andDo(MockMvcResultPrinter.print())
@@ -457,11 +456,10 @@ public class MgmtSoftwareModuleResourceTest extends AbstractRestIntegrationTestW
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
final SoftwareModule missingName = entityFactory.generateSoftwareModule(osType, null, "version 1", null, null); mvc.perform(post("/rest/v1/softwaremodules")
mvc.perform( .content("[{\"description\":\"Desc123\",\"key\":\"test123\", \"type\":\"os\"}]")
post("/rest/v1/softwaremodules").content(JsonBuilder.softwareModules(Lists.newArrayList(missingName))) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest());
.andDo(MockMvcResultPrinter.print()).andExpect(status().isBadRequest());
final SoftwareModule toLongName = entityFactory.generateSoftwareModule(osType, final SoftwareModule toLongName = entityFactory.generateSoftwareModule(osType,
RandomStringUtils.randomAscii(80), "version 1", null, null); RandomStringUtils.randomAscii(80), "version 1", null, null);

View File

@@ -318,8 +318,7 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractRestIntegrationT
final SoftwareModuleType testType = softwareManagement.createSoftwareModuleType( final SoftwareModuleType testType = softwareManagement.createSoftwareModuleType(
entityFactory.generateSoftwareModuleType("test123", "TestName123", "Desc123", 5)); entityFactory.generateSoftwareModuleType("test123", "TestName123", "Desc123", 5));
final List<SoftwareModuleType> types = new ArrayList<>(); final List<SoftwareModuleType> types = Lists.newArrayList(testType);
types.add(testType);
// SM does not exist // SM does not exist
mvc.perform(get("/rest/v1/softwaremoduletypes/12345678")).andDo(MockMvcResultPrinter.print()) mvc.perform(get("/rest/v1/softwaremoduletypes/12345678")).andDo(MockMvcResultPrinter.print())
@@ -337,9 +336,9 @@ public class MgmtSoftwareModuleTypeResourceTest extends AbstractRestIntegrationT
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
final SoftwareModuleType missingName = entityFactory.generateSoftwareModuleType("test123", null, "Desc123", 5);
mvc.perform(post("/rest/v1/softwaremoduletypes") mvc.perform(post("/rest/v1/softwaremoduletypes")
.content(JsonBuilder.softwareModuleTypes(Lists.newArrayList(missingName))) .content(
"[{\"description\":\"Desc123\",\"id\":9223372036854775807,\"key\":\"test123\",\"maxAssignments\":5}]")
.contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print()) .contentType(MediaType.APPLICATION_JSON)).andDo(MockMvcResultPrinter.print())
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());

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

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.validation.constraints.NotNull;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Action.Status;
import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.ActionStatus;
@@ -64,7 +66,7 @@ public interface EntityFactory {
* *
* @return {@link ActionStatus} object * @return {@link ActionStatus} object
*/ */
ActionStatus generateActionStatus(Action action, Status status, Long occurredAt); ActionStatus generateActionStatus(@NotNull Action action, @NotNull Status status, Long occurredAt);
/** /**
* Generates an {@link ActionStatus} object without persisting it. * Generates an {@link ActionStatus} object without persisting it.
@@ -81,7 +83,7 @@ public interface EntityFactory {
* *
* @return {@link ActionStatus} object * @return {@link ActionStatus} object
*/ */
ActionStatus generateActionStatus(Action action, final Status status, Long occurredAt, ActionStatus generateActionStatus(@NotNull Action action, @NotNull Status status, Long occurredAt,
final Collection<String> messages); final Collection<String> messages);
/** /**
@@ -99,7 +101,8 @@ public interface EntityFactory {
* *
* @return {@link ActionStatus} object * @return {@link ActionStatus} object
*/ */
ActionStatus generateActionStatus(Action action, Status status, Long occurredAt, final String message); ActionStatus generateActionStatus(@NotNull Action action, @NotNull Status status, Long occurredAt,
final String message);
/** /**
* Generates an empty {@link DistributionSet} without persisting it. * Generates an empty {@link DistributionSet} without persisting it.
@@ -124,8 +127,8 @@ public interface EntityFactory {
* *
* @return {@link DistributionSet} object * @return {@link DistributionSet} object
*/ */
DistributionSet generateDistributionSet(String name, String version, String description, DistributionSetType type, DistributionSet generateDistributionSet(@NotNull String name, @NotNull String version, String description,
Collection<SoftwareModule> moduleList); @NotNull DistributionSetType type, Collection<SoftwareModule> moduleList);
/** /**
* Generates an empty {@link DistributionSetMetadata} element without * Generates an empty {@link DistributionSetMetadata} element without
@@ -148,7 +151,8 @@ public interface EntityFactory {
* *
* @return {@link DistributionSetMetadata} object * @return {@link DistributionSetMetadata} object
*/ */
DistributionSetMetadata generateDistributionSetMetadata(DistributionSet distributionSet, String key, String value); DistributionSetMetadata generateDistributionSetMetadata(@NotNull DistributionSet distributionSet,
@NotNull String key, String value);
/** /**
* Generates an empty {@link DistributionSetTag} without persisting it. * Generates an empty {@link DistributionSetTag} without persisting it.
@@ -164,7 +168,7 @@ public interface EntityFactory {
* of the tag * of the tag
* @return {@link DistributionSetTag} object * @return {@link DistributionSetTag} object
*/ */
DistributionSetTag generateDistributionSetTag(String name); DistributionSetTag generateDistributionSetTag(@NotNull String name);
/** /**
* Generates a {@link DistributionSetTag} without persisting it. * Generates a {@link DistributionSetTag} without persisting it.
@@ -177,7 +181,7 @@ public interface EntityFactory {
* of the tag * of the tag
* @return {@link DistributionSetTag} object * @return {@link DistributionSetTag} object
*/ */
DistributionSetTag generateDistributionSetTag(String name, String description, String colour); DistributionSetTag generateDistributionSetTag(@NotNull String name, String description, String colour);
/** /**
* Generates an empty {@link DistributionSetType} without persisting it. * Generates an empty {@link DistributionSetType} without persisting it.
@@ -198,7 +202,7 @@ public interface EntityFactory {
* *
* @return {@link DistributionSetType} object * @return {@link DistributionSetType} object
*/ */
DistributionSetType generateDistributionSetType(String key, String name, String description); DistributionSetType generateDistributionSetType(@NotNull String key, @NotNull String name, String description);
/** /**
* Generates an empty {@link Rollout} without persisting it. * Generates an empty {@link Rollout} without persisting it.
@@ -237,8 +241,8 @@ public interface EntityFactory {
* *
* @return {@link SoftwareModule} object * @return {@link SoftwareModule} object
*/ */
SoftwareModule generateSoftwareModule(SoftwareModuleType type, String name, String version, String description, SoftwareModule generateSoftwareModule(@NotNull SoftwareModuleType type, @NotNull String name,
String vendor); @NotNull String version, String description, String vendor);
/** /**
* Generates an empty {@link SoftwareModuleMetadata} pair without persisting * Generates an empty {@link SoftwareModuleMetadata} pair without persisting
@@ -260,7 +264,8 @@ public interface EntityFactory {
* *
* @return {@link SoftwareModuleMetadata} object * @return {@link SoftwareModuleMetadata} object
*/ */
SoftwareModuleMetadata generateSoftwareModuleMetadata(SoftwareModule softwareModule, String key, String value); SoftwareModuleMetadata generateSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key,
String value);
/** /**
* Generates an empty {@link SoftwareModuleType} without persisting it. * Generates an empty {@link SoftwareModuleType} without persisting it.
@@ -283,7 +288,8 @@ public interface EntityFactory {
* *
* @return {@link SoftwareModuleType} object * @return {@link SoftwareModuleType} object
*/ */
SoftwareModuleType generateSoftwareModuleType(String key, String name, String description, int maxAssignments); SoftwareModuleType generateSoftwareModuleType(@NotNull String key, @NotNull String name, String description,
int maxAssignments);
/** /**
* Generates an empty {@link Target} without persisting it. * Generates an empty {@link Target} without persisting it.
@@ -307,7 +313,7 @@ public interface EntityFactory {
* *
* @return {@link Target} object * @return {@link Target} object
*/ */
Target generateTarget(@NotEmpty String controllerID, @NotEmpty String securityToken); Target generateTarget(@NotEmpty String controllerID, String securityToken);
/** /**
* Generates an empty {@link TargetFilterQuery} without persisting it. * Generates an empty {@link TargetFilterQuery} without persisting it.
@@ -330,7 +336,7 @@ public interface EntityFactory {
* of the tag * of the tag
* @return {@link TargetTag} object * @return {@link TargetTag} object
*/ */
TargetTag generateTargetTag(String name); TargetTag generateTargetTag(@NotNull String name);
/** /**
* Generates a {@link TargetTag} without persisting it. * Generates a {@link TargetTag} without persisting it.
@@ -343,7 +349,7 @@ public interface EntityFactory {
* of the tag * of the tag
* @return {@link TargetTag} object * @return {@link TargetTag} object
*/ */
TargetTag generateTargetTag(String name, String description, String colour); TargetTag generateTargetTag(@NotNull String name, String description, String colour);
/** /**
* Generates an empty {@link LocalArtifact} without persisting it. * Generates an empty {@link LocalArtifact} without persisting it.

View File

@@ -47,10 +47,10 @@ public interface ActionStatus extends TenantAwareBaseEntity {
* @return current {@link Status#DOWNLOAD} progress if known by the update * @return current {@link Status#DOWNLOAD} progress if known by the update
* server. * server.
*/ */
int getDownloadProgressPercent(); short getDownloadProgressPercent();
/** /**
* @return list of message entries that can be added to the * @return immutable list of message entries that in the
* {@link ActionStatus}. * {@link ActionStatus}.
*/ */
List<String> getMessages(); List<String> getMessages();

View File

@@ -37,6 +37,6 @@ public interface Artifact extends TenantAwareBaseEntity {
/** /**
* @return size of the artifact in bytes. * @return size of the artifact in bytes.
*/ */
Long getSize(); long getSize();
} }

View File

@@ -44,6 +44,6 @@ public interface BaseEntity extends Serializable, Identifiable<Long> {
/** /**
* @return version of the {@link BaseEntity}. * @return version of the {@link BaseEntity}.
*/ */
long getOptLockRevision(); int getOptLockRevision();
} }

View File

@@ -26,10 +26,25 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement;
public interface DistributionSet extends NamedVersionedEntity { public interface DistributionSet extends NamedVersionedEntity {
/** /**
* @return {@link Set} of assigned {@link DistributionSetTag}s. * @return immutable {@link Set} of assigned {@link DistributionSetTag}s.
*/ */
Set<DistributionSetTag> getTags(); Set<DistributionSetTag> getTags();
/**
* @param tag
* to add
* @return <code>true</code> if tag could be added sucessfully (i.e. was not
* already in the list).
*/
boolean addTag(final DistributionSetTag tag);
/**
* @param tag
* to remove
* @return <code>true</code> if tag was in the list and removed
*/
boolean removeTag(final DistributionSetTag tag);
/** /**
* @return <code>true</code> if the set is deleted and only kept for history * @return <code>true</code> if the set is deleted and only kept for history
* purposes. * purposes.

View File

@@ -17,8 +17,8 @@ import java.util.List;
public interface DistributionSetTag extends Tag { public interface DistributionSetTag extends Tag {
/** /**
* @return {@link List} of {@link DistributionSet}s this {@link Tag} is * @return immutable {@link List} of {@link DistributionSet}s this
* assigned to. * {@link Tag} is assigned to.
*/ */
List<DistributionSet> getAssignedToDistributionSet(); List<DistributionSet> getAssignedToDistributionSet();

View File

@@ -27,15 +27,15 @@ public interface DistributionSetType extends NamedEntity {
boolean isDeleted(); boolean isDeleted();
/** /**
* @return set of {@link SoftwareModuleType}s that need to be in a * @return immutable set of {@link SoftwareModuleType}s that need to be in a
* {@link DistributionSet} of this type to be * {@link DistributionSet} of this type to be
* {@link DistributionSet#isComplete()}. * {@link DistributionSet#isComplete()}.
*/ */
Set<SoftwareModuleType> getMandatoryModuleTypes(); Set<SoftwareModuleType> getMandatoryModuleTypes();
/** /**
* @return set of optional {@link SoftwareModuleType}s that can be in a * @return immutable set of optional {@link SoftwareModuleType}s that can be
* {@link DistributionSet} of this type. * in a {@link DistributionSet} of this type.
*/ */
Set<SoftwareModuleType> getOptionalModuleTypes(); Set<SoftwareModuleType> getOptionalModuleTypes();

View File

@@ -38,7 +38,7 @@ public interface Rollout extends NamedEntity {
void setDistributionSet(DistributionSet distributionSet); void setDistributionSet(DistributionSet distributionSet);
/** /**
* @return list of deployment groups of the rollout. * @return immutable list of deployment groups of the rollout.
*/ */
List<RolloutGroup> getRolloutGroups(); List<RolloutGroup> getRolloutGroups();

View File

@@ -155,7 +155,7 @@ public interface RolloutGroup extends NamedEntity {
/** /**
* @return the total amount of targets containing in this group * @return the total amount of targets containing in this group
*/ */
long getTotalTargets(); int getTotalTargets();
/** /**
* @return the totalTargetCountStatus * @return the totalTargetCountStatus

View File

@@ -11,6 +11,10 @@ package org.eclipse.hawkbit.repository.model;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
/**
* Software package as sub element of a {@link DistributionSet}.
*
*/
public interface SoftwareModule extends NamedVersionedEntity { public interface SoftwareModule extends NamedVersionedEntity {
/** /**
@@ -40,12 +44,12 @@ public interface SoftwareModule extends NamedVersionedEntity {
Optional<LocalArtifact> getLocalArtifactByFilename(String fileName); Optional<LocalArtifact> getLocalArtifactByFilename(String fileName);
/** /**
* @return the artifacts * @return immutable list of all artifacts
*/ */
List<Artifact> getArtifacts(); List<Artifact> getArtifacts();
/** /**
* @return local artifacts only * @return immutable list of local artifacts only
*/ */
List<LocalArtifact> getLocalArtifacts(); List<LocalArtifact> getLocalArtifacts();
@@ -104,7 +108,8 @@ public interface SoftwareModule extends NamedVersionedEntity {
List<SoftwareModuleMetadata> getMetadata(); List<SoftwareModuleMetadata> getMetadata();
/** /**
* @return the assignedTo * @return immutable list of {@link DistributionSet}s the module is assigned
* to
*/ */
List<DistributionSet> getAssignedTo(); List<DistributionSet> getAssignedTo();

View File

@@ -32,12 +32,12 @@ public interface Target extends NamedEntity {
String getControllerId(); String getControllerId();
/** /**
* @return assigned {@link TargetTag}s. * @return immutable set of assigned {@link TargetTag}s.
*/ */
Set<TargetTag> getTags(); Set<TargetTag> getTags();
/** /**
* @return {@link Action} history of the {@link Target}. * @return immutable {@link Action} history of the {@link Target}.
*/ */
List<Action> getActions(); List<Action> getActions();
@@ -64,4 +64,19 @@ public interface Target extends NamedEntity {
*/ */
void setSecurityToken(String token); void setSecurityToken(String token);
/**
* @param tag
* to add
* @return <code>true</code> if tag could be added sucessfully (i.e. was not
* already in the list).
*/
public boolean addTag(TargetTag tag);
/**
* @param tag
* to remove
* @return <code>true</code> if tag was in the list and removed
*/
public boolean removeTag(TargetTag tag);
} }

View File

@@ -36,7 +36,8 @@ public interface TargetInfo extends Serializable {
/** /**
* @return time in {@link TimeUnit#MILLISECONDS} GMT when the {@link Target} * @return time in {@link TimeUnit#MILLISECONDS} GMT when the {@link Target}
* polled the server the last time. * polled the server the last time or <code>null</code> if target
* has never queried yet.
*/ */
Long getLastTargetQuery(); Long getLastTargetQuery();

View File

@@ -17,7 +17,7 @@ import java.util.List;
public interface TargetTag extends Tag { public interface TargetTag extends Tag {
/** /**
* @return {@link List} of targets assigned to this {@link Tag}. * @return immutable {@link List} of targets assigned to this {@link Tag}.
*/ */
List<Target> getAssignedToTargets(); List<Target> getAssignedToTargets();

View File

@@ -89,6 +89,10 @@
<groupId>cz.jirutka.rsql</groupId> <groupId>cz.jirutka.rsql</groupId>
<artifactId>rsql-parser</artifactId> <artifactId>rsql-parser</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit; package org.eclipse.hawkbit;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ArtifactManagement;
@@ -73,6 +72,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import com.google.common.collect.Maps;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
/** /**
@@ -197,7 +197,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
@Override @Override
protected Map<String, Object> getVendorProperties() { protected Map<String, Object> getVendorProperties() {
final Map<String, Object> properties = new HashMap<>(); final Map<String, Object> properties = Maps.newHashMapWithExpectedSize(5);
// 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

View File

@@ -30,6 +30,7 @@ import org.springframework.cache.annotation.CacheEvict;
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.domain.Slice; import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType; import org.springframework.data.jpa.repository.EntityGraph.EntityGraphType;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -103,7 +104,7 @@ public interface ActionRepository extends BaseEntityRepository<JpaAction, Long>,
* @return the found {@link Action} * @return the found {@link Action}
*/ */
@EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD) @EntityGraph(value = "Action.ds", type = EntityGraphType.LOAD)
Optional<Action> findFirstByTargetAndActiveOrderByIdAsc(final JpaTarget target, boolean active); Optional<Action> findFirstByTargetAndActive(final Sort sort, final JpaTarget target, boolean active);
/** /**
* Retrieves latest {@link UpdateAction} for given target and * Retrieves latest {@link UpdateAction} for given target and

View File

@@ -9,7 +9,7 @@
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
@@ -54,6 +54,8 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
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;
@@ -163,12 +165,15 @@ public class JpaControllerManagement implements ControllerManagement {
@Override @Override
public Optional<Action> findOldestActiveActionByTarget(final Target target) { public Optional<Action> findOldestActiveActionByTarget(final Target target) {
return actionRepository.findFirstByTargetAndActiveOrderByIdAsc((JpaTarget) target, true); // used in favorite to findFirstByTargetAndActiveOrderByIdAsc due to
// DATAJPA-841 issue.
return actionRepository.findFirstByTargetAndActive(new Sort(Direction.ASC, "id"), (JpaTarget) target, true);
} }
@Override @Override
public List<SoftwareModule> findSoftwareModulesByDistributionSet(final DistributionSet distributionSet) { public List<SoftwareModule> findSoftwareModulesByDistributionSet(final DistributionSet distributionSet) {
return new ArrayList<>(softwareModuleRepository.findByAssignedTo((JpaDistributionSet) distributionSet)); return Collections
.unmodifiableList(softwareModuleRepository.findByAssignedTo((JpaDistributionSet) distributionSet));
} }
@Override @Override

View File

@@ -597,7 +597,7 @@ public class JpaDeploymentManagement implements DeploymentManagement {
multiselect.where(cb.equal(actionRoot.get(JpaAction_.target), target)); multiselect.where(cb.equal(actionRoot.get(JpaAction_.target), target));
multiselect.orderBy(cb.desc(actionRoot.get(JpaAction_.id))); multiselect.orderBy(cb.desc(actionRoot.get(JpaAction_.id)));
multiselect.groupBy(actionRoot.get(JpaAction_.id)); multiselect.groupBy(actionRoot.get(JpaAction_.id));
return new ArrayList<>(entityManager.createQuery(multiselect).getResultList()); return Collections.unmodifiableList(entityManager.createQuery(multiselect).getResultList());
} }
@Override @Override

View File

@@ -15,7 +15,6 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -68,6 +67,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
/** /**
@@ -130,26 +130,24 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
final DistributionSetTag myTag = tagManagement.findDistributionSetTag(tagName); final DistributionSetTag myTag = tagManagement.findDistributionSetTag(tagName);
DistributionSetTagAssignmentResult result; DistributionSetTagAssignmentResult result;
final List<JpaDistributionSet> toBeChangedDSs = new ArrayList<>();
for (final JpaDistributionSet set : sets) { final List<JpaDistributionSet> toBeChangedDSs = sets.stream().filter(set -> set.addTag(myTag))
if (set.getTags().add(myTag)) { .collect(Collectors.toList());
toBeChangedDSs.add(set);
}
}
// un-assignment case // un-assignment case
if (toBeChangedDSs.isEmpty()) { if (toBeChangedDSs.isEmpty()) {
for (final JpaDistributionSet set : sets) { for (final JpaDistributionSet set : sets) {
if (set.getTags().remove(myTag)) { if (set.removeTag(myTag)) {
toBeChangedDSs.add(set); toBeChangedDSs.add(set);
} }
} }
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0, result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), 0,
toBeChangedDSs.size(), Collections.emptyList(), toBeChangedDSs.size(), Collections.emptyList(),
new ArrayList<>(distributionSetRepository.save(toBeChangedDSs)), myTag); Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)), myTag);
} else { } else {
result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(), result = new DistributionSetTagAssignmentResult(dsIds.size() - toBeChangedDSs.size(), toBeChangedDSs.size(),
0, new ArrayList<>(distributionSetRepository.save(toBeChangedDSs)), Collections.emptyList(), myTag); 0, Collections.unmodifiableList(distributionSetRepository.save(toBeChangedDSs)),
Collections.emptyList(), myTag);
} }
final DistributionSetTagAssignmentResult resultAssignment = result; final DistributionSetTagAssignmentResult resultAssignment = result;
@@ -178,8 +176,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
public void deleteDistributionSet(final Long... distributionSetIDs) { public void deleteDistributionSet(final Long... distributionSetIDs) {
final List<Long> toHardDelete = new ArrayList<>();
final List<Long> assigned = distributionSetRepository final List<Long> assigned = distributionSetRepository
.findAssignedToTargetDistributionSetsById(distributionSetIDs); .findAssignedToTargetDistributionSetsById(distributionSetIDs);
assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs)); assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs));
@@ -190,13 +186,10 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
// mark the rest as hard delete // mark the rest as hard delete
for (final Long setId : distributionSetIDs) { final List<Long> toHardDelete = Arrays.stream(distributionSetIDs).filter(setId -> !assigned.contains(setId))
if (!assigned.contains(setId)) { .collect(Collectors.toList());
toHardDelete.add(setId);
}
}
// hard delete the rest if exixts // hard delete the rest if exists
if (!toHardDelete.isEmpty()) { if (!toHardDelete.isEmpty()) {
// don't give the delete statement an empty list, JPA/Oracle cannot // don't give the delete statement an empty list, JPA/Oracle cannot
// handle the empty list // handle the empty list
@@ -243,7 +236,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaDistributionSet> toSave = (Collection) distributionSets; final Collection<JpaDistributionSet> toSave = (Collection) distributionSets;
return new ArrayList<>(distributionSetRepository.save(toSave)); return Collections.unmodifiableList(distributionSetRepository.save(toSave));
} }
@Override @Override
@@ -296,7 +289,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
} }
private static Page<DistributionSetType> convertDsTPage(final Page<JpaDistributionSetType> findAll) { private static Page<DistributionSetType> convertDsTPage(final Page<JpaDistributionSetType> findAll) {
return new PageImpl<>(new ArrayList<>(findAll.getContent())); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()));
} }
@Override @Override
@@ -314,7 +307,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private static Page<DistributionSet> convertDsPage(final Page<JpaDistributionSet> findAll, private static Page<DistributionSet> convertDsPage(final Page<JpaDistributionSet> findAll,
final Pageable pageable) { final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
/** /**
@@ -337,7 +330,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override @Override
public Page<DistributionSet> findDistributionSetsByDeletedAndOrCompleted(final Pageable pageReq, public Page<DistributionSet> findDistributionSetsByDeletedAndOrCompleted(final Pageable pageReq,
final Boolean deleted, final Boolean complete) { final Boolean deleted, final Boolean complete) {
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(); final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(2);
if (deleted != null) { if (deleted != null) {
final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isDeleted(deleted); final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isDeleted(deleted);
@@ -359,11 +352,12 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
final Specification<JpaDistributionSet> spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class, final Specification<JpaDistributionSet> spec = RSQLUtility.parse(rsqlParam, DistributionSetFields.class,
virtualPropertyLookup); virtualPropertyLookup);
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(); final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(2);
if (deleted != null) { if (deleted != null) {
specList.add(DistributionSetSpecification.isDeleted(deleted)); specList.add(DistributionSetSpecification.isDeleted(deleted));
} }
specList.add(spec); specList.add(spec);
return convertDsPage(findByCriteriaAPI(pageReq, specList), pageReq); return convertDsPage(findByCriteriaAPI(pageReq, specList), pageReq);
} }
@@ -388,7 +382,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
final Page<DistributionSet> findDistributionSetsByFilters = findDistributionSetsByFilters(pageable, final Page<DistributionSet> findDistributionSetsByFilters = findDistributionSetsByFilters(pageable,
dsFilterWithNoTargetLinked); dsFilterWithNoTargetLinked);
final List<DistributionSet> resultSet = new LinkedList<>(findDistributionSetsByFilters.getContent()); final List<DistributionSet> resultSet = new ArrayList<>(findDistributionSetsByFilters.getContent());
int orderIndex = 0; int orderIndex = 0;
if (installedDS != null) { if (installedDS != null) {
final boolean remove = resultSet.remove(installedDS); final boolean remove = resultSet.remove(installedDS);
@@ -419,18 +413,15 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override @Override
public List<DistributionSet> findDistributionSetsAll(final Collection<Long> dist) { public List<DistributionSet> findDistributionSetsAll(final Collection<Long> dist) {
return new ArrayList<>(distributionSetRepository.findAll(DistributionSetSpecification.byIds(dist))); return Collections
.unmodifiableList(distributionSetRepository.findAll(DistributionSetSpecification.byIds(dist)));
} }
@Override @Override
public Long countDistributionSetsAll() { public Long countDistributionSetsAll() {
final List<Specification<JpaDistributionSet>> specList = new LinkedList<>();
final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isDeleted(Boolean.FALSE); final Specification<JpaDistributionSet> spec = DistributionSetSpecification.isDeleted(Boolean.FALSE);
specList.add(spec);
return distributionSetRepository.count(SpecificationsBuilder.combineWithAnd(specList)); return distributionSetRepository.count(SpecificationsBuilder.combineWithAnd(Lists.newArrayList(spec)));
} }
@Override @Override
@@ -560,7 +551,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@Override @Override
public List<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) { public List<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) {
return new ArrayList<>(distributionSetMetadataRepository return Collections.unmodifiableList(distributionSetMetadataRepository
.findAll((Specification<JpaDistributionSetMetadata>) (root, query, cb) -> cb.equal( .findAll((Specification<JpaDistributionSetMetadata>) (root, query, cb) -> cb.equal(
root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id),
distributionSetId))); distributionSetId)));
@@ -584,7 +575,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private static Page<DistributionSetMetadata> convertMdPage(final Page<JpaDistributionSetMetadata> findAll, private static Page<DistributionSetMetadata> convertMdPage(final Page<JpaDistributionSetMetadata> findAll,
final Pageable pageable) { final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
@Override @Override
@@ -609,7 +600,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private static List<Specification<JpaDistributionSet>> buildDistributionSetSpecifications( private static List<Specification<JpaDistributionSet>> buildDistributionSetSpecifications(
final DistributionSetFilter distributionSetFilter) { final DistributionSetFilter distributionSetFilter) {
final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(); final List<Specification<JpaDistributionSet>> specList = new ArrayList<>(7);
Specification<JpaDistributionSet> spec; Specification<JpaDistributionSet> spec;
@@ -710,9 +701,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
public List<DistributionSet> assignTag(final Collection<Long> dsIds, final DistributionSetTag tag) { public List<DistributionSet> assignTag(final Collection<Long> dsIds, final DistributionSetTag tag) {
final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds); final List<JpaDistributionSet> allDs = findDistributionSetListWithDetails(dsIds);
allDs.forEach(ds -> ds.getTags().add(tag)); allDs.forEach(ds -> ds.addTag(tag));
final List<DistributionSet> save = new ArrayList<>(distributionSetRepository.save(allDs)); final List<DistributionSet> save = Collections.unmodifiableList(distributionSetRepository.save(allDs));
afterCommit.afterCommit(() -> { afterCommit.afterCommit(() -> {
@@ -732,7 +723,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaDistributionSet> distributionSets = (Collection) tag.getAssignedToDistributionSet(); final Collection<JpaDistributionSet> distributionSets = (Collection) tag.getAssignedToDistributionSet();
return new ArrayList<>(unAssignTag(distributionSets, tag)); return Collections.unmodifiableList(unAssignTag(distributionSets, tag));
} }
@Override @Override
@@ -746,7 +737,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
private List<JpaDistributionSet> unAssignTag(final Collection<JpaDistributionSet> distributionSets, private List<JpaDistributionSet> unAssignTag(final Collection<JpaDistributionSet> distributionSets,
final DistributionSetTag tag) { final DistributionSetTag tag) {
distributionSets.forEach(ds -> ds.getTags().remove(tag)); distributionSets.forEach(ds -> ds.removeTag(tag));
return distributionSetRepository.save(distributionSets); return distributionSetRepository.save(distributionSets);
} }

View File

@@ -43,11 +43,13 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery; import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTag;
import org.springframework.validation.annotation.Validated;
/** /**
* JPA Implementation of {@link EntityFactory}. * JPA Implementation of {@link EntityFactory}.
* *
*/ */
@Validated
public class JpaEntityFactory implements EntityFactory { public class JpaEntityFactory implements EntityFactory {
@Override @Override

View File

@@ -8,7 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -85,11 +85,11 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
} }
private static Page<RolloutGroup> convertPage(final Page<JpaRolloutGroup> findAll, final Pageable pageable) { private static Page<RolloutGroup> convertPage(final Page<JpaRolloutGroup> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
private static Page<Target> convertTPage(final Page<JpaTarget> findAll, final Pageable pageable) { private static Page<Target> convertTPage(final Page<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
@Override @Override
@@ -119,7 +119,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
for (final RolloutGroup rolloutGroup : rolloutGroups) { for (final RolloutGroup rolloutGroup : rolloutGroups) {
final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus( final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(
allStatesForRollout.get(rolloutGroup.getId()), rolloutGroup.getTotalTargets()); allStatesForRollout.get(rolloutGroup.getId()), Long.valueOf(rolloutGroup.getTotalTargets()));
rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus); rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus);
} }
@@ -133,7 +133,7 @@ public class JpaRolloutGroupManagement implements RolloutGroupManagement {
.getStatusCountByRolloutGroupId(rolloutGroupId); .getStatusCountByRolloutGroupId(rolloutGroupId);
final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(rolloutStatusCountItems, final TotalTargetCountStatus totalTargetCountStatus = new TotalTargetCountStatus(rolloutStatusCountItems,
rolloutGroup.getTotalTargets()); Long.valueOf(rolloutGroup.getTotalTargets()));
rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus); rolloutGroup.setTotalTargetCountStatus(totalTargetCountStatus);
return rolloutGroup; return rolloutGroup;

View File

@@ -8,7 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa; package org.eclipse.hawkbit.repository.jpa;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -144,11 +144,11 @@ public class JpaRolloutManagement implements RolloutManagement {
} }
private static Page<Rollout> convertPage(final Page<JpaRollout> findAll, final Pageable pageable) { private static Page<Rollout> convertPage(final Page<JpaRollout> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
private static Slice<Rollout> convertPage(final Slice<JpaRollout> findAll, final Pageable pageable) { private static Slice<Rollout> convertPage(final Slice<JpaRollout> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
} }
@Override @Override
@@ -656,7 +656,7 @@ public class JpaRolloutManagement implements RolloutManagement {
@Override @Override
public float getFinishedPercentForRunningGroup(final Long rolloutId, final RolloutGroup rolloutGroup) { public float getFinishedPercentForRunningGroup(final Long rolloutId, final RolloutGroup rolloutGroup) {
final Long totalGroup = rolloutGroup.getTotalTargets(); final int totalGroup = rolloutGroup.getTotalTargets();
final Long finished = actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rolloutId, final Long finished = actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rolloutId,
rolloutGroup.getId(), Action.Status.FINISHED); rolloutGroup.getId(), Action.Status.FINISHED);
if (totalGroup == 0) { if (totalGroup == 0) {

View File

@@ -11,12 +11,15 @@ package org.eclipse.hawkbit.repository.jpa;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
@@ -66,6 +69,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
/** /**
@@ -170,7 +174,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaSoftwareModule> jpaCast = (Collection) swModules; final Collection<JpaSoftwareModule> jpaCast = (Collection) swModules;
return new ArrayList<>(softwareModuleRepository.save(jpaCast)); return Collections.unmodifiableList(softwareModuleRepository.save(jpaCast));
} }
@Override @Override
@@ -189,22 +193,22 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private static Slice<SoftwareModule> convertSmPage(final Slice<JpaSoftwareModule> findAll, private static Slice<SoftwareModule> convertSmPage(final Slice<JpaSoftwareModule> findAll,
final Pageable pageable) { final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
} }
private static Page<SoftwareModule> convertSmPage(final Page<JpaSoftwareModule> findAll, final Pageable pageable) { private static Page<SoftwareModule> convertSmPage(final Page<JpaSoftwareModule> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
private static Page<SoftwareModuleMetadata> convertSmMdPage(final Page<JpaSoftwareModuleMetadata> findAll, private static Page<SoftwareModuleMetadata> convertSmMdPage(final Page<JpaSoftwareModuleMetadata> findAll,
final Pageable pageable) { final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
@Override @Override
public Long countSoftwareModulesByType(final SoftwareModuleType type) { public Long countSoftwareModulesByType(final SoftwareModuleType type) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(); final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(2);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type);
specList.add(spec); specList.add(spec);
@@ -281,7 +285,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override @Override
public Slice<SoftwareModule> findSoftwareModulesAll(final Pageable pageable) { public Slice<SoftwareModule> findSoftwareModulesAll(final Pageable pageable) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(); final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(2);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse(); Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec); specList.add(spec);
@@ -300,13 +304,9 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override @Override
public Long countSoftwareModulesAll() { public Long countSoftwareModulesAll() {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>();
final Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse(); final Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec);
return countSwModuleByCriteriaAPI(specList); return countSwModuleByCriteriaAPI(Lists.newArrayList(spec));
} }
@Override @Override
@@ -333,20 +333,20 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private static Page<SoftwareModuleType> convertSmTPage(final Page<JpaSoftwareModuleType> findAll, private static Page<SoftwareModuleType> convertSmTPage(final Page<JpaSoftwareModuleType> findAll,
final Pageable pageable) { final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
@Override @Override
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
public List<SoftwareModule> findSoftwareModulesById(final Collection<Long> ids) { public List<SoftwareModule> findSoftwareModulesById(final Collection<Long> ids) {
return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); return Collections.unmodifiableList(softwareModuleRepository.findByIdIn(ids));
} }
@Override @Override
public Slice<SoftwareModule> findSoftwareModuleByFilters(final Pageable pageable, final String searchText, public Slice<SoftwareModule> findSoftwareModuleByFilters(final Pageable pageable, final String searchText,
final SoftwareModuleType type) { final SoftwareModuleType type) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(); final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(4);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse(); Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec); specList.add(spec);
@@ -444,7 +444,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private static List<Specification<JpaSoftwareModule>> buildSpecificationList(final String searchText, private static List<Specification<JpaSoftwareModule>> buildSpecificationList(final String searchText,
final JpaSoftwareModuleType type) { final JpaSoftwareModuleType type) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(); final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(3);
if (!Strings.isNullOrEmpty(searchText)) { if (!Strings.isNullOrEmpty(searchText)) {
specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText));
} }
@@ -458,18 +458,15 @@ public class JpaSoftwareManagement implements SoftwareManagement {
private Predicate[] specificationsToPredicate(final List<Specification<JpaSoftwareModule>> specifications, private Predicate[] specificationsToPredicate(final List<Specification<JpaSoftwareModule>> specifications,
final Root<JpaSoftwareModule> root, final CriteriaQuery<?> query, final CriteriaBuilder cb, final Root<JpaSoftwareModule> root, final CriteriaQuery<?> query, final CriteriaBuilder cb,
final Predicate... additionalPredicates) { final Predicate... additionalPredicates) {
final List<Predicate> predicates = new ArrayList<>();
specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); return Stream.concat(specifications.stream().map(spec -> spec.toPredicate(root, query, cb)),
for (final Predicate predicate : additionalPredicates) { Arrays.stream(additionalPredicates)).toArray(Predicate[]::new);
predicates.add(predicate);
}
return predicates.toArray(new Predicate[predicates.size()]);
} }
@Override @Override
public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) {
final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(); final List<Specification<JpaSoftwareModule>> specList = new ArrayList<>(3);
Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse(); Specification<JpaSoftwareModule> spec = SoftwareModuleSpecification.isDeletedFalse();
specList.add(spec); specList.add(spec);
@@ -579,7 +576,7 @@ public class JpaSoftwareManagement implements SoftwareManagement {
checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId());
} }
metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L));
return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); return Collections.unmodifiableList(softwareModuleMetadataRepository.save(metadata));
} }
@Override @Override
@@ -629,8 +626,8 @@ public class JpaSoftwareManagement implements SoftwareManagement {
@Override @Override
public List<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { public List<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) {
return new ArrayList<>( return Collections
softwareModuleMetadataRepository .unmodifiableList(softwareModuleMetadataRepository
.findAll((Specification<JpaSoftwareModuleMetadata>) (root, query, .findAll((Specification<JpaSoftwareModuleMetadata>) (root, query,
cb) -> cb.and(cb.equal( cb) -> cb.and(cb.equal(
root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id), root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id),

View File

@@ -10,8 +10,8 @@ package org.eclipse.hawkbit.repository.jpa;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -115,7 +115,7 @@ public class JpaTagManagement implements TagManagement {
} }
}); });
final List<TargetTag> save = new ArrayList<>(targetTagRepository.save(targetTags)); final List<TargetTag> save = Collections.unmodifiableList(targetTagRepository.save(targetTags));
afterCommit afterCommit
.afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save))); .afterCommit(() -> eventBus.post(new TargetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
return save; return save;
@@ -145,7 +145,7 @@ public class JpaTagManagement implements TagManagement {
@Override @Override
public List<TargetTag> findAllTargetTags() { public List<TargetTag> findAllTargetTags() {
return new ArrayList<>(targetTagRepository.findAll()); return Collections.unmodifiableList(targetTagRepository.findAll());
} }
@Override @Override
@@ -156,12 +156,12 @@ public class JpaTagManagement implements TagManagement {
} }
private static Page<TargetTag> convertTPage(final Page<JpaTargetTag> findAll, final Pageable pageable) { private static Page<TargetTag> convertTPage(final Page<JpaTargetTag> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
private static Page<DistributionSetTag> convertDsPage(final Page<JpaDistributionSetTag> findAll, private static Page<DistributionSetTag> convertDsPage(final Page<JpaDistributionSetTag> findAll,
final Pageable pageable) { final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
@Override @Override
@@ -217,7 +217,8 @@ public class JpaTagManagement implements TagManagement {
throw new EntityAlreadyExistsException(); throw new EntityAlreadyExistsException();
} }
} }
final List<DistributionSetTag> save = new ArrayList<>(distributionSetTagRepository.save(distributionSetTags)); final List<DistributionSetTag> save = Collections
.unmodifiableList(distributionSetTagRepository.save(distributionSetTags));
afterCommit.afterCommit( afterCommit.afterCommit(
() -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save))); () -> eventBus.post(new DistributionSetTagCreatedBulkEvent(tenantAware.getCurrentTenant(), save)));
@@ -232,7 +233,7 @@ public class JpaTagManagement implements TagManagement {
final List<JpaDistributionSet> changed = new LinkedList<>(); final List<JpaDistributionSet> changed = new LinkedList<>();
for (final JpaDistributionSet set : distributionSetRepository.findByTag(tag)) { for (final JpaDistributionSet set : distributionSetRepository.findByTag(tag)) {
set.getTags().remove(tag); set.removeTag(tag);
changed.add(set); changed.add(set);
} }
@@ -258,7 +259,7 @@ public class JpaTagManagement implements TagManagement {
@Override @Override
public List<DistributionSetTag> findAllDistributionSetTags() { public List<DistributionSetTag> findAllDistributionSetTags() {
return new ArrayList<>(distributionSetTagRepository.findAll()); return Collections.unmodifiableList(distributionSetTagRepository.findAll());
} }
@Override @Override

View File

@@ -132,7 +132,7 @@ public class JpaTargetManagement implements TargetManagement {
@Override @Override
public List<Target> findTargetByControllerID(final Collection<String> controllerIDs) { public List<Target> findTargetByControllerID(final Collection<String> controllerIDs) {
return new ArrayList<>(targetRepository return Collections.unmodifiableList(targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs))); .findAll(TargetSpecifications.byControllerIdWithStatusAndAssignedInJoin(controllerIDs)));
} }
@@ -201,7 +201,7 @@ public class JpaTargetManagement implements TargetManagement {
toUpdate.forEach(target -> target.setNew(false)); toUpdate.forEach(target -> target.setNew(false));
return new ArrayList<>(targetRepository.save(toUpdate)); return Collections.unmodifiableList(targetRepository.save(toUpdate));
} }
@Override @Override
@@ -245,11 +245,11 @@ public class JpaTargetManagement implements TargetManagement {
} }
private static Page<Target> convertPage(final Page<JpaTarget> findAll, final Pageable pageable) { private static Page<Target> convertPage(final Page<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, findAll.getTotalElements());
} }
private static Slice<Target> convertPage(final Slice<JpaTarget> findAll, final Pageable pageable) { private static Slice<Target> convertPage(final Slice<JpaTarget> findAll, final Pageable pageable) {
return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); return new PageImpl<>(Collections.unmodifiableList(findAll.getContent()), pageable, 0);
} }
@Override @Override
@@ -291,8 +291,8 @@ public class JpaTargetManagement implements TargetManagement {
@Override @Override
public Long countTargetByFilters(final Collection<TargetUpdateStatus> status, final Boolean overdueState, public Long countTargetByFilters(final Collection<TargetUpdateStatus> status, final Boolean overdueState,
final String searchText, final Long installedOrAssignedDistributionSetId, final String searchText, final Long installedOrAssignedDistributionSetId,
final Boolean selectTargetWithNoTag, final String... tagNames) { final Boolean selectTargetWithNoTag, final String... tagNames) {
final List<Specification<JpaTarget>> specList = buildSpecificationList( final List<Specification<JpaTarget>> specList = buildSpecificationList(
new FilterParams(installedOrAssignedDistributionSetId, status, overdueState, searchText, new FilterParams(installedOrAssignedDistributionSetId, status, overdueState, searchText,
selectTargetWithNoTag, tagNames), selectTargetWithNoTag, tagNames),
@@ -301,7 +301,7 @@ public class JpaTargetManagement implements TargetManagement {
} }
private static List<Specification<JpaTarget>> buildSpecificationList(final FilterParams filterParams, private static List<Specification<JpaTarget>> buildSpecificationList(final FilterParams filterParams,
final boolean fetch) { final boolean fetch) {
final List<Specification<JpaTarget>> specList = new ArrayList<>(); final List<Specification<JpaTarget>> specList = new ArrayList<>();
if (filterParams.getFilterByStatus() != null && !filterParams.getFilterByStatus().isEmpty()) { if (filterParams.getFilterByStatus() != null && !filterParams.getFilterByStatus().isEmpty()) {
specList.add(TargetSpecifications.hasTargetUpdateStatus(filterParams.getFilterByStatus(), fetch)); specList.add(TargetSpecifications.hasTargetUpdateStatus(filterParams.getFilterByStatus(), fetch));
@@ -362,7 +362,7 @@ public class JpaTargetManagement implements TargetManagement {
// all are already assigned -> unassign // all are already assigned -> unassign
if (alreadyAssignedTargets.size() == allTargets.size()) { if (alreadyAssignedTargets.size() == allTargets.size()) {
alreadyAssignedTargets.forEach(target -> target.getTags().remove(tag)); alreadyAssignedTargets.forEach(target -> target.removeTag(tag));
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);
@@ -372,9 +372,10 @@ public class JpaTargetManagement implements TargetManagement {
allTargets.removeAll(alreadyAssignedTargets); allTargets.removeAll(alreadyAssignedTargets);
// some or none are assigned -> assign // some or none are assigned -> assign
allTargets.forEach(target -> target.getTags().add(tag)); allTargets.forEach(target -> target.addTag(tag));
final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(), final TargetTagAssignmentResult result = new TargetTagAssignmentResult(alreadyAssignedTargets.size(),
allTargets.size(), 0, new ArrayList<>(targetRepository.save(allTargets)), Collections.emptyList(), tag); allTargets.size(), 0, Collections.unmodifiableList(targetRepository.save(allTargets)),
Collections.emptyList(), tag);
afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result))); afterCommit.afterCommit(() -> eventBus.post(new TargetTagAssigmentResultEvent(result)));
@@ -390,8 +391,8 @@ public class JpaTargetManagement implements TargetManagement {
final List<JpaTarget> allTargets = targetRepository final List<JpaTarget> allTargets = targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds)); .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(targetIds));
allTargets.forEach(target -> target.getTags().add(tag)); allTargets.forEach(target -> target.addTag(tag));
final List<Target> save = new ArrayList<>(targetRepository.save(allTargets)); final List<Target> save = Collections.unmodifiableList(targetRepository.save(allTargets));
afterCommit.afterCommit(() -> { afterCommit.afterCommit(() -> {
final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save, final TargetTagAssignmentResult assigmentResult = new TargetTagAssignmentResult(0, save.size(), 0, save,
@@ -403,11 +404,12 @@ public class JpaTargetManagement implements TargetManagement {
} }
private List<Target> unAssignTag(final Collection<Target> targets, final TargetTag tag) { private List<Target> unAssignTag(final Collection<Target> targets, final TargetTag tag) {
@SuppressWarnings({ "unchecked", "rawtypes" })
final Collection<JpaTarget> toUnassign = (Collection) targets; final Collection<JpaTarget> toUnassign = (Collection) targets;
toUnassign.forEach(target -> target.getTags().remove(tag)); toUnassign.forEach(target -> target.removeTag(tag));
final List<Target> save = new ArrayList<>(targetRepository.save(toUnassign)); final List<Target> save = Collections.unmodifiableList(targetRepository.save(toUnassign));
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);
@@ -427,7 +429,7 @@ public class JpaTargetManagement implements TargetManagement {
@Modifying @Modifying
@Transactional(isolation = Isolation.READ_UNCOMMITTED) @Transactional(isolation = Isolation.READ_UNCOMMITTED)
public Target unAssignTag(final String controllerID, final TargetTag targetTag) { public Target unAssignTag(final String controllerID, final TargetTag targetTag) {
final List<Target> allTargets = new ArrayList<>(targetRepository final List<Target> allTargets = Collections.unmodifiableList(targetRepository
.findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID)))); .findAll(TargetSpecifications.byControllerIdWithStatusAndTagsInJoin(Arrays.asList(controllerID))));
final List<Target> unAssignTag = unAssignTag(allTargets, targetTag); final List<Target> unAssignTag = unAssignTag(allTargets, targetTag);
return unAssignTag.isEmpty() ? null : unAssignTag.get(0); return unAssignTag.isEmpty() ? null : unAssignTag.get(0);
@@ -481,7 +483,7 @@ public class JpaTargetManagement implements TargetManagement {
final List<JpaTarget> resultList = entityManager.createQuery(query).setFirstResult(pageable.getOffset()) final List<JpaTarget> resultList = entityManager.createQuery(query).setFirstResult(pageable.getOffset())
.setMaxResults(pageSize + 1).getResultList(); .setMaxResults(pageSize + 1).getResultList();
final boolean hasNext = resultList.size() > pageSize; final boolean hasNext = resultList.size() > pageSize;
return new SliceImpl<>(new ArrayList<>(resultList), pageable, hasNext); return new SliceImpl<>(Collections.unmodifiableList(resultList), pageable, hasNext);
} }
private static Predicate[] specificationsToPredicate(final List<Specification<JpaTarget>> specifications, private static Predicate[] specificationsToPredicate(final List<Specification<JpaTarget>> specifications,
@@ -564,13 +566,9 @@ public class JpaTargetManagement implements TargetManagement {
final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id), final CriteriaQuery<Object[]> multiselect = query.multiselect(targetRoot.get(JpaTarget_.id),
targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty)); targetRoot.get(JpaTarget_.controllerId), targetRoot.get(JpaTarget_.name), targetRoot.get(sortProperty));
final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, final Specification<JpaTarget> spec = RSQLUtility.parse(targetFilterQuery.getQuery(), TargetFields.class, virtualPropertyLookup);
virtualPropertyLookup); final Predicate[] specificationsForMultiSelect = specificationsToPredicate(Lists.newArrayList(spec), targetRoot,
final List<Specification<JpaTarget>> specList = new ArrayList<>(); multiselect, cb);
specList.add(spec);
final Predicate[] specificationsForMultiSelect = specificationsToPredicate(specList, targetRoot, multiselect,
cb);
// if we have some predicates then add it to the where clause of the // if we have some predicates then add it to the where clause of the
// multiselect // multiselect
@@ -632,18 +630,16 @@ public class JpaTargetManagement implements TargetManagement {
targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) { targets.stream().map(target -> target.getControllerId()).collect(Collectors.toList())) > 0) {
throw new EntityAlreadyExistsException(); throw new EntityAlreadyExistsException();
} }
final List<Target> savedTargets = new ArrayList<>();
for (final Target t : targets) { return targets.stream()
final Target myTarget = createTarget(t, TargetUpdateStatus.UNKNOWN, null, t.getTargetInfo().getAddress()); .map(t -> createTarget(t, TargetUpdateStatus.UNKNOWN, null, t.getTargetInfo().getAddress()))
savedTargets.add(myTarget); .collect(Collectors.toList());
}
return savedTargets;
} }
@Override @Override
public List<Target> findTargetsByTag(final String tagName) { public List<Target> findTargetsByTag(final String tagName) {
final JpaTargetTag tag = targetTagRepository.findByNameEquals(tagName); final JpaTargetTag tag = targetTagRepository.findByNameEquals(tagName);
return new ArrayList<>(targetRepository.findByTag(tag)); return Collections.unmodifiableList(targetRepository.findByTag(tag));
} }
@Override @Override

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.jpa.aspects;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -36,6 +35,8 @@ import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.transaction.TransactionSystemException; import org.springframework.transaction.TransactionSystemException;
import com.google.common.collect.Maps;
/** /**
* {@link Aspect} catches persistence exceptions and wraps them to custom * {@link Aspect} catches persistence exceptions and wraps them to custom
* specific exceptions Additionally it checks and prevents access to certain * specific exceptions Additionally it checks and prevents access to certain
@@ -49,14 +50,14 @@ public class ExceptionMappingAspectHandler implements Ordered {
private static final Logger LOG = LoggerFactory.getLogger(ExceptionMappingAspectHandler.class); private static final Logger LOG = LoggerFactory.getLogger(ExceptionMappingAspectHandler.class);
private static final Map<String, String> EXCEPTION_MAPPING = new HashMap<>(); private static final Map<String, String> EXCEPTION_MAPPING = Maps.newHashMapWithExpectedSize(4);
/** /**
* this is required to enable a certain order of exception and to select the * this is required to enable a certain order of exception and to select the
* most specific mappable exception according to the type hierarchy of the * most specific mappable exception according to the type hierarchy of the
* exception. * exception.
*/ */
private static final List<Class<?>> MAPPED_EXCEPTION_ORDER = new ArrayList<>(); private static final List<Class<?>> MAPPED_EXCEPTION_ORDER = new ArrayList<>(4);
@Autowired @Autowired
private JpaVendorAdapter jpaVendorAdapter; private JpaVendorAdapter jpaVendorAdapter;

View File

@@ -32,7 +32,7 @@ public abstract class AbstractJpaArtifact extends AbstractJpaTenantAwareBaseEnti
private String md5Hash; private String md5Hash;
@Column(name = "file_size") @Column(name = "file_size")
private Long size; private long size;
@Override @Override
public abstract SoftwareModule getSoftwareModule(); public abstract SoftwareModule getSoftwareModule();
@@ -56,11 +56,11 @@ public abstract class AbstractJpaArtifact extends AbstractJpaTenantAwareBaseEnti
} }
@Override @Override
public Long getSize() { public long getSize() {
return size; return size;
} }
public void setSize(final Long size) { public void setSize(final long size) {
this.size = size; this.size = size;
} }
} }

View File

@@ -48,7 +48,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
@Version @Version
@Column(name = "optlock_revision") @Column(name = "optlock_revision")
private long optLockRevision; private int optLockRevision;
/** /**
* Default constructor needed for JPA entities. * Default constructor needed for JPA entities.
@@ -106,11 +106,11 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
} }
@Override @Override
public long getOptLockRevision() { public int getOptLockRevision() {
return optLockRevision; return optLockRevision;
} }
public void setOptLockRevision(final long optLockRevision) { public void setOptLockRevision(final int optLockRevision) {
this.optLockRevision = optLockRevision; this.optLockRevision = optLockRevision;
} }
@@ -142,7 +142,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
final int prime = 31; final int prime = 31;
int result = 1; int result = 1;
result = prime * result + (id == null ? 0 : id.hashCode()); result = prime * result + (id == null ? 0 : id.hashCode());
result = prime * result + (int) (optLockRevision ^ optLockRevision >>> 32); result = prime * result + optLockRevision;
result = prime * result + this.getClass().getName().hashCode(); result = prime * result + this.getClass().getName().hashCode();
return result; return result;
} }
@@ -179,5 +179,4 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity {
return true; return true;
} }
} }

View File

@@ -26,7 +26,7 @@ public abstract class AbstractJpaMetaData implements MetaData {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Id @Id
@Column(name = "meta_key", length = 128) @Column(name = "meta_key", nullable = false, length = 128)
@Size(min = 1, max = 128) @Size(min = 1, max = 128)
@NotNull @NotNull
private String key; private String key;
@@ -37,7 +37,6 @@ public abstract class AbstractJpaMetaData implements MetaData {
private String value; private String value;
public AbstractJpaMetaData(final String key, final String value) { public AbstractJpaMetaData(final String key, final String value) {
super();
this.key = key; this.key = key;
this.value = value; this.value = value;
} }

View File

@@ -40,7 +40,7 @@ public abstract class AbstractJpaNamedEntity extends AbstractJpaTenantAwareBaseE
* Default constructor. * Default constructor.
*/ */
public AbstractJpaNamedEntity() { public AbstractJpaNamedEntity() {
super(); // Default constructor needed for JPA entities
} }
/** /**

View File

@@ -47,7 +47,7 @@ public abstract class AbstractJpaNamedVersionedEntity extends AbstractJpaNamedEn
} }
AbstractJpaNamedVersionedEntity() { AbstractJpaNamedVersionedEntity() {
super(); // Default constructor needed for JPA entities
} }
@Override @Override

View File

@@ -31,7 +31,7 @@ public abstract class AbstractJpaTag extends AbstractJpaNamedEntity implements T
private String colour; private String colour;
protected AbstractJpaTag() { protected AbstractJpaTag() {
super(); // Default constructor needed for JPA entities
} }
/** /**

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
@@ -134,7 +135,11 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio
@Override @Override
public List<ActionStatus> getActionStatus() { public List<ActionStatus> getActionStatus() {
return actionStatus; if (actionStatus == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(actionStatus);
} }
@Override @Override

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.persistence.CollectionTable; import javax.persistence.CollectionTable;
@@ -48,6 +49,8 @@ import com.google.common.base.Splitter;
// sub entities // sub entities
@SuppressWarnings("squid:S2160") @SuppressWarnings("squid:S2160")
public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements ActionStatus { public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements ActionStatus {
private static final int MESSAGE_ENTRY_LENGTH = 512;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Column(name = "target_occurred_at") @Column(name = "target_occurred_at")
@@ -67,14 +70,14 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
@CollectionTable(name = "sp_action_status_messages", joinColumns = @JoinColumn(name = "action_status_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_stat_msg_act_stat")), indexes = { @CollectionTable(name = "sp_action_status_messages", joinColumns = @JoinColumn(name = "action_status_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_stat_msg_act_stat")), indexes = {
@Index(name = "sp_idx_action_status_msgs_01", columnList = "action_status_id") }) @Index(name = "sp_idx_action_status_msgs_01", columnList = "action_status_id") })
@Column(name = "detail_message", length = 512) @Column(name = "detail_message", length = 512)
private final List<String> messages = new ArrayList<>(); private List<String> messages;
/** /**
* Note: filled only in {@link Status#DOWNLOAD}. * Note: filled only in {@link Status#DOWNLOAD}.
*/ */
@Transient @Transient
@CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT) @CacheField(key = CacheKeys.DOWNLOAD_PROGRESS_PERCENT)
private int downloadProgressPercent; private short downloadProgressPercent;
/** /**
* Creates a new {@link ActionStatus} object. * Creates a new {@link ActionStatus} object.
@@ -86,7 +89,7 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
* @param occurredAt * @param occurredAt
* the occurred timestamp * the occurred timestamp
*/ */
public JpaActionStatus(final Action action, final Status status, final Long occurredAt) { public JpaActionStatus(final Action action, final Status status, final long occurredAt) {
this.action = (JpaAction) action; this.action = (JpaAction) action;
this.status = status; this.status = status;
this.occurredAt = occurredAt; this.occurredAt = occurredAt;
@@ -119,7 +122,7 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
} }
@Override @Override
public int getDownloadProgressPercent() { public short getDownloadProgressPercent() {
return downloadProgressPercent; return downloadProgressPercent;
} }
@@ -136,13 +139,20 @@ public class JpaActionStatus extends AbstractJpaTenantAwareBaseEntity implements
@Override @Override
public final void addMessage(final String message) { public final void addMessage(final String message) {
if (message != null) { if (message != null) {
Splitter.fixedLength(512).split(message).forEach(messages::add); if (messages == null) {
messages = new ArrayList<>((message.length() / MESSAGE_ENTRY_LENGTH) + 1);
}
Splitter.fixedLength(MESSAGE_ENTRY_LENGTH).split(message).forEach(messages::add);
} }
} }
@Override @Override
public List<String> getMessages() { public List<String> getMessages() {
return messages; if (messages == null) {
messages = Collections.emptyList();
}
return Collections.unmodifiableList(messages);
} }
@Override @Override

View File

@@ -59,7 +59,7 @@ public class JpaActionWithStatusCount implements ActionWithStatusCount {
// Exception squid:S00107 - needed this way for JPA to fill the view // Exception squid:S00107 - needed this way for JPA to fill the view
@SuppressWarnings("squid:S00107") @SuppressWarnings("squid:S00107")
public JpaActionWithStatusCount(final Long actionId, final ActionType actionType, final boolean active, public JpaActionWithStatusCount(final Long actionId, final ActionType actionType, final boolean active,
final long forcedTime, final Status status, final Long actionCreatedAt, final Long actionLastModifiedAt, final Long forcedTime, final Status status, final Long actionCreatedAt, final Long actionLastModifiedAt,
final Long dsId, final String dsName, final String dsVersion, final Long actionStatusCount, final Long dsId, final String dsName, final String dsVersion, final Long actionStatusCount,
final String rolloutName) { final String rolloutName) {
this.dsId = dsId; this.dsId = dsId;

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@@ -82,13 +81,13 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@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 final Set<SoftwareModule> modules = new HashSet<>(); private Set<SoftwareModule> modules;
@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 = {
@JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) })
private Set<DistributionSetTag> tags = new HashSet<>(); private Set<DistributionSetTag> tags;
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@@ -106,7 +105,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = {
CascadeType.REMOVE }) CascadeType.REMOVE })
@JoinColumn(name = "ds_id", insertable = false, updatable = false) @JoinColumn(name = "ds_id", insertable = false, updatable = false)
private final List<DistributionSetMetadata> metadata = new ArrayList<>(); private List<DistributionSetMetadata> metadata;
@ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class)
@JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds"))
@@ -120,7 +119,7 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
* Default constructor. * Default constructor.
*/ */
public JpaDistributionSet() { public JpaDistributionSet() {
super(); // Default constructor for JPA
} }
/** /**
@@ -152,7 +151,29 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Override @Override
public Set<DistributionSetTag> getTags() { public Set<DistributionSetTag> getTags() {
return tags; if (tags == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(tags);
}
@Override
public boolean addTag(final DistributionSetTag tag) {
if (tags == null) {
tags = new HashSet<>();
}
return tags.add(tag);
}
@Override
public boolean removeTag(final DistributionSetTag tag) {
if (tags == null) {
return false;
}
return tags.remove(tag);
} }
@Override @Override
@@ -162,11 +183,19 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Override @Override
public List<DistributionSetMetadata> getMetadata() { public List<DistributionSetMetadata> getMetadata() {
if (metadata == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(metadata); return Collections.unmodifiableList(metadata);
} }
public List<Action> getActions() { public List<Action> getActions() {
return actions; if (actions == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(actions);
} }
@Override @Override
@@ -186,19 +215,22 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return this; return this;
} }
public DistributionSet setTags(final Set<DistributionSetTag> tags) {
this.tags = tags;
return this;
}
@Override @Override
public List<Target> getAssignedTargets() { public List<Target> getAssignedTargets() {
return assignedToTargets; if (assignedToTargets == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(assignedToTargets);
} }
@Override @Override
public List<TargetInfo> getInstalledTargets() { public List<TargetInfo> getInstalledTargets() {
return installedAtTargets; if (installedAtTargets == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(installedAtTargets);
} }
@Override @Override
@@ -209,21 +241,20 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Override @Override
public Set<SoftwareModule> getModules() { public Set<SoftwareModule> getModules() {
if (modules == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(modules); return Collections.unmodifiableSet(modules);
} }
@Override @Override
public boolean addModule(final SoftwareModule softwareModule) { public boolean addModule(final SoftwareModule softwareModule) {
if (modules == null) {
// we cannot allow that modules are added without a type defined modules = new HashSet<>();
if (type == null) {
throw new DistributionSetTypeUndefinedException();
} }
// check if it is allowed to such a module to this DS type checkTypeCompatability(softwareModule);
if (!type.containsModuleType(softwareModule.getType())) {
throw new UnsupportedSoftwareModuleForThisDistributionSetException();
}
final Optional<SoftwareModule> found = modules.stream() final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); .filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
@@ -249,8 +280,24 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
return false; return false;
} }
private void checkTypeCompatability(final SoftwareModule softwareModule) {
// we cannot allow that modules are added without a type defined
if (type == null) {
throw new DistributionSetTypeUndefinedException();
}
// check if it is allowed to such a module to this DS type
if (!type.containsModuleType(softwareModule.getType())) {
throw new UnsupportedSoftwareModuleForThisDistributionSetException();
}
}
@Override @Override
public boolean removeModule(final SoftwareModule softwareModule) { public boolean removeModule(final SoftwareModule softwareModule) {
if (modules == null) {
return false;
}
final Optional<SoftwareModule> found = modules.stream() final Optional<SoftwareModule> found = modules.stream()
.filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); .filter(module -> module.getId().equals(softwareModule.getId())).findFirst();
@@ -266,6 +313,10 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen
@Override @Override
public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) {
if (modules == null) {
return null;
}
final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type)) final Optional<SoftwareModule> result = modules.stream().filter(module -> module.getType().equals(type))
.findFirst(); .findFirst();

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.persistence.Entity; import javax.persistence.Entity;
@@ -68,7 +69,11 @@ public class JpaDistributionSetTag extends AbstractJpaTag implements Distributio
@Override @Override
public List<DistributionSet> getAssignedToDistributionSet() { public List<DistributionSet> getAssignedToDistributionSet() {
return assignedToDistributionSet; if (assignedToDistributionSet == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(assignedToDistributionSet);
} }
@Override @Override

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -24,6 +25,7 @@ import javax.persistence.Table;
import javax.persistence.UniqueConstraint; import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.DistributionSetType;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
@@ -48,7 +50,7 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
@OneToMany(targetEntity = DistributionSetTypeElement.class, cascade = { @OneToMany(targetEntity = DistributionSetTypeElement.class, cascade = {
CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true) CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "distribution_set_type", insertable = false, updatable = false) @JoinColumn(name = "distribution_set_type", insertable = false, updatable = false)
private final Set<DistributionSetTypeElement> elements = new HashSet<>(); private Set<DistributionSetTypeElement> elements;
@Column(name = "type_key", nullable = false, length = 64) @Column(name = "type_key", nullable = false, length = 64)
@Size(max = 64) @Size(max = 64)
@@ -108,23 +110,52 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
@Override @Override
public Set<SoftwareModuleType> getMandatoryModuleTypes() { public Set<SoftwareModuleType> getMandatoryModuleTypes() {
if (elements == null) {
return Collections.emptySet();
}
return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType()) return elements.stream().filter(element -> element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@Override @Override
public Set<SoftwareModuleType> getOptionalModuleTypes() { public Set<SoftwareModuleType> getOptionalModuleTypes() {
if (elements == null) {
return Collections.emptySet();
}
return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType()) return elements.stream().filter(element -> !element.isMandatory()).map(element -> element.getSmType())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@Override @Override
public boolean areModuleEntriesIdentical(final DistributionSetType dsType) { public boolean areModuleEntriesIdentical(final DistributionSetType dsType) {
if (!(dsType instanceof JpaDistributionSetType) || isOneModuleListEmpty(dsType)) {
return false;
} else if (areBothModuleListsEmpty(dsType)) {
return true;
}
return new HashSet<DistributionSetTypeElement>(((JpaDistributionSetType) dsType).elements).equals(elements); return new HashSet<DistributionSetTypeElement>(((JpaDistributionSetType) dsType).elements).equals(elements);
} }
private boolean isOneModuleListEmpty(final DistributionSetType dsType) {
return (!CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements)
&& CollectionUtils.isEmpty(elements))
|| (CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements)
&& !CollectionUtils.isEmpty(elements));
}
private boolean areBothModuleListsEmpty(final DistributionSetType dsType) {
return CollectionUtils.isEmpty(((JpaDistributionSetType) dsType).elements) && CollectionUtils.isEmpty(elements);
}
@Override @Override
public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) { public DistributionSetType addOptionalModuleType(final SoftwareModuleType smType) {
if (elements == null) {
elements = new HashSet<>();
}
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, false)); elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, false));
return this; return this;
@@ -132,6 +163,10 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
@Override @Override
public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) { public DistributionSetType addMandatoryModuleType(final SoftwareModuleType smType) {
if (elements == null) {
elements = new HashSet<>();
}
elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, true)); elements.add(new DistributionSetTypeElement(this, (JpaSoftwareModuleType) smType, true));
return this; return this;
@@ -139,6 +174,10 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
@Override @Override
public DistributionSetType removeModuleType(final Long smTypeId) { public DistributionSetType removeModuleType(final Long smTypeId) {
if (elements == null) {
return this;
}
// we search by id (standard equals compares also revison) // we search by id (standard equals compares also revison)
final Optional<DistributionSetTypeElement> found = elements.stream() final Optional<DistributionSetTypeElement> found = elements.stream()
.filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst(); .filter(element -> element.getSmType().getId().equals(smTypeId)).findFirst();
@@ -177,7 +216,11 @@ public class JpaDistributionSetType extends AbstractJpaNamedEntity implements Di
} }
public Set<DistributionSetTypeElement> getElements() { public Set<DistributionSetTypeElement> getElements() {
return elements; if (elements == null) {
return Collections.emptySet();
}
return Collections.unmodifiableSet(elements);
} }
@Override @Override

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.persistence.Column; import javax.persistence.Column;
@@ -108,11 +109,11 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event
@Override @Override
public List<RolloutGroup> getRolloutGroups() { public List<RolloutGroup> getRolloutGroups() {
return rolloutGroups; if (rolloutGroups == null) {
} return Collections.emptyList();
}
public void setRolloutGroups(final List<RolloutGroup> rolloutGroups) { return Collections.unmodifiableList(rolloutGroups);
this.rolloutGroups = rolloutGroups;
} }
@Override @Override

View File

@@ -8,7 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.ArrayList; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.persistence.CascadeType; import javax.persistence.CascadeType;
@@ -58,7 +58,7 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class)
@JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false)
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>(); private List<RolloutTargetGroup> rolloutTargetGroup;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
private JpaRolloutGroup parent; private JpaRolloutGroup parent;
@@ -92,7 +92,7 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
private String errorActionExp; private String errorActionExp;
@Column(name = "total_targets") @Column(name = "total_targets")
private long totalTargets; private int totalTargets;
@Transient @Transient
private transient TotalTargetCountStatus totalTargetCountStatus; private transient TotalTargetCountStatus totalTargetCountStatus;
@@ -118,7 +118,11 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
} }
public List<RolloutTargetGroup> getRolloutTargetGroup() { public List<RolloutTargetGroup> getRolloutTargetGroup() {
return rolloutTargetGroup; if (rolloutTargetGroup == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(rolloutTargetGroup);
} }
@Override @Override
@@ -201,11 +205,11 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
} }
@Override @Override
public long getTotalTargets() { public int getTotalTargets() {
return totalTargets; return totalTargets;
} }
public void setTotalTargets(final long totalTargets) { public void setTotalTargets(final int totalTargets) {
this.totalTargets = totalTargets; this.totalTargets = totalTargets;
} }
@@ -223,7 +227,7 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr
@Override @Override
public TotalTargetCountStatus getTotalTargetCountStatus() { public TotalTargetCountStatus getTotalTargetCountStatus() {
if (totalTargetCountStatus == null) { if (totalTargetCountStatus == null) {
totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); totalTargetCountStatus = new TotalTargetCountStatus(new Long(totalTargets));
} }
return totalTargetCountStatus; return totalTargetCountStatus;
} }

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -40,6 +41,8 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata;
import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
import org.eclipse.persistence.annotations.CascadeOnDelete; import org.eclipse.persistence.annotations.CascadeOnDelete;
import com.google.common.collect.Lists;
/** /**
* Base Software Module that is supported by OS level provisioning mechanism on * Base Software Module that is supported by OS level provisioning mechanism on
* the edge controller, e.g. OS, JVM, AgentHub. * the edge controller, e.g. OS, JVM, AgentHub.
@@ -64,7 +67,7 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
private JpaSoftwareModuleType type; private JpaSoftwareModuleType type;
@ManyToMany(mappedBy = "modules", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY) @ManyToMany(mappedBy = "modules", targetEntity = JpaDistributionSet.class, fetch = FetchType.LAZY)
private final List<DistributionSet> assignedTo = new ArrayList<>(); private List<DistributionSet> assignedTo;
@Column(name = "deleted") @Column(name = "deleted")
private boolean deleted; private boolean deleted;
@@ -82,13 +85,13 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
@CascadeOnDelete @CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, targetEntity = JpaSoftwareModuleMetadata.class) @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, targetEntity = JpaSoftwareModuleMetadata.class)
@JoinColumn(name = "sw_id", insertable = false, updatable = false) @JoinColumn(name = "sw_id", insertable = false, updatable = false)
private final List<SoftwareModuleMetadata> metadata = new ArrayList<>(); private List<SoftwareModuleMetadata> metadata;
/** /**
* Default constructor. * Default constructor.
*/ */
public JpaSoftwareModule() { public JpaSoftwareModule() {
super(); // Default constructor for JPA
} }
/** /**
@@ -120,6 +123,8 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
public void addArtifact(final LocalArtifact artifact) { public void addArtifact(final LocalArtifact artifact) {
if (null == artifacts) { if (null == artifacts) {
artifacts = new ArrayList<>(4); artifacts = new ArrayList<>(4);
artifacts.add(artifact);
return;
} }
if (!artifacts.contains(artifact)) { if (!artifacts.contains(artifact)) {
@@ -134,7 +139,9 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
@Override @Override
public void addArtifact(final ExternalArtifact artifact) { public void addArtifact(final ExternalArtifact artifact) {
if (null == externalArtifacts) { if (null == externalArtifacts) {
externalArtifacts = new ArrayList<>(4); externalArtifacts = new LinkedList<>();
externalArtifacts.add(artifact);
return;
} }
if (!externalArtifacts.contains(artifact)) { if (!externalArtifacts.contains(artifact)) {
@@ -143,28 +150,18 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
} }
/**
* @param artifactId
* to look for
* @return found {@link Artifact}
*/
@Override @Override
public Optional<LocalArtifact> getLocalArtifact(final Long artifactId) { public Optional<LocalArtifact> getLocalArtifact(final Long artifactId) {
if (null == artifacts) { if (artifacts == null) {
return Optional.empty(); return Optional.empty();
} }
return artifacts.stream().filter(artifact -> artifact.getId().equals(artifactId)).findFirst(); return artifacts.stream().filter(artifact -> artifact.getId().equals(artifactId)).findFirst();
} }
/**
* @param fileName
* to look for
* @return found {@link Artifact}
*/
@Override @Override
public Optional<LocalArtifact> getLocalArtifactByFilename(final String fileName) { public Optional<LocalArtifact> getLocalArtifactByFilename(final String fileName) {
if (null == artifacts) { if (artifacts == null) {
return Optional.empty(); return Optional.empty();
} }
@@ -177,11 +174,18 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
*/ */
@Override @Override
public List<Artifact> getArtifacts() { public List<Artifact> getArtifacts() {
final List<Artifact> result = new ArrayList<>(); if (artifacts == null && externalArtifacts == null) {
result.addAll(artifacts); return Collections.emptyList();
} else if (artifacts == null) {
return Collections.unmodifiableList(externalArtifacts);
} else if (externalArtifacts == null) {
return Collections.unmodifiableList(artifacts);
}
final List<Artifact> result = Lists.newLinkedList(artifacts);
result.addAll(externalArtifacts); result.addAll(externalArtifacts);
return result; return Collections.unmodifiableList(result);
} }
/** /**
@@ -207,7 +211,7 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
*/ */
@Override @Override
public void removeArtifact(final LocalArtifact artifact) { public void removeArtifact(final LocalArtifact artifact) {
if (null != artifacts) { if (artifacts != null) {
artifacts.remove(artifact); artifacts.remove(artifact);
} }
} }
@@ -218,7 +222,7 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
*/ */
@Override @Override
public void removeArtifact(final ExternalArtifact artifact) { public void removeArtifact(final ExternalArtifact artifact) {
if (null != externalArtifacts) { if (externalArtifacts != null) {
externalArtifacts.remove(artifact); externalArtifacts.remove(artifact);
} }
} }
@@ -248,11 +252,12 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
this.type = (JpaSoftwareModuleType) type; this.type = (JpaSoftwareModuleType) type;
} }
/**
* @return immutable list of meta data elements.
*/
@Override @Override
public List<SoftwareModuleMetadata> getMetadata() { public List<SoftwareModuleMetadata> getMetadata() {
if (metadata == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(metadata); return Collections.unmodifiableList(metadata);
} }
@@ -262,12 +267,13 @@ public class JpaSoftwareModule extends AbstractJpaNamedVersionedEntity implement
+ ", revision=" + getOptLockRevision() + ", Id=" + getId() + ", type=" + getType().getName() + "]"; + ", revision=" + getOptLockRevision() + ", Id=" + getId() + ", type=" + getType().getName() + "]";
} }
/**
* @return the assignedTo
*/
@Override @Override
public List<DistributionSet> getAssignedTo() { public List<DistributionSet> getAssignedTo() {
return assignedTo; if (assignedTo == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(assignedTo);
} }
} }

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.ArrayList; import java.util.ArrayList;
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;
@@ -85,13 +86,13 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@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 = {
@JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) })
private Set<TargetTag> tags = new HashSet<>(); private Set<TargetTag> tags;
@CascadeOnDelete @CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = {
CascadeType.REMOVE }, targetEntity = JpaAction.class) CascadeType.REMOVE }, targetEntity = JpaAction.class)
@JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ"))
private final List<Action> actions = new ArrayList<>(); private List<Action> actions;
@ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class)
@JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds"))
@@ -114,7 +115,7 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@CascadeOnDelete @CascadeOnDelete
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST })
@JoinColumn(name = "target_Id", insertable = false, updatable = false) @JoinColumn(name = "target_Id", insertable = false, updatable = false)
private final List<RolloutTargetGroup> rolloutTargetGroup = new ArrayList<>(); private List<RolloutTargetGroup> rolloutTargetGroup;
/** /**
* Constructor. * Constructor.
@@ -141,12 +142,8 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
targetInfo = new JpaTargetInfo(this); targetInfo = new JpaTargetInfo(this);
} }
/**
* empty constructor for JPA.
*/
JpaTarget() { JpaTarget() {
controllerId = null; // empty constructor for JPA.
securityToken = null;
} }
@Override @Override
@@ -161,9 +158,39 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
@Override @Override
public Set<TargetTag> getTags() { public Set<TargetTag> getTags() {
if (tags == null) {
return Collections.emptySet();
}
return tags; return tags;
} }
public List<RolloutTargetGroup> getRolloutTargetGroup() {
if (rolloutTargetGroup == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(rolloutTargetGroup);
}
@Override
public boolean addTag(final TargetTag tag) {
if (tags == null) {
tags = new HashSet<>();
}
return tags.add(tag);
}
@Override
public boolean removeTag(final TargetTag tag) {
if (tags == null) {
return false;
}
return tags.remove(tag);
}
public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) {
this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet;
} }
@@ -172,13 +199,21 @@ public class JpaTarget extends AbstractJpaNamedEntity implements Persistable<Lon
this.controllerId = controllerId; this.controllerId = controllerId;
} }
public void setTags(final Set<TargetTag> tags) {
this.tags = tags;
}
@Override @Override
public List<Action> getActions() { public List<Action> getActions() {
return actions; if (actions == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(actions);
}
public boolean addAction(final Action action) {
if (actions == null) {
actions = new ArrayList<>(4);
}
return actions.add(action);
} }
@Override @Override

View File

@@ -220,7 +220,7 @@ public class JpaTargetInfo implements Persistable<Long>, TargetInfo, EventAwareE
return lastTargetQuery; return lastTargetQuery;
} }
public void setLastTargetQuery(final Long lastTargetQuery) { public void setLastTargetQuery(final long lastTargetQuery) {
this.lastTargetQuery = lastTargetQuery; this.lastTargetQuery = lastTargetQuery;
} }

View File

@@ -8,6 +8,7 @@
*/ */
package org.eclipse.hawkbit.repository.jpa.model; package org.eclipse.hawkbit.repository.jpa.model;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.persistence.Entity; import javax.persistence.Entity;
@@ -65,7 +66,11 @@ public class JpaTargetTag extends AbstractJpaTag implements TargetTag {
@Override @Override
public List<Target> getAssignedToTargets() { public List<Target> getAssignedToTargets() {
return assignedToTargets; if (assignedToTargets == null) {
return Collections.emptyList();
}
return Collections.unmodifiableList(assignedToTargets);
} }
@Override @Override

View File

@@ -29,8 +29,8 @@ public class ThresholdRolloutGroupSuccessCondition implements RolloutGroupCondit
@Override @Override
public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) { public boolean eval(final Rollout rollout, final RolloutGroup rolloutGroup, final String expression) {
final Long totalGroup = rolloutGroup.getTotalTargets(); final long totalGroup = rolloutGroup.getTotalTargets();
final Long finished = this.actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(), final long finished = this.actionRepository.countByRolloutIdAndRolloutGroupIdAndStatus(rollout.getId(),
rolloutGroup.getId(), Action.Status.FINISHED); rolloutGroup.getId(), Action.Status.FINISHED);
try { try {
final Integer threshold = Integer.valueOf(expression); final Integer threshold = Integer.valueOf(expression);

View File

@@ -106,7 +106,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
assertThat(findActionsWithStatusCountByTarget).as("wrong action size").hasSize(1); assertThat(findActionsWithStatusCountByTarget).as("wrong action size").hasSize(1);
assertThat(findActionsWithStatusCountByTarget.get(0).getActionStatusCount()).as("wrong action status size") assertThat(findActionsWithStatusCountByTarget.get(0).getActionStatusCount()).as("wrong action status size")
.isEqualTo(3L); .isEqualTo(3);
} }
@Test @Test
@@ -842,8 +842,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet ds = testdataFactory.createDistributionSet("a"); final DistributionSet ds = testdataFactory.createDistributionSet("a");
// assign ds to create an action // assign ds to create an action
final DistributionSetAssignmentResult assignDistributionSet = deploymentManagement.assignDistributionSet( final DistributionSetAssignmentResult assignDistributionSet = deploymentManagement.assignDistributionSet(
ds.getId(), ActionType.SOFT, org.eclipse.hawkbit.repository.model.RepositoryModelConstants.NO_FORCE_TIME, ds.getId(), ActionType.SOFT,
target.getControllerId()); org.eclipse.hawkbit.repository.model.RepositoryModelConstants.NO_FORCE_TIME, target.getControllerId());
final Action action = deploymentManagement.findActionWithDetails(assignDistributionSet.getActions().get(0)); final Action action = deploymentManagement.findActionWithDetails(assignDistributionSet.getActions().get(0));
// verify preparation // verify preparation
Action findAction = deploymentManagement.findAction(action.getId()); Action findAction = deploymentManagement.findAction(action.getId());
@@ -865,8 +865,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest {
final DistributionSet ds = testdataFactory.createDistributionSet("a"); final DistributionSet ds = testdataFactory.createDistributionSet("a");
// assign ds to create an action // assign ds to create an action
final DistributionSetAssignmentResult assignDistributionSet = deploymentManagement.assignDistributionSet( final DistributionSetAssignmentResult assignDistributionSet = deploymentManagement.assignDistributionSet(
ds.getId(), ActionType.FORCED, org.eclipse.hawkbit.repository.model.RepositoryModelConstants.NO_FORCE_TIME, ds.getId(), ActionType.FORCED,
target.getControllerId()); org.eclipse.hawkbit.repository.model.RepositoryModelConstants.NO_FORCE_TIME, target.getControllerId());
final Action action = deploymentManagement.findActionWithDetails(assignDistributionSet.getActions().get(0)); final Action action = deploymentManagement.findActionWithDetails(assignDistributionSet.getActions().get(0));
// verify perparation // verify perparation
Action findAction = deploymentManagement.findAction(action.getId()); Action findAction = deploymentManagement.findAction(action.getId());

View File

@@ -396,14 +396,14 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// create a DS // create a DS
final DistributionSet ds = testdataFactory.createDistributionSet("testDs"); final DistributionSet ds = testdataFactory.createDistributionSet("testDs");
// initial opt lock revision must be zero // initial opt lock revision must be zero
assertThat(ds.getOptLockRevision()).isEqualTo(1L); assertThat(ds.getOptLockRevision()).isEqualTo(1);
// create an DS meta data entry // create an DS meta data entry
final DistributionSetMetadata dsMetadata = distributionSetManagement final DistributionSetMetadata dsMetadata = distributionSetManagement
.createDistributionSetMetadata(new JpaDistributionSetMetadata(knownKey, ds, knownValue)); .createDistributionSetMetadata(new JpaDistributionSetMetadata(knownKey, ds, knownValue));
DistributionSet changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId()); DistributionSet changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId());
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2L); assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(2);
// modifying the meta data value // modifying the meta data value
dsMetadata.setValue(knownUpdateValue); dsMetadata.setValue(knownUpdateValue);
@@ -419,7 +419,7 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
// module so opt lock // module so opt lock
// revision must be three // revision must be three
changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId()); changedLockRevisionDS = distributionSetManagement.findDistributionSetById(ds.getId());
assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(3L); assertThat(changedLockRevisionDS.getOptLockRevision()).isEqualTo(3);
assertThat(changedLockRevisionDS.getLastModifiedAt()).isGreaterThan(0L); assertThat(changedLockRevisionDS.getLastModifiedAt()).isGreaterThan(0L);
// verify updated meta data contains the updated value // verify updated meta data contains the updated value

View File

@@ -848,7 +848,7 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
final SoftwareModule ah = softwareManagement final SoftwareModule ah = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, ""));
assertThat(ah.getOptLockRevision()).isEqualTo(1L); assertThat(ah.getOptLockRevision()).isEqualTo(1);
final SoftwareModuleMetadata swMetadata1 = new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1); final SoftwareModuleMetadata swMetadata1 = new JpaSoftwareModuleMetadata(knownKey1, ah, knownValue1);
@@ -858,7 +858,7 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
.createSoftwareModuleMetadata(Lists.newArrayList(swMetadata1, swMetadata2)); .createSoftwareModuleMetadata(Lists.newArrayList(swMetadata1, swMetadata2));
final SoftwareModule changedLockRevisionModule = softwareManagement.findSoftwareModuleById(ah.getId()); final SoftwareModule changedLockRevisionModule = softwareManagement.findSoftwareModuleById(ah.getId());
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2L); assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
assertThat(softwareModuleMetadata).hasSize(2); assertThat(softwareModuleMetadata).hasSize(2);
assertThat(softwareModuleMetadata.get(0)).isNotNull(); assertThat(softwareModuleMetadata.get(0)).isNotNull();
@@ -900,7 +900,7 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
final SoftwareModule ah = softwareManagement final SoftwareModule ah = softwareManagement
.createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, "")); .createSoftwareModule(new JpaSoftwareModule(appType, "agent-hub", "1.0.1", null, ""));
// initial opt lock revision must be 1 // initial opt lock revision must be 1
assertThat(ah.getOptLockRevision()).isEqualTo(1L); assertThat(ah.getOptLockRevision()).isEqualTo(1);
// create an software module meta data entry // create an software module meta data entry
final List<SoftwareModuleMetadata> softwareModuleMetadata = softwareManagement.createSoftwareModuleMetadata( final List<SoftwareModuleMetadata> softwareModuleMetadata = softwareManagement.createSoftwareModuleMetadata(
@@ -910,7 +910,7 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
// because we are modifying the // because we are modifying the
// base software module // base software module
SoftwareModule changedLockRevisionModule = softwareManagement.findSoftwareModuleById(ah.getId()); SoftwareModule changedLockRevisionModule = softwareManagement.findSoftwareModuleById(ah.getId());
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2L); assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(2);
// modifying the meta data value // modifying the meta data value
softwareModuleMetadata.get(0).setValue(knownUpdateValue); softwareModuleMetadata.get(0).setValue(knownUpdateValue);
@@ -925,7 +925,7 @@ public class SoftwareManagementTest extends AbstractJpaIntegrationTestWithMongoD
// module so opt lock // module so opt lock
// revision must be two // revision must be two
changedLockRevisionModule = softwareManagement.findSoftwareModuleById(ah.getId()); changedLockRevisionModule = softwareManagement.findSoftwareModuleById(ah.getId());
assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(3L); assertThat(changedLockRevisionModule.getOptLockRevision()).isEqualTo(3);
// verify updated meta data contains the updated value // verify updated meta data contains the updated value
assertThat(updated).isNotNull(); assertThat(updated).isNotNull();

View File

@@ -735,7 +735,8 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
final DistributionSet ds = testdataFactory.createDistributionSet("a"); final DistributionSet ds = testdataFactory.createDistributionSet("a");
targAssigned = deploymentManagement.assignDistributionSet(ds, targAssigned).getAssignedEntity(); targAssigned = Lists
.newLinkedList(deploymentManagement.assignDistributionSet(ds, targAssigned).getAssignedEntity());
targInstalled = deploymentManagement.assignDistributionSet(ds, targInstalled).getAssignedEntity(); targInstalled = deploymentManagement.assignDistributionSet(ds, targInstalled).getAssignedEntity();
targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed"); targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed");
@@ -863,7 +864,7 @@ public class TargetManagementSearchTest extends AbstractJpaIntegrationTest {
private List<Target> sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable<Target> targs, private List<Target> sendUpdateActionStatusToTargets(final DistributionSet dsA, final Iterable<Target> targs,
final Status status, final String... msgs) { final Status status, final String... msgs) {
final List<Target> result = new ArrayList<Target>(); final List<Target> result = new ArrayList<>();
for (final Target t : targs) { for (final Target t : targs) {
final List<Action> findByTarget = actionRepository.findByTarget((JpaTarget) t); final List<Action> findByTarget = actionRepository.findByTarget((JpaTarget) t);
for (final Action action : findByTarget) { for (final Action action : findByTarget) {

View File

@@ -541,28 +541,30 @@ public class TargetManagementTest extends AbstractJpaIntegrationTest {
@Test @Test
@Description("Tests the assigment of tags to the a single target.") @Description("Tests the assigment of tags to the a single target.")
public void targetTagAssignment() { public void targetTagAssignment() {
Target t1 = testdataFactory.generateTarget("id-1", "blablub"); final Target t1 = testdataFactory.generateTarget("id-1", "blablub");
final int noT2Tags = 4; final int noT2Tags = 4;
final int noT1Tags = 3; final int noT1Tags = 3;
final List<TargetTag> t1Tags = tagManagement final List<TargetTag> t1Tags = tagManagement
.createTargetTags(testdataFactory.generateTargetTags(noT1Tags, "tag1")); .createTargetTags(testdataFactory.generateTargetTags(noT1Tags, "tag1"));
t1.getTags().addAll(t1Tags);
t1 = targetManagement.createTarget(t1);
Target t2 = testdataFactory.generateTarget("id-2", "blablub"); t1Tags.forEach(tag -> ((JpaTarget) t1).addTag(tag));
targetManagement.createTarget(t1);
final Target t2 = testdataFactory.generateTarget("id-2", "blablub");
final List<TargetTag> t2Tags = tagManagement final List<TargetTag> t2Tags = tagManagement
.createTargetTags(testdataFactory.generateTargetTags(noT2Tags, "tag2")); .createTargetTags(testdataFactory.generateTargetTags(noT2Tags, "tag2"));
t2.getTags().addAll(t2Tags);
t2 = targetManagement.createTarget(t2);
t1 = targetManagement.findTargetByControllerID(t1.getControllerId()); t2Tags.forEach(tag -> ((JpaTarget) t2).addTag(tag));
assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags).containsAll(t1Tags); targetManagement.createTarget(t2);
assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags)
final Target t11 = targetManagement.findTargetByControllerID(t1.getControllerId());
assertThat(t11.getTags()).as("Tag size is wrong").hasSize(noT1Tags).containsAll(t1Tags);
assertThat(t11.getTags()).as("Tag size is wrong").hasSize(noT1Tags)
.doesNotContain(Iterables.toArray(t2Tags, TargetTag.class)); .doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
t2 = targetManagement.findTargetByControllerID(t2.getControllerId()); final Target t21 = targetManagement.findTargetByControllerID(t2.getControllerId());
assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags).containsAll(t2Tags); assertThat(t21.getTags()).as("Tag size is wrong").hasSize(noT2Tags).containsAll(t2Tags);
assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags) assertThat(t21.getTags()).as("Tag size is wrong").hasSize(noT2Tags)
.doesNotContain(Iterables.toArray(t1Tags, TargetTag.class)); .doesNotContain(Iterables.toArray(t1Tags, TargetTag.class));
} }

View File

@@ -18,7 +18,6 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaAction;
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.ActionType;
import org.eclipse.hawkbit.repository.model.Target;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
@@ -32,7 +31,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
@Stories("RSQL filter actions") @Stories("RSQL filter actions")
public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest { public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
private Target target; private JpaTarget target;
private JpaAction action; private JpaAction action;
@Before @Before
@@ -42,7 +41,7 @@ public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
targetManagement.createTarget(target); targetManagement.createTarget(target);
action = new JpaAction(); action = new JpaAction();
action.setActionType(ActionType.SOFT); action.setActionType(ActionType.SOFT);
target.getActions().add(action); target.addAction(action);
action.setTarget(target); action.setTarget(target);
actionRepository.save(action); actionRepository.save(action);
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
@@ -51,7 +50,7 @@ public class RSQLActionFieldsTest extends AbstractJpaIntegrationTest {
newAction.setActive(i % 2 == 0); newAction.setActive(i % 2 == 0);
newAction.setTarget(target); newAction.setTarget(target);
actionRepository.save(newAction); actionRepository.save(newAction);
target.getActions().add(newAction); target.addAction(newAction);
} }
} }

View File

@@ -9,8 +9,8 @@
package org.eclipse.hawkbit.ui.artifacts.details; package org.eclipse.hawkbit.ui.artifacts.details;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -46,6 +46,7 @@ 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.Strings;
import com.google.common.collect.Maps;
import com.vaadin.data.Container; import com.vaadin.data.Container;
import com.vaadin.server.FontAwesome; import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.shared.ui.label.ContentMode;
@@ -207,8 +208,7 @@ public class ArtifactDetailsLayout extends VerticalLayout {
} }
private Container createArtifactLazyQueryContainer() { private Container createArtifactLazyQueryContainer() {
final Map<String, Object> queryConfiguration = new HashMap<>(); return getArtifactLazyQueryContainer(Collections.emptyMap());
return getArtifactLazyQueryContainer(queryConfiguration);
} }
private LazyQueryContainer getArtifactLazyQueryContainer(final Map<String, Object> queryConfig) { private LazyQueryContainer getArtifactLazyQueryContainer(final Map<String, Object> queryConfig) {
@@ -429,9 +429,12 @@ public class ArtifactDetailsLayout extends VerticalLayout {
titleOfArtifactDetails.setContentMode(ContentMode.HTML); titleOfArtifactDetails.setContentMode(ContentMode.HTML);
} }
} }
final Map<String, Object> queryConfiguration = new HashMap<>(); final Map<String, Object> queryConfiguration;
if (baseSwModuleId != null) { if (baseSwModuleId != null) {
queryConfiguration = Maps.newHashMapWithExpectedSize(1);
queryConfiguration.put(SPUIDefinitions.BY_BASE_SOFTWARE_MODULE, baseSwModuleId); queryConfiguration.put(SPUIDefinitions.BY_BASE_SOFTWARE_MODULE, baseSwModuleId);
} else {
queryConfiguration = Collections.emptyMap();
} }
final LazyQueryContainer artifactContainer = getArtifactLazyQueryContainer(queryConfiguration); final LazyQueryContainer artifactContainer = getArtifactLazyQueryContainer(queryConfiguration);
artifactDetailsTable.setContainerDataSource(artifactContainer); artifactDetailsTable.setContainerDataSource(artifactContainer);

View File

@@ -9,13 +9,13 @@
package org.eclipse.hawkbit.ui.artifacts.event; package org.eclipse.hawkbit.ui.artifacts.event;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria; import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import com.google.common.collect.Maps;
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.Component; import com.vaadin.ui.Component;
@@ -54,7 +54,7 @@ public class UploadViewAcceptCriteria extends AbstractAcceptCriteria {
} }
private static Map<String, List<String>> createDropConfigurations() { private static Map<String, List<String>> createDropConfigurations() {
final Map<String, List<String>> config = new HashMap<>(); final Map<String, List<String>> config = Maps.newHashMapWithExpectedSize(1);
// Delete drop area droppable components // Delete drop area droppable components
config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID, Arrays.asList( config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID, Arrays.asList(
UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX)); UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX));
@@ -63,7 +63,7 @@ public class UploadViewAcceptCriteria extends AbstractAcceptCriteria {
} }
private static Map<String, Object> createDropHintConfigurations() { private static Map<String, Object> createDropHintConfigurations() {
final Map<String, Object> config = new HashMap<>(); final Map<String, Object> config = Maps.newHashMapWithExpectedSize(2);
config.put(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX, UploadArtifactUIEvent.SOFTWARE_TYPE_DRAG_START); config.put(UIComponentIdProvider.UPLOAD_TYPE_BUTTON_PREFIX, UploadArtifactUIEvent.SOFTWARE_TYPE_DRAG_START);
config.put(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UploadArtifactUIEvent.SOFTWARE_DRAG_START); config.put(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, UploadArtifactUIEvent.SOFTWARE_DRAG_START);
return config; return config;

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.ui.artifacts.footer; package org.eclipse.hawkbit.ui.artifacts.footer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -21,11 +20,12 @@ import org.eclipse.hawkbit.ui.artifacts.state.CustomFile;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout; import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab; import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab;
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 com.google.common.collect.Maps;
import com.vaadin.data.Container; import com.vaadin.data.Container;
import com.vaadin.data.Item; import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer; import com.vaadin.data.util.IndexedContainer;
@@ -64,7 +64,7 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
@Override @Override
protected Map<String, ConfirmationTab> getConfimrationTabs() { protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<>(); final Map<String, ConfirmationTab> tabs = Maps.newHashMapWithExpectedSize(2);
if (!artifactUploadState.getDeleteSofwareModules().isEmpty()) { if (!artifactUploadState.getDeleteSofwareModules().isEmpty()) {
tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab()); tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab());
} }

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.ui.artifacts.smtable; package org.eclipse.hawkbit.ui.artifacts.smtable;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -25,11 +24,11 @@ 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.smtable.SwMetadataPopupLayout; import org.eclipse.hawkbit.ui.distributions.smtable.SwMetadataPopupLayout;
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.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;
@@ -37,6 +36,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
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.Maps;
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;
@@ -97,7 +97,7 @@ public class SoftwareModuleTable extends AbstractNamedVersionTable<SoftwareModul
} }
private Map<String, Object> prepareQueryConfigFilters() { private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>(); final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(2);
artifactUploadState.getSoftwareModuleFilters().getSearchText() artifactUploadState.getSoftwareModuleFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));

View File

@@ -32,11 +32,11 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleTiny;
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.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.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -572,6 +572,9 @@ public class UploadConfirmationWindow implements Button.ClickListener {
} }
// Exception squid:S3655 - Optional access is checked in
// checkIfArtifactDetailsDispalyed subroutine
@SuppressWarnings("squid:S3655")
private void processArtifactUpload() { private void processArtifactUpload() {
final List<String> itemIds = (List<String>) uploadDetailsTable.getItemIds(); final List<String> itemIds = (List<String>) uploadDetailsTable.getItemIds();
if (preUploadValidation(itemIds)) { if (preUploadValidation(itemIds)) {
@@ -593,6 +596,7 @@ public class UploadConfirmationWindow implements Button.ClickListener {
} }
refreshArtifactDetailsLayout = checkIfArtifactDetailsDispalyed(bSoftwareModule.getId()); refreshArtifactDetailsLayout = checkIfArtifactDetailsDispalyed(bSoftwareModule.getId());
} }
if (refreshArtifactDetailsLayout) { if (refreshArtifactDetailsLayout) {
uploadLayout.refreshArtifactDetailsLayout(artifactUploadState.getSelectedBaseSoftwareModule().get()); uploadLayout.refreshArtifactDetailsLayout(artifactUploadState.getSelectedBaseSoftwareModule().get());
} }

View File

@@ -34,10 +34,10 @@ import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmall;
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.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.UINotification; import org.eclipse.hawkbit.ui.utils.UINotification;
import org.eclipse.hawkbit.util.SPInfo; import org.eclipse.hawkbit.util.SPInfo;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -254,6 +254,11 @@ public class UploadLayout extends VerticalLayout {
final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles();
// selected software module at the time of file drop is // selected software module at the time of file drop is
// considered for upload // considered for upload
if (!artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) {
return;
}
final SoftwareModule selectedSw = artifactUploadState.getSelectedBaseSoftwareModule().get(); final SoftwareModule selectedSw = artifactUploadState.getSelectedBaseSoftwareModule().get();
// reset the flag // reset the flag
hasDirectory = Boolean.FALSE; hasDirectory = Boolean.FALSE;

View File

@@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -28,11 +27,12 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleNoBorderWithIcon;
import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout; import org.eclipse.hawkbit.ui.layouts.AbstractCreateUpdateTagLayout;
import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout; import org.eclipse.hawkbit.ui.management.targettable.TargetAddUpdateWindowLayout;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
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 org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent; import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.vaadin.data.Container.ItemSetChangeEvent; import com.vaadin.data.Container.ItemSetChangeEvent;
import com.vaadin.data.Container.ItemSetChangeListener; import com.vaadin.data.Container.ItemSetChangeListener;
@@ -129,8 +129,8 @@ public class CommonDialogWindow extends Window {
this.helpLink = helpLink; this.helpLink = helpLink;
this.closeListener = closeListener; this.closeListener = closeListener;
this.cancelButtonClickListener = cancelButtonClickListener; this.cancelButtonClickListener = cancelButtonClickListener;
this.orginalValues = new HashMap<>();
this.allComponents = getAllComponents(layout); this.allComponents = getAllComponents(layout);
this.orginalValues = Maps.newHashMapWithExpectedSize(allComponents.size());
this.i18n = i18n; this.i18n = i18n;
init(); init();
} }

View File

@@ -30,8 +30,8 @@ import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.spring.events.EventBus; import org.vaadin.spring.events.EventBus;
import com.google.gwt.thirdparty.guava.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.gwt.thirdparty.guava.common.collect.Sets; 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.Transferable; import com.vaadin.event.Transferable;

View File

@@ -93,7 +93,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
private VerticalLayout tagsLayout; private VerticalLayout tagsLayout;
private final Map<String, StringBuilder> assignedSWModule = new HashMap<>(); private Map<String, StringBuilder> assignedSWModule;
/** /**
* softwareLayout Initialize the component. * softwareLayout Initialize the component.
@@ -144,6 +144,10 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
} }
if (null != softwareModuleIdNameList) { if (null != softwareModuleIdNameList) {
if (assignedSWModule == null) {
assignedSWModule = new HashMap<>();
}
for (final SoftwareModuleIdName swIdName : softwareModuleIdNameList) { for (final SoftwareModuleIdName swIdName : softwareModuleIdNameList) {
final SoftwareModule softwareModule = softwareManagement.findSoftwareModuleById(swIdName.getId()); final SoftwareModule softwareModule = softwareManagement.findSoftwareModuleById(swIdName.getId());
if (assignedSWModule.containsKey(softwareModule.getType().getName())) { if (assignedSWModule.containsKey(softwareModule.getType().getName())) {
@@ -169,9 +173,11 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
} }
private Button assignSoftModuleButton(final String softwareModuleName) { private Button assignSoftModuleButton(final String softwareModuleName) {
if (getPermissionChecker().hasUpdateDistributionPermission() && distributionSetManagement if (getPermissionChecker().hasUpdateDistributionPermission()
.findDistributionSetById(manageDistUIState.getLastSelectedDistribution().get().getId()) && manageDistUIState.getLastSelectedDistribution().isPresent()
.getAssignedTargets().isEmpty()) { && distributionSetManagement
.findDistributionSetById(manageDistUIState.getLastSelectedDistribution().get().getId())
.getAssignedTargets().isEmpty()) {
final Button reassignSoftModule = SPUIComponentProvider.getButton(softwareModuleName, "", "", "", true, final Button reassignSoftModule = SPUIComponentProvider.getButton(softwareModuleName, "", "", "", true,
FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class);
reassignSoftModule.setEnabled(false); reassignSoftModule.setEnabled(false);
@@ -186,6 +192,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void updateSoftwareModule(final SoftwareModule module) { private void updateSoftwareModule(final SoftwareModule module) {
if (assignedSWModule == null) {
assignedSWModule = new HashMap<>();
}
softwareModuleTable.getContainerDataSource().getItemIds(); softwareModuleTable.getContainerDataSource().getItemIds();
if (assignedSWModule.containsKey(module.getType().getName())) { if (assignedSWModule.containsKey(module.getType().getName())) {
@@ -363,7 +372,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
if ((saveActionWindowEvent == SaveActionWindowEvent.SAVED_ASSIGNMENTS if ((saveActionWindowEvent == SaveActionWindowEvent.SAVED_ASSIGNMENTS
|| saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS) || saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS)
&& getSelectedBaseEntity() != null) { && getSelectedBaseEntity() != null) {
assignedSWModule.clear(); if (assignedSWModule != null) {
assignedSWModule.clear();
}
setSelectedBaseEntity( setSelectedBaseEntity(
distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId())); distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()));
UI.getCurrent().access(() -> populateModule()); UI.getCurrent().access(() -> populateModule());
@@ -375,7 +386,9 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet
if (saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ASSIGNMENT if (saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ASSIGNMENT
|| saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS || saveActionWindowEvent == SaveActionWindowEvent.DISCARD_ALL_ASSIGNMENTS
|| saveActionWindowEvent == SaveActionWindowEvent.DELETE_ALL_SOFWARE) { || saveActionWindowEvent == SaveActionWindowEvent.DELETE_ALL_SOFWARE) {
assignedSWModule.clear(); if (assignedSWModule != null) {
assignedSWModule.clear();
}
showUnsavedAssignment(); showUnsavedAssignment();
} }
} }

View File

@@ -57,6 +57,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
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.Maps;
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;
@@ -167,7 +168,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
} }
private Map<String, Object> prepareQueryConfigFilters() { private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>(); final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(2);
manageDistUIState.getManageDistFilters().getSearchText() manageDistUIState.getManageDistFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));
@@ -530,7 +531,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable<Distribution
return manageMetadataBtn; return manageMetadataBtn;
} }
private void showMetadataDetails(final Long itemId) { private void showMetadataDetails(final Long itemId) {
final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(itemId); final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(itemId);
UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null));
} }

View File

@@ -9,7 +9,6 @@
package org.eclipse.hawkbit.ui.distributions.event; package org.eclipse.hawkbit.ui.distributions.event;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -17,6 +16,7 @@ import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import com.google.common.collect.Maps;
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.Component; import com.vaadin.ui.Component;
@@ -66,7 +66,7 @@ public class DistributionsViewAcceptCriteria extends AbstractAcceptCriteria {
} }
private static Map<String, List<String>> createDropConfigurations() { private static Map<String, List<String>> createDropConfigurations() {
final Map<String, List<String>> config = new HashMap<>(); final Map<String, List<String>> config = Maps.newHashMapWithExpectedSize(2);
// Delete drop area droppable components // Delete drop area droppable components
config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID, config.put(UIComponentIdProvider.DELETE_BUTTON_WRAPPER_ID,
@@ -82,7 +82,7 @@ public class DistributionsViewAcceptCriteria extends AbstractAcceptCriteria {
} }
private static Map<String, Object> createDropHintConfigurations() { private static Map<String, Object> createDropHintConfigurations() {
final Map<String, Object> config = new HashMap<>(); final Map<String, Object> config = Maps.newHashMapWithExpectedSize(4);
config.put(SPUIDefinitions.DISTRIBUTION_TYPE_ID_PREFIXS, DragEvent.DISTRIBUTION_TYPE_DRAG); config.put(SPUIDefinitions.DISTRIBUTION_TYPE_ID_PREFIXS, DragEvent.DISTRIBUTION_TYPE_DRAG);
config.put(UIComponentIdProvider.DIST_TABLE_ID, DragEvent.DISTRIBUTION_DRAG); config.put(UIComponentIdProvider.DIST_TABLE_ID, DragEvent.DISTRIBUTION_DRAG);
config.put(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, DragEvent.SOFTWAREMODULE_DRAG); config.put(UIComponentIdProvider.UPLOAD_SOFTWARE_MODULE_TABLE, DragEvent.SOFTWAREMODULE_DRAG);

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.ui.distributions.footer; package org.eclipse.hawkbit.ui.distributions.footer;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -37,6 +36,7 @@ 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.Maps;
import com.vaadin.data.Container; import com.vaadin.data.Container;
import com.vaadin.data.Item; import com.vaadin.data.Item;
import com.vaadin.data.util.IndexedContainer; import com.vaadin.data.util.IndexedContainer;
@@ -90,7 +90,7 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
@Override @Override
protected Map<String, ConfirmationTab> getConfimrationTabs() { protected Map<String, ConfirmationTab> getConfimrationTabs() {
final Map<String, ConfirmationTab> tabs = new HashMap<>(); final Map<String, ConfirmationTab> tabs = Maps.newHashMapWithExpectedSize(5);
/* Create tab for SW Modules delete */ /* Create tab for SW Modules delete */
if (!manageDistUIState.getDeleteSofwareModulesList().isEmpty()) { if (!manageDistUIState.getDeleteSofwareModulesList().isEmpty()) {
tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab()); tabs.put(i18n.get("caption.delete.swmodule.accordion.tab"), createSMDeleteConfirmationTab());
@@ -112,7 +112,6 @@ public class DistributionsConfirmationWindowLayout extends AbstractConfirmationW
} }
/* Create tab for Assign Software Module */ /* Create tab for Assign Software Module */
if (!manageDistUIState.getAssignedList().isEmpty()) { if (!manageDistUIState.getAssignedList().isEmpty()) {
tabs.put(i18n.get("caption.assign.dist.accordion.tab"), createAssignSWModuleConfirmationTab()); tabs.put(i18n.get("caption.assign.dist.accordion.tab"), createAssignSWModuleConfirmationTab());
} }

View File

@@ -8,7 +8,6 @@
*/ */
package org.eclipse.hawkbit.ui.distributions.smtable; package org.eclipse.hawkbit.ui.distributions.smtable;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -40,6 +39,7 @@ import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
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.Maps;
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;
@@ -143,7 +143,7 @@ public class SwModuleTable extends AbstractNamedVersionTable<SoftwareModule, Lon
} }
private Map<String, Object> prepareQueryConfigFilters() { private Map<String, Object> prepareQueryConfigFilters() {
final Map<String, Object> queryConfig = new HashMap<>(); final Map<String, Object> queryConfig = Maps.newHashMapWithExpectedSize(3);
manageDistUIState.getSoftwareModuleFilters().getSearchText() manageDistUIState.getSoftwareModuleFilters().getSearchText()
.ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value)); .ifPresent(value -> queryConfig.put(SPUIDefinitions.FILTER_BY_TEXT, value));

View File

@@ -13,8 +13,7 @@ import static org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.Sof
import static org.eclipse.hawkbit.ui.utils.UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID; import static org.eclipse.hawkbit.ui.utils.UIComponentIdProvider.SW_MODULE_TYPE_TABLE_ID;
import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_NAME; import static org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions.VAR_NAME;
import java.util.HashMap; import java.util.Collections;
import java.util.Map;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent;
import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery; import org.eclipse.hawkbit.ui.common.SoftwareModuleTypeBeanQuery;
@@ -59,10 +58,9 @@ public class DistSMTypeFilterButtons extends AbstractFilterButtons {
@Override @Override
protected LazyQueryContainer createButtonsLazyQueryContainer() { protected LazyQueryContainer createButtonsLazyQueryContainer() {
final Map<String, Object> queryConfig = new HashMap<>();
final BeanQueryFactory<SoftwareModuleTypeBeanQuery> typeQF = new BeanQueryFactory<>( final BeanQueryFactory<SoftwareModuleTypeBeanQuery> typeQF = new BeanQueryFactory<>(
SoftwareModuleTypeBeanQuery.class); SoftwareModuleTypeBeanQuery.class);
typeQF.setQueryConfiguration(queryConfig); typeQF.setQueryConfiguration(Collections.emptyMap());
return new LazyQueryContainer(new LazyQueryDefinition(true, 20, VAR_NAME), typeQF); return new LazyQueryContainer(new LazyQueryDefinition(true, 20, VAR_NAME), typeQF);
} }

View File

@@ -52,7 +52,7 @@ public class ManageDistUIState implements ManagmentEntityState<DistributionSetId
private Set<Long> selectedSoftwareModules = emptySet(); private Set<Long> selectedSoftwareModules = emptySet();
private Set<String> selectedDeleteDistSetTypes = new HashSet<>(); private final Set<String> selectedDeleteDistSetTypes = new HashSet<>();
private Set<String> selectedDeleteSWModuleTypes = new HashSet<>(); private Set<String> selectedDeleteSWModuleTypes = new HashSet<>();
@@ -201,10 +201,6 @@ public class ManageDistUIState implements ManagmentEntityState<DistributionSetId
return selectedDeleteDistSetTypes; return selectedDeleteDistSetTypes;
} }
public void setSelectedDeleteDistSetTypes(final Set<String> selectedDeleteDistSetTypes) {
this.selectedDeleteDistSetTypes = selectedDeleteDistSetTypes;
}
public Set<String> getSelectedDeleteSWModuleTypes() { public Set<String> getSelectedDeleteSWModuleTypes() {
return selectedDeleteSWModuleTypes; return selectedDeleteSWModuleTypes;
} }

View File

@@ -1,27 +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.filter;
/**
* A filter expression interface definition to implement the UI filter
* mechanism. The filter expression can evaluate if e.g. Targets should
* currently be added to the target list or if the current enabled filtered will
* filter the target and not show the newly created target.
*
*/
@FunctionalInterface
public interface FilterExpression {
/**
* @return {@code true} if the expression evaluate that it should be
* filtered and not shown on the UI, otherwise {@code false}
*/
boolean doFilter();
}

View File

@@ -1,77 +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.filter;
import java.util.Arrays;
import java.util.List;
/**
* {@link Filters} which provides the functionality to combine
* {@link FilterExpression}s.
*
*
*
* @see FilterExpression
*
*/
public final class Filters {
/**
* private.
*/
private Filters() {
}
/**
* Combines the given filter to an or-expression and evaluate them.
*
* @param expressions
* the expressions to combine with an or-filter
* @return an or-combined filter expression
*/
public static FilterExpression or(final List<FilterExpression> expressions) {
return or(expressions.toArray(new FilterExpression[expressions.size()]));
}
/**
* Combines the given filter to an or-expression and evaluate them.
*
* @param expressions
* the expressions to combine with an or-filter
* @return an or-combined filter expression
*/
public static FilterExpression or(final FilterExpression... expressions) {
return new OrFilterExpression(expressions);
}
private static final class OrFilterExpression implements FilterExpression {
private final FilterExpression[] expresssions;
private OrFilterExpression(final FilterExpression[] expresssions) {
this.expresssions = Arrays.copyOf(expresssions, expresssions.length);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
for (final FilterExpression filterExpression : expresssions) {
if (filterExpression.doFilter()) {
return true;
}
}
return false;
}
}
}

View File

@@ -1,48 +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.filter.target;
import java.util.Optional;
import org.eclipse.hawkbit.repository.model.TargetFilterQuery;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
/**
* Checks if custom target filter is applied.
*
*/
public class CustomTargetFilter implements FilterExpression {
private final Optional<TargetFilterQuery> targetFilterQuery;
/**
* Initialize.
*
* @param targetFilterQuery
* custom target filter applied
*/
public CustomTargetFilter(final Optional<TargetFilterQuery> targetFilterQuery) {
this.targetFilterQuery = targetFilterQuery;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.ui.filter.FilterExpression#doFilter()
*/
@Override
public boolean doFilter() {
if (!targetFilterQuery.isPresent()) {
return false;
}
return true;
}
}

View File

@@ -1,67 +0,0 @@
/**
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
package org.eclipse.hawkbit.ui.filter.target;
import java.net.URI;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
/**
*
*
*
*/
public class TargetSearchTextFilter implements FilterExpression {
private final Target target;
private final String searchTextUpper;
/**
* @param target
* the target to check against the search text
* @param searchText
* the search text check against the given target
*/
public TargetSearchTextFilter(final Target target, final String searchText) {
this.target = target;
this.searchTextUpper = searchText.toUpperCase();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
return !(descriptionIgnoreCase() || nameIgnoreCase() || controllerIdIgnoreCase() || ipAddressIgnoreCase());
}
private boolean descriptionIgnoreCase() {
if (target.getDescription() == null) {
return false;
}
return target.getDescription().toUpperCase().contains(searchTextUpper);
}
private boolean nameIgnoreCase() {
if (target.getName() == null) {
return false;
}
return target.getName().toUpperCase().contains(searchTextUpper);
}
private boolean controllerIdIgnoreCase() {
return target.getControllerId().toUpperCase().contains(searchTextUpper);
}
private boolean ipAddressIgnoreCase() {
final URI targetAddress = target.getTargetInfo().getAddress();
if (targetAddress == null || targetAddress.getHost() == null) {
return false;
}
return targetAddress.getHost().toUpperCase().contains(searchTextUpper);
}
}

View File

@@ -1,42 +0,0 @@
/**
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
package org.eclipse.hawkbit.ui.filter.target;
import java.util.List;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
/**
*
*
*
*/
public class TargetStatusFilter implements FilterExpression {
private final List<TargetUpdateStatus> targetUpdateStatus;
/**
* @param target
* the target to check the update status against
* @param updateStatus
* the target update status to check against the given target
*/
public TargetStatusFilter(final List<TargetUpdateStatus> updateStatus) {
this.targetUpdateStatus = updateStatus;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
if (targetUpdateStatus.isEmpty()) {
return false;
}
return true;
}
}

View File

@@ -1,54 +0,0 @@
/**
* Copyright (c) 2011-2015 Bosch Software Innovations GmbH, Germany. All rights reserved.
*/
package org.eclipse.hawkbit.ui.filter.target;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.ui.filter.FilterExpression;
import org.springframework.util.CollectionUtils;
/**
*
*
*
*/
public class TargetTagFilter implements FilterExpression {
private final Target target;
private final Collection<String> tags;
private final boolean noTag;
/**
* @param target
* the target to check the filter against
* @param tags
* the tags to check the target against it
* @param noTag
* {@code true} indicates that targets which have no tags should
* not be filtered, otherwise {@code false}
*/
public TargetTagFilter(final Target target, final Collection<String> tags, final boolean noTag) {
this.target = target;
this.tags = tags;
this.noTag = noTag;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.hawkbit.server.ui.filter.FilterExpression#evaluate()
*/
@Override
public boolean doFilter() {
final List<String> targetTags = target.getTags().stream().map(targetTag -> targetTag.getName())
.collect(Collectors.toList());
if (targetTags.isEmpty() || (noTag && targetTags.isEmpty())) {
return false;
}
return !CollectionUtils.containsAny(targetTags, tags);
}
}

View File

@@ -26,9 +26,9 @@ import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent;
import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState;
import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
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.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.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -136,7 +136,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
private LayoutClickListener nameLayoutClickListner; private LayoutClickListener nameLayoutClickListner;
private boolean validationFailed = false; private boolean validationFailed;
/** /**
* Initialize the Campaign Status History Header. * Initialize the Campaign Status History Header.
@@ -509,6 +509,10 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button
} }
private void updateCustomFilter() { private void updateCustomFilter() {
if (!filterManagementUIState.getTfQuery().isPresent()) {
return;
}
final TargetFilterQuery targetFilterQuery = filterManagementUIState.getTfQuery().get(); final TargetFilterQuery targetFilterQuery = filterManagementUIState.getTfQuery().get();
targetFilterQuery.setName(nameTextField.getValue()); targetFilterQuery.setName(nameTextField.getValue());
targetFilterQuery.setQuery(queryTextField.getValue()); targetFilterQuery.setQuery(queryTextField.getValue());

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