diff --git a/README.md b/README.md
index fb649633b..0a9b0b4c6 100644
--- a/README.md
+++ b/README.md
@@ -14,10 +14,15 @@ see [hawkBit Wiki](https://github.com/eclipse/hawkbit/wiki)
* Having issues with hawkBit? Open a [GitHub issue](https://github.com/eclipse/hawkbit/issues).
* You can also check out our [Project Homepage](https://projects.eclipse.org/projects/iot.hawkbit) for further contact options.
+# hawkBit sandbox
+
+We offer a sandbox installation that is free for everyone to try out hawkBit. However, keep in mind that the sandbox database will be reset from time to time. It is also not possible to upload any artifacts into the sandbox. But you can use it to try out the Management UI, Management API and DDI API.
+
+https://hawkbit.eu-gb.mybluemix.net/UI/
# Compile, Run and Getting Started
-We are not providing an off the shelf installation ready hawkBit update server. However, we recommend to check out the [Example Application](examples/hawkbit-example-app) for a runtime ready Spring Boot based update server that is empowered by hawkBit.
+We are not providing an off the shelf installation ready hawkBit update server. However, we recommend to check out the [Example Application](examples/hawkbit-example-app) for a runtime ready Spring Boot based update server that is empowered by hawkBit. In addition we have [guide](https://github.com/eclipse/hawkbit/wiki/Run-hawkBit) for setting up a complete landscape.
#### Clone and build hawkBit
```
diff --git a/deployHawkBitSandbox.sh b/deployHawkBitSandbox.sh
new file mode 100644
index 000000000..d774f4205
--- /dev/null
+++ b/deployHawkBitSandbox.sh
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+
+# This script allows the deployment of the complete hawkBit sandbox including
+# data example to a cloud foundry enviroment. Expects existing CF CLI
+# installation and login to be existing already.
+
+cd examples/hawkbit-example-app/target/
+cf push
+cd ../..
+java -jar hawkbit-mgmt-api-client/target/hawkbit-mgmt-api-client-0.2.0-SNAPSHOT.jar --hawkbit.url=hawkbit.eu-gb.mybluemix.net
+cd hawkbit-device-simulator/target/
+cf push
+cd ../../..
diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md
index 869f80511..1ba29bb7e 100644
--- a/examples/hawkbit-device-simulator/README.md
+++ b/examples/hawkbit-device-simulator/README.md
@@ -2,7 +2,7 @@
The device simulator handles software update commands from the update server.
-## Run
+## Run on your own workstation
```
java -jar examples/hawkbit-device-simulator/target/hawkbit-device-simulator-*-SNAPSHOT.jar
```
@@ -11,6 +11,11 @@ Or:
run org.eclipse.hawkbit.simulator.DeviceSimulator
```
+## Deploy to cloud foundry environment
+
+- Go to ```target``` subfolder.
+- Run ```cf push```
+
## Notes
The simulator has user authentication enabled in **cloud profile**. Default credentials:
@@ -30,9 +35,9 @@ http://localhost:8083
```

-
+

-
+

@@ -54,12 +59,12 @@ Example: for 20 simulated devices (default)
http://localhost:8083/start
```
-Example: for 10 simulated devices that start with the name prefix "activeSim":
+Example: for 10 simulated devices that start with the name prefix "activeSim":
```
http://localhost:8083/start?amount=10&name=activeSim
```
-Example: for 5 simulated devices that start with the name prefix "ddi" using the Direct Device Integration API (http):
+Example: for 5 simulated devices that start with the name prefix "ddi" using the Direct Device Integration API (http):
```
http://localhost:8083/start?amount=5&name=ddi?api=ddi
```
diff --git a/examples/hawkbit-device-simulator/cf/manifest.yml b/examples/hawkbit-device-simulator/cf/manifest.yml
new file mode 100644
index 000000000..51a43ace6
--- /dev/null
+++ b/examples/hawkbit-device-simulator/cf/manifest.yml
@@ -0,0 +1,22 @@
+#
+# 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
+#
+
+---
+applications:
+- name: hawkbit-simulator
+ memory: 1024M
+ instances: 1
+ buildpack: https://github.com/cloudfoundry/java-buildpack
+ path: ${project.build.finalName}.jar
+ services:
+ - dmf-rabbit
+ env:
+ SPRING_PROFILES_ACTIVE: cloud,amqp
+ CF_STAGING_TIMEOUT: 15
+ CF_STARTUP_TIMEOUT: 15
diff --git a/examples/hawkbit-device-simulator/pom.xml b/examples/hawkbit-device-simulator/pom.xml
index a2575e9db..a23051124 100644
--- a/examples/hawkbit-device-simulator/pom.xml
+++ b/examples/hawkbit-device-simulator/pom.xml
@@ -42,6 +42,19 @@
+
+
+ src/main/resources
+
+
+ cf
+ true
+ ${project.build.directory}
+
+ manifest.yml
+
+
+
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java
index b8b5011aa..afc3a2569 100644
--- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java
@@ -14,6 +14,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
import org.eclipse.hawkbit.simulator.event.InitUpdate;
import org.eclipse.hawkbit.simulator.event.ProgressUpdate;
@@ -34,6 +35,9 @@ public class DeviceSimulatorUpdater {
@Autowired
private SpSenderService spSenderService;
+ @Autowired
+ private SimulatedDeviceFactory deviceFactory;
+
@Autowired
private EventBus eventbus;
@@ -58,7 +62,13 @@ public class DeviceSimulatorUpdater {
*/
public void startUpdate(final String tenant, final String id, final long actionId, final String swVersion,
final UpdaterCallback callback) {
- final AbstractSimulatedDevice device = repository.get(tenant, id);
+ AbstractSimulatedDevice device = repository.get(tenant, id);
+
+ // plug and play - non existing device will be auto created
+ if (device == null) {
+ device = repository.add(deviceFactory.createSimulatedDevice(id, tenant, Protocol.DMF_AMQP, -1, null, null));
+ }
+
device.setProgress(0.0);
device.setSwversion(swVersion);
eventbus.post(new InitUpdate(device));
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java
index c1f358d89..426860d8b 100644
--- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java
@@ -55,7 +55,7 @@ public class SimulationController {
* number of delay in milliseconds to delay polling of DDI
* devices
* @param gatewayToken
- * the hawkbit-update-server gatwaytoken in case authentication
+ * the hawkbit-update-server gatewaytoken in case authentication
* is enforced in hawkbit
* @return a response string that devices has been created
* @throws MalformedURLException
@@ -68,7 +68,7 @@ public class SimulationController {
@RequestParam(value = "endpoint", defaultValue = "http://localhost:8080") final String endpoint,
@RequestParam(value = "polldelay", defaultValue = "30") final int pollDelay,
@RequestParam(value = "gatewaytoken", defaultValue = "") final String gatewayToken)
- throws MalformedURLException {
+ throws MalformedURLException {
final Protocol protocol;
switch (api.toLowerCase()) {
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java
new file mode 100644
index 000000000..354263934
--- /dev/null
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationProperties.java
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.simulator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
+import org.hibernate.validator.constraints.NotEmpty;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * General simulator service properties.
+ *
+ */
+@Component
+@ConfigurationProperties("hawkbit.device.simulator")
+public class SimulationProperties {
+
+ /**
+ * List of tenants where the simulator should auto start simulations after
+ * startup.
+ */
+ private final List autostarts = new ArrayList<>();
+
+ public List getAutostarts() {
+ return this.autostarts;
+ }
+
+ /**
+ * Auto start configuration for simulation setups that the simulator begins
+ * after startup.
+ *
+ */
+ public static class Autostart {
+ /**
+ * Name prefix of simulated devices, followed by counter, e.g.
+ * simulated0, simulated1, simulated2....
+ */
+ private String name = "simulated";
+
+ /**
+ * Amount of simulated devices.
+ */
+ private int amount = 20;
+
+ /**
+ * Tenant name for the simulation.
+ */
+ @NotEmpty
+ private String tenant;
+
+ /**
+ * API for simulation.
+ */
+ private Protocol api = Protocol.DMF_AMQP;
+
+ /**
+ * Endpoint in case of DDI API based simulation.
+ */
+ private String endpoint = "http://localhost:8080";
+
+ /**
+ * Poll time in case of DDI API based simulation.
+ */
+ private int pollDelay = 30;
+
+ /**
+ * Optional gateway token for DDI API based simulation.
+ */
+ private String gatewayToken = "";
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public int getAmount() {
+ return amount;
+ }
+
+ public void setAmount(final int amount) {
+ this.amount = amount;
+ }
+
+ public String getTenant() {
+ return tenant;
+ }
+
+ public void setTenant(final String tenant) {
+ this.tenant = tenant;
+ }
+
+ public Protocol getApi() {
+ return api;
+ }
+
+ public void setApi(final Protocol api) {
+ this.api = api;
+ }
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(final String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public int getPollDelay() {
+ return pollDelay;
+ }
+
+ public void setPollDelay(final int pollDelay) {
+ this.pollDelay = pollDelay;
+ }
+
+ public String getGatewayToken() {
+ return gatewayToken;
+ }
+
+ public void setGatewayToken(final String gatewayToken) {
+ this.gatewayToken = gatewayToken;
+ }
+ }
+}
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java
new file mode 100644
index 000000000..60f3055bd
--- /dev/null
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.simulator;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.stereotype.Component;
+
+/**
+ * Execution of operations after startup. Set up of simulations.
+ *
+ */
+@Component
+public class SimulatorStartup implements ApplicationListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorStartup.class);
+
+ @Autowired
+ private SimulationProperties simulationProperties;
+
+ @Autowired
+ private SpSenderService spSenderService;
+
+ @Autowired
+ private DeviceSimulatorRepository repository;
+
+ @Autowired
+ private SimulatedDeviceFactory deviceFactory;
+
+ @Override
+ public void onApplicationEvent(final ContextRefreshedEvent event) {
+ simulationProperties.getAutostarts().forEach(autostart -> {
+ for (int i = 0; i < autostart.getAmount(); i++) {
+ final String deviceId = autostart.getName() + i;
+ try {
+ repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(),
+ autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()),
+ autostart.getGatewayToken()));
+ } catch (final MalformedURLException e) {
+ LOGGER.error("Creation of simulated device at startup failed.", e);
+ }
+
+ spSenderService.createOrUpdateThing(autostart.getTenant(), deviceId);
+ }
+ });
+ }
+
+}
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java
index 492bb3857..bf5d723a8 100644
--- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java
@@ -59,7 +59,8 @@ public class AmqpConfiguration {
}
/**
- * Create the receiver queue from sp. Receive messages from sp.
+ * Creates the receiver queue from update server for receiving message from
+ * update server.
*
* @return the queue
*/
@@ -70,7 +71,7 @@ public class AmqpConfiguration {
}
/**
- * Create the recevier exchange. Sp send messages to this exchange.
+ * Creates the receiver exchange for sending messages to update server.
*
* @return the exchange
*/
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java
index f9e6ab23d..f58355980 100644
--- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java
@@ -19,26 +19,25 @@ import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("hawkbit.device.simulator.amqp")
public class AmqpProperties {
-
/**
* Queue for receiving DMF messages from update server.
*/
- private String receiverConnectorQueueFromSp;
+ private String receiverConnectorQueueFromSp = "simulator_receiver";
/**
* Exchange for sending DMF messages to update server.
*/
- private String senderForSpExchange;
+ private String senderForSpExchange = "simulator.replyTo";
/**
* Simulator dead letter queue.
*/
- private String deadLetterQueue;
+ private String deadLetterQueue = "simulator_deadletter";
/**
* Simulator dead letter exchange.
*/
- private String deadLetterExchange;
+ private String deadLetterExchange = "simulator.deadletter";
public String getReceiverConnectorQueueFromSp() {
return receiverConnectorQueueFromSp;
diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java
index 1c314d56f..f22839422 100644
--- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java
+++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java
@@ -26,14 +26,11 @@ import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
/**
- * Handle all incoming Messages from SP.
- *
- *
+ * Handle all incoming Messages from hawkBit update server.
*
*/
@Component
public class SpReceiverService extends ReceiverService {
-
private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class);
public static final String SOFTWARE_MODULE_FIRMWARE = "firmware";
@@ -44,17 +41,6 @@ public class SpReceiverService extends ReceiverService {
/**
* Constructor.
- *
- * @param rabbitTemplate
- * the rabbit template
- * @param amqpProperties
- * the amqp properties
- * @param lwm2mSenderService
- * the lwm2mSenderService
- * @param spSenderService
- * the spSenderService
- * @param deviceUpdater
- * the updater service to simulate update process
*/
@Autowired
public SpReceiverService(final RabbitTemplate rabbitTemplate, final AmqpProperties amqpProperties,
@@ -62,12 +48,11 @@ public class SpReceiverService extends ReceiverService {
super(rabbitTemplate, amqpProperties);
this.spSenderService = spSenderService;
this.deviceUpdater = deviceUpdater;
-
}
/**
* Handle the incoming Message from Queue with the property
- * (com.bosch.sp.lwm2m.connector.amqp.receiverConnectorQueueFromSp).
+ * (hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp).
*
* @param message
* the incoming message
diff --git a/examples/hawkbit-device-simulator/src/main/resources/application.properties b/examples/hawkbit-device-simulator/src/main/resources/application.properties
index 56d0190a7..fbe7261be 100644
--- a/examples/hawkbit-device-simulator/src/main/resources/application.properties
+++ b/examples/hawkbit-device-simulator/src/main/resources/application.properties
@@ -7,18 +7,17 @@
# http://www.eclipse.org/legal/epl-v10.html
#
-
-#########################################################################################
-# PUBLIC configuration, i.e. can be changed by users at runtime (defaults provided here)
-#########################################################################################
-## Configuration for RabbitMQ communication
+## Configuration for DMF communication
hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp=simulator_receiver
hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter
hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter
hawkbit.device.simulator.amqp.senderForSpExchange=simulator.replyTo
+## Configuration for simulations
+hawkbit.device.simulator.autostarts.[0].tenant=DEFAULT
-## Configuration for RabbitMQ integration
+
+## Configuration for local RabbitMQ integration
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtualHost=/
diff --git a/examples/hawkbit-example-app/README.md b/examples/hawkbit-example-app/README.md
index eaf30f306..ecbec93c3 100644
--- a/examples/hawkbit-example-app/README.md
+++ b/examples/hawkbit-example-app/README.md
@@ -1,7 +1,15 @@
# hawkBit Example Application
-The hawkBit example application is a standalone spring-boot application with an embedded servlet container to start the hawkBit.
+The hawkBit example application is a standalone spring-boot application with an embedded servlet container to host the hawkBit Update Server.
-## Run
+We have have described several options for you to get access to the example.
+
+## Try out the example application in our hawkBit sandbox on Bluemix
+- try out Management UI https://hawkbit.eu-gb.mybluemix.net/UI
+- try out Management API https://hawkbit.eu-gb.mybluemix.net/rest/v1/targets (don't forget basic auth header)
+- try out DDI API https://hawkbit.eu-gb.mybluemix.net/DEFAULT/controller/v1/MYTESTDEVICE
+
+## On your own workstation
+### Run
```
java -jar examples/hawkbit-example-app/target/hawkbit-example-app-*-SNAPSHOT.jar
```
@@ -10,6 +18,14 @@ Or:
run org eclipse.hawkbit.app.Start
```
-## Usage
-The UI can be accessed via _http://localhost:8080/UI_.
-The REST API can be accessed via _http://localhost:8080/rest/v1_.
+### Usage
+The Management UI can be accessed via http://localhost:8080/UI
+The Management API can be accessed via http://localhost:8080/rest/v1
+
+## Deploy example app to Cloud Foundry
+
+- Go to ```target``` subfolder.
+- Select one of the two manifests
+ - **manifest-simple.yml** for a standalone hawkBit installation with embedded H2.
+ - **manifest.yml** for a standalone hawkBit installation with embedded H2 and RabbitMQ service binding for DMF integration (note: this manifest is used for the sandbox above).
+- Run ```cf push``` against you cloud foundry environment.
diff --git a/examples/hawkbit-example-app/cf/manifest-simple.yml b/examples/hawkbit-example-app/cf/manifest-simple.yml
new file mode 100644
index 000000000..c87a533f4
--- /dev/null
+++ b/examples/hawkbit-example-app/cf/manifest-simple.yml
@@ -0,0 +1,20 @@
+#
+# 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
+#
+
+---
+applications:
+- name: hawkbit-simple
+ memory: 1024M
+ instances: 1
+ buildpack: https://github.com/cloudfoundry/java-buildpack
+ path: ${project.build.finalName}.jar
+ env:
+ SPRING_PROFILES_ACTIVE: cloudsandbox
+ CF_STAGING_TIMEOUT: 15
+ CF_STARTUP_TIMEOUT: 15
diff --git a/examples/hawkbit-example-app/cf/manifest.yml b/examples/hawkbit-example-app/cf/manifest.yml
new file mode 100644
index 000000000..2145f467d
--- /dev/null
+++ b/examples/hawkbit-example-app/cf/manifest.yml
@@ -0,0 +1,22 @@
+#
+# 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
+#
+
+---
+applications:
+- name: hawkbit
+ memory: 1024M
+ instances: 1
+ buildpack: https://github.com/cloudfoundry/java-buildpack
+ path: ${project.build.finalName}.jar
+ services:
+ - dmf-rabbit
+ env:
+ SPRING_PROFILES_ACTIVE: cloudsandbox,amqp
+ CF_STAGING_TIMEOUT: 15
+ CF_STARTUP_TIMEOUT: 15
diff --git a/examples/hawkbit-example-app/pom.xml b/examples/hawkbit-example-app/pom.xml
index 33624ffd7..a5c0f864d 100644
--- a/examples/hawkbit-example-app/pom.xml
+++ b/examples/hawkbit-example-app/pom.xml
@@ -39,6 +39,20 @@
+
+
+ src/main/resources
+
+
+ cf
+ true
+ ${project.build.directory}
+
+ manifest.yml
+ manifest-simple.yml
+
+
+
diff --git a/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties b/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties
new file mode 100644
index 000000000..ecf71da41
--- /dev/null
+++ b/examples/hawkbit-example-app/src/main/resources/application-cloudsandbox.properties
@@ -0,0 +1,10 @@
+#
+# 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
+#
+
+vaadin.servlet.productionMode=true
diff --git a/examples/hawkbit-mgmt-api-client/README.md b/examples/hawkbit-mgmt-api-client/README.md
index eff301e20..ac8e7a4cd 100644
--- a/examples/hawkbit-mgmt-api-client/README.md
+++ b/examples/hawkbit-mgmt-api-client/README.md
@@ -1,4 +1,4 @@
-# HawkBit management API example
+# hawkBit Management API example client
Example client that shows how to efficiently use the hawkBit management API.
@@ -36,4 +36,3 @@ In rollout mode:
* assigning software modules to distribution sets
* creating a rollout
* starting a rollout
-
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java
index 00a9b3fba..5ac11e012 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the DistributionSet resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsets")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/distributionsets")
public interface DistributionSetResourceClient extends DistributionSetRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java
index ea9f5d28a..5fbdaf857 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the DistributionSetTag resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsettags")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/distributionsettags")
public interface DistributionSetTagResourceClient extends DistributionSetTagRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java
index 08d40dfa5..300f8ddcb 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java
@@ -15,7 +15,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
* Client binding for the DistributionSetType resource of the management API.
*
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsettypes")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/distributionsettypes")
public interface DistributionSetTypeResourceClient extends DistributionSetTypeRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java
index 78b7413e7..aed3af7a2 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the Rollout resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/rollouts")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/rollouts")
public interface RolloutResourceClient extends RolloutRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java
index 88e664d78..8610643ef 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the SoftwareModule resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/softwaremodules")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/softwaremodules")
public interface SoftwareModuleResourceClient extends SoftwareModuleRestAPI {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java
index 4896cb8d8..46410dd6c 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the oftwareModuleType resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/softwaremoduletypes")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/softwaremoduletypes")
public interface SoftwareModuleTypeResourceClient extends SoftwareModuleTypeRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java
index a82aa5443..79385fea4 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the Target resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/targets")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/targets")
public interface TargetResourceClient extends TargetRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java
index fee30c686..930931a87 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java
@@ -14,7 +14,7 @@ import org.springframework.cloud.netflix.feign.FeignClient;
/**
* Client binding for the TargetTag resource of the management API.
*/
-@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/targettags")
+@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/targettags")
public interface TargetTagResourceClient extends TargetTagRestApi {
}
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java
index c821b106c..358cff0db 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java
@@ -16,11 +16,7 @@ import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRe
import com.google.common.collect.Lists;
/**
- *
* Builder pattern for building {@link DistributionSetRequestBodyPost}.
- *
- * @author Jonathan Knoblauch
- *
*/
public class DistributionSetBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java
index e1da1f048..752834c7d 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java
@@ -19,8 +19,6 @@ import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link DistributionSetTypeRequestBodyPost}.
- *
- * @author Jonathan Knoblauch
*
*/
public class DistributionSetTypeBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java
index bea0fd9a4..2e01e0ba2 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java
@@ -15,8 +15,6 @@ import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody;
/**
*
* Builder pattern for building {@link RolloutRestRequestBody}.
- *
- * @author Jonathan Knoblauch
*
*/
public class RolloutBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java
index b209dbe8b..8d69db619 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java
@@ -16,8 +16,6 @@ import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleAssi
/**
*
* Builder pattern for building {@link SoftwareModuleAssigmentRest}.
- *
- * @author Jonathan Knoblauch
*
*/
public class SoftwareModuleAssigmentBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java
index 30b85d901..4bbfd92b4 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java
@@ -19,8 +19,6 @@ import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link SoftwareModuleRequestBodyPost}.
- *
- * @author Jonathan Knoblauch
*
*/
public class SoftwareModuleBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java
index ce128d592..a6472f0a0 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java
@@ -19,8 +19,6 @@ import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link SoftwareModuleRequestBodyPost}.
- *
- * @author Jonathan Knoblauch
*
*/
public class SoftwareModuleTypeBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java
index f3888de54..6f2eb3248 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java
@@ -17,8 +17,6 @@ import com.google.common.collect.Lists;
/**
* Builder pattern for building {@link TagRequestBodyPut}.
- *
- * @author Jonathan Knoblauch
*
*/
public class TagBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java
index 5123903d9..e496407e1 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java
@@ -19,8 +19,6 @@ import com.google.common.collect.Lists;
/**
*
* Builder pattern for building {@link TargetRequestBody}.
- *
- * @author Jonathan Knoblauch
*
*/
public class TargetBuilder {
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java
index e92f81326..cd74c0474 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java
@@ -41,7 +41,7 @@ public class CreateStartedRolloutExample {
private static final String SM_MODULE_TYPE = "firmware";
/* known distribution set type name and key */
- private static final String DS_MODULE_TYPE = "firmware";
+ private static final String DS_MODULE_TYPE = SM_MODULE_TYPE;
@Autowired
private DistributionSetResourceClient distributionSetResource;
diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java
index d17048dea..5873403f0 100644
--- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java
+++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java
@@ -41,13 +41,13 @@ public class GettingStartedDefaultScenario {
private static final String SM_MODULE_TYPE = "gettingstarted";
/* known distribution set type name and key */
- private static final String DS_MODULE_TYPE = "gettingstarted";
+ private static final String DS_MODULE_TYPE = SM_MODULE_TYPE;
/* known distribution name of this getting started example */
private static final String SM_EXAMPLE_NAME = "gettingstarted-example";
/* known distribution name of this getting started example */
- private static final String DS_EXAMPLE_NAME = "gettingstarted-example";
+ private static final String DS_EXAMPLE_NAME = SM_EXAMPLE_NAME;
@Autowired
private DistributionSetResourceClient distributionSetResource;
diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java
index 24e9667c2..9638377eb 100644
--- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java
+++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java
@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.autoconfigure.security;
import java.io.IOException;
import java.net.URI;
-import java.util.Collections;
import javax.annotation.PostConstruct;
import javax.servlet.Filter;
@@ -35,6 +34,7 @@ import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSo
import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.DosFilter;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
+import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateAnonymousDownloadFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
@@ -83,6 +83,8 @@ import org.vaadin.spring.security.web.VaadinRedirectStrategy;
import org.vaadin.spring.security.web.authentication.VaadinAuthenticationSuccessHandler;
import org.vaadin.spring.security.web.authentication.VaadinUrlAuthenticationSuccessHandler;
+import com.google.common.collect.Lists;
+
/**
* All configurations related to SP authentication and authorization layer.
*
@@ -147,6 +149,12 @@ public class SecurityManagedConfiguration {
gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+ final HttpControllerPreAuthenticateAnonymousDownloadFilter controllerAnonymousDownloadFilter = new HttpControllerPreAuthenticateAnonymousDownloadFilter(
+ tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ controllerAnonymousDownloadFilter.setAuthenticationManager(authenticationManager());
+ controllerAnonymousDownloadFilter.setCheckForPrincipalChanges(true);
+ controllerAnonymousDownloadFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
HttpSecurity httpSec = http.csrf().disable().headers()
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.DENY)).contentTypeOptions()
.xssProtection().httpStrictTransportSecurity().and();
@@ -159,15 +167,17 @@ public class SecurityManagedConfiguration {
LOG.info(
"******************\n** Anonymous controller security enabled, should only use for developing purposes **\n******************");
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
- "controllerAnonymousFilter", "anonymous", Collections.singletonList(
- new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
+ "controllerAnonymousFilter", "anonymous",
+ Lists.newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS),
+ new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)));
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
httpSec.requestMatchers().antMatchers("/*/controller/v1/**", "/*/controller/artifacts/v1/**").and()
.securityContext().disable().anonymous().authenticationFilter(anoymousFilter);
} else {
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
- .addFilter(gatewaySecurityTokenFilter).antMatcher("/*/controller/**").anonymous().disable()
- .authorizeRequests().anyRequest().authenticated().and().exceptionHandling()
+ .addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
+ .antMatcher("/*/controller/**").anonymous().disable().authorizeRequests().anyRequest()
+ .authenticated().and().exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> response
.setStatus(HttpStatus.UNAUTHORIZED.value()))
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java
new file mode 100644
index 000000000..522444961
--- /dev/null
+++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandler.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.api;
+
+/**
+ * Interface declaration of the {@link ArtifactUrlHandler} which generates the
+ * URLs to specific artifacts.
+ *
+ */
+@FunctionalInterface
+public interface ArtifactUrlHandler {
+
+ /**
+ * Returns a generated download URL for a given artifact parameters for a
+ * specific protocol.
+ *
+ * @param controllerId
+ * the authenticated controller id
+ * @param softwareModuleId
+ * the softwareModuleId belonging to the artifact
+ * @param filename
+ * the filename of the artifact
+ * @param sha1Hash
+ * the sha1Hash of the artifact
+ * @param protocol
+ * the protocol the URL should be generated
+ * @return an URL for the given artifact parameters in a given protocol
+ */
+ String getUrl(String controllerId, final Long softwareModuleId, final String filename, final String sha1Hash,
+ final UrlProtocol protocol);
+}
diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/ArtifactUrlHandlerProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java
similarity index 75%
rename from hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/ArtifactUrlHandlerProperties.java
rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java
index 91c385fae..33fe8651e 100644
--- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/ArtifactUrlHandlerProperties.java
+++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java
@@ -6,13 +6,13 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
-package org.eclipse.hawkbit.util;
+package org.eclipse.hawkbit.api;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
- *
- *
+ * Artifact handler properties class for holding all supported protocols with
+ * host, ip, port and download pattern.
*/
@ConfigurationProperties("hawkbit.artifact.url")
public class ArtifactUrlHandlerProperties {
@@ -23,23 +23,14 @@ public class ArtifactUrlHandlerProperties {
private final Https https = new Https();
private final Coap coap = new Coap();
- /**
- * @return the http
- */
public Http getHttp() {
return http;
}
- /**
- * @return the https
- */
public Https getHttps() {
return https;
}
- /**
- * @return the coap
- */
public Coap getCoap() {
return coap;
}
@@ -66,9 +57,6 @@ public class ArtifactUrlHandlerProperties {
/**
* Interface for declaring common properties through all supported protocols
* pattern.
- *
- *
- *
*/
public interface ProtocolProperties {
/**
@@ -94,9 +82,6 @@ public class ArtifactUrlHandlerProperties {
/**
* Object to hold the properties for the HTTP protocol.
- *
- *
- *
*/
public static class Http implements ProtocolProperties {
private String hostname = LOCALHOST;
@@ -108,66 +93,38 @@ public class ArtifactUrlHandlerProperties {
*/
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
- /**
- * @return the hostname
- */
@Override
public String getHostname() {
return hostname;
}
- /**
- * @param hostname
- * the hostname to set
- */
public void setHostname(final String hostname) {
this.hostname = hostname;
}
- /**
- * @return the ip
- */
@Override
public String getIp() {
return ip;
}
- /**
- * @param ip
- * the ip to set
- */
public void setIp(final String ip) {
this.ip = ip;
}
- /**
- * @return the urlPattern
- */
@Override
public String getPattern() {
return pattern;
}
- /**
- * @param urlPattern
- * the urlPattern to set
- */
public void setPattern(final String urlPattern) {
this.pattern = urlPattern;
}
- /**
- * @return the port
- */
@Override
public String getPort() {
return port;
}
- /**
- * @param port
- * the port to set
- */
public void setPort(final String port) {
this.port = port;
}
@@ -175,9 +132,6 @@ public class ArtifactUrlHandlerProperties {
/**
* Object to hold the properties for the HTTP protocol.
- *
- *
- *
*/
public static class Https implements ProtocolProperties {
private String hostname = LOCALHOST;
@@ -189,66 +143,38 @@ public class ArtifactUrlHandlerProperties {
*/
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
- /**
- * @return the hostname
- */
@Override
public String getHostname() {
return hostname;
}
- /**
- * @param hostname
- * the hostname to set
- */
public void setHostname(final String hostname) {
this.hostname = hostname;
}
- /**
- * @return the ip
- */
@Override
public String getIp() {
return ip;
}
- /**
- * @param ip
- * the ip to set
- */
public void setIp(final String ip) {
this.ip = ip;
}
- /**
- * @return the urlPattern
- */
@Override
public String getPattern() {
return pattern;
}
- /**
- * @param urlPattern
- * the urlPattern to set
- */
public void setPattern(final String urlPattern) {
this.pattern = urlPattern;
}
- /**
- * @return the port
- */
@Override
public String getPort() {
return port;
}
- /**
- * @param port
- * the port to set
- */
public void setPort(final String port) {
this.port = port;
}
@@ -256,9 +182,6 @@ public class ArtifactUrlHandlerProperties {
/**
* Object to hold the properties for the HTTP protocol.
- *
- *
- *
*/
public static class Coap implements ProtocolProperties {
private String hostname = LOCALHOST;
@@ -270,68 +193,41 @@ public class ArtifactUrlHandlerProperties {
*/
private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}";
- /**
- * @return the hostname
- */
@Override
public String getHostname() {
return hostname;
}
- /**
- * @param hostname
- * the hostname to set
- */
public void setHostname(final String hostname) {
this.hostname = hostname;
}
- /**
- * @return the ip
- */
@Override
public String getIp() {
return ip;
}
- /**
- * @param ip
- * the ip to set
- */
public void setIp(final String ip) {
this.ip = ip;
}
- /**
- * @return the urlPattern
- */
@Override
public String getPattern() {
return pattern;
}
- /**
- * @param urlPattern
- * the urlPattern to set
- */
public void setPattern(final String urlPattern) {
this.pattern = urlPattern;
}
- /**
- * @return the port
- */
@Override
public String getPort() {
return port;
}
- /**
- * @param port
- * the port to set
- */
public void setPort(final String port) {
this.port = port;
}
}
+
}
diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandler.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java
similarity index 79%
rename from hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandler.java
rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java
index 8d4cfbc28..174086613 100644
--- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandler.java
+++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java
@@ -6,17 +6,15 @@
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
-package org.eclipse.hawkbit.util;
+package org.eclipse.hawkbit.api;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import org.eclipse.hawkbit.dmf.json.model.Artifact;
-import org.eclipse.hawkbit.repository.model.LocalArtifact;
+import org.eclipse.hawkbit.api.ArtifactUrlHandlerProperties.ProtocolProperties;
import org.eclipse.hawkbit.tenancy.TenantAware;
-import org.eclipse.hawkbit.util.ArtifactUrlHandlerProperties.ProtocolProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
@@ -24,8 +22,8 @@ import org.springframework.stereotype.Component;
import com.google.common.base.Strings;
/**
- *
- *
+ * Implementation for ArtifactUrlHandler for creating urls to download resource
+ * based on pattern.
*/
@Component
@EnableConfigurationProperties(ArtifactUrlHandlerProperties.class)
@@ -48,7 +46,9 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
private TenantAware tenantAware;
@Override
- public String getUrl(final String targetId, final LocalArtifact artifact, final Artifact.UrlProtocol protocol) {
+ public String getUrl(final String targetId, final Long softwareModuleId, final String filename,
+ final String sha1Hash, final UrlProtocol protocol) {
+
final String protocolString = protocol.name().toLowerCase();
final ProtocolProperties properties = urlHandlerProperties.getProperties(protocolString);
if (properties == null || properties.getPattern() == null) {
@@ -56,8 +56,8 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
}
String urlPattern = properties.getPattern();
- final Set> entrySet = getReplaceMap(targetId, artifact, protocolString, properties)
- .entrySet();
+ final Set> entrySet = getReplaceMap(targetId, softwareModuleId, filename, sha1Hash,
+ protocolString, properties).entrySet();
for (final Entry entry : entrySet) {
if (entry.getKey().equals(PORT_PLACEHOLDER)) {
urlPattern = urlPattern.replace(":{" + entry.getKey() + "}",
@@ -69,18 +69,18 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
return urlPattern;
}
- private Map getReplaceMap(final String targetId, final LocalArtifact artifact,
- final String protocol, final ProtocolProperties properties) {
+ private Map getReplaceMap(final String targetId, final Long softwareModuleId, final String filename,
+ final String sha1Hash, final String protocol, final ProtocolProperties properties) {
final Map replaceMap = new HashMap<>();
replaceMap.put(IP_PLACEHOLDER, properties.getIp());
replaceMap.put(HOSTNAME_PLACEHOLDER, properties.getHostname());
- replaceMap.put(ARTIFACT_FILENAME_PLACEHOLDER, artifact.getFilename());
- replaceMap.put(ARTIFACT_SHA1_PLACEHOLDER, artifact.getSha1Hash());
+ replaceMap.put(ARTIFACT_FILENAME_PLACEHOLDER, filename);
+ replaceMap.put(ARTIFACT_SHA1_PLACEHOLDER, sha1Hash);
replaceMap.put(PROTOCOL_PLACEHOLDER, protocol);
replaceMap.put(PORT_PLACEHOLDER, properties.getPort());
replaceMap.put(TENANT_PLACEHOLDER, tenantAware.getCurrentTenant());
replaceMap.put(TARGET_ID_PLACEHOLDER, targetId);
- replaceMap.put(SOFTWARE_MODULE_ID_PLACDEHOLDER, String.valueOf(artifact.getSoftwareModule().getId()));
+ replaceMap.put(SOFTWARE_MODULE_ID_PLACDEHOLDER, String.valueOf(softwareModuleId));
return replaceMap;
}
diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/UrlProtocol.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/UrlProtocol.java
new file mode 100644
index 000000000..77c23ad0d
--- /dev/null
+++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/UrlProtocol.java
@@ -0,0 +1,16 @@
+/**
+ * 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;
+
+/**
+ * Represented the supported protocols for artifact url's.
+ */
+public enum UrlProtocol {
+ COAP, HTTP, HTTPS
+}
diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java
index fb5ba29bb..402185be3 100644
--- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java
+++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationKey.java
@@ -30,40 +30,60 @@ public enum TenantConfigurationKey {
/**
* boolean value {@code true} {@code false}.
*/
- AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", "hawkbit.server.ddi.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
+ AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled",
+ "hawkbit.server.ddi.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(),
+ TenantConfigurationBooleanValidator.class),
/**
*
*/
- AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", "hawkbit.server.ddi.security.authentication.header.authority", String.class, Boolean.FALSE.toString(), TenantConfigurationStringValidator.class),
+ AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority",
+ "hawkbit.server.ddi.security.authentication.header.authority", String.class, Boolean.FALSE.toString(),
+ TenantConfigurationStringValidator.class),
/**
* boolean value {@code true} {@code false}.
*/
- AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", "hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
+ AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled",
+ "hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.class, Boolean.FALSE.toString(),
+ TenantConfigurationBooleanValidator.class),
/**
* boolean value {@code true} {@code false}.
*/
- AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", "hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
+ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled",
+ "hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.class, Boolean.FALSE.toString(),
+ TenantConfigurationBooleanValidator.class),
/**
* string value which holds the name of the security token key.
*/
- AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", "hawkbit.server.ddi.security.authentication.gatewaytoken.name", String.class, null, TenantConfigurationStringValidator.class),
+ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name",
+ "hawkbit.server.ddi.security.authentication.gatewaytoken.name", String.class, null,
+ TenantConfigurationStringValidator.class),
/**
* string value which holds the actual security-key of the gateway security
* token.
*/
- AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", "hawkbit.server.ddi.security.authentication.gatewaytoken.key", String.class, null, TenantConfigurationStringValidator.class),
+ AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key",
+ "hawkbit.server.ddi.security.authentication.gatewaytoken.key", String.class, null,
+ TenantConfigurationStringValidator.class),
/**
* string value which holds the polling time interval in the format HH:mm:ss
*/
- POLLING_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null, TenantConfigurationPollingDurationValidator.class),
+ POLLING_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null,
+ TenantConfigurationPollingDurationValidator.class),
/**
* string value which holds the polling time interval in the format HH:mm:ss
*/
- POLLING_OVERDUE_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null, TenantConfigurationPollingDurationValidator.class);
+ POLLING_OVERDUE_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null,
+ TenantConfigurationPollingDurationValidator.class),
+
+ /**
+ * boolean value {@code true} {@code false}.
+ */
+ ANONYMOUS_DOWNLOAD_MODE_ENABLED("anonymous.download.enabled", "hawkbit.server.download.anonymous.enabled",
+ Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class);
private final String keyName;
private final String defaultKeyName;
diff --git a/hawkbit-dmf-amqp/pom.xml b/hawkbit-dmf-amqp/pom.xml
index 2fded8559..127103b91 100644
--- a/hawkbit-dmf-amqp/pom.xml
+++ b/hawkbit-dmf-amqp/pom.xml
@@ -25,6 +25,11 @@
org.eclipse.hawkbit
hawkbit-repository
${project.version}
+
+
+ org.eclipse.hawkbit
+ hawkbit-core
+ ${project.version}
org.eclipse.hawkbit
diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java
index 8f19d9f02..9d120c17b 100644
--- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java
+++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java
@@ -13,12 +13,14 @@ import java.util.List;
import javax.annotation.PostConstruct;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
+import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousDownload;
+import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
@@ -90,6 +92,11 @@ public class AmqpControllerAuthentfication {
tenantConfigurationManagement, controllerManagement, tenantAware, systemSecurityContext);
filterChain.add(securityTokenFilter);
+ final ControllerPreAuthenticatedAnonymousDownload anonymousDownloadFilter = new ControllerPreAuthenticatedAnonymousDownload(
+ tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ filterChain.add(anonymousDownloadFilter);
+
+ filterChain.add(new ControllerPreAuthenticatedAnonymousFilter(ddiSecruityProperties));
filterChain.add(new CoapAnonymousPreAuthenticatedFilter());
}
@@ -100,7 +107,7 @@ public class AmqpControllerAuthentfication {
* the authentication request object
* @return the authentfication object
*/
- public Authentication doAuthenticate(final TenantSecruityToken secruityToken) {
+ public Authentication doAuthenticate(final TenantSecurityToken secruityToken) {
PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(null, null);
for (final PreAuthenficationFilter filter : filterChain) {
final PreAuthenticatedAuthenticationToken authenticationRest = createAuthentication(filter, secruityToken);
@@ -115,7 +122,7 @@ public class AmqpControllerAuthentfication {
}
private static PreAuthenticatedAuthenticationToken createAuthentication(final PreAuthenficationFilter filter,
- final TenantSecruityToken secruityToken) {
+ final TenantSecurityToken secruityToken) {
if (!filter.isEnable(secruityToken)) {
return null;
diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java
index b9e6fe9da..19e0cbadf 100644
--- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java
+++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java
@@ -14,6 +14,8 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
+import org.eclipse.hawkbit.api.ArtifactUrlHandler;
+import org.eclipse.hawkbit.api.UrlProtocol;
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
@@ -25,7 +27,6 @@ import org.eclipse.hawkbit.eventbus.EventSubscriber;
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
-import org.eclipse.hawkbit.util.ArtifactUrlHandler;
import org.eclipse.hawkbit.util.IpUtil;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
@@ -152,12 +153,16 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
final Artifact artifact = new Artifact();
+
artifact.getUrls().put(Artifact.UrlProtocol.COAP,
- artifactUrlHandler.getUrl(targetId, localArtifact, Artifact.UrlProtocol.COAP));
+ artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
+ localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.COAP));
artifact.getUrls().put(Artifact.UrlProtocol.HTTP,
- artifactUrlHandler.getUrl(targetId, localArtifact, Artifact.UrlProtocol.HTTP));
+ artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
+ localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTP));
artifact.getUrls().put(Artifact.UrlProtocol.HTTPS,
- artifactUrlHandler.getUrl(targetId, localArtifact, Artifact.UrlProtocol.HTTPS));
+ artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
+ localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTPS));
artifact.setFilename(localArtifact.getFilename());
artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), null));
diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java
index cfd5485a6..41e70f91f 100644
--- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java
+++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java
@@ -28,7 +28,8 @@ import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus;
import org.eclipse.hawkbit.dmf.json.model.Artifact;
import org.eclipse.hawkbit.dmf.json.model.ArtifactHash;
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
@@ -157,25 +158,28 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
private Message handleAuthentifiactionMessage(final Message message) {
final DownloadResponse authentificationResponse = new DownloadResponse();
final MessageProperties messageProperties = message.getMessageProperties();
- final TenantSecruityToken secruityToken = convertMessage(message, TenantSecruityToken.class);
- final String sha1 = secruityToken.getSha1();
+ final TenantSecurityToken secruityToken = convertMessage(message, TenantSecurityToken.class);
+ final FileResource fileResource = secruityToken.getFileResource();
try {
SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken));
- final LocalArtifact localArtifact = artifactManagement
- .findFirstLocalArtifactsBySHA1(secruityToken.getSha1());
+
+ final LocalArtifact localArtifact = findLocalArtifactByFileResource(fileResource);
+
if (localArtifact == null) {
throw new EntityNotFoundException();
}
// check action for this download purposes, the method will throw an
// EntityNotFoundException in case the controller is not allowed to
- // download this file
- // because it's not assigned to an action and not assigned to this
- // controller.
- final Action action = controllerManagement.getActionForDownloadByTargetAndSoftwareModule(
- secruityToken.getControllerId(), localArtifact.getSoftwareModule());
- LOG.info("Found action for download authentication request action: {}, sha1: {}", action,
- secruityToken.getSha1());
+ // download this file because it's not assigned to an action and not
+ // assigned to this controller. Otherwise no controllerId is set =
+ // anonymous download
+ if (secruityToken.getControllerId() != null) {
+ final Action action = controllerManagement.getActionForDownloadByTargetAndSoftwareModule(
+ secruityToken.getControllerId(), localArtifact.getSoftwareModule());
+ LOG.info("Found action for download authentication request action: {}, resource: {}", action,
+ secruityToken.getFileResource());
+ }
final Artifact artifact = convertDbArtifact(artifactManagement.loadLocalArtifactBinary(localArtifact));
if (artifact == null) {
@@ -183,7 +187,9 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
}
authentificationResponse.setArtifact(artifact);
final String downloadId = UUID.randomUUID().toString();
- final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, sha1);
+ // SHA1 key is set, download by SHA1
+ final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1,
+ localArtifact.getSha1Hash());
cache.put(downloadId, downloadCache);
authentificationResponse
.setDownloadUrl(UriComponentsBuilder.fromUri(hostnameResolver.resolveHostname().toURI())
@@ -198,7 +204,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
authentificationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
authentificationResponse.setMessage("Building download URI failed");
} catch (final EntityNotFoundException e) {
- final String errorMessage = "Artifact with sha1 " + sha1 + "not found ";
+ final String errorMessage = "Artifact for resource " + fileResource + "not found ";
LOG.warn(errorMessage, e);
authentificationResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
authentificationResponse.setMessage(errorMessage);
@@ -207,6 +213,21 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
return getMessageConverter().toMessage(authentificationResponse, messageProperties);
}
+ private LocalArtifact findLocalArtifactByFileResource(final FileResource fileResource) {
+ if (fileResource.getSha1() != null) {
+ return artifactManagement.findFirstLocalArtifactsBySHA1(fileResource.getSha1());
+ } else if (fileResource.getFilename() != null) {
+ return artifactManagement.findLocalArtifactByFilename(fileResource.getFilename()).stream().findFirst()
+ .orElse(null);
+ } else if (fileResource.getSoftwareModuleFilenameResource() != null) {
+ return artifactManagement
+ .findByFilenameAndSoftwareModule(fileResource.getSoftwareModuleFilenameResource().getFilename(),
+ fileResource.getSoftwareModuleFilenameResource().getSoftwareModuleId())
+ .stream().findFirst().orElse(null);
+ }
+ return null;
+ }
+
private static Artifact convertDbArtifact(final DbArtifact dbArtifact) {
final Artifact artifact = new Artifact();
artifact.setSize(dbArtifact.getSize());
diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/ArtifactUrlHandler.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/ArtifactUrlHandler.java
deleted file mode 100644
index f477da03a..000000000
--- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/util/ArtifactUrlHandler.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.hawkbit.util;
-
-import org.eclipse.hawkbit.dmf.json.model.Artifact;
-import org.eclipse.hawkbit.repository.model.LocalArtifact;
-
-/**
- * Interface declaration of the {@link ArtifactUrlHandler} which generates the
- * URLs to specific artifacts.
- *
- */
-@FunctionalInterface
-public interface ArtifactUrlHandler {
-
- /**
- * Returns a generated URL for a given artifact for a specific protocol.
- *
- * @param controllerId
- * the authentifacted controller id
- * @param localArtifact
- * the artifact to retrieve a URL to
- * @param protocol
- * the protocol the URL should be generated
- * @return an URL for the given artifact in a given protocol
- */
- String getUrl(String controllerId, LocalArtifact localArtifact, final Artifact.UrlProtocol protocol);
-
-}
diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java
index 66527727a..881260579 100644
--- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java
+++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java
@@ -19,12 +19,14 @@ import static org.mockito.Mockito.when;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
+import org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.Anonymous;
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.security.SystemSecurityContext;
@@ -79,8 +81,14 @@ public class AmqpControllerAuthenticationTest {
final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class);
final Rp rp = mock(Rp.class);
+ final org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication ddiAuthentication = mock(
+ org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.class);
+ final Anonymous anonymous = mock(Anonymous.class);
when(secruityProperties.getRp()).thenReturn(rp);
when(rp.getSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d");
+ when(secruityProperties.getAuthentication()).thenReturn(ddiAuthentication);
+ when(ddiAuthentication.getAnonymous()).thenReturn(anonymous);
+ when(anonymous.isEnabled()).thenReturn(false);
authenticationManager.setSecruityProperties(secruityProperties);
tenantConfigurationManagement = mock(TenantConfigurationManagement.class);
@@ -105,7 +113,8 @@ public class AmqpControllerAuthenticationTest {
@Test
@Description("Tests authentication manager without principal")
public void testAuthenticationeBadCredantialsWithoutPricipal() {
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
+ FileResource.sha1("12345"));
try {
authenticationManager.doAuthenticate(securityToken);
fail("BadCredentialsException was excepeted since principal was missing");
@@ -118,11 +127,12 @@ public class AmqpControllerAuthenticationTest {
@Test
@Description("Tests authentication manager without wrong credential")
public void testAuthenticationBadCredantialsWithWrongCredential() {
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
+ FileResource.sha1("12345"));
when(tenantConfigurationManagement.getConfigurationValue(
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
.thenReturn(CONFIG_VALUE_TRUE);
- securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
+ securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
try {
authenticationManager.doAuthenticate(securityToken);
fail("BadCredentialsException was excepeted due to wrong credential");
@@ -135,11 +145,12 @@ public class AmqpControllerAuthenticationTest {
@Test
@Description("Tests authentication successfull")
public void testSuccessfullAuthentication() {
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
+ FileResource.sha1("12345"));
when(tenantConfigurationManagement.getConfigurationValue(
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
.thenReturn(CONFIG_VALUE_TRUE);
- securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
+ securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
final Authentication authentication = authenticationManager.doAuthenticate(securityToken);
assertThat(authentication).isNotNull();
}
@@ -149,7 +160,8 @@ public class AmqpControllerAuthenticationTest {
public void testAuthenticationMessageBadCredantialsWithoutPricipal() {
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
+ FileResource.sha1("12345"));
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
messageProperties);
@@ -167,11 +179,12 @@ public class AmqpControllerAuthenticationTest {
@Description("Tests authentication message without wrong credential")
public void testAuthenticationMessageBadCredantialsWithWrongCredential() {
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
+ FileResource.sha1("12345"));
when(tenantConfigurationManagement.getConfigurationValue(
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
.thenReturn(CONFIG_VALUE_TRUE);
- securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
+ securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
messageProperties);
@@ -189,11 +202,12 @@ public class AmqpControllerAuthenticationTest {
@Description("Tests authentication message successfull")
public void testSuccessfullMessageAuthentication() {
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
+ FileResource.sha1("12345"));
when(tenantConfigurationManagement.getConfigurationValue(
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
.thenReturn(CONFIG_VALUE_TRUE);
- securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
+ securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
messageProperties);
diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java
index 46ddd35cc..f2c3d254c 100644
--- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java
+++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
@@ -25,6 +26,7 @@ import java.util.List;
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
import org.eclipse.hawkbit.TestDataUtil;
+import org.eclipse.hawkbit.api.ArtifactUrlHandler;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
@@ -36,7 +38,6 @@ import org.eclipse.hawkbit.repository.model.Artifact;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
-import org.eclipse.hawkbit.util.ArtifactUrlHandler;
import org.eclipse.hawkbit.util.IpUtil;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
@@ -77,7 +78,8 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
amqpMessageDispatcherService.setAmqpSenderService(senderService);
final ArtifactUrlHandler artifactUrlHandlerMock = Mockito.mock(ArtifactUrlHandler.class);
- when(artifactUrlHandlerMock.getUrl(anyString(), any(), anyObject())).thenReturn("http://mockurl");
+ when(artifactUrlHandlerMock.getUrl(anyString(), anyLong(), anyString(), anyString(), anyObject()))
+ .thenReturn("http://mockurl");
amqpMessageDispatcherService.setArtifactUrlHandler(artifactUrlHandlerMock);
diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java
index 9d6ae3ba7..930ca02ad 100644
--- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java
+++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java
@@ -34,7 +34,8 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
import org.eclipse.hawkbit.dmf.json.model.ActionStatus;
import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus;
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
import org.eclipse.hawkbit.repository.ArtifactManagement;
import org.eclipse.hawkbit.repository.ControllerManagement;
@@ -263,7 +264,7 @@ public class AmqpMessageHandlerServiceTest {
@Description("Tests that an download request is denied for an artifact which does not exists")
public void authenticationRequestDeniedForArtifactWhichDoesNotExists() {
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, "123", "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
messageProperties);
@@ -282,7 +283,7 @@ public class AmqpMessageHandlerServiceTest {
@Description("Tests that an download request is denied for an artifact which is not assigned to the requested target")
public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() {
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, "123", "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
messageProperties);
@@ -306,7 +307,7 @@ public class AmqpMessageHandlerServiceTest {
@Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target")
public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException {
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
- final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, "123", "12345");
+ final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
messageProperties);
diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java
index e7ba06d19..bfc560c38 100644
--- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java
+++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java
@@ -15,7 +15,8 @@ import org.eclipse.hawkbit.AmqpTestConfiguration;
import org.eclipse.hawkbit.RepositoryApplicationConfiguration;
import org.eclipse.hawkbit.TestConfiguration;
import org.eclipse.hawkbit.TestDataUtil;
-import org.eclipse.hawkbit.dmf.json.model.Artifact;
+import org.eclipse.hawkbit.api.ArtifactUrlHandler;
+import org.eclipse.hawkbit.api.UrlProtocol;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
@@ -30,8 +31,7 @@ import ru.yandex.qatools.allure.annotations.Features;
import ru.yandex.qatools.allure.annotations.Stories;
/**
- *
- *
+ * Tests for creating urls to download artifacts.
*/
@Features("Component Tests - Artifact URL Handler")
@Stories("Test to generate the artifact download URL")
@@ -45,6 +45,9 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
private TenantAware tenantAware;
private LocalArtifact localArtifact;
private final String controllerId = "Test";
+ private String fileName;
+ private Long softwareModuleId;
+ private String sha1Hash;
@Before
public void setup() {
@@ -53,12 +56,18 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
final SoftwareModule module = dsA.getModules().iterator().next();
localArtifact = (LocalArtifact) TestDataUtil.generateArtifacts(artifactManagement, module.getId()).stream()
.findAny().get();
+ softwareModuleId = localArtifact.getSoftwareModule().getId();
+ fileName = localArtifact.getFilename();
+ sha1Hash = localArtifact.getSha1Hash();
+
}
@Test
@Description("Tests the generation of http download url.")
public void testHttpUrl() {
- final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTP);
+
+ final String url = urlHandlerProperties.getUrl(controllerId, softwareModuleId, fileName, sha1Hash,
+ UrlProtocol.HTTP);
assertEquals("http is build incorrect",
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
@@ -69,7 +78,8 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
@Test
@Description("Tests the generation of https download url.")
public void testHttpsUrl() {
- final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTPS);
+ final String url = urlHandlerProperties.getUrl(controllerId, softwareModuleId, fileName, sha1Hash,
+ UrlProtocol.HTTPS);
assertEquals("https is build incorrect",
"https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
@@ -80,7 +90,8 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
@Test
@Description("Tests the generation of coap download url.")
public void testCoapUrl() {
- final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.COAP);
+ final String url = urlHandlerProperties.getUrl(controllerId, softwareModuleId, fileName, sha1Hash,
+ UrlProtocol.COAP);
assertEquals("coap is build incorrect", "coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/"
+ controllerId + "/sha1/" + localArtifact.getSha1Hash(), url);
diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecruityToken.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecruityToken.java
deleted file mode 100644
index 351684f5e..000000000
--- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecruityToken.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- */
-package org.eclipse.hawkbit.dmf.json.model;
-
-import java.util.Map;
-import java.util.TreeMap;
-
-import com.fasterxml.jackson.annotation.JsonCreator;
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * JSON representation to authenticate a tenant.
- *
- *
- *
- */
-
-@JsonInclude(Include.NON_NULL)
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class TenantSecruityToken {
-
- public static final String AUTHORIZATION_HEADER = "Authorization";
- public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization";
- public static final String COAP_TOKEN_VALUE = "CoapToken";
-
- @JsonProperty
- private final String tenant;
- @JsonProperty
- private final String controllerId;
- @JsonProperty(required = false)
- private Map headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
- @JsonProperty(required = false)
- private final String sha1;
-
- /**
- * Constructor.
- *
- * @param tenant
- * the tenant for the security token
- * @param controllerId
- * the ID of the controller for the security token
- * @param sha1
- * the sha1 of authentication
- */
- @JsonCreator
- public TenantSecruityToken(@JsonProperty("tenant") final String tenant,
- @JsonProperty("controllerId") final String controllerId, @JsonProperty("sha1") final String sha1) {
- this.tenant = tenant;
- this.controllerId = controllerId;
- this.sha1 = sha1;
- }
-
- public String getTenant() {
- return tenant;
- }
-
- public String getControllerId() {
- return controllerId;
- }
-
- public Map getHeaders() {
- return headers;
- }
-
- public String getSha1() {
- return sha1;
- }
-
- /**
- * Gets a header value.
- *
- * @param name
- * of header
- * @return the value
- */
- public String getHeader(final String name) {
- return headers.get(name);
- }
-
- public void setHeaders(final Map headers) {
- this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
- this.headers.putAll(headers);
- }
-
-}
diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java
new file mode 100644
index 000000000..ccc3a5b42
--- /dev/null
+++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java
@@ -0,0 +1,226 @@
+/**
+ * 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.dmf.json.model;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * JSON representation to authenticate a tenant.
+ */
+
+@JsonInclude(Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class TenantSecurityToken {
+
+ public static final String AUTHORIZATION_HEADER = "Authorization";
+ public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization";
+ public static final String COAP_TOKEN_VALUE = "CoapToken";
+
+ @JsonProperty
+ private final String tenant;
+ @JsonProperty
+ private final String controllerId;
+ @JsonProperty(required = false)
+ private Map headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+
+ @JsonProperty(required = false)
+ private final FileResource fileResource;
+
+ /**
+ * Constructor.
+ *
+ * @param tenant
+ * the tenant for the security token
+ * @param controllerId
+ * the ID of the controller for the security token
+ * @param fileResource
+ * the file to obtain
+ */
+ @JsonCreator
+ public TenantSecurityToken(@JsonProperty("tenant") final String tenant,
+ @JsonProperty("controllerId") final String controllerId,
+ @JsonProperty("fileResource") final FileResource fileResource) {
+ this.tenant = tenant;
+ this.controllerId = controllerId;
+ this.fileResource = fileResource;
+ }
+
+ public String getTenant() {
+ return tenant;
+ }
+
+ public String getControllerId() {
+ return controllerId;
+ }
+
+ public Map getHeaders() {
+ return headers;
+ }
+
+ public FileResource getFileResource() {
+ return fileResource;
+ }
+
+ /**
+ * Gets a header value.
+ *
+ * @param name
+ * of header
+ * @return the value
+ */
+ public String getHeader(final String name) {
+ return headers.get(name);
+ }
+
+ public void setHeaders(final Map headers) {
+ this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ this.headers.putAll(headers);
+ }
+
+ /**
+ * File resource descriptor which is used to ask for the resource to
+ * download e.g. The lookup of the file can be different e.g. by SHA1 hash
+ * or by filename.
+ */
+ @JsonInclude(Include.NON_NULL)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class FileResource {
+ @JsonProperty(required = false)
+ private String sha1;
+ @JsonProperty(required = false)
+ private String filename;
+ @JsonProperty(required = false)
+ private SoftwareModuleFilenameResource softwareModuleFilenameResource;
+
+ public String getSha1() {
+ return sha1;
+ }
+
+ public void setSha1(final String sha1) {
+ this.sha1 = sha1;
+ }
+
+ public String getFilename() {
+ return filename;
+ }
+
+ public void setFilename(final String filename) {
+ this.filename = filename;
+ }
+
+ public SoftwareModuleFilenameResource getSoftwareModuleFilenameResource() {
+ return softwareModuleFilenameResource;
+ }
+
+ public void setSoftwareModuleFilenameResource(
+ final SoftwareModuleFilenameResource softwareModuleFilenameResource) {
+ this.softwareModuleFilenameResource = softwareModuleFilenameResource;
+ }
+
+ /**
+ * factory method to create a file resource for an SHA1 lookup.
+ *
+ * @param sha1
+ * the SHA1 key of the file to obtain
+ * @return the {@link FileResource} with SHA1 key set
+ */
+ public static FileResource sha1(final String sha1) {
+ final FileResource resource = new FileResource();
+ resource.sha1 = sha1;
+ return resource;
+ }
+
+ /**
+ * factory method to create a file resource for an filename lookup.
+ *
+ * @param filename
+ * the filename of the file to obtain
+ * @return the {@link FileResource} with filename set
+ */
+ public static FileResource filename(final String filename) {
+ final FileResource resource = new FileResource();
+ resource.filename = filename;
+ return resource;
+ }
+
+ /**
+ * factory method to create a file resource for an softwaremodule +
+ * filename lookup, because an filename is not globally unique but
+ * within a softwaremodule.
+ *
+ * @param softwareModuleId
+ * the ID of the software module which contains the artifact
+ * @param filename
+ * the name of file to obtain within the software module
+ * @return the {@link FileResource} with artifactId set
+ */
+ public static FileResource softwareModuleFilename(final Long softwareModuleId, final String filename) {
+ final FileResource resource = new FileResource();
+ resource.softwareModuleFilenameResource = new SoftwareModuleFilenameResource(softwareModuleId, filename);
+ return resource;
+ }
+
+ @Override
+ public String toString() {
+ return "FileResource [sha1=" + sha1 + ", filename=" + filename + "]";
+ }
+
+ /**
+ * Inner class which holds the pointer to an artifact based on the
+ * softwaremoduleId and the filename.
+ */
+ @JsonInclude(Include.NON_NULL)
+ @JsonIgnoreProperties(ignoreUnknown = true)
+ public static class SoftwareModuleFilenameResource {
+ @JsonProperty(required = false)
+ private Long softwareModuleId;
+ @JsonProperty(required = false)
+ private String filename;
+
+ /**
+ * Constructor.
+ *
+ * @param softwareModuleId
+ * the ID of the softwaremodule
+ * @param filename
+ * the name of the file of the artifact within the
+ * softwaremodule
+ */
+ @JsonCreator
+ public SoftwareModuleFilenameResource(@JsonProperty("softwareModuleId") final Long softwareModuleId,
+ @JsonProperty("filename") final String filename) {
+ this.softwareModuleId = softwareModuleId;
+ this.filename = filename;
+ }
+
+ public Long getSoftwareModuleId() {
+ return softwareModuleId;
+ }
+
+ public String getFilename() {
+ return filename;
+ }
+
+ public void setSoftwareModuleId(final Long softwareModuleId) {
+ this.softwareModuleId = softwareModuleId;
+ }
+
+ public void setFilename(final String filename) {
+ this.filename = filename;
+ }
+ }
+ }
+}
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java
index adb2858b9..0e67489ea 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java
+++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java
@@ -9,6 +9,8 @@
package org.eclipse.hawkbit.security;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Map;
import javax.servlet.FilterChain;
@@ -16,14 +18,19 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
+import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.util.AntPathMatcher;
import com.google.common.collect.Iterators;
@@ -79,14 +86,6 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
pathExtractor = new AntPathMatcher();
}
- /*
- * (non-Javadoc)
- *
- * @see org.springframework.security.web.authentication.preauth.
- * AbstractPreAuthenticatedProcessingFilter
- * #doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
- * javax.servlet.FilterChain)
- */
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
@@ -96,7 +95,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
return;
}
- final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables((HttpServletRequest) request);
+ final TenantSecurityToken secruityToken = createTenantSecruityTokenVariables((HttpServletRequest) request);
if (secruityToken == null) {
chain.doFilter(request, response);
return;
@@ -112,6 +111,18 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
protected abstract PreAuthenficationFilter createControllerAuthenticationFilter();
+ @Override
+ protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response,
+ final Authentication authResult) {
+ final Collection authorities = new ArrayList<>();
+ authorities.addAll(authResult.getAuthorities());
+ authorities.addAll(abstractControllerAuthenticationFilter.getSuccessfulAuthenticationAuthorities());
+ final PreAuthenticatedAuthenticationToken authTokenWithGrantedAuthorities = new PreAuthenticatedAuthenticationToken(
+ authResult.getPrincipal(), authResult.getCredentials(), authorities);
+ authTokenWithGrantedAuthorities.setDetails(authResult.getDetails());
+ super.successfulAuthentication(request, response, authTokenWithGrantedAuthorities);
+ }
+
/**
* Extracts tenant and controllerId from the request URI as path variables.
*
@@ -121,7 +132,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
* request does not match the pattern and no variables could be
* extracted
*/
- protected TenantSecruityToken createTenantSecruityTokenVariables(final HttpServletRequest request) {
+ protected TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request) {
final String requestURI = request.getRequestURI();
if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) {
@@ -153,9 +164,9 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
}
}
- private TenantSecruityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
+ private TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
final String tenant, final String controllerId) {
- final TenantSecruityToken secruityToken = new TenantSecruityToken(tenant, controllerId, "");
+ final TenantSecurityToken secruityToken = new TenantSecurityToken(tenant, controllerId, FileResource.sha1(""));
final UnmodifiableIterator forEnumeration = Iterators.forEnumeration(request.getHeaderNames());
forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header)));
return secruityToken;
@@ -163,7 +174,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
@Override
protected Object getPreAuthenticatedPrincipal(final HttpServletRequest request) {
- final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables(request);
+ final TenantSecurityToken secruityToken = createTenantSecruityTokenVariables(request);
if (secruityToken == null) {
return null;
}
@@ -172,7 +183,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
@Override
protected Object getPreAuthenticatedCredentials(final HttpServletRequest request) {
- final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables(request);
+ final TenantSecurityToken secruityToken = createTenantSecruityTokenVariables(request);
if (secruityToken == null) {
return null;
}
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
new file mode 100644
index 000000000..40fd1e555
--- /dev/null
+++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
@@ -0,0 +1,47 @@
+/**
+ * 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.security;
+
+import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
+import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.tenancy.TenantAware;
+
+/**
+ * An pre-authenticated processing filter which add the
+ * {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE_ANONYMOUS} to the
+ * security context in case the anonymous download is allowed through
+ * configuration.
+ */
+public class HttpControllerPreAuthenticateAnonymousDownloadFilter extends AbstractHttpControllerAuthenticationFilter {
+
+ /**
+ * Constructor.
+ *
+ * @param tenantConfigurationManagement
+ * the system management service to retrieve configuration
+ * properties
+ * @param tenantAware
+ * the tenant aware service to get configuration for the specific
+ * tenant
+ * @param systemSecurityContext
+ * the system security context
+ */
+ public HttpControllerPreAuthenticateAnonymousDownloadFilter(
+ final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
+ final SystemSecurityContext systemSecurityContext) {
+ super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ }
+
+ @Override
+ protected PreAuthenficationFilter createControllerAuthenticationFilter() {
+ return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware,
+ systemSecurityContext);
+ }
+
+}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java
index a5ee019dc..145287fbf 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java
@@ -321,7 +321,8 @@ public class ArtifactManagement {
}
boolean artifactIsOnlyUsedByOneSoftwareModule = true;
- for (LocalArtifact lArtifact : localArtifactRepository.findByGridFsFileName(existing.getGridFsFileName())) {
+ for (final LocalArtifact lArtifact : localArtifactRepository
+ .findByGridFsFileName(existing.getGridFsFileName())) {
if (!lArtifact.getSoftwareModule().isDeleted()
&& lArtifact.getSoftwareModule().getId() != existing.getSoftwareModule().getId()) {
artifactIsOnlyUsedByOneSoftwareModule = false;
@@ -403,7 +404,7 @@ public class ArtifactManagement {
* if file could not be found in store
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR
- + SpringEvalExpressions.IS_CONTROLLER)
+ + SpringEvalExpressions.HAS_CONTROLLER_DOWNLOAD)
public DbArtifact loadLocalArtifactBinary(@NotNull final LocalArtifact artifact) {
final DbArtifact result = artifactRepository.getArtifactBySha1(artifact.getGridFsFileName());
if (result == null) {
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java
index 8b1df00da..85e707652 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DistributionSetAssignmentResult.java
@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository;
+import java.util.Collections;
import java.util.List;
import org.eclipse.hawkbit.repository.model.AssignmentResult;
@@ -19,7 +20,7 @@ import org.eclipse.hawkbit.repository.model.Target;
* how much of the assignments had already been existed.
*
*/
-public class DistributionSetAssignmentResult extends AssignmentResult {
+public class DistributionSetAssignmentResult extends AssignmentResult {
private final List assignedTargets;
private final List actions;
@@ -45,16 +46,14 @@ public class DistributionSetAssignmentResult extends AssignmentResult {
*/
public DistributionSetAssignmentResult(final List assignedTargets, final int assigned,
final int alreadyAssigned, final List actions, final TargetManagement targetManagement) {
- super(assigned, alreadyAssigned);
+ super(assigned, alreadyAssigned, 0, Collections.emptyList(), Collections.emptyList());
this.assignedTargets = assignedTargets;
this.actions = actions;
this.targetManagement = targetManagement;
}
-
- /**
- * @return the assignedTargets
- */
- public List getAssignedTargets() {
+
+ @Override
+ public List getAssignedEntity() {
return targetManagement.findTargetByControllerID(assignedTargets);
}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java
index c6eab402a..384353b8e 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java
@@ -259,7 +259,7 @@ public class SoftwareManagement {
}
/**
- * retrieves {@link SoftwareModule}s by their name AND version.
+ * retrieves {@link SoftwareModule} by their name AND version AND type..
*
* @param name
* of the {@link SoftwareModule}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/AssignmentResult.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/AssignmentResult.java
index eda0bb9bd..2dea94f33 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/AssignmentResult.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/AssignmentResult.java
@@ -8,15 +8,21 @@
*/
package org.eclipse.hawkbit.repository.model;
+import java.util.List;
+
/**
* Generic assignment result bean.
*
*/
-public class AssignmentResult {
+public class AssignmentResult {
private final int total;
private final int assigned;
private final int alreadyAssigned;
+
+ private final int unassigned;
+ private final List assignedEntity;
+ private final List unassignedEntity;
/**
* Constructor.
@@ -24,25 +30,47 @@ public class AssignmentResult {
* @param assigned
* is the number of newly assigned elements.
* @param alreadyAssigned
- * is the number of already assigned elements.
+ * number of already assigned/ignored elements
+ * @param unassigned
+ * number of newly assigned elements
+ * @param assignedEntity
+ * {@link List} of assigned entity.
+ * @param unassignedEntity
+ * {@link List} of unassigned entity.
*/
- public AssignmentResult(final int assigned, final int alreadyAssigned) {
- super();
+ public AssignmentResult(final int assigned, final int alreadyAssigned, final int unassigned,
+ final List assignedEntity, final List unassignedEntity) {
this.assigned = assigned;
this.alreadyAssigned = alreadyAssigned;
total = assigned + alreadyAssigned;
+ this.unassigned = unassigned;
+ this.assignedEntity = assignedEntity;
+ this.unassignedEntity = unassignedEntity;
}
-
+
public int getAssigned() {
return assigned;
}
-
+
public int getTotal() {
return total;
}
-
+
public int getAlreadyAssigned() {
return alreadyAssigned;
}
+
+
+ public int getUnassigned() {
+ return unassigned;
+ }
+
+ public List getAssignedEntity() {
+ return assignedEntity;
+ }
+
+ public List getUnassignedEntity() {
+ return unassignedEntity;
+ }
}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java
index 7b2e637b9..67a99506c 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetMetadata.java
@@ -8,10 +8,6 @@
*/
package org.eclipse.hawkbit.repository.model;
-import java.io.Serializable;
-
-import javax.persistence.Basic;
-import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@@ -29,63 +25,31 @@ import javax.persistence.Table;
@IdClass(DsMetadataCompositeKey.class)
@Entity
@Table(name = "sp_ds_metadata")
-public class DistributionSetMetadata implements Serializable {
+public class DistributionSetMetadata extends MetaData {
private static final long serialVersionUID = 1L;
- @Id
- @Column(name = "meta_key", length = 128)
- private String key;
-
- @Column(name = "meta_value", length = 4000)
- @Basic
- private String value;
-
@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_ds"))
private DistributionSet distributionSet;
public DistributionSetMetadata() {
- // Default constructor for JPA.
+ // default public constructor for JPA
}
- /**
- * Parameter constructor.
- *
- * @param key
- * @param distributionSet
- * @param value
- */
public DistributionSetMetadata(final String key, final DistributionSet distributionSet, final String value) {
- this.key = key;
+ super(key, value);
this.distributionSet = distributionSet;
- this.value = value;
}
public DsMetadataCompositeKey getId() {
- return new DsMetadataCompositeKey(distributionSet, key);
- }
-
- public String getKey() {
- return key;
- }
-
- public void setKey(final String key) {
- this.key = key;
+ return new DsMetadataCompositeKey(distributionSet, getKey());
}
public void setDistributionSet(final DistributionSet distributionSet) {
this.distributionSet = distributionSet;
}
- public String getValue() {
- return value;
- }
-
- public void setValue(final String value) {
- this.value = value;
- }
-
public DistributionSet getDistributionSet() {
return distributionSet;
}
@@ -93,21 +57,14 @@ public class DistributionSetMetadata implements Serializable {
@Override
public int hashCode() {
final int prime = 31;
- int result = 1;
- result = prime * result + (distributionSet == null ? 0 : distributionSet.hashCode());
- result = prime * result + (key == null ? 0 : key.hashCode());
+ int result = super.hashCode();
+ result = prime * result + ((distributionSet == null) ? 0 : distributionSet.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof DistributionSetMetadata)) {
+ if (!super.equals(obj)) {
return false;
}
final DistributionSetMetadata other = (DistributionSetMetadata) obj;
@@ -118,14 +75,6 @@ public class DistributionSetMetadata implements Serializable {
} else if (!distributionSet.equals(other.distributionSet)) {
return false;
}
- if (key == null) {
- if (other.key != null) {
- return false;
- }
- } else if (!key.equals(other.key)) {
- return false;
- }
return true;
}
-
}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java
index eddd10c1b..f1f3b1519 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/DistributionSetTagAssignmentResult.java
@@ -14,11 +14,8 @@ import java.util.List;
* Result object for {@link DistributionSetTag} assignments.
*
*/
-public class DistributionSetTagAssignmentResult extends AssignmentResult {
+public class DistributionSetTagAssignmentResult extends AssignmentResult {
- private final int unassigned;
- private final List assignedDs;
- private final List unassignedDs;
private final DistributionSetTag distributionSetTag;
/**
@@ -40,27 +37,13 @@ public class DistributionSetTagAssignmentResult extends AssignmentResult {
public DistributionSetTagAssignmentResult(final int alreadyAssigned, final int assigned, final int unassigned,
final List assignedDs, final List unassignedDs,
final DistributionSetTag distributionSetTag) {
- super(assigned, alreadyAssigned);
- this.unassigned = unassigned;
- this.assignedDs = assignedDs;
- this.unassignedDs = unassignedDs;
+ super(assigned, alreadyAssigned,unassigned, assignedDs, unassignedDs);
this.distributionSetTag = distributionSetTag;
}
- public int getUnassigned() {
- return unassigned;
- }
-
public DistributionSetTag getDistributionSetTag() {
return distributionSetTag;
}
- public List getAssignedDs() {
- return assignedDs;
- }
-
- public List getUnassignedDs() {
- return unassignedDs;
- }
}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java
new file mode 100644
index 000000000..c41a0e8c9
--- /dev/null
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/MetaData.java
@@ -0,0 +1,98 @@
+/**
+ * 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.model;
+
+import java.io.Serializable;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Meta data for entities.
+ *
+ */
+@MappedSuperclass
+public abstract class MetaData implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "meta_key", length = 128)
+ private String key;
+
+ @Column(name = "meta_value", length = 4000)
+ @Basic
+ private String value;
+
+ public MetaData(final String key, final String value) {
+ super();
+ this.key = key;
+ this.value = value;
+ }
+
+ public MetaData() {
+ // Default constructor needed for JPA entities
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(final String value) {
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((key == null) ? 0 : key.hashCode());
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(this.getClass().isInstance(obj))) {
+ return false;
+ }
+ final MetaData other = (MetaData) obj;
+ if (key == null) {
+ if (other.key != null) {
+ return false;
+ }
+ } else if (!key.equals(other.key)) {
+ return false;
+ }
+ if (value == null) {
+ if (other.value != null) {
+ return false;
+ }
+ } else if (!value.equals(other.value)) {
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java
index c7af1f2ae..5ddd273d3 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/SoftwareModuleMetadata.java
@@ -8,9 +8,6 @@
*/
package org.eclipse.hawkbit.repository.model;
-import java.io.Serializable;
-
-import javax.persistence.Column;
import javax.persistence.ConstraintMode;
import javax.persistence.Entity;
import javax.persistence.FetchType;
@@ -28,53 +25,25 @@ import javax.persistence.Table;
@IdClass(SwMetadataCompositeKey.class)
@Entity
@Table(name = "sp_sw_metadata")
-public class SoftwareModuleMetadata implements Serializable {
+public class SoftwareModuleMetadata extends MetaData {
private static final long serialVersionUID = 1L;
- @Id
- @Column(name = "meta_key", length = 128)
- private String key;
-
- @Column(name = "meta_value", length = 4000)
- private String value;
-
@Id
@ManyToOne(targetEntity = SoftwareModule.class, fetch = FetchType.LAZY)
@JoinColumn(name = "sw_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_metadata_sw"))
private SoftwareModule softwareModule;
- /**
- * Default constructor for JPA.
- */
public SoftwareModuleMetadata() {
- // default constructor for JPA.
+ // default public constructor for JPA
}
- /**
- * Standard constructor.
- *
- * @param key
- * of the meta data element
- * @param softwareModule
- * @param value
- * of the meta data element
- */
public SoftwareModuleMetadata(final String key, final SoftwareModule softwareModule, final String value) {
- this.key = key;
+ super(key, value);
this.softwareModule = softwareModule;
- this.value = value;
}
public SwMetadataCompositeKey getId() {
- return new SwMetadataCompositeKey(softwareModule, key);
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(final String value) {
- this.value = value;
+ return new SwMetadataCompositeKey(softwareModule, getKey());
}
public SoftwareModule getSoftwareModule() {
@@ -85,47 +54,20 @@ public class SoftwareModuleMetadata implements Serializable {
this.softwareModule = softwareModule;
}
- public String getKey() {
- return key;
- }
-
- public void setKey(final String key) {
- this.key = key;
- }
-
- @Override
- public String toString() {
- return "SoftwareModuleMetadata [key=" + key + ", value=" + value + ", softwareModule=" + softwareModule + "]";
- }
-
@Override
public int hashCode() {
final int prime = 31;
- int result = 1;
- result = prime * result + ((key == null) ? 0 : key.hashCode());
+ int result = super.hashCode();
result = prime * result + ((softwareModule == null) ? 0 : softwareModule.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof SoftwareModuleMetadata)) {
+ if (!super.equals(obj)) {
return false;
}
final SoftwareModuleMetadata other = (SoftwareModuleMetadata) obj;
- if (key == null) {
- if (other.key != null) {
- return false;
- }
- } else if (!key.equals(other.key)) {
- return false;
- }
if (softwareModule == null) {
if (other.softwareModule != null) {
return false;
@@ -135,5 +77,4 @@ public class SoftwareModuleMetadata implements Serializable {
}
return true;
}
-
}
diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java
index 789e6adf2..b454d0c18 100644
--- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java
+++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetTagAssignmentResult.java
@@ -14,11 +14,8 @@ import java.util.List;
* Result object for {@link TargetTag} assignments.
*
*/
-public class TargetTagAssignmentResult extends AssignmentResult {
+public class TargetTagAssignmentResult extends AssignmentResult {
- private final int unassigned;
- private final List assignedTargets;
- private final List unassignedTargets;
private final TargetTag targetTag;
/**
@@ -39,25 +36,10 @@ public class TargetTagAssignmentResult extends AssignmentResult {
*/
public TargetTagAssignmentResult(final int alreadyAssigned, final int assigned, final int unassigned,
final List assignedTargets, final List unassignedTargets, final TargetTag targetTag) {
- super(assigned, alreadyAssigned);
- this.unassigned = unassigned;
- this.assignedTargets = assignedTargets;
- this.unassignedTargets = unassignedTargets;
+ super(assigned, alreadyAssigned, unassigned, assignedTargets, unassignedTargets);
this.targetTag = targetTag;
}
- public int getUnassigned() {
- return unassigned;
- }
-
- public List getAssignedTargets() {
- return assignedTargets;
- }
-
- public List getUnassignedTargets() {
- return unassignedTargets;
- }
-
public TargetTag getTargetTag() {
return targetTag;
}
diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java
index d77c137b1..279932ef7 100644
--- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java
+++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/ControllerManagementTest.java
@@ -48,7 +48,7 @@ public class ControllerManagementTest extends AbstractIntegrationTest {
assertThat(savedTarget.getTargetInfo().getUpdateStatus()).isEqualTo(TargetUpdateStatus.UNKNOWN);
- savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedTargets().iterator().next();
+ savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next();
final Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
assertThat(targetManagement.findTargetByControllerID(savedTarget.getControllerId()).getTargetInfo()
@@ -104,7 +104,7 @@ public class ControllerManagementTest extends AbstractIntegrationTest {
Target savedTarget = targetManagement.createTarget(target);
final List toAssign = new ArrayList<>();
toAssign.add(savedTarget);
- savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedTargets().iterator().next();
+ savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next();
Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
// test and verify
diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java
index 83db4ed96..a17054a3d 100644
--- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java
+++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java
@@ -155,8 +155,8 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
List targets = targetManagement
.createTargets(TestDataUtil.generateTargets(Constants.MAX_ENTRIES_IN_STATEMENT + 10));
- targets = deploymentManagement.assignDistributionSet(cancelDs, targets).getAssignedTargets();
- targets = deploymentManagement.assignDistributionSet(cancelDs2, targets).getAssignedTargets();
+ targets = deploymentManagement.assignDistributionSet(cancelDs, targets).getAssignedEntity();
+ targets = deploymentManagement.assignDistributionSet(cancelDs2, targets).getAssignedEntity();
targetManagement.findAllTargetIds().forEach(targetIdName -> {
assertThat(deploymentManagement.findActiveActionsByTarget(
@@ -604,7 +604,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
// activeActions, add a corresponding cancelAction and another
// UpdateAction for dsA
final Iterable deployed2DS = deploymentManagement
- .assignDistributionSet(dsA, deployResWithDsB.getDeployedTargets()).getAssignedTargets();
+ .assignDistributionSet(dsA, deployResWithDsB.getDeployedTargets()).getAssignedEntity();
actionRepository.findByDistributionSet(pageRequest, dsA).getContent().get(1);
// get final updated version of targets
@@ -761,7 +761,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
targs.add(targ);
// doing the assignment
- targs = deploymentManagement.assignDistributionSet(dsA, targs).getAssignedTargets();
+ targs = deploymentManagement.assignDistributionSet(dsA, targs).getAssignedEntity();
targ = targetManagement.findTargetByControllerID(targs.iterator().next().getControllerId());
// checking the revisions of the created entities
@@ -799,7 +799,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
assertEquals("wrong installed ds", dsA, targ.getTargetInfo().getInstalledDistributionSet());
targs = deploymentManagement.assignDistributionSet(dsB.getId(), new String[] { "target-id-A" })
- .getAssignedTargets();
+ .getAssignedEntity();
targ = targs.iterator().next();
@@ -830,7 +830,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
final List targs = new ArrayList();
targs.add(targ);
- final Iterable savedTargs = deploymentManagement.assignDistributionSet(dsA, targs).getAssignedTargets();
+ final Iterable savedTargs = deploymentManagement.assignDistributionSet(dsA, targs).getAssignedEntity();
targ = savedTargs.iterator().next();
assertThat(dsA.getOptLockRevision()).as("lock revision is wrong").isEqualTo(
@@ -926,7 +926,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
// assigning all DistributionSet to the Target in the list
// deployedTargets
for (final DistributionSet ds : dsList) {
- deployedTargets = deploymentManagement.assignDistributionSet(ds, deployedTargets).getAssignedTargets();
+ deployedTargets = deploymentManagement.assignDistributionSet(ds, deployedTargets).getAssignedEntity();
}
final DeploymentResult deploymentResult = new DeploymentResult(deployedTargets, nakedTargets, dsList,
diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java
index 90cecfc14..db9618425 100644
--- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java
+++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DistributionSetManagementTest.java
@@ -495,11 +495,11 @@ public class DistributionSetManagementTest extends AbstractIntegrationTest {
distributionSetManagement.deleteDistributionSet(dsDeleted);
dsDeleted = distributionSetManagement.findDistributionSetById(dsDeleted.getId());
- ds100Group1 = distributionSetManagement.toggleTagAssignment(ds100Group1, dsTagA).getAssignedDs();
+ ds100Group1 = distributionSetManagement.toggleTagAssignment(ds100Group1, dsTagA).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName());
- ds100Group1 = distributionSetManagement.toggleTagAssignment(ds100Group1, dsTagB).getAssignedDs();
+ ds100Group1 = distributionSetManagement.toggleTagAssignment(ds100Group1, dsTagB).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName());
- ds100Group2 = distributionSetManagement.toggleTagAssignment(ds100Group2, dsTagA).getAssignedDs();
+ ds100Group2 = distributionSetManagement.toggleTagAssignment(ds100Group2, dsTagA).getAssignedEntity();
dsTagA = distributionSetTagRepository.findByNameEquals(dsTagA.getName());
// check setup
diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java
index 73244871f..4c6af0d83 100644
--- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java
+++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TagManagementTest.java
@@ -179,29 +179,29 @@ public class TagManagementTest extends AbstractIntegrationTest {
DistributionSetTagAssignmentResult result = distributionSetManagement.toggleTagAssignment(groupA, tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(20);
- assertThat(result.getAssignedDs()).containsAll(distributionSetManagement.findDistributionSetListWithDetails(
+ assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement.findDistributionSetListWithDetails(
groupA.stream().map(set -> set.getId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
- assertThat(result.getUnassignedDs()).isEmpty();
+ assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
// toggle A+B -> A is still assigned and B is assigned as well
result = distributionSetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(20);
assertThat(result.getAssigned()).isEqualTo(20);
- assertThat(result.getAssignedDs()).containsAll(distributionSetManagement.findDistributionSetListWithDetails(
+ assertThat(result.getAssignedEntity()).containsAll(distributionSetManagement.findDistributionSetListWithDetails(
groupB.stream().map(set -> set.getId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
- assertThat(result.getUnassignedDs()).isEmpty();
+ assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
// toggle A+B -> both unassigned
result = distributionSetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(0);
- assertThat(result.getAssignedDs()).isEmpty();
+ assertThat(result.getAssignedEntity()).isEmpty();
assertThat(result.getUnassigned()).isEqualTo(40);
- assertThat(result.getUnassignedDs()).containsAll(distributionSetManagement.findDistributionSetListWithDetails(
+ assertThat(result.getUnassignedEntity()).containsAll(distributionSetManagement.findDistributionSetListWithDetails(
concat(groupB, groupA).stream().map(set -> set.getId()).collect(Collectors.toList())));
assertThat(result.getDistributionSetTag()).isEqualTo(tag);
@@ -220,29 +220,29 @@ public class TagManagementTest extends AbstractIntegrationTest {
TargetTagAssignmentResult result = targetManagement.toggleTagAssignment(groupA, tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(20);
- assertThat(result.getAssignedTargets()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
+ assertThat(result.getAssignedEntity()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
groupA.stream().map(target -> target.getControllerId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
- assertThat(result.getUnassignedTargets()).isEmpty();
+ assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getTargetTag()).isEqualTo(tag);
// toggle A+B -> A is still assigned and B is assigned as well
result = targetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(20);
assertThat(result.getAssigned()).isEqualTo(20);
- assertThat(result.getAssignedTargets()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
+ assertThat(result.getAssignedEntity()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
groupB.stream().map(target -> target.getControllerId()).collect(Collectors.toList())));
assertThat(result.getUnassigned()).isEqualTo(0);
- assertThat(result.getUnassignedTargets()).isEmpty();
+ assertThat(result.getUnassignedEntity()).isEmpty();
assertThat(result.getTargetTag()).isEqualTo(tag);
// toggle A+B -> both unassigned
result = targetManagement.toggleTagAssignment(concat(groupA, groupB), tag);
assertThat(result.getAlreadyAssigned()).isEqualTo(0);
assertThat(result.getAssigned()).isEqualTo(0);
- assertThat(result.getAssignedTargets()).isEmpty();
+ assertThat(result.getAssignedEntity()).isEmpty();
assertThat(result.getUnassigned()).isEqualTo(40);
- assertThat(result.getUnassignedTargets()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
+ assertThat(result.getUnassignedEntity()).containsAll(targetManagement.findTargetsByControllerIDsWithTags(
concat(groupB, groupA).stream().map(target -> target.getControllerId()).collect(Collectors.toList())));
assertThat(result.getTargetTag()).isEqualTo(tag);
diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java
index 0c33a651f..73d549eb7 100644
--- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java
+++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/TargetManagementSearchTest.java
@@ -64,19 +64,19 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest {
final String targetDsAIdPref = "targ-A";
List targAs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsAIdPref, targetDsAIdPref.concat(" description")));
- targAs = targetManagement.toggleTagAssignment(targAs, targTagX).getAssignedTargets();
+ targAs = targetManagement.toggleTagAssignment(targAs, targTagX).getAssignedEntity();
final String targetDsBIdPref = "targ-B";
List targBs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsBIdPref, targetDsBIdPref.concat(" description")));
- targBs = targetManagement.toggleTagAssignment(targBs, targTagY).getAssignedTargets();
- targBs = targetManagement.toggleTagAssignment(targBs, targTagW).getAssignedTargets();
+ targBs = targetManagement.toggleTagAssignment(targBs, targTagY).getAssignedEntity();
+ targBs = targetManagement.toggleTagAssignment(targBs, targTagW).getAssignedEntity();
final String targetDsCIdPref = "targ-C";
List targCs = targetManagement.createTargets(
TestDataUtil.buildTargetFixtures(100, targetDsCIdPref, targetDsCIdPref.concat(" description")));
- targCs = targetManagement.toggleTagAssignment(targCs, targTagZ).getAssignedTargets();
- targCs = targetManagement.toggleTagAssignment(targCs, targTagW).getAssignedTargets();
+ targCs = targetManagement.toggleTagAssignment(targCs, targTagZ).getAssignedEntity();
+ targCs = targetManagement.toggleTagAssignment(targCs, targTagW).getAssignedEntity();
final String targetDsDIdPref = "targ-D";
final List targDs = targetManagement.createTargets(
@@ -688,8 +688,8 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest {
final DistributionSet ds = TestDataUtil.generateDistributionSet("a", softwareManagement,
distributionSetManagement);
- targAssigned = deploymentManagement.assignDistributionSet(ds, targAssigned).getAssignedTargets();
- targInstalled = deploymentManagement.assignDistributionSet(ds, targInstalled).getAssignedTargets();
+ targAssigned = deploymentManagement.assignDistributionSet(ds, targAssigned).getAssignedEntity();
+ targInstalled = deploymentManagement.assignDistributionSet(ds, targInstalled).getAssignedEntity();
targInstalled = sendUpdateActionStatusToTargets(ds, targInstalled, Status.FINISHED, "installed");
final Slice result = targetManagement.findTargetsAllOrderByLinkedDistributionSet(pageReq, ds.getId(),
diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java
index d7efa50d5..a1c74e791 100644
--- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java
+++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/RepositoryDataGenerator.java
@@ -49,7 +49,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.data.auditing.AuditingHandler;
-import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
@@ -132,24 +131,18 @@ public final class RepositoryDataGenerator {
final DistributionSetTag dsTag = tagManagement
.createDistributionSetTag(new DistributionSetTag("For " + group + "s"));
- auditingHandler.setDateTimeProvider(new DateTimeProvider() {
- @Override
- public Calendar getNow() {
- final Calendar instance = Calendar.getInstance();
- instance.add(Calendar.MONTH, -new Random().nextInt(7));
+ auditingHandler.setDateTimeProvider(() -> {
+ final Calendar instance = Calendar.getInstance();
+ instance.add(Calendar.MONTH, -new Random().nextInt(7));
- return instance;
- }
+ return instance;
});
final List targets = createTargetTestGroup(group, 20 * sizeMultiplikator);
- auditingHandler.setDateTimeProvider(new DateTimeProvider() {
- @Override
- public Calendar getNow() {
- final Calendar instance = Calendar.getInstance();
- return instance;
- }
+ auditingHandler.setDateTimeProvider(() -> {
+ final Calendar instance = Calendar.getInstance();
+ return instance;
});
LOG.debug("initDemoRepo - start now real action history for group: {}", group);
@@ -290,7 +283,7 @@ public final class RepositoryDataGenerator {
LOG.debug("createTargetTestGroup: {} targets status updated including IP", group);
- return targetManagement.toggleTagAssignment(targAs, targTag).getAssignedTargets();
+ return targetManagement.toggleTagAssignment(targAs, targTag).getAssignedEntity();
}
private List buildTargets(final int noOfTgts, final String descriptionPrefix) {
@@ -328,75 +321,70 @@ public final class RepositoryDataGenerator {
private void initDemoRepo(final int sizeMultiplikator, final int loadtestgroups) {
final LoremIpsum jlorem = new LoremIpsum();
- runAsAllAuthorityContext(new Runnable() {
+ runAsAllAuthorityContext(() -> {
+ dbCleanupUtil.cleanupDB(null);
- @Override
- public void run() {
- dbCleanupUtil.cleanupDB(null);
+ // generate targets and assign DS
+ // 5 groups - 100 targets each -> 500
+ final String[] targetTestGroups = { "SHC", "CCU", "Vehicle", "Vending machine", "ECU" };
- // generate targets and assign DS
- // 5 groups - 100 targets each -> 500
- final String[] targetTestGroups = { "SHC", "CCU", "Vehicle", "Vending machine", "ECU" };
+ final String[] modulesTypes = { "HeadUnit_FW", "EDC17_FW", "OSGi_Bundle" };
- final String[] modulesTypes = { "HeadUnit_FW", "EDC17_FW", "OSGi_Bundle" };
+ final DistributionSetTag depTag = tagManagement
+ .createDistributionSetTag(new DistributionSetTag("deprecated"));
- final DistributionSetTag depTag = tagManagement
- .createDistributionSetTag(new DistributionSetTag("deprecated"));
+ Arrays.stream(targetTestGroups).forEach(group -> {
+ generateTestTagetGroup(group, sizeMultiplikator);
+ });
- Arrays.stream(targetTestGroups).forEach(group -> {
- generateTestTagetGroup(group, sizeMultiplikator);
- });
+ // garbage DS
+ LOG.debug("initDemoRepo - start now DS garbage");
+ TestDataUtil.generateDistributionSets("Generic Software Package", sizeMultiplikator,
+ softwareManagement, distributionSetManagement);
+ LOG.debug("initDemoRepo - DS garbage finished");
- // garbage DS
- LOG.debug("initDemoRepo - start now DS garbage");
- TestDataUtil.generateDistributionSets("Generic Software Package", sizeMultiplikator,
- softwareManagement, distributionSetManagement);
- LOG.debug("initDemoRepo - DS garbage finished");
+ LOG.debug("initDemoRepo - start now Extra Software Modules and types");
+ Arrays.stream(modulesTypes).forEach(typeName -> {
+ final SoftwareModuleType smtype = softwareManagement.createSoftwareModuleType(
+ new SoftwareModuleType(typeName.toLowerCase().replaceAll("\\s+", ""), typeName,
+ jlorem.words(5), Integer.MAX_VALUE));
- LOG.debug("initDemoRepo - start now Extra Software Modules and types");
- Arrays.stream(modulesTypes).forEach(typeName -> {
- final SoftwareModuleType smtype = softwareManagement.createSoftwareModuleType(
- new SoftwareModuleType(typeName.toLowerCase().replaceAll("\\s+", ""), typeName,
- jlorem.words(5), Integer.MAX_VALUE));
-
- for (int i = 0; i < sizeMultiplikator; i++) {
- softwareManagement.createSoftwareModule(new SoftwareModule(smtype, typeName + i, "1.0." + i,
- jlorem.words(5), "the " + typeName + " vendor Inc."));
- }
-
- });
- LOG.debug("initDemoRepo - Extra Software Modules and types finished");
-
- LOG.debug("initDemoRepo - start now target garbage");
-
- // garbage targets
- // unknown
- targetManagement
- .createTargets(TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator));
-
- // registered
- targetManagement.createTargets(
- TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator, "registered"),
- TargetUpdateStatus.REGISTERED, System.currentTimeMillis(), generateIPAddress());
-
- // pending
- final DistributionSetTag dsTag = tagManagement
- .createDistributionSetTag(new DistributionSetTag("OnlyAssignedTag"));
- final DistributionSet ds = TestDataUtil.generateDistributionSet("Pending DS", "v1.0",
- softwareManagement, distributionSetManagement,
- Arrays.asList(new DistributionSetTag[] { dsTag }));
- deploymentManagement.assignDistributionSet(ds, targetManagement.createTargets(
- TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator, "pending")));
-
- // Load test means additional 1_000_000 target
-
- for (int i = 0; i < loadtestgroups; i++) {
- targetManagement.createTargets(TestDataUtil.generateTargets(i * 1_000, 1_000, "loadtest-"));
+ for (int i1 = 0; i1 < sizeMultiplikator; i1++) {
+ softwareManagement.createSoftwareModule(new SoftwareModule(smtype, typeName + i1, "1.0." + i1,
+ jlorem.words(5), "the " + typeName + " vendor Inc."));
}
- LOG.debug("initDemoRepo complete");
+ });
+ LOG.debug("initDemoRepo - Extra Software Modules and types finished");
+
+ LOG.debug("initDemoRepo - start now target garbage");
+
+ // garbage targets
+ // unknown
+ targetManagement
+ .createTargets(TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator));
+
+ // registered
+ targetManagement.createTargets(
+ TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator, "registered"),
+ TargetUpdateStatus.REGISTERED, System.currentTimeMillis(), generateIPAddress());
+
+ // pending
+ final DistributionSetTag dsTag = tagManagement
+ .createDistributionSetTag(new DistributionSetTag("OnlyAssignedTag"));
+ final DistributionSet ds = TestDataUtil.generateDistributionSet("Pending DS", "v1.0",
+ softwareManagement, distributionSetManagement,
+ Arrays.asList(new DistributionSetTag[] { dsTag }));
+ deploymentManagement.assignDistributionSet(ds, targetManagement.createTargets(
+ TestDataUtil.generateTargets(targetTestGroups.length * sizeMultiplikator, "pending")));
+
+ // Load test means additional 1_000_000 target
+
+ for (int i2 = 0; i2 < loadtestgroups; i2++) {
+ targetManagement.createTargets(TestDataUtil.generateTargets(i2 * 1_000, 1_000, "loadtest-"));
}
+ LOG.debug("initDemoRepo complete");
});
}
/**
diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/PagedList.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/PagedList.java
index 880ee0c16..9d5cc458c 100644
--- a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/PagedList.java
+++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/model/PagedList.java
@@ -14,9 +14,11 @@ import javax.validation.constraints.NotNull;
import org.springframework.hateoas.ResourceSupport;
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
/**
* A list representation with meta data for pagination, e.g. containing the
@@ -31,8 +33,10 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include;
@JsonInclude(Include.NON_NULL)
public class PagedList extends ResourceSupport {
+ @JsonProperty
private final List content;
- private final long totalElements;
+ @JsonProperty
+ private final long total;
private final int size;
/**
@@ -46,9 +50,10 @@ public class PagedList extends ResourceSupport {
* @throws NullPointerException
* in case {@code content} is {@code null}.
*/
- public PagedList(@NotNull final List content, final long total) {
+ @JsonCreator
+ public PagedList(@JsonProperty("content") @NotNull final List content, @JsonProperty("total") final long total) {
this.size = content.size();
- this.totalElements = total;
+ this.total = total;
this.content = content;
}
@@ -63,7 +68,7 @@ public class PagedList extends ResourceSupport {
* @return the total amount of elements
*/
public long getTotal() {
- return totalElements;
+ return total;
}
public List getContent() {
diff --git a/hawkbit-rest-resource/pom.xml b/hawkbit-rest-resource/pom.xml
index 633a1f8cc..0be5d20f5 100644
--- a/hawkbit-rest-resource/pom.xml
+++ b/hawkbit-rest-resource/pom.xml
@@ -25,6 +25,11 @@
org.eclipse.hawkbit
hawkbit-repository
${project.version}
+
+
+ org.eclipse.hawkbit
+ hawkbit-core
+ ${project.version}
org.eclipse.hawkbit
diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java
index ef4468815..e035c47ee 100644
--- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java
+++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/DataConversionHelper.java
@@ -18,6 +18,8 @@ import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
+import org.eclipse.hawkbit.api.ArtifactUrlHandler;
+import org.eclipse.hawkbit.api.UrlProtocol;
import org.eclipse.hawkbit.controller.model.Artifact;
import org.eclipse.hawkbit.controller.model.Chunk;
import org.eclipse.hawkbit.controller.model.Config;
@@ -29,27 +31,29 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactHash;
import org.eclipse.hawkbit.tenancy.TenantAware;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.hateoas.Link;
import com.google.common.base.Charsets;
/**
* Utility class for the Controller API.
- *
- *
- *
- *
*/
public final class DataConversionHelper {
+ @Autowired
+ ArtifactUrlHandler artifactUrlHandler;
+
// utility class, private constructor.
private DataConversionHelper() {
}
- static List createChunks(final String targetid, final Action uAction, final TenantAware tenantAware) {
- return uAction.getDistributionSet()
- .getModules().stream().map(module -> new Chunk(mapChunkLegacyKeys(module.getType().getKey()),
- module.getVersion(), module.getName(), createArtifacts(targetid, module, tenantAware)))
+ static List createChunks(final String targetid, final Action uAction,
+ final ArtifactUrlHandler artifactUrlHandler) {
+ return uAction.getDistributionSet().getModules().stream()
+ .map(module -> new Chunk(mapChunkLegacyKeys(module.getType().getKey()), module.getVersion(),
+ module.getName(), createArtifacts(targetid, module, artifactUrlHandler)))
.collect(Collectors.toList());
}
@@ -72,23 +76,25 @@ public final class DataConversionHelper {
* of the target
* @param module
* the software module
- * @param tenantAware
- * of the tenant
* @return a list of artifacts or a empty list. Cannot be .
*/
public static List createArtifacts(final String targetid,
- final org.eclipse.hawkbit.repository.model.SoftwareModule module, final TenantAware tenantAware) {
+ final org.eclipse.hawkbit.repository.model.SoftwareModule module,
+ final ArtifactUrlHandler artifactUrlHandler) {
final List files = new ArrayList<>();
module.getLocalArtifacts().forEach(artifact -> {
final Artifact file = new Artifact();
file.setHashes(new ArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash()));
file.setFilename(artifact.getFilename());
file.setSize(artifact.getSize());
-
- file.add(linkTo(methodOn(RootController.class, tenantAware.getCurrentTenant()).downloadArtifact(targetid,
- artifact.getSoftwareModule().getId(), artifact.getFilename(), null, null)).withRel("download"));
- file.add(linkTo(methodOn(RootController.class, tenantAware.getCurrentTenant()).downloadArtifactMd5(targetid,
- artifact.getSoftwareModule().getId(), artifact.getFilename(), null, null)).withRel("md5sum"));
+ final String linkHttp = artifactUrlHandler.getUrl(targetid, artifact.getSoftwareModule().getId(),
+ artifact.getFilename(), artifact.getSha1Hash(), UrlProtocol.HTTP);
+ final String linkHttps = artifactUrlHandler.getUrl(targetid, artifact.getSoftwareModule().getId(),
+ artifact.getFilename(), artifact.getSha1Hash(), UrlProtocol.HTTPS);
+ file.add(new Link(linkHttps).withRel("download"));
+ file.add(new Link(linkHttps + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum"));
+ file.add(new Link(linkHttp).withRel("download-http"));
+ file.add(new Link(linkHttp + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum-http"));
files.add(file);
});
diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java
index 171e02d16..f704acd5e 100644
--- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java
+++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/controller/RootController.java
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
+import org.eclipse.hawkbit.api.ArtifactUrlHandler;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
import org.eclipse.hawkbit.cache.CacheWriteNotify;
import org.eclipse.hawkbit.controller.model.ActionFeedback;
@@ -84,11 +85,14 @@ public class RootController {
@Autowired
private CacheWriteNotify cacheWriteNotify;
+ @Autowired
+ private HawkbitSecurityProperties securityProperties;
+
@Autowired
private TenantAware tenantAware;
@Autowired
- private HawkbitSecurityProperties securityProperties;
+ private ArtifactUrlHandler artifactUrlHandler;
/**
* Returns all artifacts of a given software module and target.
@@ -114,7 +118,7 @@ public class RootController {
}
- return new ResponseEntity<>(DataConversionHelper.createArtifacts(targetid, softwareModule, tenantAware),
+ return new ResponseEntity<>(DataConversionHelper.createArtifacts(targetid, softwareModule, artifactUrlHandler),
HttpStatus.OK);
}
@@ -303,7 +307,7 @@ public class RootController {
if (!action.isCancelingOrCanceled()) {
- final List chunks = DataConversionHelper.createChunks(targetid, action, tenantAware);
+ final List chunks = DataConversionHelper.createChunks(targetid, action, artifactUrlHandler);
final HandlingType handlingType = action.isForce() ? HandlingType.FORCED : HandlingType.ATTEMPT;
diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java
index 01a446947..eaa0fec28 100644
--- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java
+++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java
@@ -139,9 +139,9 @@ public class DistributionSetTagResource implements DistributionSetTagRestApi {
final DistributionSetTagAssigmentResultRest tagAssigmentResultRest = new DistributionSetTagAssigmentResultRest();
tagAssigmentResultRest.setAssignedDistributionSets(
- DistributionSetMapper.toResponseDistributionSets(assigmentResult.getAssignedDs()));
+ DistributionSetMapper.toResponseDistributionSets(assigmentResult.getAssignedEntity()));
tagAssigmentResultRest.setUnassignedDistributionSets(
- DistributionSetMapper.toResponseDistributionSets(assigmentResult.getUnassignedDs()));
+ DistributionSetMapper.toResponseDistributionSets(assigmentResult.getUnassignedEntity()));
LOG.debug("Toggled assignedDS {} and unassignedDS{}", assigmentResult.getAssigned(),
assigmentResult.getUnassigned());
diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java
index 3c79c936c..4b068a41e 100644
--- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java
+++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java
@@ -263,7 +263,7 @@ public class TargetResource implements TargetRestApi {
final ActionType type = (dsId.getType() != null)
? RestResourceConversionHelper.convertActionType(dsId.getType()) : ActionType.FORCED;
final Iterator changed = this.deploymentManagement
- .assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), targetId).getAssignedTargets()
+ .assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), targetId).getAssignedEntity()
.iterator();
if (changed.hasNext()) {
return new ResponseEntity<>(HttpStatus.OK);
diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java
index 9990fb35a..1a9155828 100644
--- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java
+++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java
@@ -133,8 +133,8 @@ public class TargetTagResource implements TargetTagRestApi {
.toggleTagAssignment(findTargetControllerIds(assignedTargetRequestBodies), targetTag.getName());
final TargetTagAssigmentResultRest tagAssigmentResultRest = new TargetTagAssigmentResultRest();
- tagAssigmentResultRest.setAssignedTargets(TargetMapper.toResponse(assigmentResult.getAssignedTargets()));
- tagAssigmentResultRest.setUnassignedTargets(TargetMapper.toResponse(assigmentResult.getUnassignedTargets()));
+ tagAssigmentResultRest.setAssignedTargets(TargetMapper.toResponse(assigmentResult.getAssignedEntity()));
+ tagAssigmentResultRest.setUnassignedTargets(TargetMapper.toResponse(assigmentResult.getUnassignedEntity()));
return new ResponseEntity<>(tagAssigmentResultRest, HttpStatus.OK);
}
diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/DeploymentBaseTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/DeploymentBaseTest.java
index 2b2b7e597..5dd956ad3 100644
--- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/DeploymentBaseTest.java
+++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/DeploymentBaseTest.java
@@ -114,12 +114,12 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
assertThat(actionStatusRepository.findAll()).isEmpty();
List saved = deploymentManagement.assignDistributionSet(ds.getId(), ActionType.FORCED,
- Action.NO_FORCE_TIME, savedTarget.getControllerId()).getAssignedTargets();
+ Action.NO_FORCE_TIME, savedTarget.getControllerId()).getAssignedEntity();
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
assertThat(actionRepository.findAll()).hasSize(1);
- saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedTargets();
+ saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedEntity();
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
assertThat(actionRepository.findAll()).hasSize(2);
@@ -170,15 +170,27 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
equalTo(artifact.getSha1Hash())))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.MD5SUM")))
+
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download-http.href",
+ equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum-http.href",
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1.MD5SUM")))
+
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].size", equalTo(5 * 1024)))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].filename",
equalTo("test1.signature")))
@@ -188,11 +200,21 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
equalTo(artifactSignature.getSha1Hash())))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1.signature")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.signature.MD5SUM")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
+ equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.signature")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
@@ -236,12 +258,12 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
List saved = deploymentManagement
.assignDistributionSet(ds.getId(), ActionType.SOFT, Action.NO_FORCE_TIME, savedTarget.getControllerId())
- .getAssignedTargets();
+ .getAssignedEntity();
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
assertThat(actionRepository.findAll()).hasSize(1);
- saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedTargets();
+ saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedEntity();
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
assertThat(actionRepository.findAll()).hasSize(2);
@@ -293,12 +315,12 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
equalTo(artifact.getSha1Hash())))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1.MD5SUM")))
@@ -311,11 +333,21 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
equalTo(artifactSignature.getSha1Hash())))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1.signature")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.signature.MD5SUM")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
+ equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.signature")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
@@ -358,12 +390,12 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
assertThat(actionStatusRepository.findAll()).isEmpty();
List saved = deploymentManagement.assignDistributionSet(ds.getId(), ActionType.TIMEFORCED,
- System.currentTimeMillis(), savedTarget.getControllerId()).getAssignedTargets();
+ System.currentTimeMillis(), savedTarget.getControllerId()).getAssignedEntity();
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(1);
final Action action = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
assertThat(actionRepository.findAll()).hasSize(1);
- saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedTargets();
+ saved = deploymentManagement.assignDistributionSet(ds2, saved).getAssignedEntity();
assertThat(deploymentManagement.findActiveActionsByTarget(savedTarget)).hasSize(2);
assertThat(actionRepository.findAll()).hasSize(2);
@@ -409,15 +441,25 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].filename", equalTo("test1")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.md5",
equalTo(artifact.getMd5Hash())))
- .andExpect(
- jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
- equalTo(artifact.getSha1Hash())))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
+ equalTo(artifact.getSha1Hash())))
+
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.MD5SUM")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download-http.href",
+ equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum-http.href",
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
@@ -431,15 +473,27 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
equalTo(artifactSignature.getSha1Hash())))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
- equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1.signature")))
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
+ equalTo("https://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.signature.MD5SUM")))
+
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
+ equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ + "/controller/v1/4712/softwaremodules/"
+ + findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ + "/artifacts/test1.signature")))
+ .andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
+ "/controller/v1/4712/softwaremodules/"
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
+ "/artifacts/test1.signature.MD5SUM")))
+
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
equalTo(ds.findFirstModuleByType(appType).getVersion())))
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].name",
@@ -887,7 +941,7 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
assertThat(targetManagement.findTargetByControllerID("4712").getTargetInfo().getUpdateStatus())
.isEqualTo(TargetUpdateStatus.UNKNOWN);
- savedTarget = deploymentManagement.assignDistributionSet(savedSet, toAssign).getAssignedTargets().iterator()
+ savedTarget = deploymentManagement.assignDistributionSet(savedSet, toAssign).getAssignedEntity().iterator()
.next();
deploymentManagement.assignDistributionSet(savedSet2, toAssign2);
diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java
index a6e457f3a..fa2c5f6d4 100644
--- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java
+++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/controller/RootControllerTest.java
@@ -270,7 +270,7 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
Target savedTarget = targetManagement.createTarget(target);
final List toAssign = new ArrayList();
toAssign.add(savedTarget);
- savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedTargets().iterator().next();
+ savedTarget = deploymentManagement.assignDistributionSet(ds, toAssign).getAssignedEntity().iterator().next();
final Action savedAction = deploymentManagement.findActiveActionsByTarget(savedTarget).get(0);
mvc.perform(post("/{tenant}/controller/v1/911/deploymentBase/" + savedAction.getId() + "/feedback",
tenantAware.getCurrentTenant())
diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java
index a8ebfdd9d..8d27d5114 100644
--- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java
+++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/TargetResourceTest.java
@@ -1029,7 +1029,7 @@ public class TargetResourceTest extends AbstractIntegrationTest {
// Update
final List updatedTargets = deploymentManagement.assignDistributionSet(one, targets)
- .getAssignedTargets();
+ .getAssignedEntity();
// 2nd update
// sleep 10ms to ensure that we can sort by reportedAt
Thread.sleep(10);
diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java
index 5d4ab9283..2e222d879 100644
--- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java
+++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java
@@ -182,6 +182,12 @@ public final class SpPermission {
*/
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
+ /**
+ * The role which contains in the spring security context in case an
+ * controller is authenticated to download artifacts.
+ */
+ public static final String CONTROLLER_DOWNLOAD_ROLE = "ROLE_CONTROLLER_DOWNLOAD";
+
/**
* The role which contains the spring security context in case the
* system is executing code which is necessary to be privileged.
@@ -275,8 +281,16 @@ public final class SpPermission {
* context contains the anoynmous role or the controller specific role
* {@link SpPermission#CONTROLLER_ROLE}.
*/
- public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '"
- + CONTROLLER_ROLE + "')";
+ public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
+ + "')";
+
+ /**
+ * Spring security eval hasAuthority expression to check if the spring
+ * context contains the role to allow controllers to download specific
+ * role {@link SpPermission#CONTROLLER_DOWNLOAD_ROLE}.
+ */
+ public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE
+ + HAS_AUTH_SUFFIX;
/**
* Spring security eval hasAnyRole expression to check if the spring
diff --git a/hawkbit-security-integration/pom.xml b/hawkbit-security-integration/pom.xml
index 9d89c1806..c17317b3d 100644
--- a/hawkbit-security-integration/pom.xml
+++ b/hawkbit-security-integration/pom.xml
@@ -35,7 +35,32 @@
org.springframework.security
spring-security-web
+
+
+
+ junit
+ junit
+ test
+
+
+ org.easytesting
+ fest-assert-core
+ test
+
+
+ org.easytesting
+ fest-assert
+ test
+
+
+ org.mockito
+ mockito-core
+ test
+
+
+ ru.yandex.qatools.allure
+ allure-junit-adaptor
+ test
+
-
-
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java
index d22c432cf..9a1cd2aea 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java
@@ -8,7 +8,7 @@
*/
package org.eclipse.hawkbit.security;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
@@ -42,15 +42,15 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe
protected abstract TenantConfigurationKey getTenantConfigurationKey();
@Override
- public boolean isEnable(final TenantSecruityToken secruityToken) {
+ public boolean isEnable(final TenantSecurityToken secruityToken) {
return tenantAware.runAsTenant(secruityToken.getTenant(), configurationKeyTenantRunner);
}
@Override
- public abstract HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecruityToken secruityToken);
+ public abstract HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecurityToken secruityToken);
@Override
- public abstract HeaderAuthentication getPreAuthenticatedCredentials(TenantSecruityToken secruityToken);
+ public abstract HeaderAuthentication getPreAuthenticatedCredentials(TenantSecurityToken secruityToken);
private final class SecurityConfigurationKeyTenantRunner implements TenantAware.TenantRunner {
@Override
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java
index d9d8b9fa7..36a444c43 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/CoapAnonymousPreAuthenticatedFilter.java
@@ -8,7 +8,7 @@
*/
package org.eclipse.hawkbit.security;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
/**
* A Filter for device which download via coap.
@@ -19,19 +19,19 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
public class CoapAnonymousPreAuthenticatedFilter implements PreAuthenficationFilter {
@Override
- public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
- return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecruityToken.COAP_TOKEN_VALUE);
+ public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
+ return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecurityToken.COAP_TOKEN_VALUE);
}
@Override
- public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
- return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecruityToken.COAP_TOKEN_VALUE);
+ public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
+ return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecurityToken.COAP_TOKEN_VALUE);
}
@Override
- public boolean isEnable(final TenantSecruityToken secruityToken) {
- final String authHeader = secruityToken.getHeader(TenantSecruityToken.COAP_AUTHORIZATION_HEADER);
- return TenantSecruityToken.COAP_TOKEN_VALUE.equals(authHeader);
+ public boolean isEnable(final TenantSecurityToken secruityToken) {
+ final String authHeader = secruityToken.getHeader(TenantSecurityToken.COAP_AUTHORIZATION_HEADER);
+ return TenantSecurityToken.COAP_TOKEN_VALUE.equals(authHeader);
}
}
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java
index c30f60711..8ff1e9ebc 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java
@@ -8,7 +8,7 @@
*/
package org.eclipse.hawkbit.security;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
import org.eclipse.hawkbit.im.authentication.SpPermission;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.repository.ControllerManagement;
@@ -67,8 +67,8 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro
}
@Override
- public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
- final String authHeader = secruityToken.getHeader(TenantSecruityToken.AUTHORIZATION_HEADER);
+ public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
+ final String authHeader = secruityToken.getHeader(TenantSecurityToken.AUTHORIZATION_HEADER);
if ((authHeader != null) && authHeader.startsWith(TARGET_SECURITY_TOKEN_AUTH_SCHEME)) {
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
TARGET_SECURITY_TOKEN_AUTH_SCHEME);
@@ -81,7 +81,7 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro
}
@Override
- public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
+ public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
final String securityToken = tenantAware.runAsTenant(secruityToken.getTenant(),
new GetSecurityTokenTenantRunner(secruityToken.getTenant(), secruityToken.getControllerId()));
return new HeaderAuthentication(secruityToken.getControllerId(), securityToken);
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java
new file mode 100644
index 000000000..b4457bfcf
--- /dev/null
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.security;
+
+import java.util.Collection;
+
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
+import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.tenancy.TenantAware;
+import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+import com.google.common.collect.Lists;
+
+/**
+ * An pre-authenticated processing filter which add the
+ * {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE_ANONYMOUS} to the
+ * security context in case the anonymous download is allowed through
+ * configuration.
+ */
+public class ControllerPreAuthenticatedAnonymousDownload extends AbstractControllerAuthenticationFilter {
+
+ /**
+ * Constructor.
+ *
+ * @param tenantConfigurationManagement
+ * the tenant management service to retrieve configuration
+ * properties
+ * @param tenantAware
+ * the tenant aware service to get configuration for the specific
+ * tenant
+ * @param systemSecurityContext
+ * the system security context to get access to tenant
+ * configuration
+ */
+ public ControllerPreAuthenticatedAnonymousDownload(
+ final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
+ final SystemSecurityContext systemSecurityContext) {
+ super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ }
+
+ @Override
+ public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
+ return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
+ }
+
+ @Override
+ public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
+ return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
+ }
+
+ @Override
+ protected TenantConfigurationKey getTenantConfigurationKey() {
+ return TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED;
+ }
+
+ @Override
+ public Collection getSuccessfulAuthenticationAuthorities() {
+ return Lists.newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
+ }
+}
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java
new file mode 100644
index 000000000..cf55c47fb
--- /dev/null
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java
@@ -0,0 +1,47 @@
+/**
+ * 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.security;
+
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+
+/**
+ * An anonymous controller filter which is only enabled in case of anonymous
+ * access is granted. This should only be for development purposes.
+ *
+ * @see DdiSecurityProperties
+ */
+public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthenficationFilter {
+
+ private final DdiSecurityProperties ddiSecurityConfiguration;
+
+ /**
+ * @param ddiSecurityConfiguration
+ * the security configuration which holds the configuration if
+ * anonymous is enabled or not
+ */
+ public ControllerPreAuthenticatedAnonymousFilter(final DdiSecurityProperties ddiSecurityConfiguration) {
+ this.ddiSecurityConfiguration = ddiSecurityConfiguration;
+ }
+
+ @Override
+ public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
+ return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
+ }
+
+ @Override
+ public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
+ return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
+ }
+
+ @Override
+ public boolean isEnable(final TenantSecurityToken secruityToken) {
+ return ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled();
+ }
+
+}
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java
index 765589df4..7d1bd7b0f 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java
@@ -8,7 +8,7 @@
*/
package org.eclipse.hawkbit.security;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
@@ -56,8 +56,8 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra
}
@Override
- public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
- final String authHeader = secruityToken.getHeader(TenantSecruityToken.AUTHORIZATION_HEADER);
+ public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
+ final String authHeader = secruityToken.getHeader(TenantSecurityToken.AUTHORIZATION_HEADER);
if ((authHeader != null) && authHeader.startsWith(GATEWAY_SECURITY_TOKEN_AUTH_SCHEME)) {
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
GATEWAY_SECURITY_TOKEN_AUTH_SCHEME);
@@ -71,7 +71,7 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra
}
@Override
- public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
+ public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
final String gatewayToken = tenantAware.runAsTenant(secruityToken.getTenant(),
gatewaySecurityTokenKeyConfigRunner);
return new HeaderAuthentication(secruityToken.getControllerId(), gatewayToken);
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java
index ef8b5fbf7..6836b8a31 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java
@@ -8,7 +8,7 @@
*/
package org.eclipse.hawkbit.security;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
@@ -18,7 +18,7 @@ import org.slf4j.LoggerFactory;
/**
* An pre-authenticated processing filter which extracts the principal from a
* request URI and the credential from a request header in a the
- * {@link TenantSecruityToken}.
+ * {@link TenantSecurityToken}.
*
*
*
@@ -75,7 +75,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
}
@Override
- public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
+ public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
// retrieve the common name header and the authority name header from
// the http request and
// combine them together
@@ -97,7 +97,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
}
@Override
- public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
+ public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
final String authorityNameConfigurationValue = tenantAware.runAsTenant(secruityToken.getTenant(),
sslIssuerNameConfigTenantRunner);
String controllerId = secruityToken.getControllerId();
@@ -117,7 +117,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
* It's ok if we find the the hash in any the trusted CA chain to accept
* this request for this tenant.
*/
- private String getIssuerHashHeader(final TenantSecruityToken secruityToken, final String knownIssuerHash) {
+ private String getIssuerHashHeader(final TenantSecurityToken secruityToken, final String knownIssuerHash) {
// iterate over the headers until we get a null header.
int iHeader = 1;
String foundHash;
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java
index ca38404f7..b81b76e5c 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java
@@ -109,6 +109,7 @@ public class PreAuthTokenSourceTrustAuthenticationProvider implements Authentica
if (successAuthentication) {
final Collection controllerAuthorities = new ArrayList<>();
controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE));
+ controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
final PreAuthenticatedAuthenticationToken successToken = new PreAuthenticatedAuthenticationToken(principal,
credentials, controllerAuthorities);
successToken.setDetails(tokenDetails);
diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenficationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenficationFilter.java
index 8aa957005..5e4aacfa9 100644
--- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenficationFilter.java
+++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenficationFilter.java
@@ -8,7 +8,12 @@
*/
package org.eclipse.hawkbit.security;
-import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
/**
* Interface for Pre Authenfication.
@@ -25,7 +30,7 @@ public interface PreAuthenficationFilter {
* the secruity info
* @return is enabled diabled
*/
- boolean isEnable(TenantSecruityToken secruityToken);
+ boolean isEnable(TenantSecurityToken secruityToken);
/**
* Extract the principal information from the current secruityToken.
@@ -34,7 +39,7 @@ public interface PreAuthenficationFilter {
* the secruityToken
* @return the extracted tenant and controller id
*/
- HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecruityToken secruityToken);
+ HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecurityToken secruityToken);
/**
* Extract the principal credentials from the current secruityToken.
@@ -43,6 +48,18 @@ public interface PreAuthenficationFilter {
* the secruityToken
* @return the extracted tenant and controller id
*/
- HeaderAuthentication getPreAuthenticatedCredentials(TenantSecruityToken secruityToken);
+ HeaderAuthentication getPreAuthenticatedCredentials(TenantSecurityToken secruityToken);
+
+ /**
+ * Allows to add additional authorities to the successful authenticated
+ * token.
+ *
+ * @return the authorities granted to the principal, or an empty collection
+ * if the token has not been authenticated. Never null.
+ * @see Authentication#getAuthorities()
+ */
+ default Collection getSuccessfulAuthenticationAuthorities() {
+ return Collections.emptyList();
+ };
}
diff --git a/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java b/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java
new file mode 100644
index 000000000..b8195d023
--- /dev/null
+++ b/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.hawkbit.security;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
+import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.tenancy.TenantAware;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+
+import ru.yandex.qatools.allure.annotations.Features;
+import ru.yandex.qatools.allure.annotations.Stories;
+
+/**
+ * @author Michael Hirsch
+ *
+ */
+@Features("Unit Tests - Security")
+@Stories("Exclude path aware shallow ETag filter")
+@RunWith(MockitoJUnitRunner.class)
+public class ControllerPreAuthenticatedAnonymousDownloadTest {
+
+ private ControllerPreAuthenticatedAnonymousDownload underTest;
+
+ @Mock
+ private TenantConfigurationManagement tenantConfigurationManagementMock;
+
+ @Mock
+ private TenantAware tenantAwareMock;
+
+ @Before
+ public void before() {
+ underTest = new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagementMock, tenantAwareMock,
+ new SystemSecurityContext(tenantAwareMock));
+ }
+
+ @Test
+ public void useCorrectTenantConfiguationKey() {
+ assertThat(underTest.getTenantConfigurationKey()).as("Should be using the correct tenant configuration key")
+ .isEqualTo(underTest.getTenantConfigurationKey());
+ }
+
+ @Test
+ public void successfulAuthenticationAdditionalAuthoritiesForDownload() {
+ assertThat(underTest.getSuccessfulAuthenticationAuthorities())
+ .as("Additional authorities should be containing the download anonymous role")
+ .contains(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
+ }
+}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java
index 54ba5cc8e..b07aa0276 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java
@@ -15,12 +15,12 @@ import org.eclipse.hawkbit.ui.HawkbitUI;
import org.eclipse.hawkbit.ui.artifacts.details.ArtifactDetailsLayout;
import org.eclipse.hawkbit.ui.artifacts.event.ArtifactDetailsEvent;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
-import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType;
import org.eclipse.hawkbit.ui.artifacts.footer.SMDeleteActionsLayout;
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleTableLayout;
import org.eclipse.hawkbit.ui.artifacts.smtype.SMTypeFilterLayout;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.artifacts.upload.UploadLayout;
+import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.management.event.DragEvent;
import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
@@ -111,9 +111,9 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final SoftwareModuleEvent event) {
- if (event.getSoftwareModuleEventType() == SoftwareModuleEventType.MINIMIZED) {
+ if (BaseEntityEventType.MINIMIZED == event.getEventType()) {
minimizeSwTable();
- } else if (event.getSoftwareModuleEventType() == SoftwareModuleEventType.MAXIMIZED) {
+ } else if (BaseEntityEventType.MAXIMIZED == event.getEventType()) {
maximizeSwTable();
}
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java
index 1bc9da65c..7c5d4153f 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactDetailsLayout.java
@@ -24,6 +24,7 @@ import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent;
import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent.SoftwareModuleEventType;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.common.ConfirmationDialog;
+import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
import org.eclipse.hawkbit.ui.components.SPUIButton;
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
@@ -110,8 +111,6 @@ public class ArtifactDetailsLayout extends VerticalLayout {
private boolean fullWindowMode = false;
- private UI ui;
-
private boolean readOnly = false;
/**
@@ -122,7 +121,6 @@ public class ArtifactDetailsLayout extends VerticalLayout {
createComponents();
buildLayout();
eventBus.subscribe(this);
- ui = UI.getCurrent();
if (artifactUploadState.getSelectedBaseSoftwareModule().isPresent()) {
final SoftwareModule selectedSoftwareModule = artifactUploadState.getSelectedBaseSoftwareModule().get();
populateArtifactDetails(selectedSoftwareModule.getId(), HawkbitCommonUtil
@@ -461,23 +459,23 @@ public class ArtifactDetailsLayout extends VerticalLayout {
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final SoftwareModuleEvent softwareModuleEvent) {
- if (softwareModuleEvent.getSoftwareModuleEventType() == SoftwareModuleEventType.SELECTED_SOFTWARE_MODULE) {
- ui.access(() -> {
- if (softwareModuleEvent.getSoftwareModule() != null) {
- populateArtifactDetails(softwareModuleEvent.getSoftwareModule().getId(),
- HawkbitCommonUtil.getFormattedNameVersion(softwareModuleEvent.getSoftwareModule().getName(),
- softwareModuleEvent.getSoftwareModule().getVersion()));
+ if (BaseEntityEventType.SELECTED_ENTITY == softwareModuleEvent.getEventType()) {
+ UI.getCurrent().access(() -> {
+ if (softwareModuleEvent.getEntity() != null) {
+ populateArtifactDetails(softwareModuleEvent.getEntity().getId(),
+ HawkbitCommonUtil.getFormattedNameVersion(softwareModuleEvent.getEntity().getName(),
+ softwareModuleEvent.getEntity().getVersion()));
} else {
populateArtifactDetails(null, null);
}
});
}
if (softwareModuleEvent.getSoftwareModuleEventType() == SoftwareModuleEventType.ARTIFACTS_CHANGED) {
- ui.access(() -> {
- if (softwareModuleEvent.getSoftwareModule() != null) {
- populateArtifactDetails(softwareModuleEvent.getSoftwareModule().getId(),
- HawkbitCommonUtil.getFormattedNameVersion(softwareModuleEvent.getSoftwareModule().getName(),
- softwareModuleEvent.getSoftwareModule().getVersion()));
+ UI.getCurrent().access(() -> {
+ if (softwareModuleEvent.getEntity() != null) {
+ populateArtifactDetails(softwareModuleEvent.getEntity().getId(),
+ HawkbitCommonUtil.getFormattedNameVersion(softwareModuleEvent.getEntity().getName(),
+ softwareModuleEvent.getEntity().getVersion()));
} else {
populateArtifactDetails(null, null);
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java
index 3d0897dcd..95770cb8f 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/SoftwareModuleEvent.java
@@ -9,58 +9,53 @@
package org.eclipse.hawkbit.ui.artifacts.event;
import org.eclipse.hawkbit.repository.model.SoftwareModule;
+import org.eclipse.hawkbit.ui.common.table.BaseEntityEvent;
+import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType;
/**
* Event to represent software add, update or delete.
- *
- *
*
*/
-public class SoftwareModuleEvent {
+public class SoftwareModuleEvent extends BaseEntityEvent {
/**
* Software module events in the Upload UI.
- *
- *
*
*/
public enum SoftwareModuleEventType {
- NEW_SOFTWARE_MODULE, UPDATED_SOFTWARE_MODULE, DELETE_SOFTWARE_MODULE, SELECTED_SOFTWARE_MODULE, MAXIMIZED, MINIMIZED, ARTIFACTS_CHANGED, ASSIGN_SOFTWARE_MODULE
+ ARTIFACTS_CHANGED, ASSIGN_SOFTWARE_MODULE
}
private SoftwareModuleEventType softwareModuleEventType;
- private SoftwareModule softwareModule;
+ /**
+ * Creates software module event.
+ *
+ * @param entityEventType
+ * the event type
+ * @param softwareModule
+ * the module
+ */
+ public SoftwareModuleEvent(final BaseEntityEventType entityEventType, final SoftwareModule softwareModule) {
+ super(entityEventType, softwareModule);
+ }
/**
* Creates software module event.
*
* @param softwareModuleEventType
- * reference of {@link SoftwareModuleEventType}
+ * the event type
* @param softwareModule
- * reference of {@link SoftwareModule}
+ * the module
*/
public SoftwareModuleEvent(final SoftwareModuleEventType softwareModuleEventType,
final SoftwareModule softwareModule) {
- super();
+ super(null, softwareModule);
this.softwareModuleEventType = softwareModuleEventType;
- this.softwareModule = softwareModule;
}
public SoftwareModuleEventType getSoftwareModuleEventType() {
return softwareModuleEventType;
}
- public void setSoftwareModuleEventType(final SoftwareModuleEventType softwareModuleEventType) {
- this.softwareModuleEventType = softwareModuleEventType;
- }
-
- public SoftwareModule getSoftwareModule() {
- return softwareModule;
- }
-
- public void setSoftwareModule(final SoftwareModule softwareModule) {
- this.softwareModule = softwareModule;
- }
-
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java
index a3f045a08..060800fb8 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/event/UploadViewAcceptCriteria.java
@@ -14,12 +14,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.hawkbit.ui.common.AbstractAcceptCriteria;
-import org.eclipse.hawkbit.ui.management.event.DragEvent;
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
-import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
-import org.eclipse.hawkbit.ui.utils.UINotification;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.vaadin.spring.events.EventBus;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
@@ -28,8 +23,6 @@ import com.vaadin.ui.Component;
/**
* Upload UI View for Accept criteria.
*
- *
- *
*/
@SpringComponent
@ViewScope
@@ -41,29 +34,6 @@ public class UploadViewAcceptCriteria extends AbstractAcceptCriteria {
private static final Map DROP_HINTS_CONFIGS = createDropHintConfigurations();
- @Autowired
- private transient UINotification uiNotification;
-
- @Autowired
- private transient EventBus.SessionEventBus eventBus;
-
- @Override
- protected void analyseDragComponent(final Component compsource) {
- final String sourceID = getComponentId(compsource);
- final Object event = DROP_HINTS_CONFIGS.get(sourceID);
- eventBus.publish(this, event);
- }
-
- @Override
- protected void hideDropHints() {
- eventBus.publish(this, DragEvent.HIDE_DROP_HINT);
- }
-
- @Override
- protected void invalidDrop() {
- uiNotification.displayValidationError(SPUILabelDefinitions.ACTION_NOT_ALLOWED);
- }
-
@Override
protected String getComponentId(final Component component) {
String id = component.getId();
@@ -78,11 +48,6 @@ public class UploadViewAcceptCriteria extends AbstractAcceptCriteria {
return DROP_HINTS_CONFIGS;
}
- @Override
- protected void publishDragStartEvent(final Object event) {
- eventBus.publish(this, event);
- }
-
@Override
protected Map> getDropConfigurations() {
return DROP_CONFIGS;
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java
index ef4b17da7..ee2fc356f 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/SMDeleteActionsLayout.java
@@ -11,22 +11,15 @@ package org.eclipse.hawkbit.ui.artifacts.footer;
import java.util.HashSet;
import java.util.Set;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
-import org.eclipse.hawkbit.repository.SpPermissionChecker;
import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent;
import org.eclipse.hawkbit.ui.artifacts.event.UploadViewAcceptCriteria;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.common.footer.AbstractDeleteActionsLayout;
import org.eclipse.hawkbit.ui.management.event.DragEvent;
-import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
-import org.eclipse.hawkbit.ui.utils.UINotification;
import org.springframework.beans.factory.annotation.Autowired;
-import org.vaadin.spring.events.EventBus;
import org.vaadin.spring.events.EventScope;
import org.vaadin.spring.events.annotation.EventBusListenerMethod;
@@ -35,7 +28,6 @@ import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Component;
-import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Table.TableTransferable;
import com.vaadin.ui.UI;
@@ -50,18 +42,6 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout {
private static final long serialVersionUID = -3273982053389866299L;
- @Autowired
- private I18N i18n;
-
- @Autowired
- private SpPermissionChecker permChecker;
-
- @Autowired
- private transient EventBus.SessionEventBus eventBus;
-
- @Autowired
- private transient UINotification notification;
-
@Autowired
private ArtifactUploadState artifactUploadState;
@@ -71,22 +51,6 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout {
@Autowired
private UploadViewAcceptCriteria uploadViewAcceptCriteria;
- @Override
- @PostConstruct
- protected void init() {
- super.init();
- eventBus.subscribe(this);
- }
-
- @PreDestroy
- void destroy() {
- /*
- * It's good manners to do this, even though vaadin-spring will
- * automatically unsubscribe when this UI is garbage collected.
- */
- eventBus.unsubscribe(this);
- }
-
@EventBusListenerMethod(scope = EventScope.SESSION)
void onEvent(final UploadArtifactUIEvent event) {
@@ -211,26 +175,11 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout {
updateActionsCount(count);
}
- @Override
- protected String getNoActionsButtonLabel() {
- return i18n.get("button.no.actions");
- }
-
- @Override
- protected String getActionsButtonLabel() {
- return i18n.get("button.actions");
- }
-
@Override
protected void restoreActionCount() {
updateSWActionCount();
}
- @Override
- protected String getUnsavedActionsWindowCaption() {
- return i18n.get("caption.save.window");
- }
-
@Override
protected void unsavedActionsWindowClosed() {
final String message = uploadViewConfirmationWindowLayout.getConsolidatedMessage();
@@ -241,7 +190,7 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout {
@Override
protected Component getUnsavedActionsWindowContent() {
- uploadViewConfirmationWindowLayout.init();
+ uploadViewConfirmationWindowLayout.initialize();
return uploadViewConfirmationWindowLayout;
}
@@ -251,33 +200,4 @@ public class SMDeleteActionsLayout extends AbstractDeleteActionsLayout {
|| !artifactUploadState.getSelectedDeleteSWModuleTypes().isEmpty();
}
- @Override
- protected boolean hasCountMessage() {
- return false;
- }
-
- @Override
- protected Label getCountMessageLabel() {
- return null;
- }
-
- @Override
- protected boolean hasBulkUploadPermission() {
- return false;
- }
-
- @Override
- protected void showBulkUploadWindow() {
- /**
- * Bulk upload not supported .No implementation required.
- */
- }
-
- @Override
- protected void restoreBulkUploadStatusCount() {
- /**
- * Bulk upload not supported .No implementation required.
- */
- }
-
}
diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java
index 49e9ab59f..e6284d5d6 100644
--- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java
+++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/footer/UploadViewConfirmationWindowLayout.java
@@ -14,23 +14,17 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.annotation.PostConstruct;
-
import org.eclipse.hawkbit.repository.SoftwareManagement;
import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent;
import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState;
import org.eclipse.hawkbit.ui.artifacts.state.CustomFile;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.AbstractConfirmationWindowLayout;
import org.eclipse.hawkbit.ui.common.confirmwindow.layout.ConfirmationTab;
-import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
-import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder;
import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil;
-import org.eclipse.hawkbit.ui.utils.I18N;
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
import org.eclipse.hawkbit.ui.utils.SPUIDefinitions;
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
import org.springframework.beans.factory.annotation.Autowired;
-import org.vaadin.spring.events.EventBus;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
@@ -39,8 +33,8 @@ import com.vaadin.server.FontAwesome;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Table.Align;
-import com.vaadin.ui.themes.ValoTheme;
/**
* Abstract layout of confirm actions window.
@@ -62,32 +56,12 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
private static final String DISCARD = "Discard";
- @Autowired
- private I18N i18n;
-
@Autowired
private transient SoftwareManagement softwareManagement;
- @Autowired
- private transient EventBus.SessionEventBus eventBus;
-
@Autowired
private ArtifactUploadState artifactUploadState;
- /**
- * Initialze the component.
- */
- @PostConstruct
- void init() {
- super.inittialize();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.hawkbit.server.ui.common.confirmwindow.layout.
- * AbstractConfirmationWindowLayout# getConfimrationTabs()
- */
@Override
protected Map getConfimrationTabs() {
final Map tabs = new HashMap<>();
@@ -116,26 +90,13 @@ public class UploadViewConfirmationWindowLayout extends AbstractConfirmationWind
// Add the discard action column
tab.getTable().addGeneratedColumn(SW_DISCARD_CHGS, (source, itemId, columnId) -> {
- final Button deleteswIcon = SPUIComponentProvider.getButton("", "", SPUILabelDefinitions.DISCARD,
- ValoTheme.BUTTON_TINY + " " + "redicon", true, FontAwesome.REPLY,
- SPUIButtonStyleSmallNoBorder.class);
- deleteswIcon.setData(itemId);
- deleteswIcon.setImmediate(true);
- deleteswIcon.addClickListener(event -> discardSoftwareDelete(event, itemId, tab));
- return deleteswIcon;
+ final ClickListener clickListener = event -> discardSoftwareDelete(event, itemId, tab);
+ return createDiscardButton(itemId, clickListener);
});
- // set the visible columns
- final List