Merge branch 'master' into feature_boot_13_sec_41
Conflicts: hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/FreePortFileWriter.java Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
0
3rd-dependencies/listDeps.sh
Normal file → Executable file
0
3rd-dependencies/listDeps.sh
Normal file → Executable file
@@ -24,6 +24,12 @@ The simulator has user authentication enabled in **cloud profile**. Default cred
|
|||||||
|
|
||||||
This can be configured/disabled by spring boot properties
|
This can be configured/disabled by spring boot properties
|
||||||
|
|
||||||
|
## hawkBit APIs
|
||||||
|
|
||||||
|
The simulator supports `DDI` as well as the `DMF` integration APIs.
|
||||||
|
In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to an amqp message broker.
|
||||||
|
Configuration property `hawkbit.device.simulator.amqp.enabled=true`
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Graphical User Interface
|
### Graphical User Interface
|
||||||
|
|||||||
@@ -17,6 +17,4 @@ applications:
|
|||||||
services:
|
services:
|
||||||
- dmf-rabbit
|
- dmf-rabbit
|
||||||
env:
|
env:
|
||||||
SPRING_PROFILES_ACTIVE: cloud,amqp
|
SPRING_PROFILES_ACTIVE: cloud
|
||||||
CF_STAGING_TIMEOUT: 15
|
|
||||||
CF_STARTUP_TIMEOUT: 15
|
|
||||||
|
|||||||
@@ -118,6 +118,16 @@ public class DeviceSimulatorUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final class DeviceSimulatorUpdateThread implements Runnable {
|
private static final class DeviceSimulatorUpdateThread implements Runnable {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final String BUT_GOT_LOG_MESSAGE = " but got: ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final String DOWNLOAD_LOG_MESSAGE = "Download ";
|
||||||
|
|
||||||
private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6;
|
private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6;
|
||||||
|
|
||||||
private static final Random rndSleep = new SecureRandom();
|
private static final Random rndSleep = new SecureRandom();
|
||||||
@@ -187,7 +197,7 @@ public class DeviceSimulatorUpdater {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isErrorResponse(final UpdateStatus status) {
|
private static boolean isErrorResponse(final UpdateStatus status) {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -212,60 +222,73 @@ public class DeviceSimulatorUpdater {
|
|||||||
LOGGER.debug("Downloading {} with token {}, expected sha1 hash {} and size {}", url,
|
LOGGER.debug("Downloading {} with token {}, expected sha1 hash {} and size {}", url,
|
||||||
hideTokenDetails(targetToken), sha1Hash, size);
|
hideTokenDetails(targetToken), sha1Hash, size);
|
||||||
|
|
||||||
long overallread = 0;
|
|
||||||
try {
|
try {
|
||||||
final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts();
|
return readAndCheckDownloadUrl(url, targetToken, sha1Hash, size);
|
||||||
final HttpGet request = new HttpGet(url);
|
|
||||||
request.addHeader(HttpHeaders.AUTHORIZATION, "TargetToken " + targetToken);
|
|
||||||
|
|
||||||
final String sha1HashResult;
|
|
||||||
try (final CloseableHttpResponse response = httpclient.execute(request)) {
|
|
||||||
|
|
||||||
if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
|
|
||||||
final String message = wrongStatusCode(url, response);
|
|
||||||
return new UpdateStatus(ResponseStatus.ERROR, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.getEntity().getContentLength() != size) {
|
|
||||||
final String message = wrongContentLength(url, size, response);
|
|
||||||
return new UpdateStatus(ResponseStatus.ERROR, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exception squid:S2070 - not used for hashing sensitive
|
|
||||||
// data
|
|
||||||
@SuppressWarnings("squid:S2070")
|
|
||||||
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
|
||||||
|
|
||||||
try (final BufferedOutputStream bdos = new BufferedOutputStream(
|
|
||||||
new DigestOutputStream(ByteStreams.nullOutputStream(), md))) {
|
|
||||||
try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) {
|
|
||||||
overallread = ByteStreams.copy(bis, bdos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overallread != size) {
|
|
||||||
final String message = incompleteRead(url, size, overallread);
|
|
||||||
return new UpdateStatus(ResponseStatus.ERROR, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) {
|
|
||||||
final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult);
|
|
||||||
return new UpdateStatus(ResponseStatus.ERROR, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
|
} catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
|
||||||
LOGGER.error("Failed to download" + url, e);
|
LOGGER.error("Failed to download" + url, e);
|
||||||
return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage());
|
return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UpdateStatus readAndCheckDownloadUrl(final String url, final String targetToken,
|
||||||
|
final String sha1Hash, final long size)
|
||||||
|
throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
|
||||||
|
long overallread;
|
||||||
|
final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts();
|
||||||
|
final HttpGet request = new HttpGet(url);
|
||||||
|
request.addHeader(HttpHeaders.AUTHORIZATION, "TargetToken " + targetToken);
|
||||||
|
|
||||||
|
final String sha1HashResult;
|
||||||
|
try (final CloseableHttpResponse response = httpclient.execute(request)) {
|
||||||
|
|
||||||
|
if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
|
||||||
|
final String message = wrongStatusCode(url, response);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.getEntity().getContentLength() != size) {
|
||||||
|
final String message = wrongContentLength(url, size, response);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exception squid:S2070 - not used for hashing sensitive
|
||||||
|
// data
|
||||||
|
@SuppressWarnings("squid:S2070")
|
||||||
|
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||||
|
|
||||||
|
overallread = getOverallRead(response, md);
|
||||||
|
|
||||||
|
if (overallread != size) {
|
||||||
|
final String message = incompleteRead(url, size, overallread);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) {
|
||||||
|
final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult);
|
||||||
|
return new UpdateStatus(ResponseStatus.ERROR, message);
|
||||||
|
}
|
||||||
|
|
||||||
final String message = "Downloaded " + url + " (" + overallread + " bytes)";
|
final String message = "Downloaded " + url + " (" + overallread + " bytes)";
|
||||||
LOGGER.debug(message);
|
LOGGER.debug(message);
|
||||||
return new UpdateStatus(ResponseStatus.SUCCESSFUL, message);
|
return new UpdateStatus(ResponseStatus.SUCCESSFUL, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static long getOverallRead(final CloseableHttpResponse response, final MessageDigest md)
|
||||||
|
throws IOException {
|
||||||
|
long overallread;
|
||||||
|
try (final BufferedOutputStream bdos = new BufferedOutputStream(
|
||||||
|
new DigestOutputStream(ByteStreams.nullOutputStream(), md))) {
|
||||||
|
try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) {
|
||||||
|
overallread = ByteStreams.copy(bis, bdos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return overallread;
|
||||||
|
}
|
||||||
|
|
||||||
private static String hideTokenDetails(final String targetToken) {
|
private static String hideTokenDetails(final String targetToken) {
|
||||||
if (targetToken == null) {
|
if (targetToken == null) {
|
||||||
return "<NULL!>";
|
return "<NULL!>";
|
||||||
@@ -285,29 +308,30 @@ public class DeviceSimulatorUpdater {
|
|||||||
|
|
||||||
private static String wrongHash(final String url, final String sha1Hash, final long overallread,
|
private static String wrongHash(final String url, final String sha1Hash, final long overallread,
|
||||||
final String sha1HashResult) {
|
final String sha1HashResult) {
|
||||||
final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash
|
final String message = DOWNLOAD_LOG_MESSAGE + url + " failed with SHA1 hash missmatch (Expected: "
|
||||||
+ " but got: " + sha1HashResult + ") (" + overallread + " bytes)";
|
+ sha1Hash + BUT_GOT_LOG_MESSAGE + sha1HashResult + ") (" + overallread + " bytes)";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String incompleteRead(final String url, final long size, final long overallread) {
|
private static String incompleteRead(final String url, final long size, final long overallread) {
|
||||||
final String message = "Download " + url + " is incomplete (Expected: " + size + " but got: " + overallread
|
final String message = DOWNLOAD_LOG_MESSAGE + url + " is incomplete (Expected: " + size
|
||||||
+ ")";
|
+ BUT_GOT_LOG_MESSAGE + overallread + ")";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String wrongContentLength(final String url, final long size,
|
private static String wrongContentLength(final String url, final long size,
|
||||||
final CloseableHttpResponse response) {
|
final CloseableHttpResponse response) {
|
||||||
final String message = "Download " + url + " has wrong content length (Expected: " + size + " but got: "
|
final String message = DOWNLOAD_LOG_MESSAGE + url + " has wrong content length (Expected: " + size
|
||||||
+ response.getEntity().getContentLength() + ")";
|
+ BUT_GOT_LOG_MESSAGE + response.getEntity().getContentLength() + ")";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String wrongStatusCode(final String url, final CloseableHttpResponse response) {
|
private static String wrongStatusCode(final String url, final CloseableHttpResponse response) {
|
||||||
final String message = "Download " + url + " failed (" + response.getStatusLine().getStatusCode() + ")";
|
final String message = DOWNLOAD_LOG_MESSAGE + url + " failed (" + response.getStatusLine().getStatusCode()
|
||||||
|
+ ")";
|
||||||
LOGGER.error(message);
|
LOGGER.error(message);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
@@ -339,4 +363,5 @@ public class DeviceSimulatorUpdater {
|
|||||||
*/
|
*/
|
||||||
void updateFinished(AbstractSimulatedDevice device, final Long actionId);
|
void updateFinished(AbstractSimulatedDevice device, final Long actionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public class SimulatedDeviceFactory {
|
|||||||
final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) {
|
final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) {
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case DMF_AMQP:
|
case DMF_AMQP:
|
||||||
|
spSenderService.createOrUpdateThing(tenant, id);
|
||||||
return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec);
|
return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec);
|
||||||
case DDI_HTTP:
|
case DDI_HTTP:
|
||||||
final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger())
|
final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger())
|
||||||
|
|||||||
@@ -8,11 +8,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator;
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
||||||
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
import org.eclipse.hawkbit.simulator.amqp.AmqpProperties;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -21,22 +23,19 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* REST endpoint for controlling the device simulator.
|
* REST endpoint for controlling the device simulator.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
public class SimulationController {
|
public class SimulationController {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SpSenderService spSenderService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceSimulatorRepository repository;
|
private DeviceSimulatorRepository repository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SimulatedDeviceFactory deviceFactory;
|
private SimulatedDeviceFactory deviceFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AmqpProperties amqpProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The start resource to start a device creation.
|
* The start resource to start a device creation.
|
||||||
*
|
*
|
||||||
@@ -82,6 +81,12 @@ public class SimulationController {
|
|||||||
return ResponseEntity.badRequest().body("query param api only allows value of 'dmf' or 'ddi'");
|
return ResponseEntity.badRequest().body("query param api only allows value of 'dmf' or 'ddi'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (protocol == Protocol.DMF_AMQP && isDmfDisabled()) {
|
||||||
|
return ResponseEntity.badRequest()
|
||||||
|
.body("The AMQP interface has been disabled, to use DMF protocol you need to enable the AMQP interface via '"
|
||||||
|
+ CONFIGURATION_PREFIX + ".enabled=true'");
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++) {
|
for (int i = 0; i < amount; i++) {
|
||||||
final String deviceId = name + i;
|
final String deviceId = name + i;
|
||||||
repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint),
|
repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint),
|
||||||
@@ -90,4 +95,8 @@ public class SimulationController {
|
|||||||
|
|
||||||
return ResponseEntity.ok("Updated " + amount + " DMF connected targets!");
|
return ResponseEntity.ok("Updated " + amount + " DMF connected targets!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isDmfDisabled() {
|
||||||
|
return !amqpProperties.isEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.simulator;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
import org.eclipse.hawkbit.simulator.amqp.AmqpProperties;
|
||||||
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;
|
||||||
@@ -32,24 +32,27 @@ public class SimulatorStartup implements ApplicationListener<ContextRefreshedEve
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SimulationProperties simulationProperties;
|
private SimulationProperties simulationProperties;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SpSenderService spSenderService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DeviceSimulatorRepository repository;
|
private DeviceSimulatorRepository repository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SimulatedDeviceFactory deviceFactory;
|
private SimulatedDeviceFactory deviceFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AmqpProperties amqpProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(final ContextRefreshedEvent event) {
|
public void onApplicationEvent(final ContextRefreshedEvent event) {
|
||||||
simulationProperties.getAutostarts().forEach(autostart -> {
|
simulationProperties.getAutostarts().forEach(autostart -> {
|
||||||
for (int i = 0; i < autostart.getAmount(); i++) {
|
for (int i = 0; i < autostart.getAmount(); i++) {
|
||||||
final String deviceId = autostart.getName() + i;
|
final String deviceId = autostart.getName() + i;
|
||||||
try {
|
try {
|
||||||
repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(),
|
if (amqpProperties.isEnabled()) {
|
||||||
autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()),
|
repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(),
|
||||||
autostart.getGatewayToken()));
|
autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()),
|
||||||
|
autostart.getGatewayToken()));
|
||||||
|
}
|
||||||
|
|
||||||
} catch (final MalformedURLException e) {
|
} catch (final MalformedURLException e) {
|
||||||
LOGGER.error("Creation of simulated device at startup failed.", e);
|
LOGGER.error("Creation of simulated device at startup failed.", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator.amqp;
|
package org.eclipse.hawkbit.simulator.amqp;
|
||||||
|
|
||||||
|
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.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -27,6 +29,7 @@ import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
|||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
|
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -39,6 +42,7 @@ import org.springframework.retry.support.RetryTemplate;
|
|||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(AmqpProperties.class)
|
@EnableConfigurationProperties(AmqpProperties.class)
|
||||||
|
@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled")
|
||||||
public class AmqpConfiguration {
|
public class AmqpConfiguration {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class);
|
||||||
|
|||||||
@@ -19,6 +19,17 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties("hawkbit.device.simulator.amqp")
|
@ConfigurationProperties("hawkbit.device.simulator.amqp")
|
||||||
public class AmqpProperties {
|
public class AmqpProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The prefix for this configuration.
|
||||||
|
*/
|
||||||
|
public static final String CONFIGURATION_PREFIX = "hawkbit.device.simulator.amqp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the AMQP interface is enabled for the device simulator.
|
||||||
|
*/
|
||||||
|
private boolean enabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue for receiving DMF messages from update server.
|
* Queue for receiving DMF messages from update server.
|
||||||
*/
|
*/
|
||||||
@@ -84,4 +95,12 @@ public class AmqpProperties {
|
|||||||
public void setDeadLetterTtl(final int deadLetterTtl) {
|
public void setDeadLetterTtl(final int deadLetterTtl) {
|
||||||
this.deadLetterTtl = deadLetterTtl;
|
this.deadLetterTtl = deadLetterTtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(final boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator.amqp;
|
package org.eclipse.hawkbit.simulator.amqp;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -58,7 +59,7 @@ public abstract class SenderService extends MessageService {
|
|||||||
}
|
}
|
||||||
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
|
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
|
||||||
final String correlationId = UUID.randomUUID().toString();
|
final String correlationId = UUID.randomUUID().toString();
|
||||||
message.getMessageProperties().setCorrelationId(correlationId.getBytes());
|
message.getMessageProperties().setCorrelationId(correlationId.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, address, correlationId);
|
LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, address, correlationId);
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator.amqp;
|
package org.eclipse.hawkbit.simulator.amqp;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
||||||
@@ -22,6 +24,7 @@ import org.springframework.amqp.core.MessageProperties;
|
|||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.messaging.handler.annotation.Header;
|
import org.springframework.messaging.handler.annotation.Header;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -32,6 +35,7 @@ import com.google.common.collect.Lists;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled")
|
||||||
public class SpReceiverService extends ReceiverService {
|
public class SpReceiverService extends ReceiverService {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class);
|
||||||
|
|
||||||
@@ -67,8 +71,6 @@ public class SpReceiverService extends ReceiverService {
|
|||||||
* the incoming message
|
* the incoming message
|
||||||
* @param type
|
* @param type
|
||||||
* the action type
|
* the action type
|
||||||
* @param contentType
|
|
||||||
* the content type in message header
|
|
||||||
* @param thingId
|
* @param thingId
|
||||||
* the thing id in message header
|
* the thing id in message header
|
||||||
*/
|
*/
|
||||||
@@ -82,14 +84,11 @@ public class SpReceiverService extends ReceiverService {
|
|||||||
private void delegateMessage(final Message message, final String type, final String thingId) {
|
private void delegateMessage(final Message message, final String type, final String thingId) {
|
||||||
final MessageType messageType = MessageType.valueOf(type);
|
final MessageType messageType = MessageType.valueOf(type);
|
||||||
|
|
||||||
switch (messageType) {
|
if (MessageType.EVENT.equals(messageType)) {
|
||||||
case EVENT:
|
|
||||||
handleEventMessage(message, thingId);
|
handleEventMessage(message, thingId);
|
||||||
break;
|
return;
|
||||||
default:
|
|
||||||
LOGGER.info("No valid message type property.");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
LOGGER.info("No valid message type property.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleEventMessage(final Message message, final String thingId) {
|
private void handleEventMessage(final Message message, final String thingId) {
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ import com.vaadin.ui.Window;
|
|||||||
* Popup dialog window for setting the values of generating the simulated
|
* Popup dialog window for setting the values of generating the simulated
|
||||||
* devices, e.g. the amount.
|
* devices, e.g. the amount.
|
||||||
*
|
*
|
||||||
* @author Michael Hirsch
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
// Vaadin Inheritance
|
||||||
|
@SuppressWarnings("squid:MaximumInheritanceDepth")
|
||||||
public class GenerateDialog extends Window {
|
public class GenerateDialog extends Window {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -49,8 +50,9 @@ public class GenerateDialog extends Window {
|
|||||||
private final TextField pollDelayTextField;
|
private final TextField pollDelayTextField;
|
||||||
private final TextField pollUrlTextField;
|
private final TextField pollUrlTextField;
|
||||||
private final TextField gatewayTokenTextField;
|
private final TextField gatewayTokenTextField;
|
||||||
private final OptionGroup protocolGroup;
|
private OptionGroup protocolGroup;
|
||||||
private final Button buttonOk;
|
private Button buttonOk;
|
||||||
|
private final boolean dmfEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new pop window for setting the configuration of simulating
|
* Creates a new pop window for setting the configuration of simulating
|
||||||
@@ -59,9 +61,12 @@ public class GenerateDialog extends Window {
|
|||||||
* @param callback
|
* @param callback
|
||||||
* the callback which is called when the dialog has been
|
* the callback which is called when the dialog has been
|
||||||
* successfully confirmed.
|
* successfully confirmed.
|
||||||
|
* @param dmfEnabled
|
||||||
|
* indicates if the AMQP/DMF interface is enabled by
|
||||||
|
* configuration and if the option DMF should be enabled or not
|
||||||
*/
|
*/
|
||||||
public GenerateDialog(final GenerateDialogCallback callback) {
|
public GenerateDialog(final GenerateDialogCallback callback, final boolean dmfEnabled) {
|
||||||
|
this.dmfEnabled = dmfEnabled;
|
||||||
formLayout.setSpacing(true);
|
formLayout.setSpacing(true);
|
||||||
formLayout.setMargin(true);
|
formLayout.setMargin(true);
|
||||||
|
|
||||||
@@ -87,8 +92,8 @@ public class GenerateDialog extends Window {
|
|||||||
gatewayTokenTextField.setColumns(50);
|
gatewayTokenTextField.setColumns(50);
|
||||||
gatewayTokenTextField.setVisible(false);
|
gatewayTokenTextField.setVisible(false);
|
||||||
|
|
||||||
protocolGroup = createProtocolGroup();
|
createProtocolGroup();
|
||||||
buttonOk = createOkButton(callback);
|
createOkButton(callback);
|
||||||
|
|
||||||
namePrefixTextField.addValueChangeListener(event -> checkValid());
|
namePrefixTextField.addValueChangeListener(event -> checkValid());
|
||||||
amountTextField.addValueChangeListener(event -> checkValid());
|
amountTextField.addValueChangeListener(event -> checkValid());
|
||||||
@@ -181,26 +186,29 @@ public class GenerateDialog extends Window {
|
|||||||
final URL basePollURL, final String gatewayToken, final Protocol protocol);
|
final URL basePollURL, final String gatewayToken, final Protocol protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
private OptionGroup createProtocolGroup() {
|
private void createProtocolGroup() {
|
||||||
|
|
||||||
final OptionGroup protocolGroup = new OptionGroup("Simulated Device Protocol");
|
this.protocolGroup = new OptionGroup("Simulated Device Protocol");
|
||||||
protocolGroup.addItem(Protocol.DMF_AMQP);
|
protocolGroup.addItem(Protocol.DMF_AMQP);
|
||||||
protocolGroup.addItem(Protocol.DDI_HTTP);
|
protocolGroup.addItem(Protocol.DDI_HTTP);
|
||||||
|
protocolGroup.select(Protocol.DMF_AMQP);
|
||||||
protocolGroup.setItemCaption(Protocol.DMF_AMQP, "Device Management Federation API (AMQP push)");
|
protocolGroup.setItemCaption(Protocol.DMF_AMQP, "Device Management Federation API (AMQP push)");
|
||||||
protocolGroup.setItemCaption(Protocol.DDI_HTTP, "Direct Device Interface (HTTP poll)");
|
protocolGroup.setItemCaption(Protocol.DDI_HTTP, "Direct Device Interface (HTTP poll)");
|
||||||
protocolGroup.setNullSelectionAllowed(false);
|
protocolGroup.setNullSelectionAllowed(false);
|
||||||
protocolGroup.select(Protocol.DMF_AMQP);
|
|
||||||
protocolGroup.addValueChangeListener(event -> {
|
protocolGroup.addValueChangeListener(event -> {
|
||||||
final boolean directDeviceOptionSelected = event.getProperty().getValue().equals(Protocol.DDI_HTTP);
|
final boolean directDeviceOptionSelected = event.getProperty().getValue().equals(Protocol.DDI_HTTP);
|
||||||
pollUrlTextField.setVisible(directDeviceOptionSelected);
|
pollUrlTextField.setVisible(directDeviceOptionSelected);
|
||||||
gatewayTokenTextField.setVisible(directDeviceOptionSelected);
|
gatewayTokenTextField.setVisible(directDeviceOptionSelected);
|
||||||
});
|
});
|
||||||
return protocolGroup;
|
protocolGroup.setItemEnabled(Protocol.DMF_AMQP, dmfEnabled);
|
||||||
|
if (!dmfEnabled) {
|
||||||
|
protocolGroup.select(Protocol.DDI_HTTP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Button createOkButton(final GenerateDialogCallback callback) {
|
private void createOkButton(final GenerateDialogCallback callback) {
|
||||||
|
|
||||||
final Button buttonOk = new Button("generate");
|
this.buttonOk = new Button("generate");
|
||||||
buttonOk.setImmediate(true);
|
buttonOk.setImmediate(true);
|
||||||
buttonOk.setIcon(FontAwesome.GEARS);
|
buttonOk.setIcon(FontAwesome.GEARS);
|
||||||
buttonOk.addClickListener(event -> {
|
buttonOk.addClickListener(event -> {
|
||||||
@@ -210,14 +218,11 @@ public class GenerateDialog extends Window {
|
|||||||
Integer.valueOf(pollDelayTextField.getValue().replace(".", "")),
|
Integer.valueOf(pollDelayTextField.getValue().replace(".", "")),
|
||||||
new URL(pollUrlTextField.getValue()), gatewayTokenTextField.getValue(),
|
new URL(pollUrlTextField.getValue()), gatewayTokenTextField.getValue(),
|
||||||
(Protocol) protocolGroup.getValue());
|
(Protocol) protocolGroup.getValue());
|
||||||
} catch (final NumberFormatException e) {
|
} catch (final NumberFormatException | MalformedURLException e) {
|
||||||
LOGGER.info(e.getMessage(), e);
|
|
||||||
} catch (final MalformedURLException e) {
|
|
||||||
LOGGER.info(e.getMessage(), e);
|
LOGGER.info(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
GenerateDialog.this.close();
|
GenerateDialog.this.close();
|
||||||
});
|
});
|
||||||
return buttonOk;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextField createRequiredTextfield(final String caption, final String value, final Resource icon,
|
private TextField createRequiredTextfield(final String caption, final String value, final Resource icon,
|
||||||
@@ -226,7 +231,7 @@ public class GenerateDialog extends Window {
|
|||||||
return addTextFieldValues(textField, icon, validator);
|
return addTextFieldValues(textField, icon, validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextField createRequiredTextfield(final String caption, final Property dataSource, final Resource icon,
|
private TextField createRequiredTextfield(final String caption, final Property<?> dataSource, final Resource icon,
|
||||||
final Validator validator) {
|
final Validator validator) {
|
||||||
final TextField textField = new TextField(caption, dataSource);
|
final TextField textField = new TextField(caption, dataSource);
|
||||||
return addTextFieldValues(textField, icon, validator);
|
return addTextFieldValues(textField, icon, validator);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Status;
|
|||||||
import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository;
|
import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository;
|
||||||
import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory;
|
import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory;
|
||||||
import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus;
|
import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus;
|
||||||
|
import org.eclipse.hawkbit.simulator.amqp.AmqpProperties;
|
||||||
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
||||||
import org.eclipse.hawkbit.simulator.event.InitUpdate;
|
import org.eclipse.hawkbit.simulator.event.InitUpdate;
|
||||||
import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate;
|
import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate;
|
||||||
@@ -57,6 +58,11 @@ import com.vaadin.ui.renderers.ProgressBarRenderer;
|
|||||||
@SuppressWarnings("squid:MaximumInheritanceDepth")
|
@SuppressWarnings("squid:MaximumInheritanceDepth")
|
||||||
public class SimulatorView extends VerticalLayout implements View {
|
public class SimulatorView extends VerticalLayout implements View {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final String HTML_SPAN = ";</span>";
|
||||||
|
|
||||||
private static final String NEXT_POLL_COUNTER_SEC_COL = "nextPollCounterSec";
|
private static final String NEXT_POLL_COUNTER_SEC_COL = "nextPollCounterSec";
|
||||||
|
|
||||||
private static final String RESPONSE_STATUS_COL = "updateStatus";
|
private static final String RESPONSE_STATUS_COL = "updateStatus";
|
||||||
@@ -85,6 +91,9 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private transient EventBus eventbus;
|
private transient EventBus eventbus;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private transient AmqpProperties amqpProperties;
|
||||||
|
|
||||||
private final Label caption = new Label("DMF/DDI Simulated Devices");
|
private final Label caption = new Label("DMF/DDI Simulated Devices");
|
||||||
private final HorizontalLayout toolbar = new HorizontalLayout();
|
private final HorizontalLayout toolbar = new HorizontalLayout();
|
||||||
private final Grid grid = new Grid();
|
private final Grid grid = new Grid();
|
||||||
@@ -261,94 +270,94 @@ public class SimulatorView extends VerticalLayout implements View {
|
|||||||
final String deviceId = namePrefix + index;
|
final String deviceId = namePrefix + index;
|
||||||
beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId,
|
beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId,
|
||||||
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
|
tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken)));
|
||||||
spSenderService.createOrUpdateThing(tenant, deviceId);
|
|
||||||
}
|
}
|
||||||
}));
|
}, amqpProperties.isEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Converter<String, Protocol> createProtocolConverter() {
|
private ProtocolConverter createProtocolConverter() {
|
||||||
|
return new ProtocolConverter();
|
||||||
return new Converter<String, Protocol>() {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Protocol convertToModel(final String value, final Class<? extends Protocol> targetType,
|
|
||||||
final Locale locale) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String convertToPresentation(final Protocol value, final Class<? extends String> targetType,
|
|
||||||
final Locale locale) {
|
|
||||||
switch (value) {
|
|
||||||
case DDI_HTTP:
|
|
||||||
return "DDI API (http)";
|
|
||||||
case DMF_AMQP:
|
|
||||||
return "DMF API (amqp)";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<Protocol> getModelType() {
|
|
||||||
return Protocol.class;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<String> getPresentationType() {
|
|
||||||
return String.class;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Converter<String, Status> createStatusConverter() {
|
private StatusConverter createStatusConverter() {
|
||||||
return new Converter<String, Status>() {
|
return new StatusConverter();
|
||||||
private static final long serialVersionUID = 1L;
|
}
|
||||||
|
|
||||||
@Override
|
public static final class ProtocolConverter implements Converter<String, Protocol> {
|
||||||
public Status convertToModel(final String value, final Class<? extends Status> targetType,
|
private static final long serialVersionUID = 1L;
|
||||||
final Locale locale) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String convertToPresentation(final Status value, final Class<? extends String> targetType,
|
public Protocol convertToModel(final String value, final Class<? extends Protocol> targetType,
|
||||||
final Locale locale) {
|
final Locale locale) {
|
||||||
switch (value) {
|
return null;
|
||||||
case UNKNWON:
|
}
|
||||||
return "<span class=\"v-icon grayicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
|
||||||
+ ";\"color\":\"gray\";\">&#x"
|
|
||||||
+ Integer.toHexString(FontAwesome.QUESTION_CIRCLE.getCodepoint()) + ";</span>";
|
|
||||||
case PEDNING:
|
|
||||||
return "<span class=\"v-icon yellowicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
|
||||||
+ ";\"color\":\"yellow\";\">&#x" + Integer.toHexString(FontAwesome.REFRESH.getCodepoint())
|
|
||||||
+ ";</span>";
|
|
||||||
case FINISH:
|
|
||||||
return "<span class=\"v-icon greenicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
|
||||||
+ ";\"color\":\"green\";\">&#x"
|
|
||||||
+ Integer.toHexString(FontAwesome.CHECK_CIRCLE.getCodepoint()) + ";</span>";
|
|
||||||
case ERROR:
|
|
||||||
return "<span class=\"v-icon redicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
|
||||||
+ ";\"color\":\"red\";\">&#x"
|
|
||||||
+ Integer.toHexString(FontAwesome.EXCLAMATION_CIRCLE.getCodepoint()) + ";</span>";
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("unknown value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<Status> getModelType() {
|
public String convertToPresentation(final Protocol value, final Class<? extends String> targetType,
|
||||||
return Status.class;
|
final Locale locale) {
|
||||||
|
switch (value) {
|
||||||
|
case DDI_HTTP:
|
||||||
|
return "DDI API (http)";
|
||||||
|
case DMF_AMQP:
|
||||||
|
return "DMF API (amqp)";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<String> getPresentationType() {
|
public Class<Protocol> getModelType() {
|
||||||
return String.class;
|
return Protocol.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<String> getPresentationType() {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class StatusConverter implements Converter<String, Status> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Status convertToModel(final String value, final Class<? extends Status> targetType,
|
||||||
|
final Locale locale) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToPresentation(final Status value, final Class<? extends String> targetType,
|
||||||
|
final Locale locale) {
|
||||||
|
switch (value) {
|
||||||
|
case UNKNWON:
|
||||||
|
return "<span class=\"v-icon grayicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
||||||
|
+ ";\"color\":\"gray\";\">&#x" + Integer.toHexString(FontAwesome.QUESTION_CIRCLE.getCodepoint())
|
||||||
|
+ HTML_SPAN;
|
||||||
|
case PEDNING:
|
||||||
|
return "<span class=\"v-icon yellowicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
||||||
|
+ ";\"color\":\"yellow\";\">&#x" + Integer.toHexString(FontAwesome.REFRESH.getCodepoint())
|
||||||
|
+ HTML_SPAN;
|
||||||
|
case FINISH:
|
||||||
|
return "<span class=\"v-icon greenicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
||||||
|
+ ";\"color\":\"green\";\">&#x" + Integer.toHexString(FontAwesome.CHECK_CIRCLE.getCodepoint())
|
||||||
|
+ HTML_SPAN;
|
||||||
|
case ERROR:
|
||||||
|
return "<span class=\"v-icon redicon\" style=\"font-family: " + FontAwesome.FONT_FAMILY
|
||||||
|
+ ";\"color\":\"red\";\">&#x"
|
||||||
|
+ Integer.toHexString(FontAwesome.EXCLAMATION_CIRCLE.getCodepoint()) + HTML_SPAN;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("unknown value");
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<Status> getModelType() {
|
||||||
|
return Status.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<String> getPresentationType() {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
## Configuration for DMF communication
|
## Configuration for DMF communication
|
||||||
|
hawkbit.device.simulator.amqp.enabled=true
|
||||||
hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp=simulator_receiver
|
hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp=simulator_receiver
|
||||||
hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter
|
hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter
|
||||||
hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter
|
hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter
|
||||||
|
|||||||
@@ -10,8 +10,12 @@ package org.eclipse.hawkbit.autoconfigure.amqp;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.amqp.AmqpConfiguration;
|
import org.eclipse.hawkbit.amqp.AmqpConfiguration;
|
||||||
import org.eclipse.hawkbit.amqp.annotation.EnableAmqp;
|
import org.eclipse.hawkbit.amqp.annotation.EnableAmqp;
|
||||||
|
import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The amqp autoconfiguration.
|
* The amqp autoconfiguration.
|
||||||
@@ -24,4 +28,15 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@EnableAmqp
|
@EnableAmqp
|
||||||
public class AmqpAutoConfiguration {
|
public class AmqpAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create default error handler bean.
|
||||||
|
*
|
||||||
|
* @return the default error handler bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public ErrorHandler errorHandler() {
|
||||||
|
return new ConditionalRejectingErrorHandler();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import com.google.common.eventbus.AsyncEventBus;
|
|||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Auto configuration for the event bus.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
* Auto config fot the exception handler.
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
|
|||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
|
||||||
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
|
import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
@@ -112,6 +113,8 @@ public class SecurityManagedConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
|
// Exception squid:S00112 - Is aspectJ proxy
|
||||||
|
@SuppressWarnings({ "squid:S00112" })
|
||||||
public UserAuthenticationFilter userAuthenticationFilter() throws Exception {
|
public UserAuthenticationFilter userAuthenticationFilter() throws Exception {
|
||||||
return new UserAuthenticationFilterBasicAuth(configuration.getAuthenticationManager());
|
return new UserAuthenticationFilterBasicAuth(configuration.getAuthenticationManager());
|
||||||
}
|
}
|
||||||
@@ -281,6 +284,9 @@ public class SecurityManagedConfiguration {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SecurityProperties springSecurityProperties;
|
private SecurityProperties springSecurityProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(final HttpSecurity http) throws Exception {
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
@@ -309,14 +315,14 @@ public class SecurityManagedConfiguration {
|
|||||||
userAuthenticationFilter.destroy();
|
userAuthenticationFilter.destroy();
|
||||||
}
|
}
|
||||||
}, RequestHeaderAuthenticationFilter.class)
|
}, RequestHeaderAuthenticationFilter.class)
|
||||||
.addFilterAfter(
|
.addFilterAfter(new AuthenticationSuccessTenantMetadataCreationFilter(systemManagement,
|
||||||
new AuthenticationSuccessTenantMetadataCreationFilter(tenantAware, systemManagement),
|
systemSecurityContext), SessionManagementFilter.class)
|
||||||
SessionManagementFilter.class)
|
|
||||||
.authorizeRequests().anyRequest().authenticated()
|
.authorizeRequests().anyRequest().authenticated()
|
||||||
.antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**")
|
.antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**")
|
||||||
.hasAnyAuthority(SpPermission.SYSTEM_ADMIN);
|
.hasAnyAuthority(SpPermission.SYSTEM_ADMIN);
|
||||||
|
|
||||||
httpSec.httpBasic().and().exceptionHandling().authenticationEntryPoint(basicAuthEntryPoint);
|
httpSec.httpBasic().and().exceptionHandling().authenticationEntryPoint(basicAuthEntryPoint);
|
||||||
|
httpSec.anonymous().disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,12 +471,15 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemManagement systemManagement;
|
private SystemManagement systemManagement;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticationSuccess(final Authentication authentication) throws Exception {
|
public void onAuthenticationSuccess(final Authentication authentication) throws Exception {
|
||||||
|
|
||||||
if (authentication.getClass().equals(TenantUserPasswordAuthenticationToken.class)) {
|
if (authentication.getClass().equals(TenantUserPasswordAuthenticationToken.class)) {
|
||||||
systemManagement
|
systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(),
|
||||||
.getTenantMetadata(((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString());
|
((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString());
|
||||||
} else if (authentication.getClass().equals(UsernamePasswordAuthenticationToken.class)) {
|
} else if (authentication.getClass().equals(UsernamePasswordAuthenticationToken.class)) {
|
||||||
// TODO: vaadin4spring-ext-security does not give us the
|
// TODO: vaadin4spring-ext-security does not give us the
|
||||||
// fullyAuthenticatedToken
|
// fullyAuthenticatedToken
|
||||||
@@ -479,7 +488,8 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends
|
|||||||
// LoginView. This needs to be changed with the update of
|
// LoginView. This needs to be changed with the update of
|
||||||
// vaadin4spring 0.0.7 because it
|
// vaadin4spring 0.0.7 because it
|
||||||
// has been fixed.
|
// has been fixed.
|
||||||
systemManagement.getTenantMetadata("DEFAULT");
|
final String defaultTenant = "DEFAULT";
|
||||||
|
systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(), defaultTenant);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onAuthenticationSuccess(authentication);
|
super.onAuthenticationSuccess(authentication);
|
||||||
@@ -491,13 +501,13 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends
|
|||||||
*/
|
*/
|
||||||
class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
||||||
|
|
||||||
private final TenantAware tenantAware;
|
|
||||||
private final SystemManagement systemManagement;
|
private final SystemManagement systemManagement;
|
||||||
|
private final SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
AuthenticationSuccessTenantMetadataCreationFilter(final TenantAware tenantAware,
|
AuthenticationSuccessTenantMetadataCreationFilter(final SystemManagement systemManagement,
|
||||||
final SystemManagement systemManagement) {
|
final SystemSecurityContext systemSecurityContext) {
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
this.systemManagement = systemManagement;
|
this.systemManagement = systemManagement;
|
||||||
|
this.systemSecurityContext = systemSecurityContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -508,14 +518,16 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter {
|
|||||||
@Override
|
@Override
|
||||||
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
|
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
lazyCreateTenantMetadata();
|
||||||
final String currentTenant = tenantAware.getCurrentTenant();
|
|
||||||
if (currentTenant != null) {
|
|
||||||
// lazy initialize tenant meta data after successful authentication
|
|
||||||
systemManagement.getTenantMetadata(currentTenant);
|
|
||||||
}
|
|
||||||
|
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lazyCreateTenantMetadata() {
|
||||||
|
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
if (authentication != null && authentication.isAuthenticated()) {
|
||||||
|
systemSecurityContext.runAsSystem(() -> systemManagement.getTenantMetadata());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ public class RedisConfiguration {
|
|||||||
return new TenantAwareCacheManager(directCacheManager(), tenantAware);
|
return new TenantAwareCacheManager(directCacheManager(), tenantAware);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return bean for the direct cache manager.
|
||||||
|
*/
|
||||||
@Bean(name = "directCacheManager")
|
@Bean(name = "directCacheManager")
|
||||||
public CacheManager directCacheManager() {
|
public CacheManager directCacheManager() {
|
||||||
return new RedisCacheManager(redisTemplate());
|
return new RedisCacheManager(redisTemplate());
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import com.google.common.eventbus.EventBus;
|
|||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* The distributor for events.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@EventSubscriber
|
@EventSubscriber
|
||||||
@@ -100,11 +100,11 @@ public class EventDistributor {
|
|||||||
return topics;
|
return topics;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logDistributingEvent(final Event event, final String channel) {
|
private static void logDistributingEvent(final Event event, final String channel) {
|
||||||
LOGGER.trace("distributing event {} from node {} to topic {}", event, NODE_ID, channel);
|
LOGGER.trace("distributing event {} from node {} to topic {}", event, NODE_ID, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logNotDistributingEvent(final Event event, final String channel) {
|
private static void logNotDistributingEvent(final Event event, final String channel) {
|
||||||
LOGGER.debug("no redis template configured, event {} will not be distributed to channel {} from node {}", event,
|
LOGGER.debug("no redis template configured, event {} will not be distributed to channel {} from node {}", event,
|
||||||
channel, NODE_ID);
|
channel, NODE_ID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
*/
|
*/
|
||||||
@ConfigurationProperties("hawkbit.artifact.url")
|
@ConfigurationProperties("hawkbit.artifact.url")
|
||||||
public class ArtifactUrlHandlerProperties {
|
public class ArtifactUrlHandlerProperties {
|
||||||
private static final String DEFAULT_IP_LOCALHOST = "127.0.0.1";
|
|
||||||
private static final String DEFAULT_PORT = "8080";
|
|
||||||
private static final String LOCALHOST = "localhost";
|
|
||||||
|
|
||||||
private final Http http = new Http();
|
private final Http http = new Http();
|
||||||
private final Https https = new Https();
|
private final Https https = new Https();
|
||||||
@@ -55,227 +52,45 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for declaring common properties through all supported protocols
|
|
||||||
* pattern.
|
|
||||||
*/
|
|
||||||
public interface ProtocolProperties {
|
|
||||||
/**
|
|
||||||
* @return the hostname value to resolve in the pattern.
|
|
||||||
*/
|
|
||||||
String getHostname();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the IP address value to resolve in the pattern.
|
|
||||||
*/
|
|
||||||
String getIp();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the port value to resolve in the pattern.
|
|
||||||
*/
|
|
||||||
String getPort();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the pattern to build the URL.
|
|
||||||
*/
|
|
||||||
String getPattern();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return <code>true</code> if the {@link ProtocolProperties} is
|
|
||||||
* enabled.
|
|
||||||
*/
|
|
||||||
boolean isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to hold the properties for the HTTP protocol.
|
* Object to hold the properties for the HTTP protocol.
|
||||||
*/
|
*/
|
||||||
public static class Http implements ProtocolProperties {
|
public static class Http extends DefaultProtocolProperties {
|
||||||
private String hostname = LOCALHOST;
|
|
||||||
private String ip = DEFAULT_IP_LOCALHOST;
|
|
||||||
private String port = DEFAULT_PORT;
|
|
||||||
/**
|
|
||||||
* An ant-URL pattern with placeholder to build the URL on. The URL can
|
|
||||||
* have specific artifact placeholder.
|
|
||||||
*/
|
|
||||||
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables HTTP URI generation in DDI and DMF.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
private boolean enabled = true;
|
public Http() {
|
||||||
|
setPattern(
|
||||||
@Override
|
"{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}");
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(final boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHostname() {
|
|
||||||
return hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHostname(final String hostname) {
|
|
||||||
this.hostname = hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIp() {
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIp(final String ip) {
|
|
||||||
this.ip = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPattern() {
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPattern(final String urlPattern) {
|
|
||||||
this.pattern = urlPattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(final String port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to hold the properties for the HTTP protocol.
|
* Object to hold the properties for the HTTP protocol.
|
||||||
*/
|
*/
|
||||||
public static class Https implements ProtocolProperties {
|
public static class Https extends DefaultProtocolProperties {
|
||||||
private String hostname = LOCALHOST;
|
|
||||||
private String ip = DEFAULT_IP_LOCALHOST;
|
|
||||||
private String port = DEFAULT_PORT;
|
|
||||||
/**
|
|
||||||
* An ant-URL pattern with placeholder to build the URL on. The URL can
|
|
||||||
* have specific artifact placeholder.
|
|
||||||
*/
|
|
||||||
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables HTTPS URI generation in DDI and DMF.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
private boolean enabled = true;
|
public Https() {
|
||||||
|
setPattern(
|
||||||
@Override
|
"{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}");
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(final boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHostname() {
|
|
||||||
return hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHostname(final String hostname) {
|
|
||||||
this.hostname = hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIp() {
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIp(final String ip) {
|
|
||||||
this.ip = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPattern() {
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPattern(final String urlPattern) {
|
|
||||||
this.pattern = urlPattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(final String port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to hold the properties for the HTTP protocol.
|
* Object to hold the properties for the HTTP protocol.
|
||||||
*/
|
*/
|
||||||
public static class Coap implements ProtocolProperties {
|
public static class Coap extends DefaultProtocolProperties {
|
||||||
private String hostname = LOCALHOST;
|
|
||||||
private String ip = DEFAULT_IP_LOCALHOST;
|
|
||||||
private String port = "5683";
|
|
||||||
/**
|
|
||||||
* An ant-URL pattern with placeholder to build the URL on. The URL can
|
|
||||||
* have specific artifact placeholder.
|
|
||||||
*/
|
|
||||||
private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables CoAP URI generation in DMF.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
private boolean enabled = true;
|
public Coap() {
|
||||||
|
setPattern("{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}");
|
||||||
@Override
|
setPort("5683");
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnabled(final boolean enabled) {
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getHostname() {
|
|
||||||
return hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHostname(final String hostname) {
|
|
||||||
this.hostname = hostname;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getIp() {
|
|
||||||
return ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIp(final String ip) {
|
|
||||||
this.ip = ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPattern() {
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPattern(final String urlPattern) {
|
|
||||||
this.pattern = urlPattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPort() {
|
|
||||||
return port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPort(final String port) {
|
|
||||||
this.port = port;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/**
|
||||||
|
* 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.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object to hold the properties for the base protocols.
|
||||||
|
*/
|
||||||
|
public class DefaultProtocolProperties implements ProtocolProperties {
|
||||||
|
// The IP address is not hardcoded. It's the default value, if the IP
|
||||||
|
// address is not configured.
|
||||||
|
@SuppressWarnings("squid:S1313")
|
||||||
|
private static final String DEFAULT_IP_LOCALHOST = "127.0.0.1";
|
||||||
|
private static final String LOCALHOST = "localhost";
|
||||||
|
|
||||||
|
private String hostname = LOCALHOST;
|
||||||
|
private String ip = DEFAULT_IP_LOCALHOST;
|
||||||
|
private String port = "";
|
||||||
|
/**
|
||||||
|
* An ant-URL pattern with placeholder to build the URL on. The URL can have
|
||||||
|
* specific artifact placeholder.
|
||||||
|
*/
|
||||||
|
private String pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables protocol.
|
||||||
|
*/
|
||||||
|
private boolean enabled = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(final boolean enabled) {
|
||||||
|
this.enabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHostname() {
|
||||||
|
return hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHostname(final String hostname) {
|
||||||
|
this.hostname = hostname;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getIp() {
|
||||||
|
return ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIp(final String ip) {
|
||||||
|
this.ip = ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPattern() {
|
||||||
|
return pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPattern(final String urlPattern) {
|
||||||
|
this.pattern = urlPattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPort() {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(final String port) {
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,6 @@ import java.util.Map;
|
|||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.api.ArtifactUrlHandlerProperties.ProtocolProperties;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* 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.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for declaring common properties through all supported protocols
|
||||||
|
* pattern.
|
||||||
|
*/
|
||||||
|
public interface ProtocolProperties {
|
||||||
|
/**
|
||||||
|
* @return the hostname value to resolve in the pattern.
|
||||||
|
*/
|
||||||
|
String getHostname();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the IP address value to resolve in the pattern.
|
||||||
|
*/
|
||||||
|
String getIp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the port value to resolve in the pattern.
|
||||||
|
*/
|
||||||
|
String getPort();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pattern to build the URL.
|
||||||
|
*/
|
||||||
|
String getPattern();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <code>true</code> if the {@link ProtocolProperties} is enabled.
|
||||||
|
*/
|
||||||
|
boolean isEnabled();
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ import org.springframework.cache.CacheManager;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
* A cache interface which handles multi tenancy.
|
||||||
*/
|
*/
|
||||||
public interface TenancyCacheManager extends CacheManager {
|
public interface TenancyCacheManager extends CacheManager {
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class TenantAwareCacheManager implements TenancyCacheManager {
|
|||||||
public Collection<String> getCacheNames() {
|
public Collection<String> getCacheNames() {
|
||||||
String currentTenant = tenantAware.getCurrentTenant();
|
String currentTenant = tenantAware.getCurrentTenant();
|
||||||
if (currentTenant == null) {
|
if (currentTenant == null) {
|
||||||
return null;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTenant = currentTenant.toUpperCase();
|
currentTenant = currentTenant.toUpperCase();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.net.URI;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CancelTargetAssignmentEvent extends AbstractEvent {
|
public class CancelTargetAssignmentEvent extends DefaultEvent {
|
||||||
|
|
||||||
private final String controllerId;
|
private final String controllerId;
|
||||||
private final Long actionId;
|
private final Long actionId;
|
||||||
|
|||||||
@@ -12,11 +12,10 @@ package org.eclipse.hawkbit.eventbus.event;
|
|||||||
* Abstract event definition class which holds the necessary revsion and tenant
|
* Abstract event definition class which holds the necessary revsion and tenant
|
||||||
* information which every event needs.
|
* information which every event needs.
|
||||||
*
|
*
|
||||||
* @author Michael Hirsch
|
|
||||||
* @see AbstractDistributedEvent for events which should be distributed to other
|
* @see AbstractDistributedEvent for events which should be distributed to other
|
||||||
* cluster nodes
|
* cluster nodes
|
||||||
*/
|
*/
|
||||||
public class AbstractEvent implements Event {
|
public class DefaultEvent implements Event {
|
||||||
|
|
||||||
private final long revision;
|
private final long revision;
|
||||||
private final String tenant;
|
private final String tenant;
|
||||||
@@ -27,7 +26,7 @@ public class AbstractEvent implements Event {
|
|||||||
* @param tenant
|
* @param tenant
|
||||||
* the tenant of the event
|
* the tenant of the event
|
||||||
*/
|
*/
|
||||||
protected AbstractEvent(final long revision, final String tenant) {
|
protected DefaultEvent(final long revision, final String tenant) {
|
||||||
this.revision = revision;
|
this.revision = revision;
|
||||||
this.tenant = tenant;
|
this.tenant = tenant;
|
||||||
}
|
}
|
||||||
@@ -9,9 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.eventbus.event;
|
package org.eclipse.hawkbit.eventbus.event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* The event when a target is deleted.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public class TargetDeletedEvent extends AbstractDistributedEvent {
|
public class TargetDeletedEvent extends AbstractDistributedEvent {
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ package org.eclipse.hawkbit.exception;
|
|||||||
* Generic Custom Exception to wrap the Runtime and checked exception
|
* Generic Custom Exception to wrap the Runtime and checked exception
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
public abstract class AbstractServerRtException extends RuntimeException {
|
||||||
public abstract class SpServerRtException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@@ -28,7 +27,7 @@ public abstract class SpServerRtException extends RuntimeException {
|
|||||||
* @param error
|
* @param error
|
||||||
* detail
|
* detail
|
||||||
*/
|
*/
|
||||||
public SpServerRtException(final SpServerError error) {
|
public AbstractServerRtException(final SpServerError error) {
|
||||||
super(error.getMessage());
|
super(error.getMessage());
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -41,7 +40,7 @@ public abstract class SpServerRtException extends RuntimeException {
|
|||||||
* @param error
|
* @param error
|
||||||
* detail
|
* detail
|
||||||
*/
|
*/
|
||||||
public SpServerRtException(final String message, final SpServerError error) {
|
public AbstractServerRtException(final String message, final SpServerError error) {
|
||||||
super(message);
|
super(message);
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -56,7 +55,7 @@ public abstract class SpServerRtException extends RuntimeException {
|
|||||||
* @param cause
|
* @param cause
|
||||||
* of the exception
|
* of the exception
|
||||||
*/
|
*/
|
||||||
public SpServerRtException(final String message, final SpServerError error, final Throwable cause) {
|
public AbstractServerRtException(final String message, final SpServerError error, final Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -69,7 +68,7 @@ public abstract class SpServerRtException extends RuntimeException {
|
|||||||
* @param cause
|
* @param cause
|
||||||
* of the exception
|
* of the exception
|
||||||
*/
|
*/
|
||||||
public SpServerRtException(final SpServerError error, final Throwable cause) {
|
public AbstractServerRtException(final SpServerError error, final Throwable cause) {
|
||||||
super(error.getMessage(), cause);
|
super(error.getMessage(), cause);
|
||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ package org.eclipse.hawkbit.exception;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class GenericSpServerException extends SpServerRtException {
|
public class GenericSpServerException extends AbstractServerRtException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_GENERIC_ERROR;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_GENERIC_ERROR;
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,8 @@ package org.eclipse.hawkbit.repository;
|
|||||||
/**
|
/**
|
||||||
* Sort fields for {@link ActionRest}.
|
* Sort fields for {@link ActionRest}.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum ActionFields implements FieldNameProvider,FieldValueConverter<ActionFields> {
|
public enum ActionFields implements FieldNameProvider, FieldValueConverter<ActionFields> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The status field.
|
* The status field.
|
||||||
@@ -42,13 +39,10 @@ public enum ActionFields implements FieldNameProvider,FieldValueConverter<Action
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object convertValue(final ActionFields e, final String value) {
|
public Object convertValue(final ActionFields e, final String value) {
|
||||||
switch (e) {
|
if (STATUS.equals(e)) {
|
||||||
case STATUS:
|
|
||||||
return convertStatusValue(value);
|
return convertStatusValue(value);
|
||||||
|
|
||||||
default:
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object convertStatusValue(final String value) {
|
private static Object convertStatusValue(final String value) {
|
||||||
@@ -64,11 +58,9 @@ public enum ActionFields implements FieldNameProvider,FieldValueConverter<Action
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] possibleValues(final ActionFields e) {
|
public String[] possibleValues(final ActionFields e) {
|
||||||
switch (e) {
|
if (STATUS.equals(e)) {
|
||||||
case STATUS:
|
|
||||||
return new String[] { ACTIVE, INACTIVE };
|
return new String[] { ACTIVE, INACTIVE };
|
||||||
default:
|
|
||||||
return new String[0];
|
|
||||||
}
|
}
|
||||||
|
return new String[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public interface FieldNameProvider {
|
|||||||
/**
|
/**
|
||||||
* Separator for the sub attributes
|
* Separator for the sub attributes
|
||||||
*/
|
*/
|
||||||
public static final String SUB_ATTRIBUTE_SEPERATOR = ".";
|
String SUB_ATTRIBUTE_SEPERATOR = ".";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the string representation of the underlying persistence field
|
* @return the string representation of the underlying persistence field
|
||||||
@@ -30,13 +30,24 @@ public interface FieldNameProvider {
|
|||||||
*/
|
*/
|
||||||
String getFieldName();
|
String getFieldName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the sub entity the given field.
|
||||||
|
*
|
||||||
|
* @param propertyField
|
||||||
|
* the given field
|
||||||
|
* @return <true> contains <false> contains not
|
||||||
|
*/
|
||||||
default boolean containsSubEntityAttribute(final String propertyField) {
|
default boolean containsSubEntityAttribute(final String propertyField) {
|
||||||
return FieldNameProvider.containsSubEntityAttribute(propertyField, getSubEntityAttributes());
|
return FieldNameProvider.containsSubEntityAttribute(propertyField, getSubEntityAttributes());
|
||||||
};
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return all sub entities attributes.
|
||||||
|
*/
|
||||||
default List<String> getSubEntityAttributes() {
|
default List<String> getSubEntityAttributes() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the database column for the key
|
* the database column for the key
|
||||||
@@ -59,11 +70,11 @@ public interface FieldNameProvider {
|
|||||||
/**
|
/**
|
||||||
* Is the entity field a {@link Map}.
|
* Is the entity field a {@link Map}.
|
||||||
*
|
*
|
||||||
* @return
|
* @return <true> is a map <false> is not a map
|
||||||
*/
|
*/
|
||||||
default boolean isMap() {
|
default boolean isMap() {
|
||||||
return getKeyFieldName() != null;
|
return getKeyFieldName() != null;
|
||||||
};
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a sub attribute exists.
|
* Check if a sub attribute exists.
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public final class DurationHelper {
|
|||||||
* the defined min/max range.
|
* the defined min/max range.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static class DurationRangeValidator {
|
public static final class DurationRangeValidator {
|
||||||
final Duration min;
|
final Duration min;
|
||||||
final Duration max;
|
final Duration max;
|
||||||
|
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
package org.eclipse.hawkbit.tenancy.configuration;
|
package org.eclipse.hawkbit.tenancy.configuration;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link #InvalidTenantConfigurationKeyException} is thrown when an invalid
|
* The {@link #InvalidTenantConfigurationKeyException} is thrown when an invalid
|
||||||
* configuration key is used.
|
* configuration key is used.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InvalidTenantConfigurationKeyException extends SpServerRtException {
|
public class InvalidTenantConfigurationKeyException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_KEY_INVALID;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_KEY_INVALID;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public interface TenantConfigurationValidator {
|
|||||||
* @throws TenantConfigurationValidatorException
|
* @throws TenantConfigurationValidatorException
|
||||||
* is thrown, when parameter is invalid.
|
* is thrown, when parameter is invalid.
|
||||||
*/
|
*/
|
||||||
default void validate(final Object tenantConfigurationValue) throws TenantConfigurationValidatorException {
|
default void validate(final Object tenantConfigurationValue) {
|
||||||
if (tenantConfigurationValue != null
|
if (tenantConfigurationValue != null
|
||||||
&& validateToClass().isAssignableFrom(tenantConfigurationValue.getClass())) {
|
&& validateToClass().isAssignableFrom(tenantConfigurationValue.getClass())) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
package org.eclipse.hawkbit.tenancy.configuration.validator;
|
package org.eclipse.hawkbit.tenancy.configuration.validator;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception which is thrown, when the validation of the configuration value has
|
* Exception which is thrown, when the validation of the configuration value has
|
||||||
* not been successful.
|
* not been successful.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TenantConfigurationValidatorException extends SpServerRtException {
|
public class TenantConfigurationValidatorException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_VALUE_INVALID;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_VALUE_INVALID;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public class DdiArtifactHash {
|
|||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
public DdiArtifactHash() {
|
public DdiArtifactHash() {
|
||||||
|
// needed for json create
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class DdiChunk {
|
|||||||
private List<DdiArtifact> artifacts;
|
private List<DdiArtifact> artifacts;
|
||||||
|
|
||||||
public DdiChunk() {
|
public DdiChunk() {
|
||||||
|
// needed for json create
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,8 +34,11 @@ public class DdiConfig {
|
|||||||
this.polling = polling;
|
this.polling = polling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
public DdiConfig() {
|
public DdiConfig() {
|
||||||
|
// needed for json create.
|
||||||
}
|
}
|
||||||
|
|
||||||
public DdiPolling getPolling() {
|
public DdiPolling getPolling() {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class DdiControllerBase extends ResourceSupport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DdiControllerBase() {
|
public DdiControllerBase() {
|
||||||
|
// needed for json create
|
||||||
}
|
}
|
||||||
|
|
||||||
public DdiConfig getConfig() {
|
public DdiConfig getConfig() {
|
||||||
|
|||||||
@@ -23,8 +23,11 @@ public class DdiDeployment {
|
|||||||
|
|
||||||
private List<DdiChunk> chunks;
|
private List<DdiChunk> chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
public DdiDeployment() {
|
public DdiDeployment() {
|
||||||
|
// needed for json create.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import javax.validation.constraints.NotNull;
|
|||||||
|
|
||||||
import org.springframework.hateoas.ResourceSupport;
|
import org.springframework.hateoas.ResourceSupport;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,10 +22,10 @@ public class DdiDeploymentBase extends ResourceSupport {
|
|||||||
|
|
||||||
@JsonProperty("id")
|
@JsonProperty("id")
|
||||||
@NotNull
|
@NotNull
|
||||||
private String deplyomentId;
|
private final String deplyomentId;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private DdiDeployment deployment;
|
private final DdiDeployment deployment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -34,15 +35,13 @@ public class DdiDeploymentBase extends ResourceSupport {
|
|||||||
* @param deployment
|
* @param deployment
|
||||||
* details.
|
* details.
|
||||||
*/
|
*/
|
||||||
public DdiDeploymentBase(final String id, final DdiDeployment deployment) {
|
@JsonCreator
|
||||||
deplyomentId = id;
|
public DdiDeploymentBase(@JsonProperty("id") final String id,
|
||||||
|
@JsonProperty("deplyomentId") final DdiDeployment deployment) {
|
||||||
|
this.deplyomentId = id;
|
||||||
this.deployment = deployment;
|
this.deployment = deployment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DdiDeploymentBase() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public DdiDeployment getDeployment() {
|
public DdiDeployment getDeployment() {
|
||||||
return deployment;
|
return deployment;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,11 +30,15 @@ public class DdiPolling {
|
|||||||
* between polls
|
* between polls
|
||||||
*/
|
*/
|
||||||
public DdiPolling(final String sleep) {
|
public DdiPolling(final String sleep) {
|
||||||
super();
|
|
||||||
this.sleep = sleep;
|
this.sleep = sleep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
*/
|
||||||
public DdiPolling() {
|
public DdiPolling() {
|
||||||
|
// needed for json create
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSleep() {
|
public String getSleep() {
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
@Stories("Deployment Action Resource")
|
@Stories("Deployment Action Resource")
|
||||||
public class DdiDeploymentBaseTest extends AbstractRestIntegrationTestWithMongoDB {
|
public class DdiDeploymentBaseTest extends AbstractRestIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
private static final String HTTP_LOCALHOST = "http://localhost:8080/";
|
private static final String HTTP_LOCALHOST = "http://localhost/";
|
||||||
private static final String HTTPS_LOCALHOST = "https://localhost:8080/";
|
private static final String HTTPS_LOCALHOST = "https://localhost/";
|
||||||
|
|
||||||
@Test()
|
@Test()
|
||||||
@Description("Ensures that artifacts are not found, when softare module does not exists.")
|
@Description("Ensures that artifacts are not found, when softare module does not exists.")
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ddi.rest.resource;
|
package org.eclipse.hawkbit.ddi.rest.resource;
|
||||||
|
|
||||||
|
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE;
|
||||||
|
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS;
|
||||||
|
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION;
|
||||||
|
import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE;
|
||||||
import static org.fest.assertions.api.Assertions.assertThat;
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
import static org.hamcrest.Matchers.startsWith;
|
||||||
@@ -23,7 +27,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
@@ -57,7 +60,8 @@ public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoD
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.")
|
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.")
|
||||||
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = "ROLE_CONTROLLER", autoCreateTenant = false)
|
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = { CONTROLLER_ROLE,
|
||||||
|
SYSTEM_ROLE }, autoCreateTenant = false)
|
||||||
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
||||||
|
|
||||||
mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print())
|
||||||
@@ -91,13 +95,11 @@ public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoD
|
|||||||
|
|
||||||
// make a poll, audit information should not be changed, run as
|
// make a poll, audit information should not be changed, run as
|
||||||
// controller principal!
|
// controller principal!
|
||||||
securityRule.runAs(
|
securityRule.runAs(WithSpringAuthorityRule.withUser("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||||
WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> {
|
mvc.perform(get("/{tenant}/controller/v1/" + knownTargetControllerId, tenantAware.getCurrentTenant()))
|
||||||
mvc.perform(
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
get("/{tenant}/controller/v1/" + knownTargetControllerId, tenantAware.getCurrentTenant()))
|
return null;
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
});
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
// verify that audit information has not changed
|
// verify that audit information has not changed
|
||||||
final Target targetVerify = targetManagement.findTargetByControllerID(knownTargetControllerId);
|
final Target targetVerify = targetManagement.findTargetByControllerID(knownTargetControllerId);
|
||||||
@@ -143,22 +145,19 @@ public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoD
|
|||||||
@Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.")
|
@Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.")
|
||||||
@WithUser(principal = "knownpricipal", allSpPermissions = false)
|
@WithUser(principal = "knownpricipal", allSpPermissions = false)
|
||||||
public void pollWithModifiedGloablPollingTime() throws Exception {
|
public void pollWithModifiedGloablPollingTime() throws Exception {
|
||||||
securityRule.runAs(
|
securityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> {
|
||||||
WithSpringAuthorityRule.withUser("tenantadmin", SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION),
|
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
||||||
() -> {
|
"00:02:00");
|
||||||
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL,
|
return null;
|
||||||
"00:02:00");
|
});
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
securityRule.runAs(
|
securityRule.runAs(WithSpringAuthorityRule.withUser("controller", CONTROLLER_ROLE_ANONYMOUS), () -> {
|
||||||
WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> {
|
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||||
mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
||||||
.andExpect(content().contentType(MediaTypes.HAL_JSON))
|
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00")));
|
||||||
.andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00")));
|
return null;
|
||||||
return null;
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
||||||
import org.springframework.retry.support.RetryTemplate;;
|
import org.springframework.retry.support.RetryTemplate;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The spring AMQP configuration which is enabled by using the profile
|
* The spring AMQP configuration which is enabled by using the profile
|
||||||
@@ -263,13 +264,16 @@ public class AmqpConfiguration {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Listener factory.
|
* Returns the Listener factory.
|
||||||
*
|
*
|
||||||
|
* @param errorHandler
|
||||||
|
* the error hander
|
||||||
* @return the {@link SimpleMessageListenerContainer} that gets used receive
|
* @return the {@link SimpleMessageListenerContainer} that gets used receive
|
||||||
* AMQP messages
|
* AMQP messages
|
||||||
*/
|
*/
|
||||||
@Bean(name = { "listenerContainerFactory" })
|
@Bean(name = { "listenerContainerFactory" })
|
||||||
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory() {
|
public RabbitListenerContainerFactory<SimpleMessageListenerContainer> listenerContainerFactory(
|
||||||
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory);
|
final ErrorHandler errorHandler) {
|
||||||
|
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory, errorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
* A controller which handles the amqp authentfication.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class AmqpControllerAuthentfication {
|
public class AmqpControllerAuthentfication {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.amqp;
|
|||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -137,6 +138,13 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost());
|
return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executed on a authentication request.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the amqp message
|
||||||
|
* @return the rpc message back to supplier.
|
||||||
|
*/
|
||||||
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory")
|
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory")
|
||||||
public Message onAuthenticationRequest(final Message message) {
|
public Message onAuthenticationRequest(final Message message) {
|
||||||
checkContentTypeJson(message);
|
checkContentTypeJson(message);
|
||||||
@@ -152,6 +160,19 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * Executed if a amqp message arrives.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the message
|
||||||
|
* @param type
|
||||||
|
* the type
|
||||||
|
* @param tenant
|
||||||
|
* the tenant
|
||||||
|
* @param virtualHost
|
||||||
|
* the virtual host
|
||||||
|
* @return the rpc message back to supplier.
|
||||||
|
*/
|
||||||
public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) {
|
public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) {
|
||||||
checkContentTypeJson(message);
|
checkContentTypeJson(message);
|
||||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||||
@@ -417,7 +438,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String convertCorrelationId(final Message message) {
|
private static String convertCorrelationId(final Message message) {
|
||||||
return new String(message.getMessageProperties().getCorrelationId());
|
return new String(message.getMessageProperties().getCorrelationId(), StandardCharsets.UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Action getUpdateActionStatus(final ActionStatus actionStatus) {
|
private Action getUpdateActionStatus(final ActionStatus actionStatus) {
|
||||||
|
|||||||
@@ -39,16 +39,6 @@ public class BaseAmqpService {
|
|||||||
this.rabbitTemplate = rabbitTemplate;
|
this.rabbitTemplate = rabbitTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clean message properties before sending a message.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the message to cleaned up
|
|
||||||
*/
|
|
||||||
protected void cleanMessageHeaderProperties(final Message message) {
|
|
||||||
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is needed to convert a incoming message to is originally object type.
|
* Is needed to convert a incoming message to is originally object type.
|
||||||
*
|
*
|
||||||
@@ -68,7 +58,7 @@ public class BaseAmqpService {
|
|||||||
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
|
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMessageBodyEmpty(final Message message) {
|
private static boolean isMessageBodyEmpty(final Message message) {
|
||||||
return message == null || message.getBody() == null || message.getBody().length == 0;
|
return message == null || message.getBody() == null || message.getBody().length == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,8 +88,7 @@ public class BaseAmqpService {
|
|||||||
return rabbitTemplate.getMessageConverter();
|
return rabbitTemplate.getMessageConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final String getStringHeaderKey(final Message message, final String key,
|
protected String getStringHeaderKey(final Message message, final String key, final String errorMessageIfNull) {
|
||||||
final String errorMessageIfNull) {
|
|
||||||
final Map<String, Object> header = message.getMessageProperties().getHeaders();
|
final Map<String, Object> header = message.getMessageProperties().getHeaders();
|
||||||
final Object value = header.get(key);
|
final Object value = header.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
@@ -117,4 +106,15 @@ public class BaseAmqpService {
|
|||||||
protected RabbitTemplate getRabbitTemplate() {
|
protected RabbitTemplate getRabbitTemplate() {
|
||||||
return rabbitTemplate;
|
return rabbitTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean message properties before sending a message.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the message to cleaned up
|
||||||
|
*/
|
||||||
|
protected void cleanMessageHeaderProperties(final Message message) {
|
||||||
|
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFacto
|
|||||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
|
||||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link RabbitListenerContainerFactory} that can be configured through
|
* {@link RabbitListenerContainerFactory} that can be configured through
|
||||||
@@ -28,10 +29,13 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList
|
|||||||
* for the container factory
|
* for the container factory
|
||||||
* @param amqpProperties
|
* @param amqpProperties
|
||||||
* to configure the container factory
|
* to configure the container factory
|
||||||
|
* @param errorHandler
|
||||||
|
* the error handler which should be use
|
||||||
*/
|
*/
|
||||||
public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties,
|
public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties,
|
||||||
final ConnectionFactory rabbitConnectionFactory) {
|
final ConnectionFactory rabbitConnectionFactory, final ErrorHandler errorHandler) {
|
||||||
this.amqpProperties = amqpProperties;
|
this.amqpProperties = amqpProperties;
|
||||||
|
setErrorHandler(errorHandler);
|
||||||
setDefaultRequeueRejected(true);
|
setDefaultRequeueRejected(true);
|
||||||
setConnectionFactory(rabbitConnectionFactory);
|
setConnectionFactory(rabbitConnectionFactory);
|
||||||
setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
@@ -46,7 +47,7 @@ public class DefaultAmqpSenderService implements AmqpSenderService {
|
|||||||
|
|
||||||
final String correlationId = UUID.randomUUID().toString();
|
final String correlationId = UUID.randomUUID().toString();
|
||||||
final String exchange = extractExchange(replyTo);
|
final String exchange = extractExchange(replyTo);
|
||||||
message.getMessageProperties().setCorrelationId(correlationId.getBytes());
|
message.getMessageProperties().setCorrelationId(correlationId.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOGGER.isTraceEnabled()) {
|
||||||
LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, exchange, correlationId);
|
LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, exchange, correlationId);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Description("Tests authentication manager without principal")
|
@Description("Tests authentication manager without principal")
|
||||||
public void testAuthenticationeBadCredantialsWithoutPricipal() {
|
public void testAuthenticationeBadCredantialsWithoutPricipal() {
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
FileResource.sha1("12345"));
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
try {
|
try {
|
||||||
authenticationManager.doAuthenticate(securityToken);
|
authenticationManager.doAuthenticate(securityToken);
|
||||||
fail("BadCredentialsException was excepeted since principal was missing");
|
fail("BadCredentialsException was excepeted since principal was missing");
|
||||||
@@ -128,7 +128,7 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Description("Tests authentication manager without wrong credential")
|
@Description("Tests authentication manager without wrong credential")
|
||||||
public void testAuthenticationBadCredantialsWithWrongCredential() {
|
public void testAuthenticationBadCredantialsWithWrongCredential() {
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
FileResource.sha1("12345"));
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
@@ -146,7 +146,7 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Description("Tests authentication successfull")
|
@Description("Tests authentication successfull")
|
||||||
public void testSuccessfullAuthentication() {
|
public void testSuccessfullAuthentication() {
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
FileResource.sha1("12345"));
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
@@ -161,7 +161,7 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
final MessageProperties messageProperties = createMessageProperties(null);
|
final MessageProperties messageProperties = createMessageProperties(null);
|
||||||
|
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
FileResource.sha1("12345"));
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
public void testAuthenticationMessageBadCredantialsWithWrongCredential() {
|
public void testAuthenticationMessageBadCredantialsWithWrongCredential() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(null);
|
final MessageProperties messageProperties = createMessageProperties(null);
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
FileResource.sha1("12345"));
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
@@ -201,7 +201,7 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
public void testSuccessfullMessageAuthentication() {
|
public void testSuccessfullMessageAuthentication() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(null);
|
final MessageProperties messageProperties = createMessageProperties(null);
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
FileResource.sha1("12345"));
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
|
|||||||
@@ -279,7 +279,8 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests that an download request is denied for an artifact which does not exists")
|
@Description("Tests that an download request is denied for an artifact which does not exists")
|
||||||
public void authenticationRequestDeniedForArtifactWhichDoesNotExists() {
|
public void authenticationRequestDeniedForArtifactWhichDoesNotExists() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(null);
|
final MessageProperties messageProperties = createMessageProperties(null);
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123",
|
||||||
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -297,7 +298,8 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests that an download request is denied for an artifact which is not assigned to the requested target")
|
@Description("Tests that an download request is denied for an artifact which is not assigned to the requested target")
|
||||||
public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() {
|
public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(null);
|
final MessageProperties messageProperties = createMessageProperties(null);
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123",
|
||||||
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -320,7 +322,8 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target")
|
@Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target")
|
||||||
public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException {
|
public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException {
|
||||||
final MessageProperties messageProperties = createMessageProperties(null);
|
final MessageProperties messageProperties = createMessageProperties(null);
|
||||||
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123",
|
||||||
|
FileResource.createFileResourceBySha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
|
org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
|
||||||
public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB {
|
public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
private static final String HTTPS_LOCALHOST = "https://localhost:8080/";
|
private static final String HTTPS_LOCALHOST = "https://localhost/";
|
||||||
private static final String HTTP_LOCALHOST = "http://localhost:8080/";
|
private static final String HTTP_LOCALHOST = "http://localhost/";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ArtifactUrlHandler urlHandlerProperties;
|
private ArtifactUrlHandler urlHandlerProperties;
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ public class TenantSecurityToken {
|
|||||||
* the SHA1 key of the file to obtain
|
* the SHA1 key of the file to obtain
|
||||||
* @return the {@link FileResource} with SHA1 key set
|
* @return the {@link FileResource} with SHA1 key set
|
||||||
*/
|
*/
|
||||||
public static FileResource sha1(final String sha1) {
|
public static FileResource createFileResourceBySha1(final String sha1) {
|
||||||
final FileResource resource = new FileResource();
|
final FileResource resource = new FileResource();
|
||||||
resource.sha1 = sha1;
|
resource.sha1 = sha1;
|
||||||
return resource;
|
return resource;
|
||||||
@@ -148,7 +148,7 @@ public class TenantSecurityToken {
|
|||||||
* the filename of the file to obtain
|
* the filename of the file to obtain
|
||||||
* @return the {@link FileResource} with filename set
|
* @return the {@link FileResource} with filename set
|
||||||
*/
|
*/
|
||||||
public static FileResource filename(final String filename) {
|
public static FileResource createFileResourceByFilename(final String filename) {
|
||||||
final FileResource resource = new FileResource();
|
final FileResource resource = new FileResource();
|
||||||
resource.filename = filename;
|
resource.filename = filename;
|
||||||
return resource;
|
return resource;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import com.google.common.collect.UnmodifiableIterator;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractHttpControllerAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
public abstract class AbstractHttpControllerAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHttpControllerAuthenticationFilter.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpControllerAuthenticationFilter.class);
|
||||||
|
|
||||||
private static final String TENANT_PLACE_HOLDER = "tenant";
|
private static final String TENANT_PLACE_HOLDER = "tenant";
|
||||||
private static final String CONTROLLER_ID_PLACE_HOLDER = "controllerId";
|
private static final String CONTROLLER_ID_PLACE_HOLDER = "controllerId";
|
||||||
@@ -73,10 +73,12 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
/**
|
/**
|
||||||
* Constructor for sub-classes.
|
* Constructor for sub-classes.
|
||||||
*
|
*
|
||||||
* @param systemManagement
|
* @param tenantConfigurationManagement
|
||||||
* the system management service
|
* the tenant configuration service
|
||||||
* @param tenantAware
|
* @param tenantAware
|
||||||
* the tenant aware service
|
* the tenant aware service
|
||||||
|
* @param systemSecurityContext
|
||||||
|
* the system secruity context
|
||||||
*/
|
*/
|
||||||
public AbstractHttpControllerAuthenticationFilter(final TenantConfigurationManagement tenantConfigurationManagement,
|
public AbstractHttpControllerAuthenticationFilter(final TenantConfigurationManagement tenantConfigurationManagement,
|
||||||
final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) {
|
final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) {
|
||||||
@@ -136,28 +138,28 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
final String requestURI = request.getRequestURI();
|
final String requestURI = request.getRequestURI();
|
||||||
|
|
||||||
if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) {
|
if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) {
|
||||||
LOGGER.debug("retrieving principal from URI request {}", requestURI);
|
LOG.debug("retrieving principal from URI request {}", requestURI);
|
||||||
final Map<String, String> extractUriTemplateVariables = pathExtractor
|
final Map<String, String> extractUriTemplateVariables = pathExtractor
|
||||||
.extractUriTemplateVariables(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI);
|
.extractUriTemplateVariables(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI);
|
||||||
final String controllerId = extractUriTemplateVariables.get(CONTROLLER_ID_PLACE_HOLDER);
|
final String controllerId = extractUriTemplateVariables.get(CONTROLLER_ID_PLACE_HOLDER);
|
||||||
final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
|
final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
LOGGER.trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId,
|
LOG.trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId,
|
||||||
requestURI);
|
requestURI);
|
||||||
}
|
}
|
||||||
return createTenantSecruityTokenVariables(request, tenant, controllerId);
|
return createTenantSecruityTokenVariables(request, tenant, controllerId);
|
||||||
} else if (pathExtractor.match(request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI)) {
|
} else if (pathExtractor.match(request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI)) {
|
||||||
LOGGER.debug("retrieving path variables from URI request {}", requestURI);
|
LOG.debug("retrieving path variables from URI request {}", requestURI);
|
||||||
final Map<String, String> extractUriTemplateVariables = pathExtractor.extractUriTemplateVariables(
|
final Map<String, String> extractUriTemplateVariables = pathExtractor.extractUriTemplateVariables(
|
||||||
request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI);
|
request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI);
|
||||||
final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
|
final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER);
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
LOGGER.trace("Parsed tenant {} from path request {}", tenant, requestURI);
|
LOG.trace("Parsed tenant {} from path request {}", tenant, requestURI);
|
||||||
}
|
}
|
||||||
return createTenantSecruityTokenVariables(request, tenant, "anonymous");
|
return createTenantSecruityTokenVariables(request, tenant, "anonymous");
|
||||||
} else {
|
} else {
|
||||||
if (LOGGER.isTraceEnabled()) {
|
if (LOG.isTraceEnabled()) {
|
||||||
LOGGER.trace("request {} does not match the path pattern {}, request gets ignored", requestURI,
|
LOG.trace("request {} does not match the path pattern {}, request gets ignored", requestURI,
|
||||||
CONTROLLER_REQUEST_ANT_PATTERN);
|
CONTROLLER_REQUEST_ANT_PATTERN);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -166,7 +168,8 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
|
|
||||||
private TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
|
private TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
|
||||||
final String tenant, final String controllerId) {
|
final String tenant, final String controllerId) {
|
||||||
final TenantSecurityToken secruityToken = new TenantSecurityToken(tenant, controllerId, FileResource.sha1(""));
|
final TenantSecurityToken secruityToken = new TenantSecurityToken(tenant, controllerId,
|
||||||
|
FileResource.createFileResourceBySha1(""));
|
||||||
final UnmodifiableIterator<String> forEnumeration = Iterators.forEnumeration(request.getHeaderNames());
|
final UnmodifiableIterator<String> forEnumeration = Iterators.forEnumeration(request.getHeaderNames());
|
||||||
forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header)));
|
forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header)));
|
||||||
return secruityToken;
|
return secruityToken;
|
||||||
|
|||||||
@@ -22,15 +22,11 @@ import org.springframework.util.AntPathMatcher;
|
|||||||
* An {@link AuthenticationDetailsSource} implementation which retrieves the
|
* An {@link AuthenticationDetailsSource} implementation which retrieves the
|
||||||
* tenant from a request pattern {@link #TENANT_AWARE_CONTROLLER_PATTERN} and
|
* tenant from a request pattern {@link #TENANT_AWARE_CONTROLLER_PATTERN} and
|
||||||
* stores the retrieved tenant in the {@link TenantAwareAuthenticationDetails}.
|
* stores the retrieved tenant in the {@link TenantAwareAuthenticationDetails}.
|
||||||
*
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ControllerTenantAwareAuthenticationDetailsSource
|
public class ControllerTenantAwareAuthenticationDetailsSource
|
||||||
implements AuthenticationDetailsSource<HttpServletRequest, TenantAwareAuthenticationDetails> {
|
implements AuthenticationDetailsSource<HttpServletRequest, TenantAwareAuthenticationDetails> {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final String TENANT_AWARE_CONTROLLER_PATTERN = "/{tenant}/controller/**";
|
private static final String TENANT_AWARE_CONTROLLER_PATTERN = "/{tenant}/controller/**";
|
||||||
private static final Logger LOGGER = LoggerFactory
|
private static final Logger LOGGER = LoggerFactory
|
||||||
.getLogger(ControllerTenantAwareAuthenticationDetailsSource.class);
|
.getLogger(ControllerTenantAwareAuthenticationDetailsSource.class);
|
||||||
@@ -38,19 +34,12 @@ public class ControllerTenantAwareAuthenticationDetailsSource
|
|||||||
private final AntPathMatcher pathExtractor;
|
private final AntPathMatcher pathExtractor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
public ControllerTenantAwareAuthenticationDetailsSource() {
|
public ControllerTenantAwareAuthenticationDetailsSource() {
|
||||||
pathExtractor = new AntPathMatcher();
|
pathExtractor = new AntPathMatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* org.springframework.security.authentication.AuthenticationDetailsSource#
|
|
||||||
* buildDetails(java. lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public TenantAwareAuthenticationDetails buildDetails(final HttpServletRequest request) {
|
public TenantAwareAuthenticationDetails buildDetails(final HttpServletRequest request) {
|
||||||
return new TenantAwareWebAuthenticationDetails(getTenantFromRequestUri(request), request.getRemoteAddr(), true);
|
return new TenantAwareWebAuthenticationDetails(getTenantFromRequestUri(request), request.getRemoteAddr(), true);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen
|
|||||||
public class HttpDownloadAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
public class HttpDownloadAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
|
||||||
|
|
||||||
public static final String REQUEST_ID_REGEX_PATTERN = ".*\\/downloadId\\/.*";
|
public static final String REQUEST_ID_REGEX_PATTERN = ".*\\/downloadId\\/.*";
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HttpDownloadAuthenticationFilter.class);
|
private static final Logger LOG = LoggerFactory.getLogger(HttpDownloadAuthenticationFilter.class);
|
||||||
|
|
||||||
private final Pattern pattern;
|
private final Pattern pattern;
|
||||||
private final Cache cache;
|
private final Cache cache;
|
||||||
@@ -50,7 +50,7 @@ public class HttpDownloadAuthenticationFilter extends AbstractPreAuthenticatedPr
|
|||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
LOGGER.debug("retrieving id from URI request {}", requestURI);
|
LOG.debug("retrieving id from URI request {}", requestURI);
|
||||||
final String[] groups = requestURI.split("\\/");
|
final String[] groups = requestURI.split("\\/");
|
||||||
final String id = groups[groups.length - 1];
|
final String id = groups[groups.length - 1];
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public class MgmtArtifactHash {
|
|||||||
* Default constructor.
|
* Default constructor.
|
||||||
*/
|
*/
|
||||||
public MgmtArtifactHash() {
|
public MgmtArtifactHash() {
|
||||||
|
// used for jackson to instantiate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@RequestMapping(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
|
@RequestMapping(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING)
|
||||||
|
@FunctionalInterface
|
||||||
public interface MgmtDownloadArtifactRestApi {
|
public interface MgmtDownloadArtifactRestApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@RequestMapping(MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE)
|
@RequestMapping(MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE)
|
||||||
|
@FunctionalInterface
|
||||||
public interface MgmtDownloadRestApi {
|
public interface MgmtDownloadRestApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
|||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
import org.eclipse.hawkbit.repository.model.TargetWithActionType;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
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;
|
||||||
@@ -72,15 +72,15 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemManagement systemManagement;
|
private SystemManagement systemManagement;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TenantAware currentTenant;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EntityFactory entityFactory;
|
private EntityFactory entityFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private DistributionSetManagement distributionSetManagement;
|
private DistributionSetManagement distributionSetManagement;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResponseEntity<PagedList<MgmtDistributionSet>> getDistributionSets(
|
public ResponseEntity<PagedList<MgmtDistributionSet>> getDistributionSets(
|
||||||
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
|
@RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam,
|
||||||
@@ -119,8 +119,9 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi {
|
|||||||
|
|
||||||
LOG.debug("creating {} distribution sets", sets.size());
|
LOG.debug("creating {} distribution sets", sets.size());
|
||||||
// set default Ds type if ds type is null
|
// set default Ds type if ds type is null
|
||||||
sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(this.systemManagement
|
final String defaultDsKey = systemSecurityContext
|
||||||
.getTenantMetadata(this.currentTenant.getCurrentTenant()).getDefaultDsType().getKey()));
|
.runAsSystem(() -> this.systemManagement.getTenantMetadata().getDefaultDsType().getKey());
|
||||||
|
sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey));
|
||||||
|
|
||||||
final Iterable<DistributionSet> createdDSets = this.distributionSetManagement
|
final Iterable<DistributionSet> createdDSets = this.distributionSetManagement
|
||||||
.createDistributionSets(MgmtDistributionSetMapper.dsFromRequest(sets, this.softwareManagement,
|
.createDistributionSets(MgmtDistributionSetMapper.dsFromRequest(sets, this.softwareManagement,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.eclipse.hawkbit.artifact.repository.ArtifactRepository;
|
|||||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||||
import org.eclipse.hawkbit.cache.CacheConstants;
|
import org.eclipse.hawkbit.cache.CacheConstants;
|
||||||
import org.eclipse.hawkbit.cache.DownloadArtifactCache;
|
import org.eclipse.hawkbit.cache.DownloadArtifactCache;
|
||||||
|
import org.eclipse.hawkbit.cache.DownloadType;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtDownloadRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtDownloadRestApi;
|
||||||
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
|
import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -73,14 +74,11 @@ public class MgmtDownloadResource implements MgmtDownloadRestApi {
|
|||||||
|
|
||||||
final DownloadArtifactCache artifactCache = (DownloadArtifactCache) cacheWrapper.get();
|
final DownloadArtifactCache artifactCache = (DownloadArtifactCache) cacheWrapper.get();
|
||||||
DbArtifact artifact = null;
|
DbArtifact artifact = null;
|
||||||
switch (artifactCache.getDownloadType()) {
|
|
||||||
case BY_SHA1:
|
|
||||||
artifact = artifactRepository.getArtifactBySha1(artifactCache.getId());
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
if (DownloadType.BY_SHA1.equals(artifactCache.getDownloadType())) {
|
||||||
|
artifact = artifactRepository.getArtifactBySha1(artifactCache.getId());
|
||||||
|
} else {
|
||||||
LOGGER.warn("Download Type {} not supported", artifactCache.getDownloadType());
|
LOGGER.warn("Download Type {} not supported", artifactCache.getDownloadType());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (artifact == null) {
|
if (artifact == null) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
|||||||
* 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 class MgmtSystemMapper {
|
public final class MgmtSystemMapper {
|
||||||
|
|
||||||
private MgmtSystemMapper() {
|
private MgmtSystemMapper() {
|
||||||
// Utility class
|
// Utility class
|
||||||
@@ -51,6 +51,8 @@ public class MgmtSystemMapper {
|
|||||||
* maps a TenantConfigurationValue from the repository model to a
|
* maps a TenantConfigurationValue from the repository model to a
|
||||||
* MgmtSystemTenantConfigurationValue, the RESTful model.
|
* MgmtSystemTenantConfigurationValue, the RESTful model.
|
||||||
*
|
*
|
||||||
|
* @param key
|
||||||
|
* the key
|
||||||
* @param repoConfValue
|
* @param repoConfValue
|
||||||
* configuration value as repository model
|
* configuration value as repository model
|
||||||
* @return configuration value as RESTful model
|
* @return configuration value as RESTful model
|
||||||
|
|||||||
@@ -9,16 +9,16 @@
|
|||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-repository</artifactId>
|
<artifactId>hawkbit-repository</artifactId>
|
||||||
<version>0.2.0-SNAPSHOT</version>
|
<version>0.2.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>hawkbit-repository-api</artifactId>
|
<artifactId>hawkbit-repository-api</artifactId>
|
||||||
<name>hawkBit :: Repository API</name>
|
<name>hawkBit :: Repository API</name>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-security-core</artifactId>
|
<artifactId>hawkbit-security-core</artifactId>
|
||||||
@@ -36,14 +36,33 @@
|
|||||||
<groupId>cz.jirutka.rsql</groupId>
|
<groupId>cz.jirutka.rsql</groupId>
|
||||||
<artifactId>rsql-parser</artifactId>
|
<artifactId>rsql-parser</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.hateoas</groupId>
|
<groupId>org.springframework.hateoas</groupId>
|
||||||
<artifactId>spring-hateoas</artifactId>
|
<artifactId>spring-hateoas</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
<!-- Optional -->
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<dependency>
|
||||||
<optional>true</optional>
|
<groupId>org.springframework.boot</groupId>
|
||||||
</dependency>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
</dependencies>
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- TEST -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.yandex.qatools.allure</groupId>
|
||||||
|
<artifactId>allure-junit-adaptor</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easytesting</groupId>
|
||||||
|
<artifactId>fest-assert-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easytesting</groupId>
|
||||||
|
<artifactId>fest-assert</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -183,6 +183,8 @@ public interface ControllerManagement {
|
|||||||
* @return the security context of the target, in case no target exists for
|
* @return the security context of the target, in case no target exists for
|
||||||
* the given controllerId {@code null} is returned
|
* the given controllerId {@code null} is returned
|
||||||
*/
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
|
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET_SEC_TOKEN)
|
||||||
String getSecurityTokenByControllerId(@NotEmpty String controllerId);
|
String getSecurityTokenByControllerId(@NotEmpty String controllerId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldExc
|
|||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
|
import org.eclipse.hawkbit.repository.model.DistributionSetFilter;
|
||||||
|
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
|
import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult;
|
||||||
@@ -32,7 +33,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
|||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
import org.eclipse.hawkbit.repository.model.Tag;
|
import org.eclipse.hawkbit.repository.model.Tag;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
|
|
||||||
import org.hibernate.validator.constraints.NotEmpty;
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
@@ -44,9 +44,6 @@ import org.springframework.security.access.prepost.PreAuthorize;
|
|||||||
*/
|
*/
|
||||||
public interface DistributionSetManagement {
|
public interface DistributionSetManagement {
|
||||||
|
|
||||||
// TODO rename/document the whole with details thing (document what the
|
|
||||||
// details are and maybe find a better name, e.g. with dependencies?)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns {@link SoftwareModule} to existing {@link DistributionSet}.
|
* Assigns {@link SoftwareModule} to existing {@link DistributionSet}.
|
||||||
*
|
*
|
||||||
@@ -284,6 +281,16 @@ public interface DistributionSetManagement {
|
|||||||
Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId,
|
Page<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId,
|
||||||
@NotNull Pageable pageable);
|
@NotNull Pageable pageable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all meta data by the given distribution set id.
|
||||||
|
*
|
||||||
|
* @param distributionSetId
|
||||||
|
* the distribution set id to retrieve the meta data from
|
||||||
|
* @return list of distributionSetMetadata for a given distribution set Id.
|
||||||
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||||
|
List<DistributionSetMetadata> findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* finds all meta data by the given distribution set id.
|
* finds all meta data by the given distribution set id.
|
||||||
*
|
*
|
||||||
@@ -320,7 +327,6 @@ public interface DistributionSetManagement {
|
|||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||||
List<DistributionSet> findDistributionSetsAll(Collection<Long> dist);
|
List<DistributionSet> findDistributionSetsAll(Collection<Long> dist);
|
||||||
|
|
||||||
// TODO discuss: use enum instead of the true,false,null switch ?
|
|
||||||
/**
|
/**
|
||||||
* finds all {@link DistributionSet}s.
|
* finds all {@link DistributionSet}s.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -340,6 +340,7 @@ public interface SoftwareManagement {
|
|||||||
* to search for
|
* to search for
|
||||||
* @return {@link List} of found {@link SoftwareModule}s
|
* @return {@link List} of found {@link SoftwareModule}s
|
||||||
*/
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||||
List<SoftwareModule> findSoftwareModulesById(@NotEmpty Collection<Long> ids);
|
List<SoftwareModule> findSoftwareModulesById(@NotEmpty Collection<Long> ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -482,5 +483,23 @@ public interface SoftwareManagement {
|
|||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY)
|
||||||
SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm);
|
SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds all meta data by the given software module id.
|
||||||
|
*
|
||||||
|
* @param softwareModuleId
|
||||||
|
* the software module id to retrieve the meta data from
|
||||||
|
|
||||||
|
*
|
||||||
|
* @throws RSQLParameterUnsupportedFieldException
|
||||||
|
* if a field in the RSQL string is used but not provided by the
|
||||||
|
* given {@code fieldNameProvider}
|
||||||
|
* @throws RSQLParameterSyntaxException
|
||||||
|
* if the RSQL syntax is wrong
|
||||||
|
* @return result of all meta data entries for a given software
|
||||||
|
* module id.
|
||||||
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY)
|
||||||
|
List<SoftwareModuleMetadata> findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ public interface SystemManagement {
|
|||||||
/**
|
/**
|
||||||
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()}
|
* @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()}
|
||||||
*/
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
|
+ SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
|
+ SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||||
TenantMetaData getTenantMetadata();
|
TenantMetaData getTenantMetadata();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,6 +80,7 @@ public interface SystemManagement {
|
|||||||
* to retrieve data for
|
* to retrieve data for
|
||||||
* @return {@link TenantMetaData} of given tenant
|
* @return {@link TenantMetaData} of given tenant
|
||||||
*/
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE)
|
||||||
TenantMetaData getTenantMetadata(@NotNull String tenant);
|
TenantMetaData getTenantMetadata(@NotNull String tenant);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,6 +90,7 @@ public interface SystemManagement {
|
|||||||
* to update
|
* to update
|
||||||
* @return updated {@link TenantMetaData} entity
|
* @return updated {@link TenantMetaData} entity
|
||||||
*/
|
*/
|
||||||
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION)
|
||||||
TenantMetaData updateTenantMetadata(@NotNull TenantMetaData metaData);
|
TenantMetaData updateTenantMetadata(@NotNull TenantMetaData metaData);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the {@link AbstractBaseEntityEvent} of creating a new {@link DistributionSet}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DistributionCreatedEvent extends AbstractBaseEntityEvent<DistributionSet> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param distributionSet
|
||||||
|
* the distributionSet which has been created
|
||||||
|
*/
|
||||||
|
public DistributionCreatedEvent(final DistributionSet distributionSet) {
|
||||||
|
super(distributionSet);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
|
||||||
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the {@link AbstractDistributedEvent} for deletion of
|
||||||
|
* {@link DistributionSet}.
|
||||||
|
*/
|
||||||
|
public class DistributionDeletedEvent extends AbstractDistributedEvent {
|
||||||
|
private static final long serialVersionUID = -3308850381757843098L;
|
||||||
|
private final Long distributionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tenant
|
||||||
|
* the tenant for this event
|
||||||
|
* @param distributionId
|
||||||
|
* the ID of the distribution set which has been deleted
|
||||||
|
*/
|
||||||
|
public DistributionDeletedEvent(final String tenant, final Long distributionId) {
|
||||||
|
super(-1, tenant);
|
||||||
|
this.distributionId = distributionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getDistributionSetId() {
|
||||||
|
return distributionId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the {@link AbstractBaseEntityEvent} for update a {@link DistributionSet}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DistributionSetUpdateEvent extends AbstractBaseEntityEvent<DistributionSet> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param ds Distribution Set
|
||||||
|
*/
|
||||||
|
public DistributionSetUpdateEvent(final DistributionSet ds) {
|
||||||
|
super(ds);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.eventbus.event;
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.AbstractEvent;
|
import org.eclipse.hawkbit.eventbus.event.DefaultEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event declaration for the UI to notify the UI that a rollout has been
|
* Event declaration for the UI to notify the UI that a rollout has been
|
||||||
@@ -17,7 +17,7 @@ import org.eclipse.hawkbit.eventbus.event.AbstractEvent;
|
|||||||
* @author Michael Hirsch
|
* @author Michael Hirsch
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RolloutChangeEvent extends AbstractEvent {
|
public class RolloutChangeEvent extends DefaultEvent {
|
||||||
|
|
||||||
private final Long rolloutId;
|
private final Long rolloutId;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.repository.eventbus.event;
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.AbstractEvent;
|
import org.eclipse.hawkbit.eventbus.event.DefaultEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event declaration for the UI to notify the UI that a rollout has been
|
* Event declaration for the UI to notify the UI that a rollout has been
|
||||||
@@ -17,7 +17,7 @@ import org.eclipse.hawkbit.eventbus.event.AbstractEvent;
|
|||||||
* @author Michael Hirsch
|
* @author Michael Hirsch
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RolloutGroupChangeEvent extends AbstractEvent {
|
public class RolloutGroupChangeEvent extends DefaultEvent {
|
||||||
|
|
||||||
private final Long rolloutId;
|
private final Long rolloutId;
|
||||||
private final Long rolloutGroupId;
|
private final Long rolloutGroupId;
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ package org.eclipse.hawkbit.repository.eventbus.event;
|
|||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.AbstractEvent;
|
import org.eclipse.hawkbit.eventbus.event.DefaultEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event that gets sent when a distribution set gets assigned to a target.
|
* Event that gets sent when a distribution set gets assigned to a target.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TargetAssignDistributionSetEvent extends AbstractEvent {
|
public class TargetAssignDistributionSetEvent extends DefaultEvent {
|
||||||
|
|
||||||
private final Collection<SoftwareModule> softwareModules;
|
private final Collection<SoftwareModule> softwareModules;
|
||||||
private final String controllerId;
|
private final String controllerId;
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent;
|
||||||
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Defines the {@link AbstractBaseEntityEvent} of deleting a {@link Target}.
|
||||||
|
*/
|
||||||
|
public class TargetDeletedEvent extends AbstractDistributedEvent {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final long targetId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tenant
|
||||||
|
* the tenant for this event
|
||||||
|
* @param targetId
|
||||||
|
* the ID of the target which has been deleted
|
||||||
|
*/
|
||||||
|
public TargetDeletedEvent(final String tenant, final long targetId) {
|
||||||
|
super(-1, tenant);
|
||||||
|
this.targetId = targetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the targetId
|
||||||
|
*/
|
||||||
|
public long getTargetId() {
|
||||||
|
return targetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.repository.eventbus.event;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the {@link AbstractBaseEntityEvent} of updating a {@link Target}.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TargetUpdatedEvent extends AbstractBaseEntityEvent<Target> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 5665118668865832477L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param baseEntity
|
||||||
|
* Target entity
|
||||||
|
*/
|
||||||
|
public TargetUpdatedEvent(final Target baseEntity) {
|
||||||
|
super(baseEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if artifact deletion failed.
|
* Thrown if artifact deletion failed.
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class ArtifactDeleteFailedException extends SpServerRtException {
|
public final class ArtifactDeleteFailedException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class ArtifactUploadFailedException extends SpServerRtException {
|
public final class ArtifactUploadFailedException extends AbstractServerRtException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if cancelation of actions is performened where the action is not
|
* Thrown if cancelation of actions is performened where the action is not
|
||||||
@@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class CancelActionNotAllowedException extends SpServerRtException {
|
public final class CancelActionNotAllowedException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ConcurrentModificationException} is thrown when a given entity in's
|
* {@link ConcurrentModificationException} is thrown when a given entity in's
|
||||||
@@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ConcurrentModificationException extends SpServerRtException {
|
public class ConcurrentModificationException extends AbstractServerRtException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_CONCURRENT_MODIFICATION;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_CONCURRENT_MODIFICATION;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if DS creation failed.
|
* Thrown if DS creation failed.
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class DistributionSetCreationFailedMissingMandatoryModuleException extends SpServerRtException {
|
public final class DistributionSetCreationFailedMissingMandatoryModuleException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
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;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class DistributionSetTypeUndefinedException extends SpServerRtException {
|
public class DistributionSetTypeUndefinedException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the {@link EntityAlreadyExistsException} is thrown when a entity is tried to
|
* the {@link EntityAlreadyExistsException} is thrown when a entity is tried to
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class EntityAlreadyExistsException extends SpServerRtException {
|
public class EntityAlreadyExistsException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link EntityLockedException} is thrown when an entity has been locked by
|
* The {@link EntityLockedException} is thrown when an entity has been locked by
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class EntityLockedException extends SpServerRtException {
|
public class EntityLockedException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_ENTITY_LOCKED;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_ENTITY_LOCKED;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the {@link EntityNotFoundException} is thrown when a entity is tried find but
|
* the {@link EntityNotFoundException} is thrown when a entity is tried find but
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class EntityNotFoundException extends SpServerRtException {
|
public class EntityNotFoundException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_NOT_EXISTS;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_NOT_EXISTS;
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the {@link EntityReadOnlyException} is thrown when a entity is in read only
|
* the {@link EntityReadOnlyException} is thrown when a entity is in read only
|
||||||
* mode and a user tries to change it.
|
* mode and a user tries to change it.
|
||||||
*/
|
*/
|
||||||
public class EntityReadOnlyException extends SpServerRtException {
|
public class EntityReadOnlyException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_READ_ONLY;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_READ_ONLY;
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when force quitting an actions is not allowed. e.g. the action is not
|
* Thrown when force quitting an actions is not allowed. e.g. the action is not
|
||||||
* active or it is not canceled before.
|
* active or it is not canceled before.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class ForceQuitActionNotAllowedException extends SpServerRtException {
|
public final class ForceQuitActionNotAllowedException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class GridFSDBFileNotFoundException extends SpServerRtException {
|
public final class GridFSDBFileNotFoundException extends AbstractServerRtException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if a distribution set is assigned to a a target that is incomplete
|
* Thrown if a distribution set is assigned to a a target that is incomplete
|
||||||
@@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class IncompleteDistributionSetException extends SpServerRtException {
|
public final class IncompleteDistributionSetException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception which is thrown in case the current security context object does
|
* Exception which is thrown in case the current security context object does
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InsufficientPermissionException extends SpServerRtException {
|
public class InsufficientPermissionException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if MD5 checksum check fails.
|
* Thrown if MD5 checksum check fails.
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InvalidMD5HashException extends SpServerRtException {
|
public class InvalidMD5HashException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if SHA1 checksum check fails.
|
* Thrown if SHA1 checksum check fails.
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class InvalidSHA1HashException extends SpServerRtException {
|
public class InvalidSHA1HashException extends AbstractServerRtException {
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception which is thrown when trying to set an invalid target address.
|
* Exception which is thrown when trying to set an invalid target address.
|
||||||
*/
|
*/
|
||||||
public class InvalidTargetAddressException extends SpServerRtException {
|
public class InvalidTargetAddressException extends AbstractServerRtException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown if a multi part exception occurred.
|
* Thrown if a multi part exception occurred.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final class MultiPartFileUploadException extends SpServerRtException {
|
public final class MultiPartFileUploadException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception used by the REST API in case of RSQL search filter query.
|
* Exception used by the REST API in case of RSQL search filter query.
|
||||||
@@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RSQLParameterSyntaxException extends SpServerRtException {
|
public class RSQLParameterSyntaxException extends AbstractServerRtException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception used by the REST API in case of invalid field name in the rsql
|
* Exception used by the REST API in case of invalid field name in the rsql
|
||||||
@@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RSQLParameterUnsupportedFieldException extends SpServerRtException {
|
public class RSQLParameterUnsupportedFieldException extends AbstractServerRtException {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the {@link RolloutIllegalStateException} is thrown when a rollout is changing
|
* the {@link RolloutIllegalStateException} is thrown when a rollout is changing
|
||||||
@@ -17,7 +17,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
* rollout, or trying to resume a already finished rollout.
|
* rollout, or trying to resume a already finished rollout.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RolloutIllegalStateException extends SpServerRtException {
|
public class RolloutIllegalStateException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_ROLLOUT_ILLEGAL_STATE;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_ROLLOUT_ILLEGAL_STATE;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
package org.eclipse.hawkbit.repository.exception;
|
package org.eclipse.hawkbit.repository.exception;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.exception.SpServerError;
|
import org.eclipse.hawkbit.exception.SpServerError;
|
||||||
import org.eclipse.hawkbit.exception.SpServerRtException;
|
import org.eclipse.hawkbit.exception.AbstractServerRtException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the {@link TenantNotExistException} is thrown when e.g. a controller tries to
|
* the {@link TenantNotExistException} is thrown when e.g. a controller tries to
|
||||||
@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TenantNotExistException extends SpServerRtException {
|
public class TenantNotExistException extends AbstractServerRtException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_TENANT_NOT_EXISTS;
|
private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_TENANT_NOT_EXISTS;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user