Code format hawkbit-runtime (#1947)
Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -3,10 +3,10 @@ hawkBit Sandbox
|
|||||||
|
|
||||||
## Try out the update server in our hawkBit sandbox
|
## Try out the update server in our hawkBit sandbox
|
||||||
|
|
||||||
- try out Management API https://hawkbit.eclipseprojects.io/rest/v1/targets (don't forget basic auth header; username: demo, passwd: demo)
|
- try out Management API https://hawkbit.eclipseprojects.io/rest/v1/targets (don't forget basic auth header; username:
|
||||||
|
demo, passwd: demo)
|
||||||
- try out DDI API https://hawkbit.eclipseprojects.io/DEFAULT/controller/v1/MYTESTDEVICE
|
- try out DDI API https://hawkbit.eclipseprojects.io/DEFAULT/controller/v1/MYTESTDEVICE
|
||||||
|
|
||||||
|
|
||||||
## Sandbox Setup
|
## Sandbox Setup
|
||||||
|
|
||||||
**1. File Structure**
|
**1. File Structure**
|
||||||
@@ -35,11 +35,12 @@ Reset the Sandbox once a week with a cron-job and log its output.
|
|||||||
$ sudo /.sandbox/scripts/initialize-cronjobs.sh
|
$ sudo /.sandbox/scripts/initialize-cronjobs.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
**3. Nginx Reverse Proxy**
|
**3. Nginx Reverse Proxy**
|
||||||
|
|
||||||
Start the stack for the Nginx reverse proxy with Let's Encrypt support. Thanks to JrCs for providing the Docker container
|
Start the stack for the Nginx reverse proxy with Let's Encrypt support. Thanks to JrCs for providing the Docker
|
||||||
and instructions with his [Docker-Letsencrypt-Nginx-Companion](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion).
|
container
|
||||||
|
and instructions with
|
||||||
|
his [Docker-Letsencrypt-Nginx-Companion](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion).
|
||||||
|
|
||||||
```
|
```
|
||||||
$ docker stack deploy -c /.sandbox/stacks/sandbox/docker-compose-stack.yml proxy
|
$ docker stack deploy -c /.sandbox/stacks/sandbox/docker-compose-stack.yml proxy
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
hawkBit Runtime
|
hawkBit Runtime
|
||||||
===
|
===
|
||||||
|
|
||||||
|
|
||||||
| Folder | Description |
|
| Folder | Description |
|
||||||
|--------------------------|----------------------------------------------------------------------------------------------------------------------------|
|
|--------------------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `.sandbox/` | Content of the hawkBit sandbox installation running on [hawkbit.eclipseprojects.io](https://hawkbit.eclipseprojects.io/UI/). |
|
| `.sandbox/` | Content of the hawkBit sandbox installation running on [hawkbit.eclipseprojects.io](https://hawkbit.eclipseprojects.io/UI/). |
|
||||||
| `docker/` | Docker related files, such es Dockerfiles, compose and stack files to quickly start up an hawkBit. |
|
| `docker/` | Docker related files, such es Dockerfiles, compose and stack files to quickly start up an hawkBit. |
|
||||||
| `docker/docker_build/` | Docker images build related files, such es Dockerfiles and build shell scripts. |
|
| `docker/docker_build/` | Docker images build related files, such es Dockerfiles and build shell scripts. |
|
||||||
@@ -12,4 +11,5 @@ hawkBit Runtime
|
|||||||
| `hawkbit-dmf-server/` | Spring-Boot application of hawkBit DMF server. |
|
| `hawkbit-dmf-server/` | Spring-Boot application of hawkBit DMF server. |
|
||||||
| `hawkbit-mgmt-server/` | Spring-Boot application of hawkBit Management server. Provides REST Management API and rollouts / auto assigment processing |
|
| `hawkbit-mgmt-server/` | Spring-Boot application of hawkBit Management server. Provides REST Management API and rollouts / auto assigment processing |
|
||||||
|
|
||||||
Note: micro service setup requires all services using DB to use same shared DB. So, they don't work with default in memory H2 database. Docker compose with mysql shows an example setup.
|
Note: micro service setup requires all services using DB to use same shared DB. So, they don't work with default in
|
||||||
|
memory H2 database. Docker compose with mysql shows an example setup.
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ Start the hawkBit Update Server together with an MySQL and RabbitMQ instance as
|
|||||||
$ docker-compose up -d
|
$ docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## C: Docker Stack
|
## C: Docker Stack
|
||||||
|
|
||||||
Start the hawkBit Update Server and Device Simulator together with an MySQL and RabbitMQ instance as services within a swarm
|
Start the hawkBit Update Server and Device Simulator together with an MySQL and RabbitMQ instance as services within a
|
||||||
|
swarm
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ docker swarm init
|
$ docker swarm init
|
||||||
@@ -33,7 +33,7 @@ $ docker stack deploy -c docker-compose-deps-mysql.yml hawkbit
|
|||||||
# Access
|
# Access
|
||||||
|
|
||||||
| Service / Container | URL | Login | A | B | C |
|
| Service / Container | URL | Login | A | B | C |
|
||||||
|---|---|---|---|---|---|
|
|--------------------------|--------------------------------------------------|-------------|----------|----------|----------|
|
||||||
| hawkBit Update Server | [http://localhost:8080/](http://localhost:8080/) | admin:admin | ✓ | ✓ | ✓ |
|
| hawkBit Update Server | [http://localhost:8080/](http://localhost:8080/) | admin:admin | ✓ | ✓ | ✓ |
|
||||||
| hawkBit Device Simulator | [http://localhost:8083/](http://localhost:8083/) | - | | | ✓ |
|
| hawkBit Device Simulator | [http://localhost:8083/](http://localhost:8083/) | - | | | ✓ |
|
||||||
| MySQL | localhost:3306/hawkbit | root | | ✓ | ✓ |
|
| MySQL | localhost:3306/hawkbit | root | | ✓ | ✓ |
|
||||||
@@ -41,7 +41,9 @@ $ docker stack deploy -c docker-compose-deps-mysql.yml hawkbit
|
|||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
You can override application.properties by setting an environment variable SPRING_APPLICATION_JSON for hawkbit container.
|
You can override application.properties by setting an environment variable SPRING_APPLICATION_JSON for hawkbit
|
||||||
|
container.
|
||||||
|
|
||||||
```
|
```
|
||||||
hawkbit:
|
hawkbit:
|
||||||
image: "hawkbit/hawkbit-update-server:latest-mysql"
|
image: "hawkbit/hawkbit-update-server:latest-mysql"
|
||||||
|
|||||||
@@ -1,55 +1,82 @@
|
|||||||
hawkBit Docker Build
|
hawkBit Docker Build
|
||||||
===
|
===
|
||||||
This directory contains docker files for building both hawkBit docker flavours:
|
This directory contains docker files for building both hawkBit docker flavours:
|
||||||
|
|
||||||
* _standard_ - hawkBit images without mysql driver
|
* _standard_ - hawkBit images without mysql driver
|
||||||
* _mysql_ - with MariaDB Java connector with support for MySQL.
|
* _mysql_ - with MariaDB Java connector with support for MySQL.
|
||||||
|
|
||||||
Both flavours of are almost the same, just mysql has in addition a MariaDB Java connector and is started, by default, with mysql Spring profile.
|
Both flavours of are almost the same, just mysql has in addition a MariaDB Java connector and is started, by default,
|
||||||
|
with mysql Spring profile.
|
||||||
|
|
||||||
For every flavour there are two build types:
|
For every flavour there are two build types:
|
||||||
|
|
||||||
* _release_ - uses officially released hawkBit versions, downloading them from https://repo1.maven.org
|
* _release_ - uses officially released hawkBit versions, downloading them from https://repo1.maven.org
|
||||||
* _development/dev_ - uses the local maven repository with built by developer (or just downloaded from any maven repository) hawkBit applications
|
* _development/dev_ - uses the local maven repository with built by developer (or just downloaded from any maven
|
||||||
|
repository) hawkBit applications
|
||||||
|
|
||||||
## Build overview
|
## Build overview
|
||||||
|
|
||||||
Building images supports the following build arguments (i.e. ARG-s which could be passed using _--build-arg_):
|
Building images supports the following build arguments (i.e. ARG-s which could be passed using _--build-arg_):
|
||||||
* _JAVA_VERSION_ - **[OPTIONAL, if not set a default is used]** the Java version of the eclipse-temurin jre-alpine base image to be used.
|
|
||||||
* _HAWKBIT_APP_ - **[OPTIONAL, if not set _hawkbit-update-server_ is used]** the application to be build. Currently, there is just _hawkbit-update-server_ but in future, if hawkBit is split to micro-services, there could be different micro-service apps.
|
* _JAVA_VERSION_ - **[OPTIONAL, if not set a default is used]** the Java version of the eclipse-temurin jre-alpine base
|
||||||
* _HAWKBIT_VERSION_ - **[OPTIONAL, if not set a default, should be the last officially released version, is used]** the application version
|
image to be used.
|
||||||
|
* _HAWKBIT_APP_ - **[OPTIONAL, if not set _hawkbit-update-server_ is used]** the application to be build. Currently,
|
||||||
|
there is just _hawkbit-update-server_ but in future, if hawkBit is split to micro-services, there could be different
|
||||||
|
micro-service apps.
|
||||||
|
* _HAWKBIT_VERSION_ - **[OPTIONAL, if not set a default, should be the last officially released version, is used]** the
|
||||||
|
application version
|
||||||
* _CONTAINER_PORT_ - **[OPTIONAL, if not set 8080 is used]** on which the app opens the http server (if available)
|
* _CONTAINER_PORT_ - **[OPTIONAL, if not set 8080 is used]** on which the app opens the http server (if available)
|
||||||
* _MARIADB_DRIVER_VERSION_ (mysql flavours only!) - **[OPTIONAL, if not set a default is used]** the version of MariaDB connector to be used
|
* _MARIADB_DRIVER_VERSION_ (mysql flavours only!) - **[OPTIONAL, if not set a default is used]** the version of MariaDB
|
||||||
|
connector to be used
|
||||||
|
|
||||||
Additionally, tge _development_ builds shall be started with docker build context the local maven repository
|
Additionally, tge _development_ builds shall be started with docker build context the local maven repository
|
||||||
|
|
||||||
## Build standard
|
## Build standard
|
||||||
|
|
||||||
Standard flavour could be build, for example, with (fixed version 0.4.1 is just an example):
|
Standard flavour could be build, for example, with (fixed version 0.4.1 is just an example):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build --build-arg HAWKBIT_APP=hawkbit-update-server --build-arg HAWKBIT_VERSION=0.4.1 -t hawkbit_update_server:0.4.1 . -f Dockerfile
|
docker build --build-arg HAWKBIT_APP=hawkbit-update-server --build-arg HAWKBIT_VERSION=0.4.1 -t hawkbit_update_server:0.4.1 . -f Dockerfile
|
||||||
```
|
```
|
||||||
|
|
||||||
or just by:
|
or just by:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build --build-arg HAWKBIT_VERSION=0.4.1 -t hawkbit_update_server:0.4.1 .
|
docker build --build-arg HAWKBIT_VERSION=0.4.1 -t hawkbit_update_server:0.4.1 .
|
||||||
```
|
```
|
||||||
|
|
||||||
having that docker uses by default _Dockerfile_ and the _hawkbit-update-server_ is the default _HAWKBIT_APP_.
|
having that docker uses by default _Dockerfile_ and the _hawkbit-update-server_ is the default _HAWKBIT_APP_.
|
||||||
|
|
||||||
To build standard development docker images, e.g. snapshot based, you could use something like:
|
To build standard development docker images, e.g. snapshot based, you could use something like:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build -t hawkbit_update_server:0-SNAPSHOT -f Dockerfile_dev ~/.m2/repository
|
docker build -t hawkbit_update_server:0-SNAPSHOT -f Dockerfile_dev ~/.m2/repository
|
||||||
```
|
```
|
||||||
Note that here you have to use your maven repository containing the hawkBit app as docker build context, in the example case _~/.m2/repository_
|
|
||||||
|
Note that here you have to use your maven repository containing the hawkBit app as docker build context, in the example
|
||||||
|
case _~/.m2/repository_
|
||||||
|
|
||||||
## Build mysql
|
## Build mysql
|
||||||
|
|
||||||
Mysql flavour could be build, for example, with:
|
Mysql flavour could be build, for example, with:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build --build-arg HAWKBIT_APP=hawkbit-update-server --build-arg HAWKBIT_VERSION=0.4.1 -t hawkbit_update_server:0.4.1-mysql . -f Dockerfile-mysql
|
docker build --build-arg HAWKBIT_APP=hawkbit-update-server --build-arg HAWKBIT_VERSION=0.4.1 -t hawkbit_update_server:0.4.1-mysql . -f Dockerfile-mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
or just by:
|
or just by:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build --build-arg -t hawkbit_update_server:0.4.1-mysql --build-arg HAWKBIT_VERSION=0.4.1 . -f Dockerfile-mysql
|
docker build --build-arg -t hawkbit_update_server:0.4.1-mysql --build-arg HAWKBIT_VERSION=0.4.1 . -f Dockerfile-mysql
|
||||||
```
|
```
|
||||||
|
|
||||||
having that the _hawkbit-update-server_ is the default _HAWKBIT_APP_.
|
having that the _hawkbit-update-server_ is the default _HAWKBIT_APP_.
|
||||||
|
|
||||||
To build development mysql docker images, e.g. snapshot based, you could use something like:
|
To build development mysql docker images, e.g. snapshot based, you could use something like:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
docker build -t hawkbit_update_server:0-SNAPSHOT-mysql -f Dockerfile_dev-mysql ~/.m2/repository
|
docker build -t hawkbit_update_server:0-SNAPSHOT-mysql -f Dockerfile_dev-mysql ~/.m2/repository
|
||||||
```
|
```
|
||||||
Note that here you have to use your maven repository containing the hawkBit app as docker build context, in the example case _~/.m2/repository_
|
|
||||||
|
Note that here you have to use your maven repository containing the hawkBit app as docker build context, in the example
|
||||||
|
case _~/.m2/repository_
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
# hawkBit DDI Server (EXPERIMENTAL!)
|
# hawkBit DDI Server (EXPERIMENTAL!)
|
||||||
The hawkBit DDI Server is a standalone spring-boot application with an embedded servlet container. It should be started with at least hawkbit-mgmt-server.
|
|
||||||
|
The hawkBit DDI Server is a standalone spring-boot application with an embedded servlet container. It should be started
|
||||||
|
with at least hawkbit-mgmt-server.
|
||||||
|
|
||||||
## On your own workstation
|
## On your own workstation
|
||||||
|
|
||||||
@@ -18,14 +20,22 @@ run org.eclipse.hawkbit.app.ddi.DDIStart
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
The Management API can be accessed via http://localhost:8081/rest/v1
|
The Management API can be accessed via http://localhost:8081/rest/v1
|
||||||
The root url http://localhost:8081 will redirect directly to the Swagger Management UI
|
The root url http://localhost:8081 will redirect directly to the Swagger Management UI
|
||||||
|
|
||||||
### Clustering (Experimental!!!)
|
### Clustering (Experimental!!!)
|
||||||
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
|
|
||||||
|
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any
|
||||||
|
micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g.
|
||||||
|
auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions
|
||||||
|
of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not
|
||||||
|
run schedulers!
|
||||||
|
|
||||||
## Optional Protostuff for Sprign cloud bus
|
## Optional Protostuff for Sprign cloud bus
|
||||||
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
|
||||||
|
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could
|
||||||
|
use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
||||||
|
|
||||||
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
|
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
import org.springframework.web.servlet.view.RedirectView;
|
import org.springframework.web.servlet.view.RedirectView;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link SpringBootApplication} annotated class with a main method to start.
|
* A {@link SpringBootApplication} annotated class with a main method to start.
|
||||||
* The minimal configuration for the stand alone hawkBit DDI server.
|
* The minimal configuration for the stand alone hawkBit DDI server.
|
||||||
@@ -31,8 +30,7 @@ public class DDIStart {
|
|||||||
/**
|
/**
|
||||||
* Main method to start the spring-boot application.
|
* Main method to start the spring-boot application.
|
||||||
*
|
*
|
||||||
* @param args
|
* @param args the VM arguments.
|
||||||
* the VM arguments.
|
|
||||||
*/
|
*/
|
||||||
public static void main(final String[] args) {
|
public static void main(final String[] args) {
|
||||||
SpringApplication.run(DDIStart.class, args);
|
SpringApplication.run(DDIStart.class, args);
|
||||||
|
|||||||
@@ -24,11 +24,10 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
@ExtendWith(SharedSqlTestDatabaseExtension.class)
|
@ExtendWith(SharedSqlTestDatabaseExtension.class)
|
||||||
public abstract class AbstractSecurityTest {
|
public abstract class AbstractSecurityTest {
|
||||||
|
|
||||||
|
protected MockMvc mvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext context;
|
private WebApplicationContext context;
|
||||||
|
|
||||||
protected MockMvc mvc;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
|
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
|
||||||
|
|||||||
@@ -9,17 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app.ddi;
|
package org.eclipse.hawkbit.app.ddi;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.security.web.firewall.RequestRejectedException;
|
|
||||||
|
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
|
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app.ddi;
|
package org.eclipse.hawkbit.app.ddi;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
@@ -18,17 +21,14 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
|
|
||||||
@Feature("Integration Test - Security")
|
@Feature("Integration Test - Security")
|
||||||
@Story("PreAuthorized enabled")
|
@Story("PreAuthorized enabled")
|
||||||
@TestPropertySource(properties = {"spring.flyway.enabled=true"})
|
@TestPropertySource(properties = { "spring.flyway.enabled=true" })
|
||||||
public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests whether request fail if a role is forbidden for the user")
|
@Description("Tests whether request fail if a role is forbidden for the user")
|
||||||
@WithUser(authorities = { SpPermission.READ_TARGET } )
|
@WithUser(authorities = { SpPermission.READ_TARGET })
|
||||||
public void failIfNoRole() throws Exception {
|
public void failIfNoRole() throws Exception {
|
||||||
mvc.perform(get("/DEFAULT/controller/v1/controllerId")).andExpect(result ->
|
mvc.perform(get("/DEFAULT/controller/v1/controllerId")).andExpect(result ->
|
||||||
assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value()));
|
assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value()));
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# hawkBit DMF Server (EXPERIMENTAL!)
|
# hawkBit DMF Server (EXPERIMENTAL!)
|
||||||
The hawkBit DMF Server is a standalone spring-boot application with an embedded servlet container. It should be started with at least hawkbit-mgmt-server.
|
|
||||||
|
The hawkBit DMF Server is a standalone spring-boot application with an embedded servlet container. It should be started
|
||||||
|
with at least hawkbit-mgmt-server.
|
||||||
|
|
||||||
## On your own workstation
|
## On your own workstation
|
||||||
|
|
||||||
@@ -18,10 +20,17 @@ run org.eclipse.hawkbit.app.dmf.DMFStart
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Clustering (Experimental!!!)
|
### Clustering (Experimental!!!)
|
||||||
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
|
|
||||||
|
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any
|
||||||
|
micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g.
|
||||||
|
auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions
|
||||||
|
of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not
|
||||||
|
run schedulers!
|
||||||
|
|
||||||
## Optional Protostuff for Sprign cloud bus
|
## Optional Protostuff for Sprign cloud bus
|
||||||
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
|
||||||
|
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could
|
||||||
|
use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
||||||
|
|
||||||
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
|
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# hawkBit Management Server (EXPERIMENTAL!)
|
# hawkBit Management Server (EXPERIMENTAL!)
|
||||||
The hawkBit Management Server is a standalone spring-boot application with an embedded servlet container. It should be started with at least one (or both) of the device interface servers - hawkbit-ddi-server or/and hawkbit-dmf-server.
|
|
||||||
|
The hawkBit Management Server is a standalone spring-boot application with an embedded servlet container. It should be
|
||||||
|
started with at least one (or both) of the device interface servers - hawkbit-ddi-server or/and hawkbit-dmf-server.
|
||||||
|
|
||||||
## On your own workstation
|
## On your own workstation
|
||||||
|
|
||||||
@@ -18,14 +20,22 @@ run org.eclipse.hawkbit.app.mgmt.MgmtServerStart
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
The Management API can be accessed via http://localhost:8080/rest/v1
|
The Management API can be accessed via http://localhost:8080/rest/v1
|
||||||
The root url http://localhost:8080 will redirect directly to the Swagger Management UI
|
The root url http://localhost:8080 will redirect directly to the Swagger Management UI
|
||||||
|
|
||||||
### Clustering (Experimental!!!)
|
### Clustering (Experimental!!!)
|
||||||
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g. auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not run schedulers!
|
|
||||||
|
The micro-service instances are configured to communicate via Spring Cloud Bus. You could run multiple instances of any
|
||||||
|
micro-service but hawkbit-mgmt-server. Management server run some schedulers which shall not run simultaneously - e.g.
|
||||||
|
auto assignment checker and rollouts executor. To run multiple management server instances you shall do some extensions
|
||||||
|
of hawkbit to ensure that they wont run schedulers simultaneously or you shall configure all instances but one to do not
|
||||||
|
run schedulers!
|
||||||
|
|
||||||
## Optional Protostuff for Sprign cloud bus
|
## Optional Protostuff for Sprign cloud bus
|
||||||
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
|
||||||
|
The micro-service instances are configured to communicate via Spring Cloud Bus. Optionally, you could
|
||||||
|
use [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
||||||
|
|
||||||
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
|
**Note**: If Protostuff is enabled it shall be enabled on all microservices!
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
|
|||||||
@@ -37,10 +37,8 @@ public class ErrorController extends BasicErrorController {
|
|||||||
/**
|
/**
|
||||||
* A new {@link ErrorController}.
|
* A new {@link ErrorController}.
|
||||||
*
|
*
|
||||||
* @param errorAttributes
|
* @param errorAttributes the error attributes
|
||||||
* the error attributes
|
* @param serverProperties configuration properties
|
||||||
* @param serverProperties
|
|
||||||
* configuration properties
|
|
||||||
*/
|
*/
|
||||||
public ErrorController(final ErrorAttributes errorAttributes, final ServerProperties serverProperties) {
|
public ErrorController(final ErrorAttributes errorAttributes, final ServerProperties serverProperties) {
|
||||||
super(errorAttributes, serverProperties.getError());
|
super(errorAttributes, serverProperties.getError());
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.springframework.web.servlet.view.RedirectView;
|
|||||||
/**
|
/**
|
||||||
* A {@link SpringBootApplication} annotated class with a main method to start.
|
* A {@link SpringBootApplication} annotated class with a main method to start.
|
||||||
* The minimal configuration for the stand alone hawkBit server.
|
* The minimal configuration for the stand alone hawkBit server.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
|
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
|
||||||
@EnableHawkbitManagedSecurityConfiguration
|
@EnableHawkbitManagedSecurityConfiguration
|
||||||
|
|||||||
@@ -24,11 +24,10 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
@ExtendWith(SharedSqlTestDatabaseExtension.class)
|
@ExtendWith(SharedSqlTestDatabaseExtension.class)
|
||||||
public abstract class AbstractSecurityTest {
|
public abstract class AbstractSecurityTest {
|
||||||
|
|
||||||
|
protected MockMvc mvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext context;
|
private WebApplicationContext context;
|
||||||
|
|
||||||
protected MockMvc mvc;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
|
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
|
||||||
|
|||||||
@@ -9,17 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app.mgmt;
|
package org.eclipse.hawkbit.app.mgmt;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.security.web.firewall.RequestRejectedException;
|
|
||||||
|
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
|
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
|
||||||
|
|||||||
@@ -14,19 +14,17 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import io.qameta.allure.Description;
|
||||||
|
import io.qameta.allure.Feature;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpRole;
|
import org.eclipse.hawkbit.im.authentication.SpRole;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
|
||||||
import io.qameta.allure.Feature;
|
|
||||||
import io.qameta.allure.Story;
|
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
properties = {
|
properties = {
|
||||||
"hawkbit.dmf.rabbitmq.enabled=false",
|
"hawkbit.dmf.rabbitmq.enabled=false",
|
||||||
@@ -35,7 +33,7 @@ import io.qameta.allure.Story;
|
|||||||
CorsTest.ALLOWED_ORIGIN_FIRST + "," +
|
CorsTest.ALLOWED_ORIGIN_FIRST + "," +
|
||||||
CorsTest.ALLOWED_ORIGIN_SECOND,
|
CorsTest.ALLOWED_ORIGIN_SECOND,
|
||||||
"hawkbit.server.security.cors.exposedHeaders=" +
|
"hawkbit.server.security.cors.exposedHeaders=" +
|
||||||
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN})
|
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN })
|
||||||
@Feature("Integration Test - Security")
|
@Feature("Integration Test - Security")
|
||||||
@Story("CORS")
|
@Story("CORS")
|
||||||
public class CorsTest extends AbstractSecurityTest {
|
public class CorsTest extends AbstractSecurityTest {
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app.mgmt;
|
package org.eclipse.hawkbit.app.mgmt;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
@@ -19,18 +24,13 @@ import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
|
|
||||||
@Feature("Integration Test - Security")
|
@Feature("Integration Test - Security")
|
||||||
@Story("PreAuthorized enabled")
|
@Story("PreAuthorized enabled")
|
||||||
public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests whether request fail if a role is forbidden for the user")
|
@Description("Tests whether request fail if a role is forbidden for the user")
|
||||||
@WithUser(authorities = { SpPermission.READ_TARGET } )
|
@WithUser(authorities = { SpPermission.READ_TARGET })
|
||||||
public void failIfNoRole() throws Exception {
|
public void failIfNoRole() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/distributionsets")).andExpect(result ->
|
mvc.perform(get("/rest/v1/distributionsets")).andExpect(result ->
|
||||||
assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value()));
|
assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value()));
|
||||||
@@ -57,7 +57,7 @@ public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests whether read tenant config request fail if a tenant config (or read read) is not " +
|
@Description("Tests whether read tenant config request fail if a tenant config (or read read) is not " +
|
||||||
"granted for the user")
|
"granted for the user")
|
||||||
@WithUser(authorities = { SpPermission.READ_TARGET } )
|
@WithUser(authorities = { SpPermission.READ_TARGET })
|
||||||
public void onlyDSIfNoTenantConfig() throws Exception {
|
public void onlyDSIfNoTenantConfig() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> {
|
mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> {
|
||||||
// returns default DS type because of READ_TARGET
|
// returns default DS type because of READ_TARGET
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple;
|
package org.eclipse.hawkbit.ui.simple;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.sdk.HawkbitClient;
|
import java.util.function.Supplier;
|
||||||
import org.eclipse.hawkbit.sdk.Tenant;
|
|
||||||
import feign.FeignException;
|
import feign.FeignException;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtDistributionSetRestApi;
|
||||||
@@ -24,8 +24,9 @@ import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetRestApi;
|
|||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTagRestApi;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTargetTypeRestApi;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtTenantManagementRestApi;
|
||||||
|
import org.eclipse.hawkbit.sdk.HawkbitClient;
|
||||||
|
import org.eclipse.hawkbit.sdk.Tenant;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class HawkbitMgmtClient {
|
public class HawkbitMgmtClient {
|
||||||
@@ -49,7 +50,7 @@ public class HawkbitMgmtClient {
|
|||||||
this.tenant = tenant;
|
this.tenant = tenant;
|
||||||
this.hawkbitClient = hawkbitClient;
|
this.hawkbitClient = hawkbitClient;
|
||||||
|
|
||||||
softwareModuleRestApi = service(MgmtSoftwareModuleRestApi .class);
|
softwareModuleRestApi = service(MgmtSoftwareModuleRestApi.class);
|
||||||
softwareModuleTypeRestApi = service(MgmtSoftwareModuleTypeRestApi.class);
|
softwareModuleTypeRestApi = service(MgmtSoftwareModuleTypeRestApi.class);
|
||||||
distributionSetRestApi = service(MgmtDistributionSetRestApi.class);
|
distributionSetRestApi = service(MgmtDistributionSetRestApi.class);
|
||||||
distributionSetTypeRestApi = service(MgmtDistributionSetTypeRestApi.class);
|
distributionSetTypeRestApi = service(MgmtDistributionSetTypeRestApi.class);
|
||||||
@@ -77,6 +78,7 @@ public class HawkbitMgmtClient {
|
|||||||
boolean hasTargetRead() {
|
boolean hasTargetRead() {
|
||||||
return hasRead(() -> targetRestApi.getTarget("_#ETE$ER"));
|
return hasRead(() -> targetRestApi.getTarget("_#ETE$ER"));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasConfigRead() {
|
boolean hasConfigRead() {
|
||||||
return hasRead(() -> tenantManagementRestApi.getTenantConfigurationValue("_#ETE$ER"));
|
return hasRead(() -> tenantManagementRestApi.getTenantConfigurationValue("_#ETE$ER"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,13 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple;
|
package org.eclipse.hawkbit.ui.simple;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.TargetView;
|
import java.util.Optional;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.RolloutView;
|
|
||||||
import org.eclipse.hawkbit.ui.simple.security.AuthenticatedUser;
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.AboutView;
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.ConfigView;
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.DistributionSetView;
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.SoftwareModuleView;
|
|
||||||
import com.vaadin.flow.component.Unit;
|
import com.vaadin.flow.component.Unit;
|
||||||
import com.vaadin.flow.component.applayout.AppLayout;
|
import com.vaadin.flow.component.applayout.AppLayout;
|
||||||
import com.vaadin.flow.component.applayout.DrawerToggle;
|
import com.vaadin.flow.component.applayout.DrawerToggle;
|
||||||
@@ -39,18 +34,22 @@ import com.vaadin.flow.component.sidenav.SideNavItem;
|
|||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.server.auth.AccessAnnotationChecker;
|
import com.vaadin.flow.server.auth.AccessAnnotationChecker;
|
||||||
import com.vaadin.flow.theme.lumo.LumoUtility;
|
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.security.AuthenticatedUser;
|
||||||
import java.util.Optional;
|
import org.eclipse.hawkbit.ui.simple.view.AboutView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.ConfigView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.DistributionSetView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.RolloutView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.SoftwareModuleView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.TargetView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main view is a top-level placeholder for other views.
|
* The main view is a top-level placeholder for other views.
|
||||||
*/
|
*/
|
||||||
public class MainLayout extends AppLayout {
|
public class MainLayout extends AppLayout {
|
||||||
|
|
||||||
private H2 viewTitle;
|
|
||||||
|
|
||||||
private final transient AuthenticatedUser authenticatedUser;
|
private final transient AuthenticatedUser authenticatedUser;
|
||||||
private final AccessAnnotationChecker accessChecker;
|
private final AccessAnnotationChecker accessChecker;
|
||||||
|
private H2 viewTitle;
|
||||||
|
|
||||||
public MainLayout(final AuthenticatedUser authenticatedUser, final AccessAnnotationChecker accessChecker) {
|
public MainLayout(final AuthenticatedUser authenticatedUser, final AccessAnnotationChecker accessChecker) {
|
||||||
this.authenticatedUser = authenticatedUser;
|
this.authenticatedUser = authenticatedUser;
|
||||||
@@ -62,6 +61,15 @@ public class MainLayout extends AppLayout {
|
|||||||
addHeaderContent();
|
addHeaderContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterNavigation() {
|
||||||
|
super.afterNavigation();
|
||||||
|
viewTitle.setText(
|
||||||
|
Optional.ofNullable(getContent().getClass().getAnnotation(PageTitle.class))
|
||||||
|
.map(PageTitle::value)
|
||||||
|
.orElse(""));
|
||||||
|
}
|
||||||
|
|
||||||
private void addHeaderContent() {
|
private void addHeaderContent() {
|
||||||
final DrawerToggle toggle = new DrawerToggle();
|
final DrawerToggle toggle = new DrawerToggle();
|
||||||
toggle.setAriaLabel("Menu toggle");
|
toggle.setAriaLabel("Menu toggle");
|
||||||
@@ -143,13 +151,4 @@ public class MainLayout extends AppLayout {
|
|||||||
|
|
||||||
return layout;
|
return layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void afterNavigation() {
|
|
||||||
super.afterNavigation();
|
|
||||||
viewTitle.setText(
|
|
||||||
Optional.ofNullable(getContent().getClass().getAnnotation(PageTitle.class))
|
|
||||||
.map(PageTitle::value)
|
|
||||||
.orElse(""));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,13 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple;
|
package org.eclipse.hawkbit.ui.simple;
|
||||||
|
|
||||||
|
import static feign.Util.ISO_8859_1;
|
||||||
|
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import com.vaadin.flow.component.page.AppShellConfigurator;
|
import com.vaadin.flow.component.page.AppShellConfigurator;
|
||||||
import com.vaadin.flow.server.PWA;
|
import com.vaadin.flow.server.PWA;
|
||||||
import com.vaadin.flow.theme.Theme;
|
import com.vaadin.flow.theme.Theme;
|
||||||
@@ -35,15 +42,8 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import static feign.Util.ISO_8859_1;
|
|
||||||
|
|
||||||
@Theme(themeClass = Lumo.class)
|
@Theme(themeClass = Lumo.class)
|
||||||
@PWA(name="hawkBit UI", shortName="hawkBit UI")
|
@PWA(name = "hawkBit UI", shortName = "hawkBit UI")
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@Import(FeignClientsConfiguration.class)
|
@Import(FeignClientsConfiguration.class)
|
||||||
public class SimpleUIApp implements AppShellConfigurator {
|
public class SimpleUIApp implements AppShellConfigurator {
|
||||||
@@ -86,7 +86,7 @@ public class SimpleUIApp implements AppShellConfigurator {
|
|||||||
// accepts all user / pass, just delegating them to the feign client
|
// accepts all user / pass, just delegating them to the feign client
|
||||||
@Bean
|
@Bean
|
||||||
AuthenticationManager authenticationManager(final HawkbitMgmtClient hawkbitClient) {
|
AuthenticationManager authenticationManager(final HawkbitMgmtClient hawkbitClient) {
|
||||||
return authentication-> {
|
return authentication -> {
|
||||||
final String username = authentication.getName();
|
final String username = authentication.getName();
|
||||||
final String password = authentication.getCredentials().toString();
|
final String password = authentication.getCredentials().toString();
|
||||||
|
|
||||||
@@ -119,6 +119,7 @@ public class SimpleUIApp implements AppShellConfigurator {
|
|||||||
return new UsernamePasswordAuthenticationToken(
|
return new UsernamePasswordAuthenticationToken(
|
||||||
username, password,
|
username, password,
|
||||||
roles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).toList()) {
|
roles.stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role)).toList()) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eraseCredentials() {
|
public void eraseCredentials() {
|
||||||
// don't erase credentials because they will be used
|
// don't erase credentials because they will be used
|
||||||
|
|||||||
@@ -9,13 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.security;
|
package org.eclipse.hawkbit.ui.simple.security;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.vaadin.flow.spring.security.AuthenticationContext;
|
import com.vaadin.flow.spring.security.AuthenticationContext;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class AuthenticatedUser {
|
public class AuthenticatedUser {
|
||||||
|
|
||||||
private final AuthenticationContext authenticationContext;
|
private final AuthenticationContext authenticationContext;
|
||||||
|
|
||||||
public AuthenticatedUser(final AuthenticationContext authenticationContext) {
|
public AuthenticatedUser(final AuthenticationContext authenticationContext) {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.security;
|
package org.eclipse.hawkbit.ui.simple.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.LoginView;
|
|
||||||
import com.vaadin.flow.spring.security.VaadinWebSecurity;
|
import com.vaadin.flow.spring.security.VaadinWebSecurity;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.LoginView;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view;
|
package org.eclipse.hawkbit.ui.simple.view;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
import com.vaadin.flow.component.html.H2;
|
import com.vaadin.flow.component.html.H2;
|
||||||
import com.vaadin.flow.component.html.Image;
|
import com.vaadin.flow.component.html.Image;
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
@@ -17,12 +18,12 @@ import com.vaadin.flow.router.PageTitle;
|
|||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import com.vaadin.flow.router.RouteAlias;
|
import com.vaadin.flow.router.RouteAlias;
|
||||||
import com.vaadin.flow.theme.lumo.LumoUtility.Margin;
|
import com.vaadin.flow.theme.lumo.LumoUtility.Margin;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
||||||
|
|
||||||
@PageTitle("About")
|
@PageTitle("About")
|
||||||
@Route(value = "about", layout = MainLayout.class)
|
@Route(value = "about", layout = MainLayout.class)
|
||||||
@RouteAlias(value = "", layout = MainLayout.class)
|
@RouteAlias(value = "", layout = MainLayout.class)
|
||||||
@RolesAllowed({"ANONYMOUS"})
|
@RolesAllowed({ "ANONYMOUS" })
|
||||||
public class AboutView extends VerticalLayout {
|
public class AboutView extends VerticalLayout {
|
||||||
|
|
||||||
public AboutView() {
|
public AboutView() {
|
||||||
|
|||||||
@@ -12,21 +12,21 @@ package org.eclipse.hawkbit.ui.simple.view;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
|
||||||
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest;
|
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.Key;
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
import com.vaadin.flow.component.checkbox.Checkbox;
|
import com.vaadin.flow.component.checkbox.Checkbox;
|
||||||
import com.vaadin.flow.component.Component;
|
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
import com.vaadin.flow.component.textfield.TextField;
|
|
||||||
import com.vaadin.flow.component.textfield.NumberField;
|
import com.vaadin.flow.component.textfield.NumberField;
|
||||||
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.hawkbit.mgmt.json.model.system.MgmtSystemTenantConfigurationValueRequest;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
||||||
|
|
||||||
@PageTitle("Config")
|
@PageTitle("Config")
|
||||||
@Route(value = "config", layout = MainLayout.class)
|
@Route(value = "config", layout = MainLayout.class)
|
||||||
@@ -75,7 +75,8 @@ public class ConfigView extends VerticalLayout {
|
|||||||
nf.getElement().getStyle().set(WIDTH, PX_300);
|
nf.getElement().getStyle().set(WIDTH, PX_300);
|
||||||
value = nf;
|
value = nf;
|
||||||
} else {
|
} else {
|
||||||
log.debug("Unexpected value type: {} -> {} (class: {})", k, v.getValue(), v.getValue() == null ? "null" : v.getValue().getClass());
|
log.debug("Unexpected value type: {} -> {} (class: {})", k, v.getValue(),
|
||||||
|
v.getValue() == null ? "null" : v.getValue().getClass());
|
||||||
}
|
}
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
add(value);
|
add(value);
|
||||||
|
|||||||
@@ -9,12 +9,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view;
|
package org.eclipse.hawkbit.ui.simple.view;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
import java.util.Collections;
|
||||||
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
import java.util.Date;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
import java.util.HashSet;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
import java.util.List;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
import java.util.Map;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.Key;
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
@@ -33,26 +38,22 @@ import com.vaadin.flow.component.textfield.TextField;
|
|||||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetRequestBodyPost;
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSetRequestBodyPost;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetType;
|
import org.eclipse.hawkbit.mgmt.json.model.distributionsettype.MgmtDistributionSetType;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleAssigment;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleAssigment;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
|
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
||||||
import java.util.Collections;
|
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
||||||
import java.util.Date;
|
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
||||||
import java.util.HashSet;
|
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
||||||
import java.util.List;
|
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
||||||
import java.util.Map;
|
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@PageTitle("Distribution Sets")
|
@PageTitle("Distribution Sets")
|
||||||
@Route(value = "distribution_sets", layout = MainLayout.class)
|
@Route(value = "distribution_sets", layout = MainLayout.class)
|
||||||
@RolesAllowed({"DISTRIBUTION_SET_READ"})
|
@RolesAllowed({ "DISTRIBUTION_SET_READ" })
|
||||||
@Uses(Icon.class)
|
@Uses(Icon.class)
|
||||||
public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
|
public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
|
|||||||
return new SelectionGrid<>(
|
return new SelectionGrid<>(
|
||||||
new SelectionGrid.EntityRepresentation<>(
|
new SelectionGrid.EntityRepresentation<>(
|
||||||
MgmtSoftwareModule.class, MgmtSoftwareModule::getModuleId) {
|
MgmtSoftwareModule.class, MgmtSoftwareModule::getModuleId) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addColumns(Grid<MgmtSoftwareModule> grid) {
|
protected void addColumns(Grid<MgmtSoftwareModule> grid) {
|
||||||
grid.addColumn(MgmtSoftwareModule::getModuleId).setHeader(Constants.ID).setAutoWidth(true);
|
grid.addColumn(MgmtSoftwareModule::getModuleId).setHeader(Constants.ID).setAutoWidth(true);
|
||||||
@@ -258,7 +260,7 @@ public class DistributionSetView extends TableView<MgmtDistributionSet, Long> {
|
|||||||
close();
|
close();
|
||||||
final long distributionSetId = hawkbitClient.getDistributionSetRestApi()
|
final long distributionSetId = hawkbitClient.getDistributionSetRestApi()
|
||||||
.createDistributionSets(
|
.createDistributionSets(
|
||||||
List.of((MgmtDistributionSetRequestBodyPost)new MgmtDistributionSetRequestBodyPost()
|
List.of((MgmtDistributionSetRequestBodyPost) new MgmtDistributionSetRequestBodyPost()
|
||||||
.setType(type.getValue().getKey())
|
.setType(type.getValue().getKey())
|
||||||
.setName(name.getValue())
|
.setName(name.getValue())
|
||||||
.setVersion(version.getValue())
|
.setVersion(version.getValue())
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view;
|
package org.eclipse.hawkbit.ui.simple.view;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.security.AuthenticatedUser;
|
|
||||||
import com.vaadin.flow.component.login.LoginI18n;
|
import com.vaadin.flow.component.login.LoginI18n;
|
||||||
import com.vaadin.flow.component.login.LoginOverlay;
|
import com.vaadin.flow.component.login.LoginOverlay;
|
||||||
import com.vaadin.flow.router.BeforeEnterEvent;
|
import com.vaadin.flow.router.BeforeEnterEvent;
|
||||||
@@ -19,6 +18,7 @@ import com.vaadin.flow.router.Route;
|
|||||||
import com.vaadin.flow.router.internal.RouteUtil;
|
import com.vaadin.flow.router.internal.RouteUtil;
|
||||||
import com.vaadin.flow.server.VaadinService;
|
import com.vaadin.flow.server.VaadinService;
|
||||||
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.security.AuthenticatedUser;
|
||||||
|
|
||||||
@AnonymousAllowed
|
@AnonymousAllowed
|
||||||
@PageTitle("Login")
|
@PageTitle("Login")
|
||||||
|
|||||||
@@ -9,17 +9,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view;
|
package org.eclipse.hawkbit.ui.simple.view;
|
||||||
|
|
||||||
import com.vaadin.flow.component.checkbox.Checkbox;
|
import java.time.ZoneOffset;
|
||||||
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
import java.util.Date;
|
||||||
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
import java.util.List;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
import java.util.Map;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
import java.util.stream.Stream;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.Key;
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.Text;
|
import com.vaadin.flow.component.Text;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.checkbox.Checkbox;
|
||||||
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
|
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
|
||||||
import com.vaadin.flow.component.dependency.Uses;
|
import com.vaadin.flow.component.dependency.Uses;
|
||||||
import com.vaadin.flow.component.formlayout.FormLayout;
|
import com.vaadin.flow.component.formlayout.FormLayout;
|
||||||
@@ -37,7 +40,6 @@ import com.vaadin.flow.component.textfield.TextField;
|
|||||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtActionType;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
import org.eclipse.hawkbit.mgmt.json.model.distributionset.MgmtDistributionSet;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutCondition;
|
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutCondition;
|
||||||
@@ -46,18 +48,17 @@ import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutResponseBody;
|
|||||||
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPost;
|
import org.eclipse.hawkbit.mgmt.json.model.rollout.MgmtRolloutRestRequestBodyPost;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroupResponseBody;
|
import org.eclipse.hawkbit.mgmt.json.model.rolloutgroup.MgmtRolloutGroupResponseBody;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import java.time.ZoneOffset;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@PageTitle("Rollouts")
|
@PageTitle("Rollouts")
|
||||||
@Route(value = "rollouts", layout = MainLayout.class)
|
@Route(value = "rollouts", layout = MainLayout.class)
|
||||||
@RolesAllowed({"ROLLOUT_READ"})
|
@RolesAllowed({ "ROLLOUT_READ" })
|
||||||
@Uses(Icon.class)
|
@Uses(Icon.class)
|
||||||
public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
||||||
|
|
||||||
@@ -103,6 +104,7 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
|||||||
private static SelectionGrid<MgmtRolloutGroupResponseBody, Long> createGroupGrid() {
|
private static SelectionGrid<MgmtRolloutGroupResponseBody, Long> createGroupGrid() {
|
||||||
return new SelectionGrid<>(
|
return new SelectionGrid<>(
|
||||||
new SelectionGrid.EntityRepresentation<>(MgmtRolloutGroupResponseBody.class, MgmtRolloutGroupResponseBody::getRolloutGroupId) {
|
new SelectionGrid.EntityRepresentation<>(MgmtRolloutGroupResponseBody.class, MgmtRolloutGroupResponseBody::getRolloutGroupId) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addColumns(final Grid<MgmtRolloutGroupResponseBody> grid) {
|
protected void addColumns(final Grid<MgmtRolloutGroupResponseBody> grid) {
|
||||||
grid.addColumn(MgmtRolloutGroupResponseBody::getRolloutGroupId).setHeader(Constants.ID).setAutoWidth(true);
|
grid.addColumn(MgmtRolloutGroupResponseBody::getRolloutGroupId).setHeader(Constants.ID).setAutoWidth(true);
|
||||||
@@ -120,7 +122,8 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
|||||||
private final Grid<MgmtRolloutResponseBody> grid;
|
private final Grid<MgmtRolloutResponseBody> grid;
|
||||||
private final transient HawkbitMgmtClient hawkbitClient;
|
private final transient HawkbitMgmtClient hawkbitClient;
|
||||||
|
|
||||||
private Actions(final MgmtRolloutResponseBody rollout, final Grid<MgmtRolloutResponseBody> grid, final HawkbitMgmtClient hawkbitClient) {
|
private Actions(final MgmtRolloutResponseBody rollout, final Grid<MgmtRolloutResponseBody> grid,
|
||||||
|
final HawkbitMgmtClient hawkbitClient) {
|
||||||
this.rolloutId = rollout.getRolloutId();
|
this.rolloutId = rollout.getRolloutId();
|
||||||
this.grid = grid;
|
this.grid = grid;
|
||||||
this.hawkbitClient = hawkbitClient;
|
this.hawkbitClient = hawkbitClient;
|
||||||
@@ -258,10 +261,6 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
|||||||
|
|
||||||
private static class CreateDialog extends Utils.BaseDialog<Void> {
|
private static class CreateDialog extends Utils.BaseDialog<Void> {
|
||||||
|
|
||||||
private enum StartType {
|
|
||||||
MANUAL, AUTO, SCHEDULED
|
|
||||||
}
|
|
||||||
|
|
||||||
private final TextField name;
|
private final TextField name;
|
||||||
private final Select<MgmtDistributionSet> distributionSet;
|
private final Select<MgmtDistributionSet> distributionSet;
|
||||||
private final Select<MgmtTargetFilterQuery> targetFilter;
|
private final Select<MgmtTargetFilterQuery> targetFilter;
|
||||||
@@ -274,7 +273,6 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
|||||||
private final NumberField triggerThreshold;
|
private final NumberField triggerThreshold;
|
||||||
private final NumberField errorThreshold;
|
private final NumberField errorThreshold;
|
||||||
private final Checkbox dynamic = new Checkbox(Constants.DYNAMIC);
|
private final Checkbox dynamic = new Checkbox(Constants.DYNAMIC);
|
||||||
|
|
||||||
private final Button create = new Button("Create");
|
private final Button create = new Button("Create");
|
||||||
|
|
||||||
private CreateDialog(final HawkbitMgmtClient hawkbitClient) {
|
private CreateDialog(final HawkbitMgmtClient hawkbitClient) {
|
||||||
@@ -443,5 +441,9 @@ public class RolloutView extends TableView<MgmtRolloutResponseBody, Long> {
|
|||||||
hawkbitClient.getRolloutRestApi().create(request).getBody();
|
hawkbitClient.getRolloutRestApi().create(request).getBody();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum StartType {
|
||||||
|
MANUAL, AUTO, SCHEDULED
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view;
|
package org.eclipse.hawkbit.ui.simple.view;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
import java.io.File;
|
||||||
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
import java.io.IOException;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
import java.io.InputStream;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
import java.util.Collections;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
import java.util.Date;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.Key;
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
@@ -35,30 +43,22 @@ import com.vaadin.flow.component.upload.receivers.FileBuffer;
|
|||||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModule;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleRequestBodyPost;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremodule.MgmtSoftwareModuleRequestBodyPost;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType;
|
import org.eclipse.hawkbit.mgmt.json.model.softwaremoduletype.MgmtSoftwareModuleType;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@PageTitle("Software Modules")
|
@PageTitle("Software Modules")
|
||||||
@Route(value = "software_modules", layout = MainLayout.class)
|
@Route(value = "software_modules", layout = MainLayout.class)
|
||||||
@RolesAllowed({"SOFTWARE_MODULE_READ"})
|
@RolesAllowed({ "SOFTWARE_MODULE_READ" })
|
||||||
@Uses(Icon.class)
|
@Uses(Icon.class)
|
||||||
public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
|
public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
|
||||||
|
|
||||||
@@ -73,6 +73,7 @@ public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
|
|||||||
new SelectionGrid.EntityRepresentation<>(MgmtSoftwareModule.class, MgmtSoftwareModule::getModuleId) {
|
new SelectionGrid.EntityRepresentation<>(MgmtSoftwareModule.class, MgmtSoftwareModule::getModuleId) {
|
||||||
|
|
||||||
private final SoftwareModuleDetails details = new SoftwareModuleDetails(hawkbitClient);
|
private final SoftwareModuleDetails details = new SoftwareModuleDetails(hawkbitClient);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addColumns(final Grid<MgmtSoftwareModule> grid) {
|
protected void addColumns(final Grid<MgmtSoftwareModule> grid) {
|
||||||
grid.addColumn(MgmtSoftwareModule::getModuleId).setHeader(Constants.ID).setAutoWidth(true);
|
grid.addColumn(MgmtSoftwareModule::getModuleId).setHeader(Constants.ID).setAutoWidth(true);
|
||||||
@@ -108,6 +109,7 @@ public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
|
|||||||
private static SelectionGrid<MgmtArtifact, Long> createArtifactGrid() {
|
private static SelectionGrid<MgmtArtifact, Long> createArtifactGrid() {
|
||||||
return new SelectionGrid<>(
|
return new SelectionGrid<>(
|
||||||
new SelectionGrid.EntityRepresentation<>(MgmtArtifact.class, MgmtArtifact::getArtifactId) {
|
new SelectionGrid.EntityRepresentation<>(MgmtArtifact.class, MgmtArtifact::getArtifactId) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addColumns(final Grid<MgmtArtifact> grid) {
|
protected void addColumns(final Grid<MgmtArtifact> grid) {
|
||||||
grid.addColumn(MgmtArtifact::getArtifactId).setHeader(Constants.ID).setAutoWidth(true);
|
grid.addColumn(MgmtArtifact::getArtifactId).setHeader(Constants.ID).setAutoWidth(true);
|
||||||
@@ -329,7 +331,7 @@ public class SoftwareModuleView extends TableView<MgmtSoftwareModule, Long> {
|
|||||||
|
|
||||||
public MultipartFileImpl(final FileBuffer fileBuffer, final long contentLength, final String mimeType) {
|
public MultipartFileImpl(final FileBuffer fileBuffer, final long contentLength, final String mimeType) {
|
||||||
this.fileBuffer = fileBuffer;
|
this.fileBuffer = fileBuffer;
|
||||||
this. contentLength = contentLength;
|
this.contentLength = contentLength;
|
||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,17 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view;
|
package org.eclipse.hawkbit.ui.simple.view;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
import java.util.Collections;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
import java.util.Date;
|
||||||
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
import java.util.LinkedList;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
import java.util.List;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
import java.util.Map;
|
||||||
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.Key;
|
import com.vaadin.flow.component.Key;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
@@ -33,27 +38,23 @@ import com.vaadin.flow.component.textfield.TextField;
|
|||||||
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
import com.vaadin.flow.data.renderer.ComponentRenderer;
|
||||||
import com.vaadin.flow.router.PageTitle;
|
import com.vaadin.flow.router.PageTitle;
|
||||||
import com.vaadin.flow.router.Route;
|
import com.vaadin.flow.router.Route;
|
||||||
import jakarta.annotation.security.RolesAllowed;
|
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
|
import org.eclipse.hawkbit.mgmt.json.model.tag.MgmtTag;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTarget;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
|
import org.eclipse.hawkbit.mgmt.json.model.target.MgmtTargetRequestBody;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQuery;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
|
import org.eclipse.hawkbit.mgmt.json.model.targetfilter.MgmtTargetFilterQueryRequestBody;
|
||||||
import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetType;
|
import org.eclipse.hawkbit.mgmt.json.model.targettype.MgmtTargetType;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.HawkbitMgmtClient;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.MainLayout;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.Filter;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.SelectionGrid;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.TableView;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.util.Utils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@PageTitle("Targets")
|
@PageTitle("Targets")
|
||||||
@Route(value = "targets", layout = MainLayout.class)
|
@Route(value = "targets", layout = MainLayout.class)
|
||||||
@RolesAllowed({"TARGET_READ"})
|
@RolesAllowed({ "TARGET_READ" })
|
||||||
@Uses(Icon.class)
|
@Uses(Icon.class)
|
||||||
public class TargetView extends TableView<MgmtTarget, String> {
|
public class TargetView extends TableView<MgmtTarget, String> {
|
||||||
|
|
||||||
@@ -156,7 +157,8 @@ public class TargetView extends TableView<MgmtTarget, String> {
|
|||||||
.getFilters(0, 30, null, null, null)
|
.getFilters(0, 30, null, null, null)
|
||||||
.getBody().getContent())
|
.getBody().getContent())
|
||||||
.orElse(Collections.emptyList()));
|
.orElse(Collections.emptyList()));
|
||||||
savedFilters.setItemLabelGenerator(query -> Optional.ofNullable(query).map(MgmtTargetFilterQuery::getName).orElse("<select saved filter>"));
|
savedFilters.setItemLabelGenerator(
|
||||||
|
query -> Optional.ofNullable(query).map(MgmtTargetFilterQuery::getName).orElse("<select saved filter>"));
|
||||||
savedFilters.setWidthFull();
|
savedFilters.setWidthFull();
|
||||||
|
|
||||||
textFilter.setWidthFull();
|
textFilter.setWidthFull();
|
||||||
|
|||||||
@@ -9,6 +9,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view.util;
|
package org.eclipse.hawkbit.ui.simple.view.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.HasValue;
|
import com.vaadin.flow.component.HasValue;
|
||||||
import com.vaadin.flow.component.button.Button;
|
import com.vaadin.flow.component.button.Button;
|
||||||
@@ -19,15 +28,6 @@ import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
|||||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
import com.vaadin.flow.theme.lumo.LumoUtility;
|
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class Filter extends Div {
|
public class Filter extends Div {
|
||||||
|
|
||||||
private transient Rsql rsql;
|
private transient Rsql rsql;
|
||||||
@@ -46,7 +46,7 @@ public class Filter extends Div {
|
|||||||
filtersDiv.add(primaryRsql.components());
|
filtersDiv.add(primaryRsql.components());
|
||||||
filtersDiv.addClassName(LumoUtility.Gap.SMALL);
|
filtersDiv.addClassName(LumoUtility.Gap.SMALL);
|
||||||
|
|
||||||
final Button searchBtn = Utils.tooltip(new Button(VaadinIcon.REFRESH.create()),"Search");
|
final Button searchBtn = Utils.tooltip(new Button(VaadinIcon.REFRESH.create()), "Search");
|
||||||
searchBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
searchBtn.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
searchBtn.addClickListener(e -> changeListener.accept(rsql.filter()));
|
searchBtn.addClickListener(e -> changeListener.accept(rsql.filter()));
|
||||||
final Button resetBtn = Utils.tooltip(new Button(VaadinIcon.ERASER.create()), "Reset");
|
final Button resetBtn = Utils.tooltip(new Button(VaadinIcon.ERASER.create()), "Reset");
|
||||||
|
|||||||
@@ -9,11 +9,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view.util;
|
package org.eclipse.hawkbit.ui.simple.view.util;
|
||||||
|
|
||||||
import com.vaadin.flow.component.grid.Grid;
|
|
||||||
import com.vaadin.flow.component.grid.GridVariant;
|
|
||||||
import com.vaadin.flow.data.provider.Query;
|
|
||||||
import com.vaadin.flow.theme.lumo.LumoUtility;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -21,12 +16,16 @@ import java.util.function.BiFunction;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
|
import com.vaadin.flow.component.grid.GridVariant;
|
||||||
|
import com.vaadin.flow.data.provider.Query;
|
||||||
|
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||||
|
|
||||||
// id type shall have proper equals and hashCode - i.e. eligible hash set element
|
// id type shall have proper equals and hashCode - i.e. eligible hash set element
|
||||||
public class SelectionGrid<T,ID> extends Grid<T> {
|
public class SelectionGrid<T, ID> extends Grid<T> {
|
||||||
|
|
||||||
private volatile String rsqlFilter;
|
private volatile String rsqlFilter;
|
||||||
|
|
||||||
|
|
||||||
public SelectionGrid(
|
public SelectionGrid(
|
||||||
final EntityRepresentation<T, ID> entityRepresentation) {
|
final EntityRepresentation<T, ID> entityRepresentation) {
|
||||||
this(entityRepresentation, null);
|
this(entityRepresentation, null);
|
||||||
|
|||||||
@@ -9,16 +9,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view.util;
|
package org.eclipse.hawkbit.ui.simple.view.util;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ui.simple.view.Constants;
|
|
||||||
import com.vaadin.flow.component.html.Div;
|
|
||||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
|
||||||
import com.vaadin.flow.data.provider.Query;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletionStage;
|
import java.util.concurrent.CompletionStage;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.html.Div;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.data.provider.Query;
|
||||||
|
import org.eclipse.hawkbit.ui.simple.view.Constants;
|
||||||
|
|
||||||
public class TableView<T, ID> extends Div implements Constants {
|
public class TableView<T, ID> extends Div implements Constants {
|
||||||
|
|
||||||
protected SelectionGrid<T, ID> selectionGrid;
|
protected SelectionGrid<T, ID> selectionGrid;
|
||||||
@@ -30,12 +30,14 @@ public class TableView<T, ID> extends Div implements Constants {
|
|||||||
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
||||||
this(rsql, null, entityRepresentation, queryFn, null, null);
|
this(rsql, null, entityRepresentation, queryFn, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableView(
|
public TableView(
|
||||||
final Filter.Rsql rsql, final Filter.Rsql alternativeRsql,
|
final Filter.Rsql rsql, final Filter.Rsql alternativeRsql,
|
||||||
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
||||||
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
final BiFunction<Query<T, Void>, String, Stream<T>> queryFn) {
|
||||||
this(rsql, alternativeRsql, entityRepresentation, queryFn,null, null);
|
this(rsql, alternativeRsql, entityRepresentation, queryFn, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableView(
|
public TableView(
|
||||||
final Filter.Rsql rsql,
|
final Filter.Rsql rsql,
|
||||||
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
||||||
@@ -44,6 +46,7 @@ public class TableView<T, ID> extends Div implements Constants {
|
|||||||
final Function<SelectionGrid<T, ID>, CompletionStage<Void>> removeHandler) {
|
final Function<SelectionGrid<T, ID>, CompletionStage<Void>> removeHandler) {
|
||||||
this(rsql, null, entityRepresentation, queryFn, addHandler, removeHandler);
|
this(rsql, null, entityRepresentation, queryFn, addHandler, removeHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableView(
|
public TableView(
|
||||||
final Filter.Rsql rsql, final Filter.Rsql alternativeRsql,
|
final Filter.Rsql rsql, final Filter.Rsql alternativeRsql,
|
||||||
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
final SelectionGrid.EntityRepresentation<T, ID> entityRepresentation,
|
||||||
|
|||||||
@@ -9,6 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.ui.simple.view.util;
|
package org.eclipse.hawkbit.ui.simple.view.util;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.CompletionStage;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.vaadin.flow.component.Component;
|
import com.vaadin.flow.component.Component;
|
||||||
import com.vaadin.flow.component.HasValue;
|
import com.vaadin.flow.component.HasValue;
|
||||||
import com.vaadin.flow.component.Text;
|
import com.vaadin.flow.component.Text;
|
||||||
@@ -28,14 +36,6 @@ import com.vaadin.flow.component.textfield.TextField;
|
|||||||
import com.vaadin.flow.data.value.ValueChangeMode;
|
import com.vaadin.flow.data.value.ValueChangeMode;
|
||||||
import com.vaadin.flow.theme.lumo.LumoUtility;
|
import com.vaadin.flow.theme.lumo.LumoUtility;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.CompletionStage;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
private Utils() {
|
private Utils() {
|
||||||
@@ -45,6 +45,7 @@ public class Utils {
|
|||||||
public static TextField textField(final String label) {
|
public static TextField textField(final String label) {
|
||||||
return textField(label, null);
|
return textField(label, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextField textField(final String label, final Consumer<HasValue.ValueChangeEvent<String>> changeListener) {
|
public static TextField textField(final String label, final Consumer<HasValue.ValueChangeEvent<String>> changeListener) {
|
||||||
final TextField textField = new TextField(label);
|
final TextField textField = new TextField(label);
|
||||||
textField.setWidthFull();
|
textField.setWidthFull();
|
||||||
@@ -60,6 +61,7 @@ public class Utils {
|
|||||||
public static NumberField numberField(final String label) {
|
public static NumberField numberField(final String label) {
|
||||||
return numberField(label, null);
|
return numberField(label, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NumberField numberField(final String label, final Consumer<HasValue.ValueChangeEvent<Double>> changeListener) {
|
public static NumberField numberField(final String label, final Consumer<HasValue.ValueChangeEvent<Double>> changeListener) {
|
||||||
final NumberField numberField = new NumberField(label);
|
final NumberField numberField = new NumberField(label);
|
||||||
numberField.setWidthFull();
|
numberField.setWidthFull();
|
||||||
@@ -109,7 +111,7 @@ public class Utils {
|
|||||||
public static <T> void remove(final Collection<T> remove, final Set<T> from, final Function<T, ?> idFn) {
|
public static <T> void remove(final Collection<T> remove, final Set<T> from, final Function<T, ?> idFn) {
|
||||||
remove.forEach(toRemove -> {
|
remove.forEach(toRemove -> {
|
||||||
final Object id = idFn.apply(toRemove);
|
final Object id = idFn.apply(toRemove);
|
||||||
for (final Iterator<T> i = from.iterator(); i.hasNext();) {
|
for (final Iterator<T> i = from.iterator(); i.hasNext(); ) {
|
||||||
if (idFn.apply(i.next()).equals(id)) {
|
if (idFn.apply(i.next()).equals(id)) {
|
||||||
i.remove();
|
i.remove();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,11 +19,11 @@ logging.pattern.console=%clr(%d{${logging.pattern.dateformat:yyyy-MM-dd'T'HH:mm:
|
|||||||
### Vaadin start ###`
|
### Vaadin start ###`
|
||||||
# build with mvn vaadin:build-frontend to enable / disable
|
# build with mvn vaadin:build-frontend to enable / disable
|
||||||
vaadin.frontend.hotdeploy=false
|
vaadin.frontend.hotdeploy=false
|
||||||
logging.level.org.atmosphere = warn
|
logging.level.org.atmosphere=warn
|
||||||
spring.mustache.check-template-location = false
|
spring.mustache.check-template-location=false
|
||||||
# Launch the default browser when starting the application in development mode
|
# Launch the default browser when starting the application in development mode
|
||||||
vaadin.launch-browser=true
|
vaadin.launch-browser=true
|
||||||
# To improve the performance during development.
|
# To improve the performance during development.
|
||||||
# For more information https://vaadin.com/docs/flow/spring/tutorial-spring-configuration.html#special-configuration-parameters
|
# For more information https://vaadin.com/docs/flow/spring/tutorial-spring-configuration.html#special-configuration-parameters
|
||||||
vaadin.whitelisted-packages = com.vaadin,org.vaadin,dev.hilla,org.eclipse.hawkbit
|
vaadin.whitelisted-packages=com.vaadin,org.vaadin,dev.hilla,org.eclipse.hawkbit
|
||||||
### Vaadin end ###
|
### Vaadin end ###
|
||||||
@@ -41,7 +41,8 @@ Add to your `pom.xml` :
|
|||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
Optional as well is the addition of [Protostuff](https://github.com/protostuff/protostuff) based message payload serialization for improved performance.
|
Optional as well is the addition of [Protostuff](https://github.com/protostuff/protostuff) based message payload
|
||||||
|
serialization for improved performance.
|
||||||
|
|
||||||
Add to your `application.properties` :
|
Add to your `application.properties` :
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
|
|||||||
@@ -37,10 +37,8 @@ public class ErrorController extends BasicErrorController {
|
|||||||
/**
|
/**
|
||||||
* A new {@link ErrorController}.
|
* A new {@link ErrorController}.
|
||||||
*
|
*
|
||||||
* @param errorAttributes
|
* @param errorAttributes the error attributes
|
||||||
* the error attributes
|
* @param serverProperties configuration properties
|
||||||
* @param serverProperties
|
|
||||||
* configuration properties
|
|
||||||
*/
|
*/
|
||||||
public ErrorController(final ErrorAttributes errorAttributes, final ServerProperties serverProperties) {
|
public ErrorController(final ErrorAttributes errorAttributes, final ServerProperties serverProperties) {
|
||||||
super(errorAttributes, serverProperties.getError());
|
super(errorAttributes, serverProperties.getError());
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.springframework.web.servlet.view.RedirectView;
|
|||||||
/**
|
/**
|
||||||
* A {@link SpringBootApplication} annotated class with a main method to start.
|
* A {@link SpringBootApplication} annotated class with a main method to start.
|
||||||
* The minimal configuration for the stand alone hawkBit server.
|
* The minimal configuration for the stand alone hawkBit server.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
|
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
|
||||||
@EnableHawkbitManagedSecurityConfiguration
|
@EnableHawkbitManagedSecurityConfiguration
|
||||||
|
|||||||
@@ -24,11 +24,10 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
@ExtendWith(SharedSqlTestDatabaseExtension.class)
|
@ExtendWith(SharedSqlTestDatabaseExtension.class)
|
||||||
public abstract class AbstractSecurityTest {
|
public abstract class AbstractSecurityTest {
|
||||||
|
|
||||||
|
protected MockMvc mvc;
|
||||||
@Autowired
|
@Autowired
|
||||||
private WebApplicationContext context;
|
private WebApplicationContext context;
|
||||||
|
|
||||||
protected MockMvc mvc;
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() {
|
public void setup() {
|
||||||
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
|
final DefaultMockMvcBuilder builder = MockMvcBuilders.webAppContextSetup(context)
|
||||||
|
|||||||
@@ -9,17 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app;
|
package org.eclipse.hawkbit.app;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.security.web.firewall.RequestRejectedException;
|
|
||||||
|
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
import io.qameta.allure.Story;
|
import io.qameta.allure.Story;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.test.context.TestPropertySource;
|
import org.springframework.test.context.TestPropertySource;
|
||||||
|
|
||||||
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
|
@TestPropertySource(properties = { "hawkbit.server.security.allowedHostNames=localhost",
|
||||||
|
|||||||
@@ -14,19 +14,17 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import io.qameta.allure.Description;
|
||||||
|
import io.qameta.allure.Feature;
|
||||||
|
import io.qameta.allure.Story;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpRole;
|
import org.eclipse.hawkbit.im.authentication.SpRole;
|
||||||
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.test.web.servlet.ResultActions;
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
|
|
||||||
import io.qameta.allure.Description;
|
|
||||||
import io.qameta.allure.Feature;
|
|
||||||
import io.qameta.allure.Story;
|
|
||||||
|
|
||||||
@SpringBootTest(
|
@SpringBootTest(
|
||||||
properties = {
|
properties = {
|
||||||
"hawkbit.dmf.rabbitmq.enabled=false",
|
"hawkbit.dmf.rabbitmq.enabled=false",
|
||||||
@@ -35,7 +33,7 @@ import io.qameta.allure.Story;
|
|||||||
CorsTest.ALLOWED_ORIGIN_FIRST + "," +
|
CorsTest.ALLOWED_ORIGIN_FIRST + "," +
|
||||||
CorsTest.ALLOWED_ORIGIN_SECOND,
|
CorsTest.ALLOWED_ORIGIN_SECOND,
|
||||||
"hawkbit.server.security.cors.exposedHeaders=" +
|
"hawkbit.server.security.cors.exposedHeaders=" +
|
||||||
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN})
|
HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN })
|
||||||
@Feature("Integration Test - Security")
|
@Feature("Integration Test - Security")
|
||||||
@Story("CORS")
|
@Story("CORS")
|
||||||
public class CorsTest extends AbstractSecurityTest {
|
public class CorsTest extends AbstractSecurityTest {
|
||||||
|
|||||||
@@ -9,6 +9,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app;
|
package org.eclipse.hawkbit.app;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import io.qameta.allure.Description;
|
import io.qameta.allure.Description;
|
||||||
import io.qameta.allure.Feature;
|
import io.qameta.allure.Feature;
|
||||||
@@ -19,18 +24,13 @@ import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
||||||
|
|
||||||
@Feature("Integration Test - Security")
|
@Feature("Integration Test - Security")
|
||||||
@Story("PreAuthorized enabled")
|
@Story("PreAuthorized enabled")
|
||||||
public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests whether request fail if a role is forbidden for the user")
|
@Description("Tests whether request fail if a role is forbidden for the user")
|
||||||
@WithUser(authorities = { SpPermission.READ_TARGET } )
|
@WithUser(authorities = { SpPermission.READ_TARGET })
|
||||||
public void failIfNoRole() throws Exception {
|
public void failIfNoRole() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/distributionsets")).andExpect(result ->
|
mvc.perform(get("/rest/v1/distributionsets")).andExpect(result ->
|
||||||
assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value()));
|
assertThat(result.getResponse().getStatus()).isEqualTo(HttpStatus.FORBIDDEN.value()));
|
||||||
@@ -57,7 +57,7 @@ public class PreAuthorizeEnabledTest extends AbstractSecurityTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests whether read tenant config request fail if a tenant config (or read read) is not " +
|
@Description("Tests whether read tenant config request fail if a tenant config (or read read) is not " +
|
||||||
"granted for the user")
|
"granted for the user")
|
||||||
@WithUser(authorities = { SpPermission.READ_TARGET } )
|
@WithUser(authorities = { SpPermission.READ_TARGET })
|
||||||
public void onlyDSIfNoTenantConfig() throws Exception {
|
public void onlyDSIfNoTenantConfig() throws Exception {
|
||||||
mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> {
|
mvc.perform(get("/rest/v1/system/configs")).andExpect(result -> {
|
||||||
// returns default DS type because of READ_TARGET
|
// returns default DS type because of READ_TARGET
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
SPDX-License-Identifier: EPL-2.0
|
SPDX-License-Identifier: EPL-2.0
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|||||||
Reference in New Issue
Block a user