Merge branch 'master' into Stabilise_tests
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -16,13 +16,13 @@
|
|||||||
*.jar
|
*.jar
|
||||||
*.war
|
*.war
|
||||||
|
|
||||||
######################
|
|
||||||
# Sonar
|
# Sonar
|
||||||
######################
|
|
||||||
.sonar_lock
|
.sonar_lock
|
||||||
|
|
||||||
# Eclipse IDE
|
# Created by spring-boot-configuration-processor
|
||||||
|
.factorypath
|
||||||
|
|
||||||
|
# Eclipse IDE
|
||||||
*.pydevproject
|
*.pydevproject
|
||||||
.project
|
.project
|
||||||
.metadata
|
.metadata
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
Please read this if you intend to contribute to the project.
|
Please read this if you intend to contribute to the project.
|
||||||
|
|
||||||
## Code Conventions
|
## Conventions
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
* Java files:
|
* Java files:
|
||||||
* we follow the standard eclipse IDE (built in) code formatter with the following changes:
|
* we follow the standard eclipse IDE (built in) code formatter with the following changes:
|
||||||
@@ -19,6 +21,37 @@ Please read this if you intend to contribute to the project.
|
|||||||
* Sonarqube:
|
* Sonarqube:
|
||||||
* Our rule set is defined [here](http://sonar.eu-gb.mybluemix.net)
|
* Our rule set is defined [here](http://sonar.eu-gb.mybluemix.net)
|
||||||
|
|
||||||
|
### Test documentation
|
||||||
|
|
||||||
|
Please documented the test cases that you contribute by means of [Allure](http://allure.qatools.ru) annotations and proper test method naming.
|
||||||
|
|
||||||
|
All test classes are documented with [Allure's](https://github.com/allure-framework/allure-core/wiki/Features-and-Stories) **@Features** and **@Stories** annotations in the following format:
|
||||||
|
```
|
||||||
|
@Features("TEST_TYPE - HAWKBIT_COMPONENT")
|
||||||
|
@Stories("Test class description")
|
||||||
|
```
|
||||||
|
|
||||||
|
Test types are:
|
||||||
|
* Unit Tests - for single units tests with a mocked environment
|
||||||
|
* Component Tests - for complete components including lower layers, e.g. Spring MVC test on rest API including repository and database.
|
||||||
|
* Integration Tests - including clients, e.g. Selenium UI tests with various browsers.
|
||||||
|
* System Tests - on target environments, e.g. Cloud Foundry.
|
||||||
|
|
||||||
|
Examples for hawkBit components:
|
||||||
|
* Management API
|
||||||
|
* Direct Device Integration API
|
||||||
|
* Device Management Federation API
|
||||||
|
* Management UI
|
||||||
|
* Repository
|
||||||
|
* Security
|
||||||
|
|
||||||
|
```
|
||||||
|
@Features("Component Tests - Management API")
|
||||||
|
@Stories("Distribution Set Type Resource")
|
||||||
|
```
|
||||||
|
|
||||||
|
In addition all test method's name describes in **camel case** what the test is all about and has a long description aith Allures **@Description** annotation.
|
||||||
|
|
||||||
## Legal considerations for your contribution
|
## Legal considerations for your contribution
|
||||||
|
|
||||||
The following steps are necessary to comply with the Eclipse Foundation's IP policy.
|
The following steps are necessary to comply with the Eclipse Foundation's IP policy.
|
||||||
|
|||||||
9
MIGRATION.md
Normal file
9
MIGRATION.md
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# hawkBit Migration Guides
|
||||||
|
## Release 0.2
|
||||||
|
### Configuration Property changes
|
||||||
|
- hawkbit.server.controller._ have changed to hawkbit.server.ddi._
|
||||||
|
- info.build._ have changed to hawkbit.server.build._
|
||||||
|
- hawkbit.server.demo._ have changed to hawkbit.server.ui.demo._
|
||||||
|
- hawkbit.server.email.support has changed to hawkbit.server.ui.links.support
|
||||||
|
- hawkbit.server.email.request.account has changed to hawkbit.server.ui.links.requestAccount
|
||||||
|
- hawkbit.server.im.login.url has changed to hawkbit.server.ui.links.userManagement
|
||||||
@@ -100,7 +100,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>19.0</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.netflix.feign</groupId>
|
<groupId>com.netflix.feign</groupId>
|
||||||
@@ -116,13 +115,18 @@
|
|||||||
<groupId>com.jayway.jsonpath</groupId>
|
<groupId>com.jayway.jsonpath</groupId>
|
||||||
<artifactId>json-path</artifactId>
|
<artifactId>json-path</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.vaadin</groupId>
|
<groupId>com.vaadin</groupId>
|
||||||
<artifactId>vaadin-bom</artifactId>
|
<artifactId>vaadin-bom</artifactId>
|
||||||
<version>7.5.5</version>
|
<version>7.6.3</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
<scope>import</scope>
|
<scope>import</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|||||||
@@ -9,21 +9,35 @@
|
|||||||
package org.eclipse.hawkbit.simulator.amqp;
|
package org.eclipse.hawkbit.simulator.amqp;
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bean which holds the necessary properties for configuring the AMQP
|
* Bean which holds the necessary properties for configuring the AMQP
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
@ConfigurationProperties("hawkbit.device.simulator.amqp")
|
@ConfigurationProperties("hawkbit.device.simulator.amqp")
|
||||||
public class AmqpProperties {
|
public class AmqpProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue for receiving DMF messages from update server.
|
||||||
|
*/
|
||||||
private String receiverConnectorQueueFromSp;
|
private String receiverConnectorQueueFromSp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchange for sending DMF messages to update server.
|
||||||
|
*/
|
||||||
private String senderForSpExchange;
|
private String senderForSpExchange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulator dead letter queue.
|
||||||
|
*/
|
||||||
private String deadLetterQueue;
|
private String deadLetterQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulator dead letter exchange.
|
||||||
|
*/
|
||||||
private String deadLetterExchange;
|
private String deadLetterExchange;
|
||||||
|
|
||||||
public String getReceiverConnectorQueueFromSp() {
|
public String getReceiverConnectorQueueFromSp() {
|
||||||
|
|||||||
@@ -8,21 +8,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.app;
|
package org.eclipse.hawkbit.app;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.eventbus.EventSubscriber;
|
|
||||||
import org.eclipse.hawkbit.eventbus.event.EntityEvent;
|
|
||||||
import org.eclipse.hawkbit.ui.DispatcherRunnable;
|
|
||||||
import org.eclipse.hawkbit.ui.HawkbitUI;
|
import org.eclipse.hawkbit.ui.HawkbitUI;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.eclipse.hawkbit.ui.push.DelayedEventBusPushStrategy;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
|
|
||||||
import org.vaadin.spring.events.EventBus.SessionEventBus;
|
|
||||||
|
|
||||||
import com.google.common.eventbus.AllowConcurrentEvents;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.eventbus.Subscribe;
|
|
||||||
import com.vaadin.annotations.Push;
|
import com.vaadin.annotations.Push;
|
||||||
import com.vaadin.server.VaadinSession;
|
|
||||||
import com.vaadin.server.VaadinSession.State;
|
|
||||||
import com.vaadin.server.WrappedSession;
|
|
||||||
import com.vaadin.shared.communication.PushMode;
|
import com.vaadin.shared.communication.PushMode;
|
||||||
import com.vaadin.shared.ui.ui.Transport;
|
import com.vaadin.shared.ui.ui.Transport;
|
||||||
import com.vaadin.spring.annotation.SpringUI;
|
import com.vaadin.spring.annotation.SpringUI;
|
||||||
@@ -34,44 +25,15 @@ import com.vaadin.spring.annotation.SpringUI;
|
|||||||
* easiest way to get an hawkBit UI running is to extend the {@link HawkbitUI}
|
* easiest way to get an hawkBit UI running is to extend the {@link HawkbitUI}
|
||||||
* and to annotated it with {@link SpringUI} as in this example.
|
* and to annotated it with {@link SpringUI} as in this example.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringUI
|
@SpringUI
|
||||||
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET)
|
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET)
|
||||||
@EventSubscriber
|
|
||||||
public class MyUI extends HawkbitUI {
|
public class MyUI extends HawkbitUI {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
@Autowired
|
||||||
* An {@link com.google.common.eventbus.EventBus} subscriber which
|
public MyUI(final EventBus systemEventBus, final org.vaadin.spring.events.EventBus.SessionEventBus eventBus) {
|
||||||
* subscribes {@link EntityEvent} from the repository to dispatch these
|
super(new DelayedEventBusPushStrategy(eventBus, systemEventBus));
|
||||||
* events to the UI {@link SessionEventBus}.
|
|
||||||
*
|
|
||||||
* @param event
|
|
||||||
* the entity event which has been published from the repository
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@Subscribe
|
|
||||||
@AllowConcurrentEvents
|
|
||||||
public void dispatch(final org.eclipse.hawkbit.eventbus.event.Event event) {
|
|
||||||
final VaadinSession session = getSession();
|
|
||||||
if (session != null && session.getState() == State.OPEN) {
|
|
||||||
final WrappedSession wrappedSession = session.getSession();
|
|
||||||
if (wrappedSession != null) {
|
|
||||||
final SecurityContext userContext = (SecurityContext) wrappedSession
|
|
||||||
.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
|
||||||
if (eventSecurityCheck(userContext, event)) {
|
|
||||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
|
||||||
try {
|
|
||||||
access(new DispatcherRunnable(eventBus, session, userContext, event));
|
|
||||||
} finally {
|
|
||||||
SecurityContextHolder.setContext(oldContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,23 +7,20 @@
|
|||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
|
|
||||||
# need to re-name these properties in the defaulthawkbit.properties and code!
|
hawkbit.server.ddi.security.authentication.anonymous.enabled=true
|
||||||
hawkbit.server.controller.security.authentication.anonymous.enabled=true
|
hawkbit.server.ddi.security.authentication.targettoken.enabled=false
|
||||||
hawkbit.server.controller.security.authentication.header.enabled=false
|
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false
|
||||||
hawkbit.server.controller.security.authentication.targettoken.enabled=false
|
|
||||||
hawkbit.server.controller.security.authentication.gatewaytoken.enabled=false
|
|
||||||
|
|
||||||
spring.profiles.active=amqp
|
spring.profiles.active=amqp
|
||||||
|
|
||||||
vaadin.servlet.productionMode=false
|
vaadin.servlet.productionMode=false
|
||||||
vaadin.static.servlet.productionMode=false
|
|
||||||
|
|
||||||
## Configuration for RabbitMQ integration
|
## Configuration for RabbitMQ integration
|
||||||
hawkbit.server.amqp.username=guest
|
spring.rabbitmq.username=guest
|
||||||
hawkbit.server.amqp.password=guest
|
spring.rabbitmq.password=guest
|
||||||
hawkbit.server.amqp.virtualHost=/
|
spring.rabbitmq.virtualHost=/
|
||||||
hawkbit.server.amqp.host=localhost
|
spring.rabbitmq.host=localhost
|
||||||
hawkbit.server.amqp.port=5672
|
spring.rabbitmq.port=5672
|
||||||
hawkbit.server.amqp.deadLetterQueue=sp_deadletter
|
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter
|
||||||
hawkbit.server.amqp.deadLetterExchange=sp.deadletter
|
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
|
||||||
hawkbit.server.amqp.receiverQueue=sp_receiver
|
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver
|
||||||
|
|||||||
@@ -87,5 +87,10 @@
|
|||||||
<artifactId>google-collections</artifactId>
|
<artifactId>google-collections</artifactId>
|
||||||
<version>1.0-rc2</version>
|
<version>1.0-rc2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -9,17 +9,30 @@
|
|||||||
package org.eclipse.hawkbit.mgmt.client;
|
package org.eclipse.hawkbit.mgmt.client;
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration bean which holds the configuration of the client e.g. the base
|
* Configuration bean which holds the configuration of the client e.g. the base
|
||||||
* URL of the hawkbit-server and the credentials to use the RESTful Management
|
* URL of the hawkbit-server and the credentials to use the RESTful Management
|
||||||
* API.
|
* API.
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
@ConfigurationProperties(prefix = "hawkbit")
|
@ConfigurationProperties(prefix = "hawkbit")
|
||||||
public class ClientConfigurationProperties {
|
public class ClientConfigurationProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update server URI.
|
||||||
|
*/
|
||||||
private String url = "localhost:8080";
|
private String url = "localhost:8080";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update server user name.
|
||||||
|
*/
|
||||||
private String username = "admin";
|
private String username = "admin";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update server password.
|
||||||
|
*/
|
||||||
private String password = "admin"; // NOSONAR this password is only used for
|
private String password = "admin"; // NOSONAR this password is only used for
|
||||||
// examples
|
// examples
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public class SoftwareModuleAssigmentBuilder {
|
|||||||
private final List<Long> ids;
|
private final List<Long> ids;
|
||||||
|
|
||||||
public SoftwareModuleAssigmentBuilder() {
|
public SoftwareModuleAssigmentBuilder() {
|
||||||
ids = new ArrayList<Long>();
|
ids = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,4 +11,4 @@ hawkbit.url=localhost:8080
|
|||||||
hawkbit.username=admin
|
hawkbit.username=admin
|
||||||
hawkbit.password=admin
|
hawkbit.password=admin
|
||||||
|
|
||||||
spring.main.banner-mode=OFF
|
spring.main.show-banner=false
|
||||||
@@ -34,6 +34,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|||||||
import com.google.common.io.BaseEncoding;
|
import com.google.common.io.BaseEncoding;
|
||||||
import com.mongodb.gridfs.GridFSDBFile;
|
import com.mongodb.gridfs.GridFSDBFile;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Component Tests - Repository")
|
||||||
|
@Stories("Artifact Store MongoDB")
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringApplicationConfiguration(classes = { ArtifactStoreAutoConfiguration.class, TestConfiguration.class })
|
@SpringApplicationConfiguration(classes = { ArtifactStoreAutoConfiguration.class, TestConfiguration.class })
|
||||||
public class ArtifactStoreTest {
|
public class ArtifactStoreTest {
|
||||||
@@ -48,6 +54,7 @@ public class ArtifactStoreTest {
|
|||||||
private GridFsOperations gridFs;
|
private GridFsOperations gridFs;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that storage in MongoDB is correctly executed.s")
|
||||||
public void storeArtifactInMongoDB() {
|
public void storeArtifactInMongoDB() {
|
||||||
final int filelengthBytes = 128;
|
final int filelengthBytes = 128;
|
||||||
final String filename = "testfile.json";
|
final String filename = "testfile.json";
|
||||||
@@ -60,6 +67,7 @@ public class ArtifactStoreTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that search by SHA1 hash (which is used by hawkBit as artifact ID) finds the expected results.")
|
||||||
public void findArtifactBySHA1Hash() throws NoSuchAlgorithmException {
|
public void findArtifactBySHA1Hash() throws NoSuchAlgorithmException {
|
||||||
final int filelengthBytes = 128;
|
final int filelengthBytes = 128;
|
||||||
final String filename = "testfile.json";
|
final String filename = "testfile.json";
|
||||||
@@ -72,6 +80,7 @@ public class ArtifactStoreTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that search by MD5 hash finds the expected results.")
|
||||||
public void findArtifactByMD5Hash() throws NoSuchAlgorithmException {
|
public void findArtifactByMD5Hash() throws NoSuchAlgorithmException {
|
||||||
final int filelengthBytes = 128;
|
final int filelengthBytes = 128;
|
||||||
final String filename = "testfile.json";
|
final String filename = "testfile.json";
|
||||||
@@ -84,6 +93,7 @@ public class ArtifactStoreTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that artifact content can be read through InputStream.")
|
||||||
public void getInputStreamFromArtifact() throws IOException {
|
public void getInputStreamFromArtifact() throws IOException {
|
||||||
final int filelengthBytes = 128;
|
final int filelengthBytes = 128;
|
||||||
final String filename = "testfile.json";
|
final String filename = "testfile.json";
|
||||||
@@ -103,7 +113,8 @@ public class ArtifactStoreTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void deleteArtifactWithOnlyOneTenantLast() throws NoSuchAlgorithmException {
|
@Description("Ensures that artifact delete actually results in deletion from database.")
|
||||||
|
public void deleteArtifact() throws NoSuchAlgorithmException {
|
||||||
final int filelengthBytes = 128;
|
final int filelengthBytes = 128;
|
||||||
final String filename = "testfile.json";
|
final String filename = "testfile.json";
|
||||||
final String contentType = "application/json";
|
final String contentType = "application/json";
|
||||||
|
|||||||
@@ -72,5 +72,10 @@
|
|||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-context-support</artifactId>
|
<artifactId>spring-context-support</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.autoconfigure.conf;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ControllerPollProperties;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable the Controlle Poll.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
@ConditionalOnClass(ControllerPollProperties.class)
|
|
||||||
@EnableConfigurationProperties(ControllerPollProperties.class)
|
|
||||||
public class ControllerPollAutoConfiguration {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -13,17 +13,29 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
/**
|
/**
|
||||||
* Properties for the async configurer.
|
* Properties for the async configurer.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("hawkbit.threadpool")
|
@ConfigurationProperties("hawkbit.threadpool")
|
||||||
public class AsyncConfigurerThreadpoolProperties {
|
public class AsyncConfigurerThreadpoolProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max queue size for central event executor.
|
||||||
|
*/
|
||||||
private Integer queuesize = 250;
|
private Integer queuesize = 250;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core processing threads for central event executor.
|
||||||
|
*/
|
||||||
private Integer corethreads = 5;
|
private Integer corethreads = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum thread pool size for central event executor.
|
||||||
|
*/
|
||||||
private Integer maxthreads = 50;
|
private Integer maxthreads = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the number of threads is greater than the core, this is the maximum
|
||||||
|
* time that excess idle threads will wait for new tasks before terminating.
|
||||||
|
*/
|
||||||
private Long idletimeout = 10000L;
|
private Long idletimeout = 10000L;
|
||||||
|
|
||||||
public Integer getQueuesize() {
|
public Integer getQueuesize() {
|
||||||
|
|||||||
@@ -26,10 +26,9 @@ import org.springframework.security.concurrent.DelegatingSecurityContextExecutor
|
|||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Central event processors inside update server.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(AsyncConfigurerThreadpoolProperties.class)
|
@EnableConfigurationProperties(AsyncConfigurerThreadpoolProperties.class)
|
||||||
public class ExecutorAutoConfiguration {
|
public class ExecutorAutoConfiguration {
|
||||||
@@ -40,7 +39,7 @@ public class ExecutorAutoConfiguration {
|
|||||||
private AsyncConfigurerThreadpoolProperties asyncConfigurerProperties;
|
private AsyncConfigurerThreadpoolProperties asyncConfigurerProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ExecutorService for general pupose multi threaded operations
|
* @return ExecutorService for general purpose multi threaded operations
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.eclipse.hawkbit.im.authentication.SpPermission;
|
|||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.im.authentication.UserAuthenticationFilter;
|
import org.eclipse.hawkbit.im.authentication.UserAuthenticationFilter;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||||
import org.eclipse.hawkbit.security.SecurityProperties;
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -53,7 +53,7 @@ import org.springframework.security.web.authentication.www.BasicAuthenticationFi
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(SecurityProperties.class)
|
@EnableConfigurationProperties(DdiSecurityProperties.class)
|
||||||
public class SecurityAutoConfiguration {
|
public class SecurityAutoConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -31,29 +31,27 @@ import org.eclipse.hawkbit.repository.ControllerManagement;
|
|||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
import org.eclipse.hawkbit.rest.resource.RestConstants;
|
import org.eclipse.hawkbit.rest.resource.RestConstants;
|
||||||
import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource;
|
import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource;
|
||||||
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.DosFilter;
|
import org.eclipse.hawkbit.security.DosFilter;
|
||||||
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
|
||||||
import org.eclipse.hawkbit.security.HttpDownloadAuthenticationFilter;
|
import org.eclipse.hawkbit.security.HttpDownloadAuthenticationFilter;
|
||||||
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
|
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
|
||||||
import org.eclipse.hawkbit.security.SecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
|
||||||
import org.springframework.boot.context.embedded.FilterRegistrationBean;
|
import org.springframework.boot.context.embedded.FilterRegistrationBean;
|
||||||
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
|
import org.springframework.boot.context.embedded.ServletListenerRegistrationBean;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.context.EnvironmentAware;
|
|
||||||
import org.springframework.context.annotation.AdviceMode;
|
import org.springframework.context.annotation.AdviceMode;
|
||||||
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.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
@@ -94,17 +92,11 @@ import org.vaadin.spring.security.web.authentication.VaadinUrlAuthenticationSucc
|
|||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
|
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
|
||||||
@EnableWebMvcSecurity
|
@EnableWebMvcSecurity
|
||||||
@Order(value = Ordered.HIGHEST_PRECEDENCE)
|
@Order(value = Ordered.HIGHEST_PRECEDENCE)
|
||||||
public class SecurityManagedConfiguration implements EnvironmentAware {
|
public class SecurityManagedConfiguration {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class);
|
private static final Logger LOG = LoggerFactory.getLogger(SecurityManagedConfiguration.class);
|
||||||
|
|
||||||
private static final String SP_SERVER_CONFIG_PREFIX = "hawkbit.server.";
|
@Autowired
|
||||||
private RelaxedPropertyResolver environment;
|
private HawkbitSecurityProperties securityProperties;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnvironment(final Environment environment) {
|
|
||||||
this.environment = new RelaxedPropertyResolver(environment, SP_SERVER_CONFIG_PREFIX);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link WebSecurityConfigurer} for the internal SP controller API.
|
* {@link WebSecurityConfigurer} for the internal SP controller API.
|
||||||
@@ -123,7 +115,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SecurityProperties securityConfiguration;
|
private DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
@Autowired
|
@Autowired
|
||||||
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
||||||
|
|
||||||
@@ -132,7 +124,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
|
final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
|
||||||
|
|
||||||
final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
|
final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
|
||||||
securityConfiguration.getRpCnHeader(), securityConfiguration.getRpSslIssuerHashHeader(),
|
ddiSecurityConfiguration.getRp().getCnHeader(), ddiSecurityConfiguration.getRp().getSslIssuerHashHeader(),
|
||||||
systemManagement, tenantAware);
|
systemManagement, tenantAware);
|
||||||
securityHeaderFilter.setAuthenticationManager(authenticationManager());
|
securityHeaderFilter.setAuthenticationManager(authenticationManager());
|
||||||
securityHeaderFilter.setCheckForPrincipalChanges(true);
|
securityHeaderFilter.setCheckForPrincipalChanges(true);
|
||||||
@@ -158,7 +150,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
|
httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (securityConfiguration.getAnonymousEnabled()) {
|
if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"******************\n** Anonymous controller security enabled, should only use for developing purposes **\n******************");
|
"******************\n** Anonymous controller security enabled, should only use for developing purposes **\n******************");
|
||||||
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
||||||
@@ -189,7 +181,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.authenticationProvider(
|
auth.authenticationProvider(
|
||||||
new PreAuthTokenSourceTrustAuthenticationProvider(securityConfiguration.getRpTrustedIPs()));
|
new PreAuthTokenSourceTrustAuthenticationProvider(ddiSecurityConfiguration.getRp().getTrustedIPs()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,13 +196,10 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
public FilterRegistrationBean dosFilter() {
|
public FilterRegistrationBean dosFilter() {
|
||||||
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
final FilterRegistrationBean filterRegBean = new FilterRegistrationBean();
|
||||||
|
|
||||||
filterRegBean
|
filterRegBean.setFilter(new DosFilter(securityProperties.getDos().getFilter().getMaxRead(),
|
||||||
.setFilter(
|
securityProperties.getDos().getFilter().getMaxWrite(),
|
||||||
new DosFilter(environment.getProperty("security.dos.filter.maxRead", Integer.class, 200),
|
securityProperties.getDos().getFilter().getWhitelist(), securityProperties.getClients().getBlacklist(),
|
||||||
environment.getProperty("security.dos.filter.maxWrite", Integer.class, 50),
|
securityProperties.getClients().getRemoteIpHeader()));
|
||||||
environment.getProperty("security.dos.filter.whitelist"), environment
|
|
||||||
.getProperty("security.clients.blacklist"),
|
|
||||||
environment.getProperty("security.rp.remote_ip_header", String.class, "X-Forwarded-For")));
|
|
||||||
filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*");
|
filterRegBean.addUrlPatterns("/{tenant}/controller/v1/*", "/rest/*");
|
||||||
return filterRegBean;
|
return filterRegBean;
|
||||||
}
|
}
|
||||||
@@ -310,8 +299,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
@Configuration
|
@Configuration
|
||||||
@Order(400)
|
@Order(400)
|
||||||
@EnableVaadinSecurity
|
@EnableVaadinSecurity
|
||||||
public static class UISecurityConfigurationAdapter extends WebSecurityConfigurerAdapter
|
public static class UISecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
|
||||||
implements EnvironmentAware {
|
|
||||||
|
|
||||||
private static final String XFRAME_OPTION_DENY = "DENY";
|
private static final String XFRAME_OPTION_DENY = "DENY";
|
||||||
private static final String XFRAME_OPTION_SAMEORIGIN = "SAMEORIGIN";
|
private static final String XFRAME_OPTION_SAMEORIGIN = "SAMEORIGIN";
|
||||||
@@ -320,13 +308,8 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
private VaadinSecurityContext vaadinSecurityContext;
|
private VaadinSecurityContext vaadinSecurityContext;
|
||||||
@Autowired
|
@Autowired
|
||||||
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
private org.springframework.boot.autoconfigure.security.SecurityProperties springSecurityProperties;
|
||||||
|
@Autowired
|
||||||
private RelaxedPropertyResolver environment;
|
private HawkbitSecurityProperties securityProperties;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnvironment(final Environment environment) {
|
|
||||||
this.environment = new RelaxedPropertyResolver(environment, SP_SERVER_CONFIG_PREFIX);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* post construct for setting the authentication success handler for the
|
* post construct for setting the authentication success handler for the
|
||||||
@@ -379,13 +362,13 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
protected void configure(final HttpSecurity http) throws Exception {
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
// configuration xframe-option
|
// configuration xframe-option
|
||||||
final String confXframeOption = environment.getProperty("security.xframe.option", XFRAME_OPTION_DENY);
|
final String confXframeOption = securityProperties.getXframe().getOption();
|
||||||
final String confAllowFromUri = environment.getProperty("security.xframe.option.allowfrom");
|
final String confAllowFromUri = securityProperties.getXframe().getAllowfrom();
|
||||||
if (confXframeOption.equals(XFAME_OPTION_ALLOW_FROM) && confAllowFromUri == null) {
|
if (confXframeOption.equals(XFAME_OPTION_ALLOW_FROM) && confAllowFromUri.isEmpty()) {
|
||||||
// if allow-from option is specified but no allowFromUri throw
|
// if allow-from option is specified but no allowFromUri throw
|
||||||
// exception
|
// exception
|
||||||
throw new IllegalStateException("hawkbit.server.security.xframe.option has been specified as ALLOW-FROM"
|
throw new IllegalStateException("hawkbit.server.security.xframe.option has been specified as ALLOW-FROM"
|
||||||
+ " but no hawkbit.server.security.xframe.option.allowfrom has been set, "
|
+ " but no hawkbit.server.security.xframe.allowfrom has been set, "
|
||||||
+ "please ensure to set allow from URIs");
|
+ "please ensure to set allow from URIs");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +444,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
public static class IdRestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
|
public static class IdRestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SecurityProperties securityConfiguration;
|
private DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Qualifier(CacheConstants.DOWNLOAD_ID_CACHE)
|
@Qualifier(CacheConstants.DOWNLOAD_ID_CACHE)
|
||||||
@@ -484,7 +467,7 @@ public class SecurityManagedConfiguration implements EnvironmentAware {
|
|||||||
@Override
|
@Override
|
||||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||||
auth.authenticationProvider(
|
auth.authenticationProvider(
|
||||||
new PreAuthTokenSourceTrustAuthenticationProvider(securityConfiguration.getRpTrustedIPs()));
|
new PreAuthTokenSourceTrustAuthenticationProvider(ddiSecurityConfiguration.getRp().getTrustedIPs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.autoconfigure.url;
|
|||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.HawkbitServerProperties;
|
||||||
import org.eclipse.hawkbit.api.HostnameResolver;
|
import org.eclipse.hawkbit.api.HostnameResolver;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
@@ -27,11 +28,11 @@ import com.google.common.base.Throwables;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(ServerProperties.class)
|
@EnableConfigurationProperties(HawkbitServerProperties.class)
|
||||||
public class PropertyHostnameResolverAutoConfiguration {
|
public class PropertyHostnameResolverAutoConfiguration {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ServerProperties serverProperties;
|
private HawkbitServerProperties serverProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the default autoconfigure hostname resolver implementation which
|
* @return the default autoconfigure hostname resolver implementation which
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.autoconfigure.url;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Properties for the server e.g. the server's URL which must be configured.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@ConfigurationProperties("hawkbit.server")
|
|
||||||
public class ServerProperties {
|
|
||||||
|
|
||||||
private String url = "http://localhost:8080";
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(final String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,5 +11,4 @@ org.eclipse.hawkbit.autoconfigure.eventbus.EventBusAutoConfiguration,\
|
|||||||
org.eclipse.hawkbit.autoconfigure.scheduling.AsyncConfigurerAutoConfiguration,\
|
org.eclipse.hawkbit.autoconfigure.scheduling.AsyncConfigurerAutoConfiguration,\
|
||||||
org.eclipse.hawkbit.autoconfigure.cache.RedisAutoConfiguration,\
|
org.eclipse.hawkbit.autoconfigure.cache.RedisAutoConfiguration,\
|
||||||
org.eclipse.hawkbit.autoconfigure.scheduling.ExecutorAutoConfiguration,\
|
org.eclipse.hawkbit.autoconfigure.scheduling.ExecutorAutoConfiguration,\
|
||||||
org.eclipse.hawkbit.autoconfigure.conf.ControllerPollAutoConfiguration,\
|
|
||||||
org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration
|
org.eclipse.hawkbit.autoconfigure.amqp.AmqpAutoConfiguration
|
||||||
|
|||||||
@@ -7,12 +7,6 @@
|
|||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
|
|
||||||
# Tomcat / Server
|
|
||||||
server.tomcat.compression=on
|
|
||||||
spring.http.gzip.mime-types=text/html,text/xml,text/plain,application/json,application/javascript,text/css,application/x-javascript,text/javascript,application/vnd.ms-fontobject,application/x-font-opentype,application/x-font-truetype,application/x-font-ttf,application/xml,font/eot,font/opentype,font/otf,image/svg+xml,image/vnd.microsoft.icon
|
|
||||||
server.tomcat.compressable-mime-types=${spring.http.gzip.mime-types}
|
|
||||||
spring.http.gzip.min-gzip-size=256
|
|
||||||
|
|
||||||
# JPA / Datasource
|
# JPA / Datasource
|
||||||
spring.jpa.eclipselink.eclipselink.weaving=false
|
spring.jpa.eclipselink.eclipselink.weaving=false
|
||||||
spring.jpa.database=H2
|
spring.jpa.database=H2
|
||||||
@@ -21,7 +15,6 @@ spring.datasource.driverClassName=org.h2.Driver
|
|||||||
|
|
||||||
# MongoDB for artifact-repository
|
# MongoDB for artifact-repository
|
||||||
spring.data.mongodb.uri=mongodb://localhost/artifactrepo
|
spring.data.mongodb.uri=mongodb://localhost/artifactrepo
|
||||||
spring.data.mongo.repositories.enabled=true
|
|
||||||
|
|
||||||
# Flyway DDL
|
# Flyway DDL
|
||||||
flyway.enabled=true
|
flyway.enabled=true
|
||||||
@@ -29,15 +22,10 @@ flyway.initOnMigrate=true
|
|||||||
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
|
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
|
||||||
|
|
||||||
# Vaadin Servlet
|
# Vaadin Servlet
|
||||||
vaadin.static.servlet.productionMode=true
|
|
||||||
vaadin.servlet.productionMode=true
|
vaadin.servlet.productionMode=true
|
||||||
vaadin.servlet.urlMapping=/UI/*
|
vaadin.servlet.urlMapping=/UI/*
|
||||||
vaadin.servlet.params.heartbeatInterval=60
|
vaadin.servlet.heartbeatInterval=60
|
||||||
vaadin.servlet.params.closeIdleSessions=false
|
vaadin.servlet.closeIdleSessions=false
|
||||||
|
|
||||||
# Spring MVC
|
|
||||||
spring.mvc.favicon.enabled=false
|
|
||||||
|
|
||||||
|
|
||||||
# Defines the thread pool executor
|
# Defines the thread pool executor
|
||||||
hawkbit.threadpool.corethreads=5
|
hawkbit.threadpool.corethreads=5
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
<groupId>redis.clients</groupId>
|
<groupId>redis.clients</groupId>
|
||||||
<artifactId>jedis</artifactId>
|
<artifactId>jedis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Test -->
|
<!-- Test -->
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer
|
|||||||
* The spring Redis configuration which is enabled by using the profile
|
* The spring Redis configuration which is enabled by using the profile
|
||||||
* {@code redis} to use a Redis server as cache.
|
* {@code redis} to use a Redis server as cache.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(RedisProperties.class)
|
@EnableConfigurationProperties(RedisProperties.class)
|
||||||
|
|||||||
@@ -14,14 +14,18 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
* Bean which holds the necessary properties for configuring the Redis
|
* Bean which holds the necessary properties for configuring the Redis
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("hawkbit.server.redis")
|
@ConfigurationProperties("hawkbit.server.redis")
|
||||||
public class RedisProperties {
|
public class RedisProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis server hostname.
|
||||||
|
*/
|
||||||
private String host;
|
private String host;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis server port.
|
||||||
|
*/
|
||||||
private int port;
|
private int port;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ import org.springframework.hateoas.Identifiable;
|
|||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Cluster Cache")
|
||||||
|
@Stories("EventDistributor Test")
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
// TODO: create description annotations
|
||||||
public class EventDistributorTest {
|
public class EventDistributorTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ import static org.fest.assertions.api.Assertions.assertThat;
|
|||||||
import org.eclipse.hawkbit.cache.RedisProperties;
|
import org.eclipse.hawkbit.cache.RedisProperties;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Cluster Cache")
|
||||||
|
@Stories("Redis Properties Test")
|
||||||
public class RedisPropertiesTest {
|
public class RedisPropertiesTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -43,6 +43,11 @@
|
|||||||
<artifactId>allure-junit-adaptor</artifactId>
|
<artifactId>allure-junit-adaptor</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -9,18 +9,26 @@
|
|||||||
package org.eclipse.hawkbit;
|
package org.eclipse.hawkbit;
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the polling time for the controllers in HH:MM:SS notation.
|
* Defines the polling time for the controllers in HH:MM:SS notation.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Component
|
||||||
@ConfigurationProperties(prefix = "hawkbit.controller")
|
@ConfigurationProperties(prefix = "hawkbit.controller")
|
||||||
public class ControllerPollProperties {
|
public class ControllerPollProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recommended target polling time for DDI API. Final choice is up to the
|
||||||
|
* target.
|
||||||
|
*/
|
||||||
private String pollingTime = "00:05:00";
|
private String pollingTime = "00:05:00";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assumed time frame where the target is considered overdue when no DDI
|
||||||
|
* polling has been registered by the update server.
|
||||||
|
*/
|
||||||
private String pollingOverdueTime = "00:05:00";
|
private String pollingOverdueTime = "00:05:00";
|
||||||
|
|
||||||
public String getPollingTime() {
|
public String getPollingTime() {
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Properties for the server e.g. the server's URL which must be configured.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ConfigurationProperties("hawkbit.server")
|
||||||
|
public class HawkbitServerProperties {
|
||||||
|
/**
|
||||||
|
* Defines under which URI the update server can be reached. Used to
|
||||||
|
* calculate download URLs for DMF transmitted update actions.
|
||||||
|
*/
|
||||||
|
private String url = "http://localhost:8080";
|
||||||
|
|
||||||
|
private final Build build = new Build();
|
||||||
|
|
||||||
|
public Build getBuild() {
|
||||||
|
return build;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build information of the hawkBit instance. Influenced by maven.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class Build {
|
||||||
|
/**
|
||||||
|
* Project artifact ID.
|
||||||
|
*/
|
||||||
|
private String artifact = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project name.
|
||||||
|
*/
|
||||||
|
private String name = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project description.
|
||||||
|
*/
|
||||||
|
private String description = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Project version.
|
||||||
|
*/
|
||||||
|
private String version = "";
|
||||||
|
|
||||||
|
public String getArtifact() {
|
||||||
|
return artifact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArtifact(final String artifact) {
|
||||||
|
this.artifact = artifact;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(final String version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(final String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,7 +51,12 @@ public class TenantAwareCacheManager implements TenancyCacheManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cache getCache(final String name) {
|
public Cache getCache(final String name) {
|
||||||
final String currentTenant = tenantAware.getCurrentTenant().toUpperCase();
|
String currentTenant = tenantAware.getCurrentTenant();
|
||||||
|
if (currentTenant == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTenant = currentTenant.toUpperCase();
|
||||||
if (currentTenant.contains(TENANT_CACHE_DELIMITER)) {
|
if (currentTenant.contains(TENANT_CACHE_DELIMITER)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -60,7 +65,12 @@ public class TenantAwareCacheManager implements TenancyCacheManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getCacheNames() {
|
public Collection<String> getCacheNames() {
|
||||||
final String currentTenant = tenantAware.getCurrentTenant().toUpperCase();
|
String currentTenant = tenantAware.getCurrentTenant();
|
||||||
|
if (currentTenant == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTenant = currentTenant.toUpperCase();
|
||||||
if (currentTenant.contains(TENANT_CACHE_DELIMITER)) {
|
if (currentTenant.contains(TENANT_CACHE_DELIMITER)) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ public enum ActionStatusFields implements FieldNameProvider {
|
|||||||
/**
|
/**
|
||||||
* The id field.
|
* The id field.
|
||||||
*/
|
*/
|
||||||
ID("id");
|
ID("id"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The reportedAt field.
|
||||||
|
*/
|
||||||
|
REPORTEDAT("createdAt");
|
||||||
|
|
||||||
private final String fieldName;
|
private final String fieldName;
|
||||||
|
|
||||||
|
|||||||
@@ -22,35 +22,35 @@ public enum TenantConfigurationKey {
|
|||||||
* boolean value {@code true} {@code false}.
|
* boolean value {@code true} {@code false}.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled",
|
AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled",
|
||||||
"hawkbit.server.controller.security.authentication.header.enabled", Boolean.FALSE.toString()),
|
"hawkbit.server.ddi.security.authentication.header.enabled", Boolean.FALSE.toString()),
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority",
|
AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority",
|
||||||
"hawkbit.server.controller.security.authentication.header.authority", Boolean.FALSE.toString()),
|
"hawkbit.server.ddi.security.authentication.header.authority", Boolean.FALSE.toString()),
|
||||||
/**
|
/**
|
||||||
* boolean value {@code true} {@code false}.
|
* boolean value {@code true} {@code false}.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled",
|
AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled",
|
||||||
"hawkbit.server.controller.security.authentication.targettoken.enabled", Boolean.FALSE.toString()),
|
"hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.FALSE.toString()),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* boolean value {@code true} {@code false}.
|
* boolean value {@code true} {@code false}.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled",
|
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled",
|
||||||
"hawkbit.server.controller.security.authentication.gatewaytoken.enabled", Boolean.FALSE.toString()),
|
"hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.FALSE.toString()),
|
||||||
/**
|
/**
|
||||||
* string value which holds the name of the security token key.
|
* string value which holds the name of the security token key.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name",
|
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name",
|
||||||
"hawkbit.server.controller.security.authentication.gatewaytoken.name", null),
|
"hawkbit.server.ddi.security.authentication.gatewaytoken.name", null),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* string value which holds the actual security-key of the gateway security
|
* string value which holds the actual security-key of the gateway security
|
||||||
* token.
|
* token.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key",
|
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key",
|
||||||
"hawkbit.server.controller.security.authentication.gatewaytoken.key", null);
|
"hawkbit.server.ddi.security.authentication.gatewaytoken.key", null);
|
||||||
|
|
||||||
private final String keyName;
|
private final String keyName;
|
||||||
private final String defaultKeyName;
|
private final String defaultKeyName;
|
||||||
|
|||||||
@@ -21,7 +21,13 @@ import org.mockito.runners.MockitoJUnitRunner;
|
|||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Cluster Event Bus")
|
||||||
|
@Stories("EventBus Subscriber Processor Test")
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
// TODO: create description annotations
|
||||||
public class EventBusSubscriberProcessorTest {
|
public class EventBusSubscriberProcessorTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
|
|||||||
@@ -60,6 +60,11 @@
|
|||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- Test -->
|
<!-- Test -->
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
|||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
import org.springframework.amqp.support.converter.MessageConverter;
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
@@ -121,11 +122,22 @@ public class AmqpConfiguration {
|
|||||||
/**
|
/**
|
||||||
* Create amqp handler service bean.
|
* Create amqp handler service bean.
|
||||||
*
|
*
|
||||||
* @return
|
* @return handler service bean
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public AmqpMessageHandlerService amqpMessageHandlerService() {
|
public AmqpMessageHandlerService amqpMessageHandlerService() {
|
||||||
return new AmqpMessageHandlerService();
|
return new AmqpMessageHandlerService(rabbitTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create default amqp sender service bean.
|
||||||
|
*
|
||||||
|
* @return the default amqp sender service bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public AmqpSenderService amqpSenderServiceBean() {
|
||||||
|
return new DefaultAmqpSenderService(rabbitTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter;
|
|||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
|
||||||
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
|
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
|
||||||
import org.eclipse.hawkbit.security.PreAuthenficationFilter;
|
import org.eclipse.hawkbit.security.PreAuthenficationFilter;
|
||||||
import org.eclipse.hawkbit.security.SecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -55,7 +55,7 @@ public class AmqpControllerAuthentfication {
|
|||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private SecurityProperties secruityProperties;
|
private DdiSecurityProperties ddiSecruityProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -78,8 +78,8 @@ public class AmqpControllerAuthentfication {
|
|||||||
filterChain.add(gatewaySecurityTokenFilter);
|
filterChain.add(gatewaySecurityTokenFilter);
|
||||||
|
|
||||||
final ControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new ControllerPreAuthenticatedSecurityHeaderFilter(
|
final ControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new ControllerPreAuthenticatedSecurityHeaderFilter(
|
||||||
secruityProperties.getRpCnHeader(), secruityProperties.getRpSslIssuerHashHeader(), systemManagement,
|
ddiSecruityProperties.getRp().getCnHeader(), ddiSecruityProperties.getRp().getSslIssuerHashHeader(),
|
||||||
tenantAware);
|
systemManagement, tenantAware);
|
||||||
filterChain.add(securityHeaderFilter);
|
filterChain.add(securityHeaderFilter);
|
||||||
|
|
||||||
final ControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new ControllerPreAuthenticateSecurityTokenFilter(
|
final ControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new ControllerPreAuthenticateSecurityTokenFilter(
|
||||||
@@ -127,18 +127,15 @@ public class AmqpControllerAuthentfication {
|
|||||||
|
|
||||||
LOGGER.debug("preAuthenticatedPrincipal = {} trying to authenticate", principal);
|
LOGGER.debug("preAuthenticatedPrincipal = {} trying to authenticate", principal);
|
||||||
|
|
||||||
final PreAuthenticatedAuthenticationToken authRequest = new PreAuthenticatedAuthenticationToken(principal,
|
return new PreAuthenticatedAuthenticationToken(principal, credentials);
|
||||||
credentials);
|
|
||||||
|
|
||||||
return authRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setControllerManagement(final ControllerManagement controllerManagement) {
|
public void setControllerManagement(final ControllerManagement controllerManagement) {
|
||||||
this.controllerManagement = controllerManagement;
|
this.controllerManagement = controllerManagement;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSecruityProperties(final SecurityProperties secruityProperties) {
|
public void setSecruityProperties(final DdiSecurityProperties secruityProperties) {
|
||||||
this.secruityProperties = secruityProperties;
|
this.ddiSecruityProperties = secruityProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSystemManagement(final SystemManagement systemManagement) {
|
public void setSystemManagement(final SystemManagement systemManagement) {
|
||||||
|
|||||||
@@ -25,35 +25,43 @@ import org.eclipse.hawkbit.eventbus.EventSubscriber;
|
|||||||
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
|
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
|
||||||
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
|
||||||
import org.eclipse.hawkbit.util.ArtifactUrlHandler;
|
import org.eclipse.hawkbit.util.ArtifactUrlHandler;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.core.MessageProperties;
|
import org.springframework.amqp.core.MessageProperties;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link AmqpMessageDispatcherService} handles all outgoing AMQP messages.
|
* {@link AmqpMessageDispatcherService} create all outgoing AMQP messages and
|
||||||
*
|
* delegate the messages to a {@link AmqpSenderService}.
|
||||||
*
|
*
|
||||||
|
* Additionally the dispatcher listener/subscribe for some target events e.g.
|
||||||
|
* assignment.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@EventSubscriber
|
@EventSubscriber
|
||||||
public class AmqpMessageDispatcherService {
|
public class AmqpMessageDispatcherService extends BaseAmqpService {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TenantAware tenantAware;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ArtifactUrlHandler artifactUrlHandler;
|
private ArtifactUrlHandler artifactUrlHandler;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AmqpSenderService amqpSenderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param messageConverter
|
||||||
|
* message converter
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
public AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate) {
|
||||||
|
super(rabbitTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to send a message to a RabbitMQ Exchange after the Distribution
|
* Method to send a message to a RabbitMQ Exchange after the Distribution
|
||||||
* set has been assign to a Target.
|
* set has been assign to a Target.
|
||||||
@@ -79,11 +87,10 @@ public class AmqpMessageDispatcherService {
|
|||||||
downloadAndUpdateRequest.addSoftwareModule(amqpSoftwareModule);
|
downloadAndUpdateRequest.addSoftwareModule(amqpSoftwareModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Message message = rabbitTemplate.getMessageConverter().toMessage(
|
final Message message = getMessageConverter().toMessage(downloadAndUpdateRequest,
|
||||||
downloadAndUpdateRequest,
|
|
||||||
createConnectorMessageProperties(targetAssignDistributionSetEvent.getTenant(), controllerId,
|
createConnectorMessageProperties(targetAssignDistributionSetEvent.getTenant(), controllerId,
|
||||||
EventTopic.DOWNLOAD_AND_INSTALL));
|
EventTopic.DOWNLOAD_AND_INSTALL));
|
||||||
sendMessage(targetAdress.getHost(), message);
|
amqpSenderService.sendMessage(message, targetAdress);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,29 +105,13 @@ public class AmqpMessageDispatcherService {
|
|||||||
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent) {
|
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent) {
|
||||||
final String controllerId = cancelTargetAssignmentDistributionSetEvent.getControllerId();
|
final String controllerId = cancelTargetAssignmentDistributionSetEvent.getControllerId();
|
||||||
final Long actionId = cancelTargetAssignmentDistributionSetEvent.getActionId();
|
final Long actionId = cancelTargetAssignmentDistributionSetEvent.getActionId();
|
||||||
final Message message = rabbitTemplate.getMessageConverter().toMessage(
|
final Message message = getMessageConverter().toMessage(actionId, createConnectorMessageProperties(
|
||||||
actionId,
|
cancelTargetAssignmentDistributionSetEvent.getTenant(), controllerId, EventTopic.CANCEL_DOWNLOAD));
|
||||||
createConnectorMessageProperties(cancelTargetAssignmentDistributionSetEvent.getTenant(), controllerId,
|
|
||||||
EventTopic.CANCEL_DOWNLOAD));
|
|
||||||
|
|
||||||
sendMessage(cancelTargetAssignmentDistributionSetEvent.getTargetAdress().getHost(), message);
|
amqpSenderService.sendMessage(message, cancelTargetAssignmentDistributionSetEvent.getTargetAdress());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Send message to exchange.
|
|
||||||
*
|
|
||||||
* @param exchange
|
|
||||||
* the exchange
|
|
||||||
* @param message
|
|
||||||
* the message
|
|
||||||
*/
|
|
||||||
public void sendMessage(final String exchange, final Message message) {
|
|
||||||
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
|
|
||||||
rabbitTemplate.setExchange(exchange);
|
|
||||||
rabbitTemplate.send(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MessageProperties createConnectorMessageProperties(final String tenant, final String controllerId,
|
private MessageProperties createConnectorMessageProperties(final String tenant, final String controllerId,
|
||||||
final EventTopic topic) {
|
final EventTopic topic) {
|
||||||
final MessageProperties messageProperties = createMessageProperties();
|
final MessageProperties messageProperties = createMessageProperties();
|
||||||
@@ -155,9 +146,8 @@ public class AmqpMessageDispatcherService {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<Artifact> convertedArtifacts = localArtifacts.stream()
|
return localArtifacts.stream().map(localArtifact -> convertArtifact(targetId, localArtifact))
|
||||||
.map(localArtifact -> convertArtifact(targetId, localArtifact)).collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return convertedArtifacts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
|
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
|
||||||
@@ -175,15 +165,11 @@ public class AmqpMessageDispatcherService {
|
|||||||
return artifact;
|
return artifact;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTenantAware(final TenantAware tenantAware) {
|
|
||||||
this.tenantAware = tenantAware;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRabbitTemplate(final RabbitTemplate rabbitTemplate) {
|
|
||||||
this.rabbitTemplate = rabbitTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setArtifactUrlHandler(final ArtifactUrlHandler artifactUrlHandler) {
|
public void setArtifactUrlHandler(final ArtifactUrlHandler artifactUrlHandler) {
|
||||||
this.artifactUrlHandler = artifactUrlHandler;
|
this.artifactUrlHandler = artifactUrlHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAmqpSenderService(final AmqpSenderService amqpSenderService) {
|
||||||
|
this.amqpSenderService = amqpSenderService;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.net.URI;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@@ -50,8 +49,6 @@ import org.springframework.amqp.core.Message;
|
|||||||
import org.springframework.amqp.core.MessageProperties;
|
import org.springframework.amqp.core.MessageProperties;
|
||||||
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
import org.springframework.amqp.rabbit.annotation.RabbitListener;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
|
|
||||||
import org.springframework.amqp.support.converter.MessageConverter;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
@@ -72,19 +69,14 @@ import com.google.common.eventbus.EventBus;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* {@link AmqpMessageHandlerService} handles all incoming AMQP messages.
|
* {@link AmqpMessageHandlerService} handles all incoming AMQP messages for the
|
||||||
*
|
* queue which is configure for the property hawkbit.dmf.rabbitmq.receiverQueue.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class AmqpMessageHandlerService {
|
public class AmqpMessageHandlerService extends BaseAmqpService {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AmqpMessageHandlerService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AmqpMessageHandlerService.class);
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ControllerManagement controllerManagement;
|
private ControllerManagement controllerManagement;
|
||||||
|
|
||||||
@@ -105,7 +97,23 @@ public class AmqpMessageHandlerService {
|
|||||||
private HostnameResolver hostnameResolver;
|
private HostnameResolver hostnameResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /** Method to handle all incoming amqp messages.
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param defaultTemplate
|
||||||
|
* the configured amqp template.
|
||||||
|
*/
|
||||||
|
public AmqpMessageHandlerService(final RabbitTemplate defaultTemplate) {
|
||||||
|
super(defaultTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue}", containerFactory = "listenerContainerFactory")
|
||||||
|
private Message onMessage(final Message message, @Header(MessageHeaderKey.TYPE) final String type,
|
||||||
|
@Header(MessageHeaderKey.TENANT) final String tenant) {
|
||||||
|
return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to handle all incoming amqp messages.
|
||||||
*
|
*
|
||||||
* @param message
|
* @param message
|
||||||
* incoming message
|
* incoming message
|
||||||
@@ -115,11 +123,11 @@ public class AmqpMessageHandlerService {
|
|||||||
* the contentType of the message
|
* the contentType of the message
|
||||||
* @param tenant
|
* @param tenant
|
||||||
* the contentType of the message
|
* the contentType of the message
|
||||||
|
* @param virtualHost
|
||||||
|
* the virtual host
|
||||||
* @return a message if <null> no message is send back to sender
|
* @return a message if <null> no message is send back to sender
|
||||||
*/
|
*/
|
||||||
@RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue}", containerFactory = "listenerContainerFactory")
|
public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) {
|
||||||
public Message onMessage(final Message message, @Header(MessageHeaderKey.TYPE) final String type,
|
|
||||||
@Header(MessageHeaderKey.TENANT) final String tenant) {
|
|
||||||
checkContentTypeJson(message);
|
checkContentTypeJson(message);
|
||||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||||
try {
|
try {
|
||||||
@@ -127,7 +135,7 @@ public class AmqpMessageHandlerService {
|
|||||||
switch (messageType) {
|
switch (messageType) {
|
||||||
case THING_CREATED:
|
case THING_CREATED:
|
||||||
setTenantSecurityContext(tenant);
|
setTenantSecurityContext(tenant);
|
||||||
registerTarget(message);
|
registerTarget(message, virtualHost);
|
||||||
break;
|
break;
|
||||||
case EVENT:
|
case EVENT:
|
||||||
setTenantSecurityContext(tenant);
|
setTenantSecurityContext(tenant);
|
||||||
@@ -153,8 +161,8 @@ public class AmqpMessageHandlerService {
|
|||||||
final String sha1 = secruityToken.getSha1();
|
final String sha1 = secruityToken.getSha1();
|
||||||
try {
|
try {
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken));
|
SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken));
|
||||||
final LocalArtifact localArtifact = artifactManagement.findFirstLocalArtifactsBySHA1(secruityToken
|
final LocalArtifact localArtifact = artifactManagement
|
||||||
.getSha1());
|
.findFirstLocalArtifactsBySHA1(secruityToken.getSha1());
|
||||||
if (localArtifact == null) {
|
if (localArtifact == null) {
|
||||||
throw new EntityNotFoundException();
|
throw new EntityNotFoundException();
|
||||||
}
|
}
|
||||||
@@ -177,9 +185,9 @@ public class AmqpMessageHandlerService {
|
|||||||
final String downloadId = UUID.randomUUID().toString();
|
final String downloadId = UUID.randomUUID().toString();
|
||||||
final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, sha1);
|
final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, sha1);
|
||||||
cache.put(downloadId, downloadCache);
|
cache.put(downloadId, downloadCache);
|
||||||
authentificationResponse.setDownloadUrl(UriComponentsBuilder
|
authentificationResponse
|
||||||
.fromUri(hostnameResolver.resolveHostname().toURI()).path("/api/v1/downloadserver/downloadId/")
|
.setDownloadUrl(UriComponentsBuilder.fromUri(hostnameResolver.resolveHostname().toURI())
|
||||||
.path(downloadId).build().toUriString());
|
.path("/api/v1/downloadserver/downloadId/").path(downloadId).build().toUriString());
|
||||||
authentificationResponse.setResponseCode(HttpStatus.OK.value());
|
authentificationResponse.setResponseCode(HttpStatus.OK.value());
|
||||||
} catch (final BadCredentialsException | AuthenticationServiceException | CredentialsExpiredException e) {
|
} catch (final BadCredentialsException | AuthenticationServiceException | CredentialsExpiredException e) {
|
||||||
LOG.error("Login failed", e);
|
LOG.error("Login failed", e);
|
||||||
@@ -196,7 +204,7 @@ public class AmqpMessageHandlerService {
|
|||||||
authentificationResponse.setMessage(errorMessage);
|
authentificationResponse.setMessage(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rabbitTemplate.getMessageConverter().toMessage(authentificationResponse, messageProperties);
|
return getMessageConverter().toMessage(authentificationResponse, messageProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Artifact convertDbArtifact(final DbArtifact dbArtifact) {
|
private static Artifact convertDbArtifact(final DbArtifact dbArtifact) {
|
||||||
@@ -207,11 +215,6 @@ public class AmqpMessageHandlerService {
|
|||||||
return artifact;
|
return artifact;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void logAndThrowMessageError(final Message message, final String error) {
|
|
||||||
LOG.error("Error \"{}\" reported by message {}", error, message.getMessageProperties().getMessageId());
|
|
||||||
throw new IllegalArgumentException(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setSecurityContext(final Authentication authentication) {
|
private static void setSecurityContext(final Authentication authentication) {
|
||||||
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
||||||
securityContextImpl.setAuthentication(authentication);
|
securityContextImpl.setAuthentication(authentication);
|
||||||
@@ -219,22 +222,13 @@ public class AmqpMessageHandlerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void setTenantSecurityContext(final String tenantId) {
|
private static void setTenantSecurityContext(final String tenantId) {
|
||||||
final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken(UUID.randomUUID()
|
final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken(
|
||||||
.toString(), "AMQP-Controller", Collections.singletonList(new SimpleGrantedAuthority(
|
UUID.randomUUID().toString(), "AMQP-Controller",
|
||||||
SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
Collections.singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
||||||
authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenantId, true));
|
authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenantId, true));
|
||||||
setSecurityContext(authenticationToken);
|
setSecurityContext(authenticationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStringHeaderKey(final Message message, final String key, final String errorMessageIfNull) {
|
|
||||||
final Map<String, Object> header = message.getMessageProperties().getHeaders();
|
|
||||||
final Object value = header.get(key);
|
|
||||||
if (value == null) {
|
|
||||||
logAndThrowMessageError(message, errorMessageIfNull);
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to create a new target or to find the target if it already exists.
|
* Method to create a new target or to find the target if it already exists.
|
||||||
*
|
*
|
||||||
@@ -243,14 +237,15 @@ public class AmqpMessageHandlerService {
|
|||||||
* @param ip
|
* @param ip
|
||||||
* the ip of the target/thing
|
* the ip of the target/thing
|
||||||
*/
|
*/
|
||||||
private void registerTarget(final Message message) {
|
private void registerTarget(final Message message, final String virtualHost) {
|
||||||
final String thingId = getStringHeaderKey(message, MessageHeaderKey.THING_ID, "ThingId is null");
|
final String thingId = getStringHeaderKey(message, MessageHeaderKey.THING_ID, "ThingId is null");
|
||||||
final String replyTo = message.getMessageProperties().getReplyTo();
|
final String replyTo = message.getMessageProperties().getReplyTo();
|
||||||
|
|
||||||
if (StringUtils.isEmpty(replyTo)) {
|
if (StringUtils.isEmpty(replyTo)) {
|
||||||
logAndThrowMessageError(message, "No ReplyTo was set for the createThing Event.");
|
logAndThrowMessageError(message, "No ReplyTo was set for the createThing Event.");
|
||||||
}
|
}
|
||||||
final URI amqpUri = IpUtil.createAmqpUri(replyTo);
|
|
||||||
|
final URI amqpUri = IpUtil.createAmqpUri(virtualHost, replyTo);
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(thingId, amqpUri);
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(thingId, amqpUri);
|
||||||
LOG.debug("Target {} reported online state.", thingId);
|
LOG.debug("Target {} reported online state.", thingId);
|
||||||
|
|
||||||
@@ -267,8 +262,8 @@ public class AmqpMessageHandlerService {
|
|||||||
final DistributionSet distributionSet = action.getDistributionSet();
|
final DistributionSet distributionSet = action.getDistributionSet();
|
||||||
final List<SoftwareModule> softwareModuleList = controllerManagement
|
final List<SoftwareModule> softwareModuleList = controllerManagement
|
||||||
.findSoftwareModulesByDistributionSet(distributionSet);
|
.findSoftwareModulesByDistributionSet(distributionSet);
|
||||||
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), target
|
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(),
|
||||||
.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress()));
|
target.getControllerId(), action.getId(), softwareModuleList, target.getTargetInfo().getAddress()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,13 +276,11 @@ public class AmqpMessageHandlerService {
|
|||||||
* the topic of the event.
|
* the topic of the event.
|
||||||
*/
|
*/
|
||||||
private void handleIncomingEvent(final Message message, final EventTopic topic) {
|
private void handleIncomingEvent(final Message message, final EventTopic topic) {
|
||||||
switch (topic) {
|
if (EventTopic.UPDATE_ACTION_STATUS.equals(topic)) {
|
||||||
case UPDATE_ACTION_STATUS:
|
|
||||||
updateActionStatus(message);
|
updateActionStatus(message);
|
||||||
return;
|
return;
|
||||||
default:
|
|
||||||
logAndThrowMessageError(message, "Got event without appropriate topic.");
|
|
||||||
}
|
}
|
||||||
|
logAndThrowMessageError(message, "Got event without appropriate topic.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,28 +329,24 @@ public class AmqpMessageHandlerService {
|
|||||||
logAndThrowMessageError(message, "Status for action does not exisit.");
|
logAndThrowMessageError(message, "Status for action does not exisit.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Action addUpdateActionStatus;
|
final Action addUpdateActionStatus = getUpdateActionStatus(action, actionStatus);
|
||||||
|
|
||||||
if (!actionStatus.getStatus().equals(Status.CANCELED)) {
|
|
||||||
addUpdateActionStatus = controllerManagement.addUpdateActionStatus(actionStatus, action);
|
|
||||||
} else {
|
|
||||||
addUpdateActionStatus = controllerManagement.addCancelActionStatus(actionStatus, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!addUpdateActionStatus.isActive()) {
|
if (!addUpdateActionStatus.isActive()) {
|
||||||
lookIfUpdateAvailable(action.getTarget());
|
lookIfUpdateAvailable(action.getTarget());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private Action getUpdateActionStatus(final Action action, final ActionStatus actionStatus) {
|
||||||
* @param message
|
if (actionStatus.getStatus().equals(Status.CANCELED)) {
|
||||||
* @param actionUpdateStatus
|
return controllerManagement.addCancelActionStatus(actionStatus, action);
|
||||||
* @return
|
}
|
||||||
*/
|
return controllerManagement.addUpdateActionStatus(actionStatus, action);
|
||||||
|
}
|
||||||
|
|
||||||
private Action checkActionExist(final Message message, final ActionUpdateStatus actionUpdateStatus) {
|
private Action checkActionExist(final Message message, final ActionUpdateStatus actionUpdateStatus) {
|
||||||
final Long actionId = actionUpdateStatus.getActionId();
|
final Long actionId = actionUpdateStatus.getActionId();
|
||||||
LOG.debug("Target notifies intermediate about action {} with status {}.", actionId, actionUpdateStatus
|
LOG.debug("Target notifies intermediate about action {} with status {}.", actionId,
|
||||||
.getActionStatus().name());
|
actionUpdateStatus.getActionStatus().name());
|
||||||
|
|
||||||
if (actionId == null) {
|
if (actionId == null) {
|
||||||
logAndThrowMessageError(message, "Invalid message no action id");
|
logAndThrowMessageError(message, "Invalid message no action id");
|
||||||
@@ -366,8 +355,8 @@ public class AmqpMessageHandlerService {
|
|||||||
final Action action = controllerManagement.findActionWithDetails(actionId);
|
final Action action = controllerManagement.findActionWithDetails(actionId);
|
||||||
|
|
||||||
if (action == null) {
|
if (action == null) {
|
||||||
logAndThrowMessageError(message, "Got intermediate notification about action " + actionId
|
logAndThrowMessageError(message,
|
||||||
+ " but action does not exist");
|
"Got intermediate notification about action " + actionId + " but action does not exist");
|
||||||
}
|
}
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
@@ -381,38 +370,12 @@ public class AmqpMessageHandlerService {
|
|||||||
// back to running action status
|
// back to running action status
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logAndThrowMessageError(message, "Cancel Recjected message is not allowed, if action is on state: "
|
logAndThrowMessageError(message,
|
||||||
+ action.getStatus());
|
"Cancel recjected message is not allowed, if action is on state: " + action.getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void checkContentTypeJson(final Message message) {
|
||||||
* Is needed to convert a incoming message to is originally object type.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the message to convert.
|
|
||||||
* @param clazz
|
|
||||||
* the class of the originally object.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
private <T> T convertMessage(final Message message, final Class<T> clazz) {
|
|
||||||
message.getMessageProperties().getHeaders()
|
|
||||||
.put(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME, clazz.getTypeName());
|
|
||||||
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is needed to verify if an incoming message has the content type json.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the to verify
|
|
||||||
* @param contentType
|
|
||||||
* the content type
|
|
||||||
* @return true if the content type has json, false it not.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static void checkContentTypeJson(final Message message) {
|
|
||||||
final MessageProperties messageProperties = message.getMessageProperties();
|
final MessageProperties messageProperties = message.getMessageProperties();
|
||||||
if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) {
|
if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) {
|
||||||
return;
|
return;
|
||||||
@@ -428,14 +391,6 @@ public class AmqpMessageHandlerService {
|
|||||||
this.hostnameResolver = hostnameResolver;
|
this.hostnameResolver = hostnameResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRabbitTemplate(final RabbitTemplate rabbitTemplate) {
|
|
||||||
this.rabbitTemplate = rabbitTemplate;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageConverter getMessageConverter() {
|
|
||||||
return rabbitTemplate.getMessageConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAuthenticationManager(final AmqpControllerAuthentfication authenticationManager) {
|
void setAuthenticationManager(final AmqpControllerAuthentfication authenticationManager) {
|
||||||
this.authenticationManager = authenticationManager;
|
this.authenticationManager = authenticationManager;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,16 +15,27 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
* Bean which holds the necessary properties for configuring the AMQP
|
* Bean which holds the necessary properties for configuring the AMQP
|
||||||
* connection.
|
* connection.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("hawkbit.dmf.rabbitmq")
|
@ConfigurationProperties("hawkbit.dmf.rabbitmq")
|
||||||
public class AmqpProperties {
|
public class AmqpProperties {
|
||||||
|
/**
|
||||||
|
* DMF API dead letter queue.
|
||||||
|
*/
|
||||||
private String deadLetterQueue = "dmf_connector_deadletter";
|
private String deadLetterQueue = "dmf_connector_deadletter";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DMF API dead letter exchange.
|
||||||
|
*/
|
||||||
private String deadLetterExchange = "dmf.connector.deadletter";
|
private String deadLetterExchange = "dmf.connector.deadletter";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DMF API receiving queue.
|
||||||
|
*/
|
||||||
private String receiverQueue = "dmf_receiver";
|
private String receiverQueue = "dmf_receiver";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Missing queue fatal.
|
||||||
|
*/
|
||||||
private boolean missingQueuesFatal = false;
|
private boolean missingQueuesFatal = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to send a amqp message.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface AmqpSenderService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the given message to the given uri. The uri contains the (virtual)
|
||||||
|
* host and exchange e.g amqp://host/exchange.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the amqp message
|
||||||
|
* @param uri
|
||||||
|
* the reply to uri
|
||||||
|
*/
|
||||||
|
void sendMessage(Message message, URI uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the exchange from the uri. Default implementation removes the
|
||||||
|
* first /.
|
||||||
|
*
|
||||||
|
* @param amqpUri
|
||||||
|
* the amqp uri
|
||||||
|
* @return the exchange.
|
||||||
|
*/
|
||||||
|
default String extractExchange(final URI amqpUri) {
|
||||||
|
return amqpUri.getPath().substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
|
||||||
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base class which provide basis amqp staff.
|
||||||
|
*/
|
||||||
|
public class BaseAmqpService {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(BaseAmqpService.class);
|
||||||
|
private final RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param rabbitTemplate
|
||||||
|
* the rabbit template.
|
||||||
|
*/
|
||||||
|
public BaseAmqpService(final RabbitTemplate rabbitTemplate) {
|
||||||
|
this.rabbitTemplate = rabbitTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean message properties before sending a message.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the message to cleaned up
|
||||||
|
*/
|
||||||
|
protected void cleanMessageHeaderProperties(final Message message) {
|
||||||
|
message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is needed to convert a incoming message to is originally object type.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the message to convert.
|
||||||
|
* @param clazz
|
||||||
|
* the class of the originally object.
|
||||||
|
* @return the converted object
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected <T> T convertMessage(final Message message, final Class<T> clazz) {
|
||||||
|
if (message == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
message.getMessageProperties().getHeaders().put(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME,
|
||||||
|
clazz.getName());
|
||||||
|
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is needed to convert a incoming message to is originally list object
|
||||||
|
* type.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* the message to convert.
|
||||||
|
* @param clazz
|
||||||
|
* the class of the list content.
|
||||||
|
* @return the list of converted objects
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected <T> List<T> convertMessageList(final Message message, final Class<T> clazz) {
|
||||||
|
if (message == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
message.getMessageProperties().getHeaders().put(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME,
|
||||||
|
ArrayList.class.getName());
|
||||||
|
message.getMessageProperties().getHeaders().put(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME,
|
||||||
|
clazz.getName());
|
||||||
|
return (List<T>) rabbitTemplate.getMessageConverter().fromMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageConverter getMessageConverter() {
|
||||||
|
return rabbitTemplate.getMessageConverter();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final String getStringHeaderKey(final Message message, final String key,
|
||||||
|
final String errorMessageIfNull) {
|
||||||
|
final Map<String, Object> header = message.getMessageProperties().getHeaders();
|
||||||
|
final Object value = header.get(key);
|
||||||
|
if (value == null) {
|
||||||
|
logAndThrowMessageError(message, errorMessageIfNull);
|
||||||
|
}
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void logAndThrowMessageError(final Message message, final String error) {
|
||||||
|
LOGGER.error("Error \"{}\" reported by message {}", error, message.getMessageProperties().getMessageId());
|
||||||
|
throw new IllegalArgumentException(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RabbitTemplate getRabbitTemplate() {
|
||||||
|
return rabbitTemplate;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.springframework.amqp.core.Message;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A default implementation for the sender service. The service sends all amqp
|
||||||
|
* message to the configured spring rabbitmq connections. The exchange is
|
||||||
|
* extracted from the uri.
|
||||||
|
*/
|
||||||
|
public class DefaultAmqpSenderService implements AmqpSenderService {
|
||||||
|
|
||||||
|
private final RabbitTemplate internalAmqpTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param internalAmqpTemplate
|
||||||
|
* the amqp template
|
||||||
|
*/
|
||||||
|
public DefaultAmqpSenderService(final RabbitTemplate internalAmqpTemplate) {
|
||||||
|
this.internalAmqpTemplate = internalAmqpTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(final Message message, final URI uri) {
|
||||||
|
internalAmqpTemplate.send(extractExchange(uri), null, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.amqp.AmqpSenderService;
|
||||||
|
import org.eclipse.hawkbit.amqp.DefaultAmqpSenderService;
|
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class AmqpTestConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to set the Jackson2JsonMessageConverter.
|
||||||
|
*
|
||||||
|
* @return the Jackson2JsonMessageConverter
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public MessageConverter jsonMessageConverter() {
|
||||||
|
return new Jackson2JsonMessageConverter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create default amqp sender service bean.
|
||||||
|
*
|
||||||
|
* @param rabbitTemplate
|
||||||
|
*
|
||||||
|
* @return the default amqp sender service bean
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Autowired
|
||||||
|
public AmqpSenderService amqpSenderServiceBean(final RabbitTemplate rabbitTemplate) {
|
||||||
|
return new DefaultAmqpSenderService(rabbitTemplate);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,8 +23,9 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
|||||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.SystemManagement;
|
import org.eclipse.hawkbit.repository.SystemManagement;
|
||||||
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
|
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||||
import org.eclipse.hawkbit.security.SecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -45,11 +46,11 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Test Amqp controller authentfication.
|
* Test Amqp controller authentication.
|
||||||
*/
|
*/
|
||||||
@Features("AMQP Authenfication Test")
|
@Features("Component Tests - Device Management Federation API")
|
||||||
@Stories("Tests the authenfication")
|
@Stories("AmqpController Authentication Test")
|
||||||
public class AmqpControllerAuthentficationTest {
|
public class AmqpControllerAuthenticationTest {
|
||||||
|
|
||||||
private static final String TENANT = "DEFAULT";
|
private static final String TENANT = "DEFAULT";
|
||||||
private static String CONTROLLLER_ID = "123";
|
private static String CONTROLLLER_ID = "123";
|
||||||
@@ -60,16 +61,18 @@ public class AmqpControllerAuthentficationTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception {
|
public void before() throws Exception {
|
||||||
amqpMessageHandlerService = new AmqpMessageHandlerService();
|
|
||||||
messageConverter = new Jackson2JsonMessageConverter();
|
messageConverter = new Jackson2JsonMessageConverter();
|
||||||
final RabbitTemplate rabbitTemplate = new RabbitTemplate();
|
final RabbitTemplate rabbitTemplate = mock(RabbitTemplate.class);
|
||||||
rabbitTemplate.setMessageConverter(messageConverter);
|
when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter);
|
||||||
amqpMessageHandlerService.setRabbitTemplate(rabbitTemplate);
|
amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate);
|
||||||
|
|
||||||
authenticationManager = new AmqpControllerAuthentfication();
|
authenticationManager = new AmqpControllerAuthentfication();
|
||||||
authenticationManager.setControllerManagement(mock(ControllerManagement.class));
|
authenticationManager.setControllerManagement(mock(ControllerManagement.class));
|
||||||
final SecurityProperties secruityProperties = mock(SecurityProperties.class);
|
|
||||||
when(secruityProperties.getRpSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d");
|
final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class);
|
||||||
|
final Rp rp = mock(Rp.class);
|
||||||
|
when(secruityProperties.getRp()).thenReturn(rp);
|
||||||
|
when(rp.getSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d");
|
||||||
authenticationManager.setSecruityProperties(secruityProperties);
|
authenticationManager.setSecruityProperties(secruityProperties);
|
||||||
systemManagement = mock(SystemManagement.class);
|
systemManagement = mock(SystemManagement.class);
|
||||||
authenticationManager.setSystemManagement(systemManagement);
|
authenticationManager.setSystemManagement(systemManagement);
|
||||||
@@ -78,7 +81,6 @@ public class AmqpControllerAuthentficationTest {
|
|||||||
final ControllerManagement controllerManagement = mock(ControllerManagement.class);
|
final ControllerManagement controllerManagement = mock(ControllerManagement.class);
|
||||||
when(controllerManagement.getSecurityTokenByControllerId(anyString())).thenReturn(CONTROLLLER_ID);
|
when(controllerManagement.getSecurityTokenByControllerId(anyString())).thenReturn(CONTROLLLER_ID);
|
||||||
authenticationManager.setControllerManagement(controllerManagement);
|
authenticationManager.setControllerManagement(controllerManagement);
|
||||||
|
|
||||||
amqpMessageHandlerService.setArtifactManagement(mock(ArtifactManagement.class));
|
amqpMessageHandlerService.setArtifactManagement(mock(ArtifactManagement.class));
|
||||||
|
|
||||||
authenticationManager.setTenantAware(new SecurityContextTenantAware());
|
authenticationManager.setTenantAware(new SecurityContextTenantAware());
|
||||||
@@ -139,7 +141,7 @@ public class AmqpControllerAuthentficationTest {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
||||||
TENANT);
|
TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
||||||
@@ -161,7 +163,7 @@ public class AmqpControllerAuthentficationTest {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
||||||
TENANT);
|
TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
||||||
@@ -183,7 +185,7 @@ public class AmqpControllerAuthentficationTest {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
||||||
TENANT);
|
TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
||||||
@@ -19,6 +19,7 @@ import static org.mockito.Matchers.eq;
|
|||||||
import static org.mockito.Mockito.spy;
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -45,7 +46,6 @@ import org.springframework.amqp.core.MessageProperties;
|
|||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
|
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
|
||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
import org.springframework.amqp.support.converter.MessageConverter;
|
|
||||||
import org.springframework.test.context.ActiveProfiles;
|
import org.springframework.test.context.ActiveProfiles;
|
||||||
|
|
||||||
import ru.yandex.qatools.allure.annotations.Description;
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
@@ -53,43 +53,44 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@ActiveProfiles({ "test" })
|
@ActiveProfiles({ "test" })
|
||||||
@Features("AMQP Dispatcher Test")
|
@Features("Component Tests - Device Management Federation API")
|
||||||
@Stories("Tests send messages")
|
@Stories("AmqpMessage Dispatcher Service Test")
|
||||||
public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWithMongoDB {
|
public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
private AmqpMessageDispatcherService amqpMessageDispatcherService;
|
private AmqpMessageDispatcherService amqpMessageDispatcherService;
|
||||||
|
|
||||||
private MessageConverter messageConverter;
|
|
||||||
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
|
private DefaultAmqpSenderService senderService;
|
||||||
|
|
||||||
private static final String CONTROLLER_ID = "1";
|
private static final String CONTROLLER_ID = "1";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void before() throws Exception {
|
public void before() throws Exception {
|
||||||
super.before();
|
super.before();
|
||||||
amqpMessageDispatcherService = new AmqpMessageDispatcherService();
|
this.rabbitTemplate = Mockito.mock(RabbitTemplate.class);
|
||||||
|
when(rabbitTemplate.getMessageConverter()).thenReturn(new Jackson2JsonMessageConverter());
|
||||||
|
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate);
|
||||||
amqpMessageDispatcherService = spy(amqpMessageDispatcherService);
|
amqpMessageDispatcherService = spy(amqpMessageDispatcherService);
|
||||||
messageConverter = new Jackson2JsonMessageConverter();
|
|
||||||
|
senderService = Mockito.mock(DefaultAmqpSenderService.class);
|
||||||
|
amqpMessageDispatcherService.setAmqpSenderService(senderService);
|
||||||
|
|
||||||
final ArtifactUrlHandler artifactUrlHandlerMock = Mockito.mock(ArtifactUrlHandler.class);
|
final ArtifactUrlHandler artifactUrlHandlerMock = Mockito.mock(ArtifactUrlHandler.class);
|
||||||
when(artifactUrlHandlerMock.getUrl(anyString(), any(), anyObject())).thenReturn("http://mockurl");
|
when(artifactUrlHandlerMock.getUrl(anyString(), any(), anyObject())).thenReturn("http://mockurl");
|
||||||
|
|
||||||
this.rabbitTemplate = Mockito.mock(RabbitTemplate.class);
|
|
||||||
when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter);
|
|
||||||
|
|
||||||
amqpMessageDispatcherService.setRabbitTemplate(rabbitTemplate);
|
|
||||||
amqpMessageDispatcherService.setTenantAware(tenantAware);
|
|
||||||
amqpMessageDispatcherService.setArtifactUrlHandler(artifactUrlHandlerMock);
|
amqpMessageDispatcherService.setArtifactUrlHandler(artifactUrlHandlerMock);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that download and install event with no software modul works")
|
@Description("Verfies that download and install event with no software modul works")
|
||||||
public void testSendDownloadRequesWithEmptySoftwareModules() {
|
public void testSendDownloadRequesWithEmptySoftwareModules() {
|
||||||
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, new ArrayList<SoftwareModule>(), IpUtil.createAmqpUri("mytest"));
|
1L, "default", CONTROLLER_ID, 1l, new ArrayList<SoftwareModule>(),
|
||||||
|
IpUtil.createAmqpUri("vHost", "mytest"));
|
||||||
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress().getHost());
|
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
||||||
assertTrue("No softwaremmodule should be contained in the request",
|
assertTrue("No softwaremmodule should be contained in the request",
|
||||||
downloadAndUpdateRequest.getSoftwareModules().isEmpty());
|
downloadAndUpdateRequest.getSoftwareModules().isEmpty());
|
||||||
@@ -101,9 +102,9 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
final DistributionSet dsA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("mytest"));
|
1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("vHost", "mytest"));
|
||||||
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress().getHost());
|
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
||||||
assertEquals("Expecting a size of 3 software modules in the reuqest", 3,
|
assertEquals("Expecting a size of 3 software modules in the reuqest", 3,
|
||||||
downloadAndUpdateRequest.getSoftwareModules().size());
|
downloadAndUpdateRequest.getSoftwareModules().size());
|
||||||
@@ -140,9 +141,9 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
Mockito.when(rabbitTemplate.convertSendAndReceive(any())).thenReturn(receivedList);
|
Mockito.when(rabbitTemplate.convertSendAndReceive(any())).thenReturn(receivedList);
|
||||||
|
|
||||||
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("mytest"));
|
1L, "default", CONTROLLER_ID, 1l, dsA.getModules(), IpUtil.createAmqpUri("vHost", "mytest"));
|
||||||
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress().getHost());
|
final Message sendMessage = createArgumentCapture(targetAssignDistributionSetEvent.getTargetAdress());
|
||||||
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
final DownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage);
|
||||||
assertEquals("DownloadAndUpdateRequest event should contains 3 software modules", 3,
|
assertEquals("DownloadAndUpdateRequest event should contains 3 software modules", 3,
|
||||||
downloadAndUpdateRequest.getSoftwareModules().size());
|
downloadAndUpdateRequest.getSoftwareModules().size());
|
||||||
@@ -159,11 +160,10 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
@Description("Verfies that send cancel event works")
|
@Description("Verfies that send cancel event works")
|
||||||
public void testSendCancelRequest() {
|
public void testSendCancelRequest() {
|
||||||
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
|
final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent(
|
||||||
1L, "default", CONTROLLER_ID, 1l, IpUtil.createAmqpUri("mytest"));
|
1L, "default", CONTROLLER_ID, 1l, IpUtil.createAmqpUri("vHost", "mytest"));
|
||||||
amqpMessageDispatcherService
|
amqpMessageDispatcherService
|
||||||
.targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent);
|
.targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent);
|
||||||
final Message sendMessage = createArgumentCapture(
|
final Message sendMessage = createArgumentCapture(cancelTargetAssignmentDistributionSetEvent.getTargetAdress());
|
||||||
cancelTargetAssignmentDistributionSetEvent.getTargetAdress().getHost());
|
|
||||||
assertCancelMessage(sendMessage);
|
assertCancelMessage(sendMessage);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -203,9 +203,9 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
MessageProperties.CONTENT_TYPE_JSON, sendMessage.getMessageProperties().getContentType());
|
MessageProperties.CONTENT_TYPE_JSON, sendMessage.getMessageProperties().getContentType());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Message createArgumentCapture(final String exchange) {
|
protected Message createArgumentCapture(final URI uri) {
|
||||||
final ArgumentCaptor<Message> argumentCaptor = ArgumentCaptor.forClass(Message.class);
|
final ArgumentCaptor<Message> argumentCaptor = ArgumentCaptor.forClass(Message.class);
|
||||||
Mockito.verify(amqpMessageDispatcherService).sendMessage(eq(exchange), argumentCaptor.capture());
|
Mockito.verify(senderService).sendMessage(argumentCaptor.capture(), eq(uri));
|
||||||
return argumentCaptor.getValue();
|
return argumentCaptor.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
@Features("AMQP Controller Test")
|
@Features("Component Tests - Device Management Federation API")
|
||||||
@Stories("Tests the servcies for message handler and dispatcher")
|
@Stories("AmqpMessage Handler Service Test")
|
||||||
public class AmqpMessageHandlerServiceTest {
|
public class AmqpMessageHandlerServiceTest {
|
||||||
|
|
||||||
private static final String TENANT = "DEFAULT";
|
private static final String TENANT = "DEFAULT";
|
||||||
@@ -99,14 +99,15 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private EventBus eventBus;
|
private EventBus eventBus;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RabbitTemplate rabbitTemplate;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void before() throws Exception {
|
public void before() throws Exception {
|
||||||
amqpMessageHandlerService = new AmqpMessageHandlerService();
|
|
||||||
amqpMessageHandlerService.setControllerManagement(controllerManagementMock);
|
|
||||||
messageConverter = new Jackson2JsonMessageConverter();
|
messageConverter = new Jackson2JsonMessageConverter();
|
||||||
final RabbitTemplate rabbitTemplate = new RabbitTemplate();
|
when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter);
|
||||||
rabbitTemplate.setMessageConverter(messageConverter);
|
amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate);
|
||||||
amqpMessageHandlerService.setRabbitTemplate(rabbitTemplate);
|
amqpMessageHandlerService.setControllerManagement(controllerManagementMock);
|
||||||
amqpMessageHandlerService.setAuthenticationManager(authenticationManagerMock);
|
amqpMessageHandlerService.setAuthenticationManager(authenticationManagerMock);
|
||||||
amqpMessageHandlerService.setArtifactManagement(artifactManagementMock);
|
amqpMessageHandlerService.setArtifactManagement(artifactManagementMock);
|
||||||
amqpMessageHandlerService.setCache(cacheMock);
|
amqpMessageHandlerService.setCache(cacheMock);
|
||||||
@@ -115,14 +116,16 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
|
||||||
@Description("Tests not allowed content-type in message")
|
@Description("Tests not allowed content-type in message")
|
||||||
public void testWrongContentType() {
|
public void testWrongContentType() {
|
||||||
final MessageProperties messageProperties = new MessageProperties();
|
final MessageProperties messageProperties = new MessageProperties();
|
||||||
messageProperties.setContentType("xml");
|
messageProperties.setContentType("xml");
|
||||||
final Message message = new Message(new byte[0], messageProperties);
|
final Message message = new Message(new byte[0], messageProperties);
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT);
|
try {
|
||||||
fail();
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
|
fail("IllegalArgumentException was excepeted due to worng content type");
|
||||||
|
} catch (final IllegalArgumentException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -138,10 +141,11 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
when(controllerManagementMock.findOrRegisterTargetIfItDoesNotexist(targetIdCaptor.capture(),
|
when(controllerManagementMock.findOrRegisterTargetIfItDoesNotexist(targetIdCaptor.capture(),
|
||||||
uriCaptor.capture())).thenReturn(null);
|
uriCaptor.capture())).thenReturn(null);
|
||||||
|
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
|
|
||||||
assertThat(targetIdCaptor.getValue()).as("Extraxted Thing should be the same").isEqualTo(knownThingId);
|
// verify
|
||||||
assertThat(uriCaptor.getValue().toString()).as("Extraxted Uri should be the same").isEqualTo("amqp://MyTest");
|
assertThat(targetIdCaptor.getValue()).as("Thing id is wrong").isEqualTo(knownThingId);
|
||||||
|
assertThat(uriCaptor.getValue().toString()).as("Uri is not right").isEqualTo("amqp://vHost/MyTest");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +157,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final Message message = messageConverter.toMessage("", messageProperties);
|
final Message message = messageConverter.toMessage("", messageProperties);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no replyTo header was set");
|
fail("IllegalArgumentException was excepeted since no replyTo header was set");
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
@@ -167,7 +171,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.THING_CREATED);
|
||||||
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.THING_CREATED.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no thingID was set");
|
fail("IllegalArgumentException was excepeted since no thingID was set");
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
@@ -183,7 +187,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
final Message message = messageConverter.toMessage(new byte[0], messageProperties);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, type, TENANT);
|
amqpMessageHandlerService.onMessage(message, type, TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted due to unknown message type");
|
fail("IllegalArgumentException was excepeted due to unknown message type");
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
@@ -196,21 +200,21 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.EVENT);
|
||||||
final Message message = new Message(new byte[0], messageProperties);
|
final Message message = new Message(new byte[0], messageProperties);
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail();
|
fail("IllegalArgumentException was excepeted due to unknown message type");
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
|
messageProperties.setHeader(MessageHeaderKey.TOPIC, "wrongTopic");
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail();
|
fail("IllegalArgumentException was excepeted due to unknown topic");
|
||||||
} catch (final IllegalArgumentException e) {
|
} catch (final IllegalArgumentException e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
|
messageProperties.setHeader(MessageHeaderKey.TOPIC, EventTopic.CANCEL_DOWNLOAD.name());
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted because there was no event topic");
|
fail("IllegalArgumentException was excepeted because there was no event topic");
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
@@ -229,7 +233,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no action id was set");
|
fail("IllegalArgumentException was excepeted since no action id was set");
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
@@ -246,7 +250,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
fail("IllegalArgumentException was excepeted since no action id was set");
|
fail("IllegalArgumentException was excepeted since no action id was set");
|
||||||
} catch (final IllegalArgumentException exception) {
|
} catch (final IllegalArgumentException exception) {
|
||||||
// test ok - exception was excepted
|
// test ok - exception was excepted
|
||||||
@@ -264,7 +268,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
||||||
TENANT);
|
TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
||||||
@@ -288,7 +292,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
||||||
TENANT);
|
TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
||||||
@@ -320,7 +324,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
|
|
||||||
// test
|
// test
|
||||||
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
final Message onMessage = amqpMessageHandlerService.onMessage(message, MessageType.AUTHENTIFICATION.name(),
|
||||||
TENANT);
|
TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
final DownloadResponse downloadResponse = (DownloadResponse) messageConverter.fromMessage(onMessage);
|
||||||
@@ -328,7 +332,8 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
assertThat(downloadResponse.getResponseCode()).as("Message body response code is wrong")
|
assertThat(downloadResponse.getResponseCode()).as("Message body response code is wrong")
|
||||||
.isEqualTo(HttpStatus.OK.value());
|
.isEqualTo(HttpStatus.OK.value());
|
||||||
assertThat(downloadResponse.getArtifact().getSize()).as("Wrong artifact size in message body").isEqualTo(1L);
|
assertThat(downloadResponse.getArtifact().getSize()).as("Wrong artifact size in message body").isEqualTo(1L);
|
||||||
assertThat(downloadResponse.getDownloadUrl()).startsWith("http://localhost/api/v1/downloadserver/downloadId/");
|
assertThat(downloadResponse.getDownloadUrl()).as("download url is wrong")
|
||||||
|
.startsWith("http://localhost/api/v1/downloadserver/downloadId/");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -355,7 +360,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
// test
|
// test
|
||||||
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT);
|
amqpMessageHandlerService.onMessage(message, MessageType.EVENT.name(), TENANT, "vHost");
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
final ArgumentCaptor<TargetAssignDistributionSetEvent> captorTargetAssignDistributionSetEvent = ArgumentCaptor
|
final ArgumentCaptor<TargetAssignDistributionSetEvent> captorTargetAssignDistributionSetEvent = ArgumentCaptor
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ package org.eclipse.hawkbit.util;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
||||||
|
import org.eclipse.hawkbit.AmqpTestConfiguration;
|
||||||
|
import org.eclipse.hawkbit.RepositoryApplicationConfiguration;
|
||||||
|
import org.eclipse.hawkbit.TestConfiguration;
|
||||||
import org.eclipse.hawkbit.TestDataUtil;
|
import org.eclipse.hawkbit.TestDataUtil;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
@@ -20,6 +23,7 @@ import org.eclipse.hawkbit.tenancy.TenantAware;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.SpringApplicationConfiguration;
|
||||||
|
|
||||||
import ru.yandex.qatools.allure.annotations.Description;
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
@@ -31,6 +35,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
*/
|
*/
|
||||||
@Features("Component Tests - Artifact URL Handler")
|
@Features("Component Tests - Artifact URL Handler")
|
||||||
@Stories("Test to generate the artifact download URL")
|
@Stories("Test to generate the artifact download URL")
|
||||||
|
@SpringApplicationConfiguration(classes = { RepositoryApplicationConfiguration.class, TestConfiguration.class,
|
||||||
|
AmqpTestConfiguration.class })
|
||||||
public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB {
|
public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -50,29 +56,33 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests generate the http download url")
|
@Description("Tests the generation of http download url.")
|
||||||
public void testHttpUrl() {
|
public void testHttpUrl() {
|
||||||
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTP);
|
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTP);
|
||||||
assertEquals("http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
assertEquals("http is build incorrect",
|
||||||
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||||
+ localArtifact.getFilename(), url);
|
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
||||||
|
+ localArtifact.getFilename(),
|
||||||
|
url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests generate the https download url")
|
@Description("Tests the generation of https download url.")
|
||||||
public void testHttpsUrl() {
|
public void testHttpsUrl() {
|
||||||
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTPS);
|
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTPS);
|
||||||
assertEquals("https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
assertEquals("https is build incorrect",
|
||||||
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
"https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||||
+ localArtifact.getFilename(), url);
|
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
||||||
|
+ localArtifact.getFilename(),
|
||||||
|
url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests generate the coap download url")
|
@Description("Tests the generation of coap download url.")
|
||||||
public void testCoapUrl() {
|
public void testCoapUrl() {
|
||||||
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.COAP);
|
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.COAP);
|
||||||
|
|
||||||
assertEquals("coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/" + controllerId + "/sha1/"
|
assertEquals("coap is build incorrect", "coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/"
|
||||||
+ localArtifact.getSha1Hash(), url);
|
+ controllerId + "/sha1/" + localArtifact.getSha1Hash(), url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,13 @@ import org.springframework.security.authentication.InsufficientAuthenticationExc
|
|||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Security")
|
||||||
|
@Stories("PreAuthToken Source TrustAuthentication Provider Test")
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
// TODO: create description annotations
|
||||||
public class PreAuthTokenSourceTrustAuthenticationProviderTest {
|
public class PreAuthTokenSourceTrustAuthenticationProviderTest {
|
||||||
|
|
||||||
private static final String REQUEST_SOURCE_IP = "127.0.0.1";
|
private static final String REQUEST_SOURCE_IP = "127.0.0.1";
|
||||||
|
|||||||
@@ -99,6 +99,11 @@
|
|||||||
<groupId>org.flywaydb</groupId>
|
<groupId>org.flywaydb</groupId>
|
||||||
<artifactId>flyway-core</artifactId>
|
<artifactId>flyway-core</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Test -->
|
<!-- Test -->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -215,7 +220,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>com.ethlo.persistence.tools</groupId>
|
<groupId>com.ethlo.persistence.tools</groupId>
|
||||||
<artifactId>eclipselink-maven-plugin</artifactId>
|
<artifactId>eclipselink-maven-plugin</artifactId>
|
||||||
<version>1.1-SNAPSHOT</version>
|
<version>2.6.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>process-classes</phase>
|
<phase>process-classes</phase>
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ public class MultiTenantJpaTransactionManager extends JpaTransactionManager {
|
|||||||
&& !definition.getName().startsWith(SystemManagement.class.getCanonicalName() + ".deleteTenant")
|
&& !definition.getName().startsWith(SystemManagement.class.getCanonicalName() + ".deleteTenant")
|
||||||
&& !definition.getName()
|
&& !definition.getName()
|
||||||
.startsWith(SystemManagement.class.getCanonicalName() + ".currentTenantKeyGenerator")
|
.startsWith(SystemManagement.class.getCanonicalName() + ".currentTenantKeyGenerator")
|
||||||
&& !definition.getName().startsWith(RolloutManagement.class.getCanonicalName() + ".rolloutScheduler")) {
|
&& !definition.getName().startsWith(RolloutManagement.class.getCanonicalName() + ".rolloutScheduler")
|
||||||
|
&& !definition.getName()
|
||||||
|
.startsWith(SystemManagement.class.getCanonicalName() + ".getOrCreateTenantMetadata")) {
|
||||||
|
|
||||||
final String currentTenant = tenantAware.getCurrentTenant();
|
final String currentTenant = tenantAware.getCurrentTenant();
|
||||||
if (currentTenant == null) {
|
if (currentTenant == null) {
|
||||||
|
|||||||
@@ -40,10 +40,6 @@ import org.springframework.validation.beanvalidation.MethodValidationPostProcess
|
|||||||
/**
|
/**
|
||||||
* General configuration for the SP Repository.
|
* General configuration for the SP Repository.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@EnableJpaRepositories(basePackages = { "org.eclipse.hawkbit.repository" })
|
@EnableJpaRepositories(basePackages = { "org.eclipse.hawkbit.repository" })
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit;
|
||||||
|
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollout Management properties.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties("hawkbit.rollout")
|
||||||
|
public class RolloutProperties {
|
||||||
|
private final Scheduler scheduler = new Scheduler();
|
||||||
|
|
||||||
|
public Scheduler getScheduler() {
|
||||||
|
return scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rollout scheduler configuration.
|
||||||
|
*/
|
||||||
|
public static class Scheduler {
|
||||||
|
// used by @Scheduled annotation which needs constant
|
||||||
|
public static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.rollout.scheduler.fixedDelay:30000}";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule where the rollout scheduler looks necessary state changes in
|
||||||
|
* milliseconds.
|
||||||
|
*/
|
||||||
|
private long fixedDelay = 30000L;
|
||||||
|
|
||||||
|
public long getFixedDelay() {
|
||||||
|
return fixedDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFixedDelay(final long fixedDelay) {
|
||||||
|
this.fixedDelay = fixedDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,45 +21,47 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
/**
|
/**
|
||||||
* {@link ActionStatus} repository.
|
* {@link ActionStatus} repository.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public interface ActionStatusRepository
|
public interface ActionStatusRepository
|
||||||
extends BaseEntityRepository<ActionStatus, Long>, JpaSpecificationExecutor<ActionStatus> {
|
extends BaseEntityRepository<ActionStatus, Long>, JpaSpecificationExecutor<ActionStatus> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param target
|
* Counts {@link ActionStatus} entries of given {@link Action} in
|
||||||
|
* repository.
|
||||||
|
*
|
||||||
* @param action
|
* @param action
|
||||||
* @return
|
* to count status entries
|
||||||
|
* @return number of actions in repository
|
||||||
*/
|
*/
|
||||||
Long countByAction(Action action);
|
Long countByAction(Action action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Counts {@link ActionStatus} entries of given {@link Action} with given
|
||||||
|
* {@link Status} in repository.
|
||||||
|
*
|
||||||
* @param action
|
* @param action
|
||||||
* @param retrieved
|
* to count status entries
|
||||||
* @return
|
* @param status
|
||||||
|
* to filter for
|
||||||
|
* @return number of actions in repository
|
||||||
*/
|
*/
|
||||||
Long countByActionAndStatus(Action action, Status retrieved);
|
Long countByActionAndStatus(Action action, Status status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Retrieves all {@link ActionStatus} entries from repository of given
|
||||||
|
* {@link Action}.
|
||||||
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
|
* parameters
|
||||||
* @param action
|
* @param action
|
||||||
* @return
|
* of the status entries
|
||||||
|
* @return pages list of {@link ActionStatus} entries
|
||||||
*/
|
*/
|
||||||
Page<ActionStatus> findByAction(Pageable pageReq, Action action);
|
Page<ActionStatus> findByAction(Pageable pageReq, Action action);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param pageReq
|
* Finds all status updates for the defined action and target including
|
||||||
* @param action
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
Page<ActionStatus> findByActionOrderByIdDesc(Pageable pageReq, Action action);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds all status updates for the defined action and target order by
|
|
||||||
* {@link ActionStatus#getId()} desc including
|
|
||||||
* {@link ActionStatus#getMessages()}.
|
* {@link ActionStatus#getMessages()}.
|
||||||
*
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
@@ -71,6 +73,6 @@ public interface ActionStatusRepository
|
|||||||
* @return Page with found targets
|
* @return Page with found targets
|
||||||
*/
|
*/
|
||||||
@EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD)
|
@EntityGraph(value = "ActionStatus.withMessages", type = EntityGraphType.LOAD)
|
||||||
Page<ActionStatus> getByActionOrderByIdDesc(Pageable pageReq, Action action);
|
Page<ActionStatus> getByAction(Pageable pageReq, Action action);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,13 +33,11 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.Target_;
|
import org.eclipse.hawkbit.repository.model.Target_;
|
||||||
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.hibernate.validator.constraints.NotEmpty;
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
|
||||||
import org.springframework.context.EnvironmentAware;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.data.jpa.domain.Specification;
|
import org.springframework.data.jpa.domain.Specification;
|
||||||
import org.springframework.data.jpa.repository.Modifying;
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@@ -57,7 +55,7 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
@Service
|
||||||
public class ControllerManagement implements EnvironmentAware {
|
public class ControllerManagement {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ControllerManagement.class);
|
||||||
private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos");
|
private static final Logger LOG_DOS = LoggerFactory.getLogger("server-security.dos");
|
||||||
|
|
||||||
@@ -85,9 +83,8 @@ public class ControllerManagement implements EnvironmentAware {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ActionStatusRepository actionStatusRepository;
|
private ActionStatusRepository actionStatusRepository;
|
||||||
|
|
||||||
private Integer maxCount = 1000;
|
@Autowired
|
||||||
|
private HawkbitSecurityProperties securityProperties;
|
||||||
private Integer maxAttributes = 100;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes the time of the last time the controller has been connected to
|
* Refreshes the time of the last time the controller has been connected to
|
||||||
@@ -379,15 +376,16 @@ public class ControllerManagement implements EnvironmentAware {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkForToManyStatusEntries(final Action action) {
|
private void checkForToManyStatusEntries(final Action action) {
|
||||||
if (maxCount > 0) {
|
if (securityProperties.getDos().getMaxStatusEntriesPerAction() > 0) {
|
||||||
|
|
||||||
final Long statusCount = actionStatusRepository.countByAction(action);
|
final Long statusCount = actionStatusRepository.countByAction(action);
|
||||||
|
|
||||||
if (statusCount >= maxCount) {
|
if (statusCount >= securityProperties.getDos().getMaxStatusEntriesPerAction()) {
|
||||||
LOG_DOS.error(
|
LOG_DOS.error(
|
||||||
"Potential denial of service (DOS) attack identfied. More status entries in the system than permitted ({})!",
|
"Potential denial of service (DOS) attack identfied. More status entries in the system than permitted ({})!",
|
||||||
maxCount);
|
securityProperties.getDos().getMaxStatusEntriesPerAction());
|
||||||
throw new ToManyStatusEntriesException(String.valueOf(maxCount));
|
throw new ToManyStatusEntriesException(
|
||||||
|
String.valueOf(securityProperties.getDos().getMaxStatusEntriesPerAction()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,10 +434,12 @@ public class ControllerManagement implements EnvironmentAware {
|
|||||||
|
|
||||||
target.getTargetInfo().getControllerAttributes().putAll(data);
|
target.getTargetInfo().getControllerAttributes().putAll(data);
|
||||||
|
|
||||||
if (target.getTargetInfo().getControllerAttributes().size() > maxAttributes) {
|
if (target.getTargetInfo().getControllerAttributes().size() > securityProperties.getDos()
|
||||||
|
.getMaxAttributeEntriesPerTarget()) {
|
||||||
LOG_DOS.info("Target tries to insert more than the allowed number of entries ({}). DOS attack anticipated!",
|
LOG_DOS.info("Target tries to insert more than the allowed number of entries ({}). DOS attack anticipated!",
|
||||||
maxAttributes);
|
securityProperties.getDos().getMaxAttributeEntriesPerTarget());
|
||||||
throw new ToManyAttributeEntriesException(String.valueOf(maxAttributes));
|
throw new ToManyAttributeEntriesException(
|
||||||
|
String.valueOf(securityProperties.getDos().getMaxAttributeEntriesPerTarget()));
|
||||||
}
|
}
|
||||||
|
|
||||||
target.getTargetInfo().setLastTargetQuery(System.currentTimeMillis());
|
target.getTargetInfo().setLastTargetQuery(System.currentTimeMillis());
|
||||||
@@ -447,19 +447,6 @@ public class ControllerManagement implements EnvironmentAware {
|
|||||||
return targetRepository.save(target);
|
return targetRepository.save(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.springframework.context.EnvironmentAware#setEnvironment(org.
|
|
||||||
* springframework.core.env. Environment)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setEnvironment(final Environment environment) {
|
|
||||||
final RelaxedPropertyResolver env = new RelaxedPropertyResolver(environment, "hawkbit.server.");
|
|
||||||
maxCount = env.getProperty("security.dos.maxStatusEntriesPerAction", Integer.class, 1000);
|
|
||||||
maxAttributes = env.getProperty("security.dos.maxAttributeEntriesPerTarget", Integer.class, 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers retrieved status for given {@link Target} and {@link Action} if
|
* Registers retrieved status for given {@link Target} and {@link Action} if
|
||||||
* it does not exist yet.
|
* it does not exist yet.
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ public class DeploymentManagement {
|
|||||||
}).collect(Collectors.toList())).stream()
|
}).collect(Collectors.toList())).stream()
|
||||||
.collect(Collectors.toMap(a -> a.getTarget().getControllerId(), Function.identity()));
|
.collect(Collectors.toMap(a -> a.getTarget().getControllerId(), Function.identity()));
|
||||||
|
|
||||||
// MECS-720 create initial action status when action is created so we
|
// create initial action status when action is created so we
|
||||||
// remember the initial
|
// remember the initial
|
||||||
// running status because we will change the status of the action itself
|
// running status because we will change the status of the action itself
|
||||||
// and with this action
|
// and with this action
|
||||||
@@ -925,7 +925,7 @@ public class DeploymentManagement {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieves all the {@link ActionStatus} entries of the given
|
* retrieves all the {@link ActionStatus} entries of the given
|
||||||
* {@link Action} and {@link Target} in the order latest first.
|
* {@link Action} and {@link Target}.
|
||||||
*
|
*
|
||||||
* @param pageReq
|
* @param pageReq
|
||||||
* pagination parameter
|
* pagination parameter
|
||||||
@@ -937,12 +937,12 @@ public class DeploymentManagement {
|
|||||||
* @return the corresponding {@link Page} of {@link ActionStatus}
|
* @return the corresponding {@link Page} of {@link ActionStatus}
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
|
||||||
public Page<ActionStatus> findActionStatusMessagesByActionInDescOrder(final Pageable pageReq, final Action action,
|
public Page<ActionStatus> findActionStatusByAction(final Pageable pageReq, final Action action,
|
||||||
final boolean withMessages) {
|
final boolean withMessages) {
|
||||||
if (withMessages) {
|
if (withMessages) {
|
||||||
return actionStatusRepository.getByActionOrderByIdDesc(pageReq, action);
|
return actionStatusRepository.getByAction(pageReq, action);
|
||||||
} else {
|
} else {
|
||||||
return actionStatusRepository.findByActionOrderByIdDesc(pageReq, action);
|
return actionStatusRepository.findByAction(pageReq, action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -294,8 +294,7 @@ public class DistributionSetManagement {
|
|||||||
// hard delete the rest if exixts
|
// hard delete the rest if exixts
|
||||||
if (!toHardDelete.isEmpty()) {
|
if (!toHardDelete.isEmpty()) {
|
||||||
// don't give the delete statement an empty list, JPA/Oracle cannot
|
// don't give the delete statement an empty list, JPA/Oracle cannot
|
||||||
// handle the empty list,
|
// handle the empty list
|
||||||
// see MECS-403
|
|
||||||
distributionSetRepository.deleteByIdIn(toHardDelete);
|
distributionSetRepository.deleteByIdIn(toHardDelete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import org.eclipse.hawkbit.repository.model.Target_;
|
|||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -55,14 +54,10 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
/**
|
/**
|
||||||
* Service layer for generating SP reportings.
|
* Service layer for generating SP reportings.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@Validated
|
@Validated
|
||||||
@Service
|
@Service
|
||||||
@ConfigurationProperties
|
|
||||||
public class ReportManagement {
|
public class ReportManagement {
|
||||||
|
|
||||||
@Value("${spring.jpa.database}")
|
@Value("${spring.jpa.database}")
|
||||||
|
|||||||
@@ -10,14 +10,13 @@ package org.eclipse.hawkbit.repository;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.RolloutProperties;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.EnvironmentAware;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@@ -31,15 +30,10 @@ import org.springframework.stereotype.Component;
|
|||||||
// don't active the rollout scheduler in test, otherwise it is hard to test
|
// don't active the rollout scheduler in test, otherwise it is hard to test
|
||||||
// rolloutmanagement and leads weird side-effects maybe.
|
// rolloutmanagement and leads weird side-effects maybe.
|
||||||
@Profile("!test")
|
@Profile("!test")
|
||||||
public class RolloutScheduler implements EnvironmentAware {
|
public class RolloutScheduler {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(RolloutScheduler.class);
|
private static final Logger logger = LoggerFactory.getLogger(RolloutScheduler.class);
|
||||||
|
|
||||||
private static final String PROP_SCHEDULER_DELAY = "hawkbit.rollout.scheduler.fixedDelay";
|
|
||||||
private static final long DEFAULT_SCHEDULER_DELAY = 30000L;
|
|
||||||
private static final String PROP_SCHEDULER_DELAY_PLACEHOLDER = "${" + PROP_SCHEDULER_DELAY + ":"
|
|
||||||
+ DEFAULT_SCHEDULER_DELAY + "}";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@@ -52,7 +46,8 @@ public class RolloutScheduler implements EnvironmentAware {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private SystemSecurityContext systemSecurityContext;
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
private long fixedDelay = DEFAULT_SCHEDULER_DELAY;
|
@Autowired
|
||||||
|
private RolloutProperties rolloutProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scheduler method called by the spring-async mechanism. Retrieves all
|
* Scheduler method called by the spring-async mechanism. Retrieves all
|
||||||
@@ -60,7 +55,7 @@ public class RolloutScheduler implements EnvironmentAware {
|
|||||||
* tenant the {@link RolloutManagement#checkRunningRollouts(long)} in the
|
* tenant the {@link RolloutManagement#checkRunningRollouts(long)} in the
|
||||||
* {@link SystemSecurityContext}.
|
* {@link SystemSecurityContext}.
|
||||||
*/
|
*/
|
||||||
@Scheduled(initialDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
@Scheduled(initialDelayString = RolloutProperties.Scheduler.PROP_SCHEDULER_DELAY_PLACEHOLDER, fixedDelayString = RolloutProperties.Scheduler.PROP_SCHEDULER_DELAY_PLACEHOLDER)
|
||||||
public void rolloutScheduler() {
|
public void rolloutScheduler() {
|
||||||
logger.debug("rollout schedule checker has been triggered.");
|
logger.debug("rollout schedule checker has been triggered.");
|
||||||
// run this code in system code privileged to have the necessary
|
// run this code in system code privileged to have the necessary
|
||||||
@@ -76,16 +71,11 @@ public class RolloutScheduler implements EnvironmentAware {
|
|||||||
logger.info("Checking rollouts for {} tenants", tenants.size());
|
logger.info("Checking rollouts for {} tenants", tenants.size());
|
||||||
for (final String tenant : tenants) {
|
for (final String tenant : tenants) {
|
||||||
tenantAware.runAsTenant(tenant, () -> {
|
tenantAware.runAsTenant(tenant, () -> {
|
||||||
rolloutManagement.checkRunningRollouts(fixedDelay);
|
rolloutManagement.checkRunningRollouts(rolloutProperties.getScheduler().getFixedDelay());
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnvironment(final Environment environment) {
|
|
||||||
fixedDelay = environment.getProperty(PROP_SCHEDULER_DELAY, Long.class, DEFAULT_SCHEDULER_DELAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ public class SystemManagement implements EnvironmentAware {
|
|||||||
* @return {@code true} in case the tenant exits or {@code false} if not
|
* @return {@code true} in case the tenant exits or {@code false} if not
|
||||||
*/
|
*/
|
||||||
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator")
|
@Cacheable(value = "currentTenant", keyGenerator = "currentTenantKeyGenerator")
|
||||||
// MECS-903 set transaction to not supported, due we call this in
|
// set transaction to not supported, due we call this in
|
||||||
// BaseEntity#prePersist methods
|
// BaseEntity#prePersist methods
|
||||||
// and it seems that JPA committing the transaction when executing this
|
// and it seems that JPA committing the transaction when executing this
|
||||||
// transactional method,
|
// transactional method,
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
|
|||||||
import org.eclipse.hawkbit.repository.model.helper.EventBusHolder;
|
import org.eclipse.hawkbit.repository.model.helper.EventBusHolder;
|
||||||
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator;
|
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator;
|
||||||
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator.DatabaseCleanupUtil;
|
import org.eclipse.hawkbit.repository.utils.RepositoryDataGenerator.DatabaseCleanupUtil;
|
||||||
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||||
import org.eclipse.hawkbit.security.SecurityProperties;
|
|
||||||
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||||
@@ -47,7 +47,7 @@ import com.mongodb.MongoClientOptions;
|
|||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
|
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
|
||||||
@EnableConfigurationProperties({ SecurityProperties.class, ControllerPollProperties.class })
|
@EnableConfigurationProperties({ DdiSecurityProperties.class, ControllerPollProperties.class })
|
||||||
@Profile("test")
|
@Profile("test")
|
||||||
public class TestConfiguration implements AsyncConfigurer {
|
public class TestConfiguration implements AsyncConfigurer {
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ import static org.fest.assertions.api.Assertions.assertThat;
|
|||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Repository")
|
||||||
|
@Stories("CacheKeys")
|
||||||
public class CacheKeysTest {
|
public class CacheKeysTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ import org.springframework.cache.CacheManager;
|
|||||||
|
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Repository")
|
||||||
|
@Stories("CacheWriteNotify")
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CacheWriteNotifyTest {
|
public class CacheWriteNotifyTest {
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ import org.springframework.cache.CacheManager;
|
|||||||
import org.springframework.cache.support.SimpleValueWrapper;
|
import org.springframework.cache.support.SimpleValueWrapper;
|
||||||
import org.springframework.hateoas.Identifiable;
|
import org.springframework.hateoas.Identifiable;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Repository")
|
||||||
|
@Stories("EventBus")
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CacheFieldEntityListenerTest {
|
public class CacheFieldEntityListenerTest {
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,16 @@ import org.eclipse.hawkbit.repository.model.Action;
|
|||||||
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
import org.eclipse.hawkbit.repository.model.Action.ActionType;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
@Features("Unit Tests - Repository")
|
||||||
|
@Stories("Deployment Management")
|
||||||
public class ActionTest {
|
public class ActionTest {
|
||||||
|
|
||||||
// issue MECS-670 timeforced update and eTAG calculation
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that timeforced moded switch from soft to forces after defined timeframe.")
|
||||||
public void timeforcedHitNewHasCodeIsGenerated() throws InterruptedException {
|
public void timeforcedHitNewHasCodeIsGenerated() throws InterruptedException {
|
||||||
|
|
||||||
final boolean active = true;
|
final boolean active = true;
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
/**
|
/**
|
||||||
* Addition tests next to {@link ArtifactManagementTest} with no running MongoDB
|
* Addition tests next to {@link ArtifactManagementTest} with no running MongoDB
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Repository")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("Artifact Management")
|
@Stories("Artifact Management")
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ public class ControllerManagementTest extends AbstractIntegrationTest {
|
|||||||
.isEqualTo(TargetUpdateStatus.IN_SYNC);
|
.isEqualTo(TargetUpdateStatus.IN_SYNC);
|
||||||
|
|
||||||
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
|
assertThat(actionStatusRepository.findAll(pageReq).getNumberOfElements()).isEqualTo(3);
|
||||||
assertThat(deploymentManagement.findActionStatusMessagesByActionInDescOrder(pageReq, savedAction, false)
|
assertThat(deploymentManagement.findActionStatusByAction(pageReq, savedAction, false).getNumberOfElements())
|
||||||
.getNumberOfElements()).isEqualTo(3);
|
.isEqualTo(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -145,7 +145,6 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test verifies that an assignment with automatic cancelation works correctly even if the update is split into multiple partitions on the database.")
|
@Description("Test verifies that an assignment with automatic cancelation works correctly even if the update is split into multiple partitions on the database.")
|
||||||
@Issue("MECS-674")
|
|
||||||
public void multiAssigmentHistoryOverMultiplePagesResultsInTwoActiveAction() {
|
public void multiAssigmentHistoryOverMultiplePagesResultsInTwoActiveAction() {
|
||||||
|
|
||||||
final DistributionSet cancelDs = TestDataUtil.generateDistributionSet("Canceled DS", "1.0", softwareManagement,
|
final DistributionSet cancelDs = TestDataUtil.generateDistributionSet("Canceled DS", "1.0", softwareManagement,
|
||||||
@@ -766,12 +765,13 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
|
|||||||
distributionSetManagement.findDistributionSetByIdWithDetails(dsA.getId()).getOptLockRevision());
|
distributionSetManagement.findDistributionSetByIdWithDetails(dsA.getId()).getOptLockRevision());
|
||||||
|
|
||||||
// verifying that the assignment is correct
|
// verifying that the assignment is correct
|
||||||
assertEquals(1, deploymentManagement.findActiveActionsByTarget(targ).size());
|
assertEquals("Active target actions are wrong", 1, deploymentManagement.findActiveActionsByTarget(targ).size());
|
||||||
assertEquals(1, deploymentManagement.findActionsByTarget(targ).size());
|
assertEquals("Target actions are wrong", 1, deploymentManagement.findActionsByTarget(targ).size());
|
||||||
assertEquals(TargetUpdateStatus.PENDING, targ.getTargetInfo().getUpdateStatus());
|
assertEquals("Target status is wrong", TargetUpdateStatus.PENDING, targ.getTargetInfo().getUpdateStatus());
|
||||||
assertEquals(dsA, targ.getAssignedDistributionSet());
|
assertEquals("Assigned ds is wrong", dsA, targ.getAssignedDistributionSet());
|
||||||
assertEquals(dsA, deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet());
|
assertEquals("Active ds is wrong", dsA,
|
||||||
assertNull(targ.getTargetInfo().getInstalledDistributionSet());
|
deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet());
|
||||||
|
assertNull("Installed ds should be null", targ.getTargetInfo().getInstalledDistributionSet());
|
||||||
|
|
||||||
final Page<Action> updAct = actionRepository.findByDistributionSet(pageReq, dsA);
|
final Page<Action> updAct = actionRepository.findByDistributionSet(pageReq, dsA);
|
||||||
final Action action = updAct.getContent().get(0);
|
final Action action = updAct.getContent().get(0);
|
||||||
@@ -782,12 +782,8 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
|
|||||||
targ = targetManagement.findTargetByControllerID(targ.getControllerId());
|
targ = targetManagement.findTargetByControllerID(targ.getControllerId());
|
||||||
|
|
||||||
assertEquals(0, deploymentManagement.findActiveActionsByTarget(targ).size());
|
assertEquals(0, deploymentManagement.findActiveActionsByTarget(targ).size());
|
||||||
// try {
|
|
||||||
assertEquals(1, deploymentManagement.findInActiveActionsByTarget(targ).size());
|
assertEquals(1, deploymentManagement.findInActiveActionsByTarget(targ).size());
|
||||||
// }
|
|
||||||
// catch( final LazyInitializationException ex ) {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
assertEquals(TargetUpdateStatus.IN_SYNC, targ.getTargetInfo().getUpdateStatus());
|
assertEquals(TargetUpdateStatus.IN_SYNC, targ.getTargetInfo().getUpdateStatus());
|
||||||
assertEquals(dsA, targ.getAssignedDistributionSet());
|
assertEquals(dsA, targ.getAssignedDistributionSet());
|
||||||
assertEquals(dsA, targ.getTargetInfo().getInstalledDistributionSet());
|
assertEquals(dsA, targ.getTargetInfo().getInstalledDistributionSet());
|
||||||
@@ -797,13 +793,15 @@ public class DeploymentManagementTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
targ = targs.iterator().next();
|
targ = targs.iterator().next();
|
||||||
|
|
||||||
assertEquals(1, deploymentManagement.findActiveActionsByTarget(targ).size());
|
assertEquals("active actions are wrong", 1, deploymentManagement.findActiveActionsByTarget(targ).size());
|
||||||
assertEquals(TargetUpdateStatus.PENDING,
|
assertEquals("target status is wrong", TargetUpdateStatus.PENDING,
|
||||||
targetManagement.findTargetByControllerID(targ.getControllerId()).getTargetInfo().getUpdateStatus());
|
targetManagement.findTargetByControllerID(targ.getControllerId()).getTargetInfo().getUpdateStatus());
|
||||||
assertEquals(dsB, targ.getAssignedDistributionSet());
|
assertEquals(dsB, targ.getAssignedDistributionSet());
|
||||||
assertEquals(dsA.getId(), targetManagement.findTargetByControllerIDWithDetails(targ.getControllerId())
|
assertEquals("Installed ds is wrong", dsA.getId(),
|
||||||
.getTargetInfo().getInstalledDistributionSet().getId());
|
targetManagement.findTargetByControllerIDWithDetails(targ.getControllerId()).getTargetInfo()
|
||||||
assertEquals(dsB, deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet());
|
.getInstalledDistributionSet().getId());
|
||||||
|
assertEquals("Active ds is wrong", dsB,
|
||||||
|
deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,13 +34,9 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
/**
|
/**
|
||||||
* Test class for {@link TagManagement}.
|
* Test class for {@link TagManagement}.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Repository")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("Tag Management")
|
@Stories("Tag Management")
|
||||||
// TODO: fully document tests -> @Description for long text and reasonable
|
|
||||||
// method name as short text
|
|
||||||
public class TagManagementTest extends AbstractIntegrationTest {
|
public class TagManagementTest extends AbstractIntegrationTest {
|
||||||
public TagManagementTest() {
|
public TagManagementTest() {
|
||||||
LOG = LoggerFactory.getLogger(TagManagementTest.class);
|
LOG = LoggerFactory.getLogger(TagManagementTest.class);
|
||||||
@@ -155,13 +151,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
return new DistributionSetFilterBuilder();
|
return new DistributionSetFilterBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#findTargetTag(java.lang.String)}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindTargetTag() {
|
@Description("Ensures that all tags are retrieved through repository.")
|
||||||
|
public void findAllTargetTags() {
|
||||||
assertThat(targetTagRepository.findAll()).isEmpty();
|
assertThat(targetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
final List<TargetTag> tags = createTargetsWithTags();
|
final List<TargetTag> tags = createTargetsWithTags();
|
||||||
@@ -170,13 +162,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
.hasSize(20);
|
.hasSize(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#createTargetTag(org.eclipse.hawkbit.repository.model.TargetTag)}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateTargetTag() {
|
@Description("Ensures that a created tag is persisted in the repository as defined.")
|
||||||
|
public void createTargetTag() {
|
||||||
assertThat(targetTagRepository.findAll()).isEmpty();
|
assertThat(targetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
final Tag tag = tagManagement.createTargetTag(new TargetTag("kai1", "kai2", "colour"));
|
final Tag tag = tagManagement.createTargetTag(new TargetTag("kai1", "kai2", "colour"));
|
||||||
@@ -186,13 +174,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
assertThat(tagManagement.findTargetTagById(tag.getId()).getColour()).isEqualTo("colour");
|
assertThat(tagManagement.findTargetTagById(tag.getId()).getColour()).isEqualTo("colour");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#deleteTargetTag(java.lang.String[])}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteTargetTagsStringArray() {
|
@Description("Ensures that a deleted tag is removed from the repository as defined.")
|
||||||
|
public void deleteTargetTas() {
|
||||||
assertThat(targetTagRepository.findAll()).isEmpty();
|
assertThat(targetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
// create test data
|
// create test data
|
||||||
@@ -217,7 +201,7 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the creation of a target tag.")
|
@Description("Tests the name update of a target tag.")
|
||||||
public void updateTargetTag() {
|
public void updateTargetTag() {
|
||||||
assertThat(targetTagRepository.findAll()).isEmpty();
|
assertThat(targetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
@@ -237,13 +221,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
assertThat(targetTagRepository.findOne(savedAssigned.getId()).getOptLockRevision()).isEqualTo(2);
|
assertThat(targetTagRepository.findOne(savedAssigned.getId()).getOptLockRevision()).isEqualTo(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#createDistributionSetTag(org.eclipse.hawkbit.repository.model.DistributionSetTag)}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDistributionSetTag() {
|
@Description("Ensures that a created tag is persisted in the repository as defined.")
|
||||||
|
public void createDistributionSetTag() {
|
||||||
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
final Tag tag = tagManagement.createDistributionSetTag(new DistributionSetTag("kai1", "kai2", "colour"));
|
final Tag tag = tagManagement.createDistributionSetTag(new DistributionSetTag("kai1", "kai2", "colour"));
|
||||||
@@ -253,13 +233,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
assertThat(tagManagement.findDistributionSetTagById(tag.getId()).getColour()).isEqualTo("colour");
|
assertThat(tagManagement.findDistributionSetTagById(tag.getId()).getColour()).isEqualTo("colour");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#createDistributionSetTags(java.lang.Iterable)}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDistributionSetTags() {
|
@Description("Ensures that a created tags are persisted in the repository as defined.")
|
||||||
|
public void createDistributionSetTags() {
|
||||||
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
final List<DistributionSetTag> tags = createDsSetsWithTags();
|
final List<DistributionSetTag> tags = createDsSetsWithTags();
|
||||||
@@ -267,13 +243,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
assertThat(distributionSetTagRepository.findAll()).hasSize(tags.size());
|
assertThat(distributionSetTagRepository.findAll()).hasSize(tags.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#deleteDistributionSetTag(java.lang.String[])}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteDistributionSetTag() {
|
@Description("Ensures that a deleted tag is removed from the repository as defined.")
|
||||||
|
public void deleteDistributionSetTag() {
|
||||||
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
// create test data
|
// create test data
|
||||||
@@ -298,24 +270,40 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = EntityAlreadyExistsException.class)
|
@Test(expected = EntityAlreadyExistsException.class)
|
||||||
public void testFailedDuplicateTargetTagNameException() {
|
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
|
||||||
|
public void failedDuplicateTargetTagNameException() {
|
||||||
tagManagement.createTargetTag(new TargetTag("A"));
|
tagManagement.createTargetTag(new TargetTag("A"));
|
||||||
tagManagement.createTargetTag(new TargetTag("A"));
|
tagManagement.createTargetTag(new TargetTag("A"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = EntityAlreadyExistsException.class)
|
@Test(expected = EntityAlreadyExistsException.class)
|
||||||
public void testFailedDuplicateDsTagNameException() {
|
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
|
||||||
|
public void failedDuplicateTargetTagNameExceptionAfterUpdate() {
|
||||||
|
tagManagement.createTargetTag(new TargetTag("A"));
|
||||||
|
final TargetTag tag = tagManagement.createTargetTag(new TargetTag("B"));
|
||||||
|
tag.setName("A");
|
||||||
|
tagManagement.updateTargetTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = EntityAlreadyExistsException.class)
|
||||||
|
@Description("Ensures that a tag cannot be created if one exists already with that name (ecpects EntityAlreadyExistsException).")
|
||||||
|
public void failedDuplicateDsTagNameException() {
|
||||||
tagManagement.createDistributionSetTag(new DistributionSetTag("A"));
|
tagManagement.createDistributionSetTag(new DistributionSetTag("A"));
|
||||||
tagManagement.createDistributionSetTag(new DistributionSetTag("A"));
|
tagManagement.createDistributionSetTag(new DistributionSetTag("A"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Test(expected = EntityAlreadyExistsException.class)
|
||||||
* Test method for
|
@Description("Ensures that a tag cannot be updated to a name that already exists on another tag (ecpects EntityAlreadyExistsException).")
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#updateDistributionSetTag(org.eclipse.hawkbit.repository.model.DistributionSetTag)}
|
public void failedDuplicateDsTagNameExceptionAfterUpdate() {
|
||||||
* .
|
tagManagement.createDistributionSetTag(new DistributionSetTag("A"));
|
||||||
*/
|
final DistributionSetTag tag = tagManagement.createDistributionSetTag(new DistributionSetTag("B"));
|
||||||
|
tag.setName("A");
|
||||||
|
tagManagement.updateDistributionSetTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateDistributionSetTag() {
|
@Description("Tests the name update of a target tag.")
|
||||||
|
public void updateDistributionSetTag() {
|
||||||
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
// create test data
|
// create test data
|
||||||
@@ -333,13 +321,9 @@ public class TagManagementTest extends AbstractIntegrationTest {
|
|||||||
assertThat(distributionSetTagRepository.findOne(savedAssigned.getId()).getName()).isEqualTo("test123");
|
assertThat(distributionSetTagRepository.findOne(savedAssigned.getId()).getName()).isEqualTo("test123");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.repository.TagManagement#findAllDistributionSetTags()}
|
|
||||||
* .
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
public void testFindDistributionSetTagsAll() {
|
@Description("Ensures that all tags are retrieved through repository.")
|
||||||
|
public void findDistributionSetTagsAll() {
|
||||||
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
assertThat(distributionSetTagRepository.findAll()).isEmpty();
|
||||||
|
|
||||||
final List<DistributionSetTag> tags = createDsSetsWithTags();
|
final List<DistributionSetTag> tags = createDsSetsWithTags();
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest {
|
|||||||
final TargetTag targTagC = tagManagement.createTargetTag(new TargetTag("TargTag-C"));
|
final TargetTag targTagC = tagManagement.createTargetTag(new TargetTag("TargTag-C"));
|
||||||
final TargetTag targTagD = tagManagement.createTargetTag(new TargetTag("TargTag-D"));
|
final TargetTag targTagD = tagManagement.createTargetTag(new TargetTag("TargTag-D"));
|
||||||
|
|
||||||
// TODO kzimmerm: test also installedDS (not only assignedDS)
|
// TODO kaizimmerm: test also installedDS (not only assignedDS)
|
||||||
|
|
||||||
final DistributionSet setA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
final DistributionSet setA = TestDataUtil.generateDistributionSet("", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
@@ -90,7 +90,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest {
|
|||||||
final PageRequest pageReq = new PageRequest(0, 500);
|
final PageRequest pageReq = new PageRequest(0, 500);
|
||||||
// try to find several targets with different filter settings
|
// try to find several targets with different filter settings
|
||||||
|
|
||||||
// TODO kzimmerm: comment and check also the content itself, not only
|
// TODO kaizimmerm: comment and check also the content itself, not only
|
||||||
// the numbers
|
// the numbers
|
||||||
// (containsOnly)
|
// (containsOnly)
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(400);
|
assertThat(targetManagement.countTargetsAll()).isEqualTo(400);
|
||||||
@@ -185,7 +185,7 @@ public class TargetManagementSearchTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO kzimmerm: add filter tests
|
// TODO kaizimmerm: add filter tests
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the correct order of targets based on selected distribution set. The system expects to have an order based on installed, assigned DS.")
|
@Description("Tests the correct order of targets based on selected distribution set. The system expects to have an order based on installed, assigned DS.")
|
||||||
public void targetSearchWithVariousFilterCombinationsAndOrderByDistributionSet() {
|
public void targetSearchWithVariousFilterCombinationsAndOrderByDistributionSet() {
|
||||||
|
|||||||
@@ -96,24 +96,26 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
final TargetTag targetTag = tagManagement.createTargetTag(new TargetTag("Tag1"));
|
final TargetTag targetTag = tagManagement.createTargetTag(new TargetTag("Tag1"));
|
||||||
|
|
||||||
final List<Target> assignedTargets = targetManagement.assignTag(assignTarget, targetTag);
|
final List<Target> assignedTargets = targetManagement.assignTag(assignTarget, targetTag);
|
||||||
assertThat(assignedTargets.size()).isEqualTo(4);
|
assertThat(assignedTargets.size()).as("Assigned targets are wrong").isEqualTo(4);
|
||||||
assignedTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(1));
|
assignedTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(1));
|
||||||
|
|
||||||
TargetTag findTargetTag = tagManagement.findTargetTag("Tag1");
|
TargetTag findTargetTag = tagManagement.findTargetTag("Tag1");
|
||||||
assertThat(assignedTargets.size()).isEqualTo(findTargetTag.getAssignedToTargets().size());
|
assertThat(assignedTargets.size()).as("Assigned targets are wrong")
|
||||||
|
.isEqualTo(findTargetTag.getAssignedToTargets().size());
|
||||||
|
|
||||||
assertThat(targetManagement.unAssignTag("NotExist", findTargetTag)).isNull();
|
assertThat(targetManagement.unAssignTag("NotExist", findTargetTag)).as("Unassign target does not work")
|
||||||
|
.isNull();
|
||||||
|
|
||||||
final Target unAssignTarget = targetManagement.unAssignTag("targetId123", findTargetTag);
|
final Target unAssignTarget = targetManagement.unAssignTag("targetId123", findTargetTag);
|
||||||
assertThat(unAssignTarget.getControllerId()).isEqualTo("targetId123");
|
assertThat(unAssignTarget.getControllerId()).as("Controller id is wrong").isEqualTo("targetId123");
|
||||||
assertThat(unAssignTarget.getTags().size()).isEqualTo(0);
|
assertThat(unAssignTarget.getTags()).as("Tag size is wrong").isEmpty();
|
||||||
findTargetTag = tagManagement.findTargetTag("Tag1");
|
findTargetTag = tagManagement.findTargetTag("Tag1");
|
||||||
assertThat(findTargetTag.getAssignedToTargets().size()).isEqualTo(3);
|
assertThat(findTargetTag.getAssignedToTargets()).as("Assigned targets are wrong").hasSize(3);
|
||||||
|
|
||||||
final List<Target> unAssignTargets = targetManagement.unAssignAllTargetsByTag(findTargetTag);
|
final List<Target> unAssignTargets = targetManagement.unAssignAllTargetsByTag(findTargetTag);
|
||||||
findTargetTag = tagManagement.findTargetTag("Tag1");
|
findTargetTag = tagManagement.findTargetTag("Tag1");
|
||||||
assertThat(findTargetTag.getAssignedToTargets().size()).isEqualTo(0);
|
assertThat(findTargetTag.getAssignedToTargets()).as("Unassigned targets are wrong").isEmpty();
|
||||||
assertThat(unAssignTargets.size()).isEqualTo(3);
|
assertThat(unAssignTargets).as("Unassigned targets are wrong").hasSize(3);
|
||||||
unAssignTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(0));
|
unAssignTargets.forEach(target -> assertThat(target.getTags().size()).isEqualTo(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,14 +123,14 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
@Description("Ensures that targets can deleted e.g. test all cascades")
|
@Description("Ensures that targets can deleted e.g. test all cascades")
|
||||||
public void deleteAndCreateTargets() {
|
public void deleteAndCreateTargets() {
|
||||||
Target target = targetManagement.createTarget(new Target("targetId123"));
|
Target target = targetManagement.createTarget(new Target("targetId123"));
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(1);
|
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1);
|
||||||
targetManagement.deleteTargets(target.getId());
|
targetManagement.deleteTargets(target.getId());
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(0);
|
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
|
||||||
|
|
||||||
target = createTargetWithAttributes("4711");
|
target = createTargetWithAttributes("4711");
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(1);
|
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(1);
|
||||||
targetManagement.deleteTargets(target.getId());
|
targetManagement.deleteTargets(target.getId());
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(0);
|
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
|
||||||
|
|
||||||
final List<Long> targets = new ArrayList<Long>();
|
final List<Long> targets = new ArrayList<Long>();
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
@@ -136,9 +138,9 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
targets.add(target.getId());
|
targets.add(target.getId());
|
||||||
targets.add(createTargetWithAttributes("" + (i * i + 1000)).getId());
|
targets.add(createTargetWithAttributes("" + (i * i + 1000)).getId());
|
||||||
}
|
}
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(10);
|
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(10);
|
||||||
targetManagement.deleteTargets(targets.toArray(new Long[targets.size()]));
|
targetManagement.deleteTargets(targets.toArray(new Long[targets.size()]));
|
||||||
assertThat(targetManagement.countTargetsAll()).isEqualTo(0);
|
assertThat(targetManagement.countTargetsAll()).as("target count is wrong").isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Target createTargetWithAttributes(final String controllerId) {
|
private Target createTargetWithAttributes(final String controllerId) {
|
||||||
@@ -150,7 +152,8 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
target = controllerManagament.updateControllerAttributes(controllerId, testData);
|
target = controllerManagament.updateControllerAttributes(controllerId, testData);
|
||||||
|
|
||||||
target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
target = targetManagement.findTargetByControllerIDWithDetails(controllerId);
|
||||||
assertThat(target.getTargetInfo().getControllerAttributes()).isEqualTo(testData);
|
assertThat(target.getTargetInfo().getControllerAttributes()).as("Controller Attributes are wrong")
|
||||||
|
.isEqualTo(testData);
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,10 +165,14 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
final DistributionSet set2 = TestDataUtil.generateDistributionSet("test2", softwareManagement,
|
final DistributionSet set2 = TestDataUtil.generateDistributionSet("test2", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
|
|
||||||
assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).isEqualTo(0);
|
assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).as("Target count is wrong")
|
||||||
assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).isEqualTo(0);
|
.isEqualTo(0);
|
||||||
assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).isEqualTo(0);
|
assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).as("Target count is wrong")
|
||||||
assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).isEqualTo(0);
|
.isEqualTo(0);
|
||||||
|
assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
|
||||||
|
.isEqualTo(0);
|
||||||
|
assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
|
||||||
|
.isEqualTo(0);
|
||||||
|
|
||||||
Target target = createTargetWithAttributes("4711");
|
Target target = createTargetWithAttributes("4711");
|
||||||
|
|
||||||
@@ -183,13 +190,19 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
target = targetManagement.findTargetByControllerIDWithDetails("4711");
|
target = targetManagement.findTargetByControllerIDWithDetails("4711");
|
||||||
// read data
|
// read data
|
||||||
|
|
||||||
assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).isEqualTo(0);
|
assertThat(targetManagement.countTargetByAssignedDistributionSet(set.getId())).as("Target count is wrong")
|
||||||
assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).isEqualTo(1);
|
.isEqualTo(0);
|
||||||
assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).isEqualTo(1);
|
assertThat(targetManagement.countTargetByInstalledDistributionSet(set.getId())).as("Target count is wrong")
|
||||||
assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).isEqualTo(0);
|
.isEqualTo(1);
|
||||||
assertThat(target.getTargetInfo().getLastTargetQuery()).isGreaterThanOrEqualTo(current);
|
assertThat(targetManagement.countTargetByAssignedDistributionSet(set2.getId())).as("Target count is wrong")
|
||||||
assertThat(target.getAssignedDistributionSet()).isEqualTo(set2);
|
.isEqualTo(1);
|
||||||
assertThat(target.getTargetInfo().getInstalledDistributionSet().getId()).isEqualTo(set.getId());
|
assertThat(targetManagement.countTargetByInstalledDistributionSet(set2.getId())).as("Target count is wrong")
|
||||||
|
.isEqualTo(0);
|
||||||
|
assertThat(target.getTargetInfo().getLastTargetQuery()).as("Target query is not work")
|
||||||
|
.isGreaterThanOrEqualTo(current);
|
||||||
|
assertThat(target.getAssignedDistributionSet()).as("Assigned ds size is wrong").isEqualTo(set2);
|
||||||
|
assertThat(target.getTargetInfo().getInstalledDistributionSet().getId()).as("Installed ds is wrong")
|
||||||
|
.isEqualTo(set.getId());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,8 +386,7 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
assertThat(firstSaved.spliterator().getExactSizeIfKnown() - nr2Del).as("Size of splited list")
|
assertThat(firstSaved.spliterator().getExactSizeIfKnown() - nr2Del).as("Size of splited list")
|
||||||
.isEqualTo(allFound.spliterator().getExactSizeIfKnown());
|
.isEqualTo(allFound.spliterator().getExactSizeIfKnown());
|
||||||
|
|
||||||
// verify that all undeleted are still found
|
assertThat(allFound).as("Not all undeleted found").doesNotContain(deletedTargets);
|
||||||
assertThat(allFound).doesNotContain(deletedTargets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -404,7 +416,7 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
targetInfo = targetInfoRepository.save(targetInfo);
|
targetInfo = targetInfoRepository.save(targetInfo);
|
||||||
}
|
}
|
||||||
final Query qry = entityManager.createNativeQuery("select * from sp_target_attributes ta");
|
final Query qry = entityManager.createNativeQuery("select * from sp_target_attributes ta");
|
||||||
final List result = qry.getResultList();
|
final List<?> result = qry.getResultList();
|
||||||
|
|
||||||
assertThat(attribs.size() * ts.spliterator().getExactSizeIfKnown()).as("Amount of all target attributes")
|
assertThat(attribs.size() * ts.spliterator().getExactSizeIfKnown()).as("Amount of all target attributes")
|
||||||
.isEqualTo(result.size());
|
.isEqualTo(result.size());
|
||||||
@@ -467,7 +479,8 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
final Target tNoAttrib = targetManagement.findTargetByControllerID(tNoAttribl.getControllerId());
|
final Target tNoAttrib = targetManagement.findTargetByControllerID(tNoAttribl.getControllerId());
|
||||||
|
|
||||||
if (tNoAttrib.getControllerId().equals(target.getControllerId())) {
|
if (tNoAttrib.getControllerId().equals(target.getControllerId())) {
|
||||||
assertThat(target.getTargetInfo().getControllerAttributes()).isEmpty();
|
assertThat(target.getTargetInfo().getControllerAttributes())
|
||||||
|
.as("Controller attributes should be empty").isEmpty();
|
||||||
continue restTarget_;
|
continue restTarget_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,7 +492,7 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
if (tNoAttrib.getControllerId().equals(target.getControllerId())) {
|
if (tNoAttrib.getControllerId().equals(target.getControllerId())) {
|
||||||
assertThat(target.getTargetInfo().getControllerAttributes().keySet().toArray())
|
assertThat(target.getTargetInfo().getControllerAttributes().keySet().toArray())
|
||||||
.doesNotContain(attribs2Del.toArray());
|
.as("Controller attributes are wrong").doesNotContain(attribs2Del.toArray());
|
||||||
continue restTarget_;
|
continue restTarget_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,12 +517,14 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
t2 = targetManagement.createTarget(t2);
|
t2 = targetManagement.createTarget(t2);
|
||||||
|
|
||||||
t1 = targetManagement.findTargetByControllerID(t1.getControllerId());
|
t1 = targetManagement.findTargetByControllerID(t1.getControllerId());
|
||||||
assertThat(t1.getTags()).hasSize(noT1Tags).containsAll(t1Tags);
|
assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags).containsAll(t1Tags);
|
||||||
assertThat(t1.getTags()).hasSize(noT1Tags).doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
|
assertThat(t1.getTags()).as("Tag size is wrong").hasSize(noT1Tags)
|
||||||
|
.doesNotContain(Iterables.toArray(t2Tags, TargetTag.class));
|
||||||
|
|
||||||
t2 = targetManagement.findTargetByControllerID(t2.getControllerId());
|
t2 = targetManagement.findTargetByControllerID(t2.getControllerId());
|
||||||
assertThat(t2.getTags()).hasSize(noT2Tags).containsAll(t2Tags);
|
assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags).containsAll(t2Tags);
|
||||||
assertThat(t2.getTags()).hasSize(noT2Tags).doesNotContain(Iterables.toArray(t1Tags, TargetTag.class));
|
assertThat(t2.getTags()).as("Tag size is wrong").hasSize(noT2Tags)
|
||||||
|
.doesNotContain(Iterables.toArray(t1Tags, TargetTag.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -531,7 +546,7 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
final TargetTag tagA = tagManagement.createTargetTag(new TargetTag("A"));
|
final TargetTag tagA = tagManagement.createTargetTag(new TargetTag("A"));
|
||||||
final TargetTag tagB = tagManagement.createTargetTag(new TargetTag("B"));
|
final TargetTag tagB = tagManagement.createTargetTag(new TargetTag("B"));
|
||||||
final TargetTag tagC = tagManagement.createTargetTag(new TargetTag("C"));
|
final TargetTag tagC = tagManagement.createTargetTag(new TargetTag("C"));
|
||||||
final TargetTag tagX = tagManagement.createTargetTag(new TargetTag("X"));
|
tagManagement.createTargetTag(new TargetTag("X"));
|
||||||
|
|
||||||
// doing different assignments
|
// doing different assignments
|
||||||
targetManagement.toggleTagAssignment(tagATargets, tagA);
|
targetManagement.toggleTagAssignment(tagATargets, tagA);
|
||||||
@@ -545,7 +560,8 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
targetManagement.toggleTagAssignment(tagABCTargets, tagB);
|
targetManagement.toggleTagAssignment(tagABCTargets, tagB);
|
||||||
targetManagement.toggleTagAssignment(tagABCTargets, tagC);
|
targetManagement.toggleTagAssignment(tagABCTargets, tagC);
|
||||||
|
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "X")).isEqualTo(0);
|
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "X"))
|
||||||
|
.as("Target count is wrong").isEqualTo(0);
|
||||||
|
|
||||||
// search for targets with tag tagA
|
// search for targets with tag tagA
|
||||||
final List<Target> targetWithTagA = new ArrayList<Target>();
|
final List<Target> targetWithTagA = new ArrayList<Target>();
|
||||||
@@ -575,11 +591,11 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
// check again target lists refreshed from DB
|
// check again target lists refreshed from DB
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "A"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "A"))
|
||||||
.isEqualTo(targetWithTagA.size());
|
.as("Target count is wrong").isEqualTo(targetWithTagA.size());
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "B"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "B"))
|
||||||
.isEqualTo(targetWithTagB.size());
|
.as("Target count is wrong").isEqualTo(targetWithTagB.size());
|
||||||
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "C"))
|
assertThat(targetManagement.countTargetByFilters(null, null, null, Boolean.FALSE, "C"))
|
||||||
.isEqualTo(targetWithTagC.size());
|
.as("Target count is wrong").isEqualTo(targetWithTagC.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -656,14 +672,15 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
targetManagement.toggleTagAssignment(targAs, targTagA);
|
targetManagement.toggleTagAssignment(targAs, targTagA);
|
||||||
|
|
||||||
assertThat(targetManagement.findTargetsByControllerIDsWithTags(
|
assertThat(targetManagement.findTargetsByControllerIDsWithTags(
|
||||||
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()))).hasSize(25);
|
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList())))
|
||||||
|
.as("Target count is wrong").hasSize(25);
|
||||||
|
|
||||||
// no lazy loading exception and tag correctly assigned
|
// no lazy loading exception and tag correctly assigned
|
||||||
assertThat(targetManagement
|
assertThat(targetManagement
|
||||||
.findTargetsByControllerIDsWithTags(
|
.findTargetsByControllerIDsWithTags(
|
||||||
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()))
|
targAs.stream().map(target -> target.getControllerId()).collect(Collectors.toList()))
|
||||||
.stream().map(target -> target.getTags().contains(targTagA)).collect(Collectors.toList()))
|
.stream().map(target -> target.getTags().contains(targTagA)).collect(Collectors.toList()))
|
||||||
.containsOnly(true);
|
.as("Tags not correctly assigned").containsOnly(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -678,7 +695,7 @@ public class TargetManagementTest extends AbstractIntegrationTest {
|
|||||||
final List<String> findAllTargetIds = findAllTargetIdNames.stream().map(TargetIdName::getControllerId)
|
final List<String> findAllTargetIds = findAllTargetIdNames.stream().map(TargetIdName::getControllerId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
assertThat(findAllTargetIds).containsOnly(createdTargetIds);
|
assertThat(findAllTargetIds).as("Target list has wrong content").containsOnly(createdTargetIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter actions")
|
@Stories("RSQL filter actions")
|
||||||
public class RSQLActionFieldsTest extends AbstractIntegrationTest {
|
public class RSQLActionFieldsTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter distribution set")
|
@Stories("RSQL filter distribution set")
|
||||||
public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest {
|
public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ public class RSQLDistributionSetFieldTest extends AbstractIntegrationTest {
|
|||||||
final Page<DistributionSet> find = distributionSetManagement.findDistributionSetsAll(
|
final Page<DistributionSet> find = distributionSetManagement.findDistributionSetsAll(
|
||||||
RSQLUtility.parse(rsqlParam, DistributionSetFields.class), new PageRequest(0, 100), false);
|
RSQLUtility.parse(rsqlParam, DistributionSetFields.class), new PageRequest(0, 100), false);
|
||||||
final long countAll = find.getTotalElements();
|
final long countAll = find.getTotalElements();
|
||||||
assertThat(find).isNotNull();
|
assertThat(find).as("Founded entity is should not be null").isNotNull();
|
||||||
assertThat(countAll).isEqualTo(excpectedEntity);
|
assertThat(countAll).as("Founded entity size is wrong").isEqualTo(excpectedEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter distribution set metadata")
|
@Stories("RSQL filter distribution set metadata")
|
||||||
public class RSQLDistributionSetMetadataFieldsTest extends AbstractIntegrationTest {
|
public class RSQLDistributionSetMetadataFieldsTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter rollout group")
|
@Stories("RSQL filter rollout group")
|
||||||
public class RSQLRolloutGroupFields extends AbstractIntegrationTest {
|
public class RSQLRolloutGroupFields extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter software module")
|
@Stories("RSQL filter software module")
|
||||||
public class RSQLSoftwareModuleFieldTest extends AbstractIntegrationTest {
|
public class RSQLSoftwareModuleFieldTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter software module metadata")
|
@Stories("RSQL filter software module metadata")
|
||||||
public class RSQLSoftwareModuleMetadataFieldsTest extends AbstractIntegrationTest {
|
public class RSQLSoftwareModuleMetadataFieldsTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter software module test type")
|
@Stories("RSQL filter software module test type")
|
||||||
public class RSQLSoftwareModuleTypeFieldsTest extends AbstractIntegrationTest {
|
public class RSQLSoftwareModuleTypeFieldsTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter target and distribution set tags")
|
@Stories("RSQL filter target and distribution set tags")
|
||||||
public class RSQLTagFieldsTest extends AbstractIntegrationTest {
|
public class RSQLTagFieldsTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import ru.yandex.qatools.allure.annotations.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL filter target")
|
@Stories("RSQL filter target")
|
||||||
public class RSQLTargetFieldTest extends AbstractIntegrationTest {
|
public class RSQLTargetFieldTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
@Features("Component Tests - RSQL filtering")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("RSQL search utility")
|
@Stories("RSQL search utility")
|
||||||
// TODO: fully document tests -> @Description for long text and reasonable
|
// TODO: fully document tests -> @Description for long text and reasonable
|
||||||
// method name as short text
|
// method name as short text
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ package org.eclipse.hawkbit.tenancy;
|
|||||||
|
|
||||||
import static org.fest.assertions.api.Assertions.assertThat;
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.AbstractIntegrationTest;
|
import org.eclipse.hawkbit.AbstractIntegrationTest;
|
||||||
import org.eclipse.hawkbit.WithSpringAuthorityRule;
|
import org.eclipse.hawkbit.WithSpringAuthorityRule;
|
||||||
import org.eclipse.hawkbit.WithUser;
|
import org.eclipse.hawkbit.WithUser;
|
||||||
@@ -31,9 +29,6 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
* CRUD-Operations are tenant aware and cannot access or delete entities not
|
* CRUD-Operations are tenant aware and cannot access or delete entities not
|
||||||
* belonging to the current tenant.
|
* belonging to the current tenant.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Repository")
|
@Features("Component Tests - Repository")
|
||||||
@Stories("Multi Tenancy")
|
@Stories("Multi Tenancy")
|
||||||
@@ -97,13 +92,9 @@ public class MultiTenancyEntityTest extends AbstractIntegrationTest {
|
|||||||
// check that the cache is not getting in the way, i.e. "bumlux" results
|
// check that the cache is not getting in the way, i.e. "bumlux" results
|
||||||
// in bumlux and not
|
// in bumlux and not
|
||||||
// mytenant
|
// mytenant
|
||||||
assertThat(
|
assertThat(securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", "bumlux"),
|
||||||
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", "bumlux"), new Callable<String>() {
|
() -> systemManagement.getTenantMetadata().getTenant().toUpperCase()))
|
||||||
@Override
|
.isEqualTo("bumlux".toUpperCase());
|
||||||
public String call() throws Exception {
|
|
||||||
return systemManagement.getTenantMetadata().getTenant().toUpperCase();
|
|
||||||
}
|
|
||||||
})).isEqualTo("bumlux".toUpperCase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -154,59 +145,38 @@ public class MultiTenancyEntityTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Target createTargetForTenant(final String controllerId, final String tenant) throws Exception {
|
private Target createTargetForTenant(final String controllerId, final String tenant) throws Exception {
|
||||||
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), new Callable<Target>() {
|
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
|
||||||
@Override
|
() -> targetManagement.createTarget(new Target(controllerId)));
|
||||||
public Target call() throws Exception {
|
|
||||||
return targetManagement.createTarget(new Target(controllerId));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Slice<Target> findTargetsForTenant(final String tenant) throws Exception {
|
private Slice<Target> findTargetsForTenant(final String tenant) throws Exception {
|
||||||
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
|
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
|
||||||
new Callable<Slice<Target>>() {
|
() -> targetManagement.findTargetsAll(pageReq));
|
||||||
@Override
|
|
||||||
public Slice<Target> call() throws Exception {
|
|
||||||
return targetManagement.findTargetsAll(pageReq);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteTargetsForTenant(final String tenant, final Long... targetIds) throws Exception {
|
private void deleteTargetsForTenant(final String tenant, final Long... targetIds) throws Exception {
|
||||||
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), new Callable<Void>() {
|
securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), () -> {
|
||||||
@Override
|
targetManagement.deleteTargets(targetIds);
|
||||||
public Void call() throws Exception {
|
return null;
|
||||||
targetManagement.deleteTargets(targetIds);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private DistributionSet createDistributionSetForTenant(final String name, final String version, final String tenant)
|
private DistributionSet createDistributionSetForTenant(final String name, final String version, final String tenant)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
|
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant), () -> {
|
||||||
new Callable<DistributionSet>() {
|
final DistributionSet ds = new DistributionSet();
|
||||||
@Override
|
ds.setName(name);
|
||||||
public DistributionSet call() throws Exception {
|
ds.setTenant(tenant);
|
||||||
final DistributionSet ds = new DistributionSet();
|
ds.setVersion(version);
|
||||||
ds.setName(name);
|
ds.setType(distributionSetManagement
|
||||||
ds.setTenant(tenant);
|
.createDistributionSetType(new DistributionSetType("typetest", "test", "foobar")));
|
||||||
ds.setVersion(version);
|
return distributionSetManagement.createDistributionSet(ds);
|
||||||
ds.setType(distributionSetManagement
|
});
|
||||||
.createDistributionSetType(new DistributionSetType("typetest", "test", "foobar")));
|
|
||||||
return distributionSetManagement.createDistributionSet(ds);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Page<DistributionSet> findDistributionSetForTenant(final String tenant) throws Exception {
|
private Page<DistributionSet> findDistributionSetForTenant(final String tenant) throws Exception {
|
||||||
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
|
return securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("user", tenant),
|
||||||
new Callable<Page<DistributionSet>>() {
|
() -> distributionSetManagement.findDistributionSetsAll(pageReq, false, false));
|
||||||
@Override
|
|
||||||
public Page<DistributionSet> call() throws Exception {
|
|
||||||
return distributionSetManagement.findDistributionSetsAll(pageReq, false, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value}
|
spring.data.mongodb.uri=mongodb://localhost/spArtifactRepository${random.value}
|
||||||
spring.data.mongodb.port=28017
|
spring.data.mongodb.port=28017
|
||||||
|
|
||||||
hawkbit.server.controller.security.authentication.header.enabled=true
|
hawkbit.server.ddi.security.authentication.header.enabled=true
|
||||||
|
|
||||||
hawkbit.server.artifact.repo.upload.maxFileSize=5MB
|
hawkbit.server.artifact.repo.upload.maxFileSize=5MB
|
||||||
|
|
||||||
@@ -29,11 +29,6 @@ flyway.initOnMigrate=true
|
|||||||
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
|
flyway.sqlMigrationSuffix=${spring.jpa.database}.sql
|
||||||
#spring.jpa.show-sql=true
|
#spring.jpa.show-sql=true
|
||||||
|
|
||||||
# SP Controller configuration
|
# DDI configuration
|
||||||
hawkbit.controller.pollingTime=00:01:00
|
hawkbit.controller.pollingTime=00:01:00
|
||||||
hawkbit.controller.pollingOverdueTime=00:01:00
|
hawkbit.controller.pollingOverdueTime=00:01:00
|
||||||
|
|
||||||
## Configuration for RabbitMQ integration
|
|
||||||
hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter
|
|
||||||
hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter
|
|
||||||
hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver
|
|
||||||
|
|||||||
@@ -25,13 +25,11 @@ import org.eclipse.hawkbit.repository.model.Artifact;
|
|||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
|
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
|
||||||
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
|
||||||
import org.springframework.context.EnvironmentAware;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
|
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
|
||||||
@@ -55,7 +53,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(ControllerConstants.ARTIFACTS_V1_REQUEST_MAPPING)
|
@RequestMapping(ControllerConstants.ARTIFACTS_V1_REQUEST_MAPPING)
|
||||||
public class ArtifactStoreController implements EnvironmentAware {
|
public class ArtifactStoreController {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(ArtifactStoreController.class);
|
private static final Logger LOG = LoggerFactory.getLogger(ArtifactStoreController.class);
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -67,14 +65,8 @@ public class ArtifactStoreController implements EnvironmentAware {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CacheWriteNotify cacheWriteNotify;
|
private CacheWriteNotify cacheWriteNotify;
|
||||||
|
|
||||||
private static final String SP_SERVER_CONFIG_PREFIX = "hawkbit.server.";
|
@Autowired
|
||||||
private RelaxedPropertyResolver environment;
|
private HawkbitSecurityProperties securityProperties;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnvironment(final Environment environment) {
|
|
||||||
this.environment = new RelaxedPropertyResolver(environment, SP_SERVER_CONFIG_PREFIX);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles GET {@link Artifact} download request. This could be full or
|
* Handles GET {@link Artifact} download request. This could be full or
|
||||||
@@ -138,8 +130,8 @@ public class ArtifactStoreController implements EnvironmentAware {
|
|||||||
|
|
||||||
private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
|
private Action checkAndReportDownloadByTarget(final HttpServletRequest request, final String targetid,
|
||||||
final LocalArtifact artifact) {
|
final LocalArtifact artifact) {
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
request, environment.getProperty("security.rp.remote_ip_header", String.class, "X-Forwarded-For")));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
final Action action = controllerManagement
|
final Action action = controllerManagement
|
||||||
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), artifact.getSoftwareModule());
|
.getActionForDownloadByTargetAndSoftwareModule(target.getControllerId(), artifact.getSoftwareModule());
|
||||||
|
|||||||
@@ -41,15 +41,13 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
|
import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper;
|
||||||
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
import org.hibernate.validator.constraints.NotEmpty;
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.bind.RelaxedPropertyResolver;
|
|
||||||
import org.springframework.context.EnvironmentAware;
|
|
||||||
import org.springframework.core.env.Environment;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -74,7 +72,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(ControllerConstants.BASE_V1_REQUEST_MAPPING)
|
@RequestMapping(ControllerConstants.BASE_V1_REQUEST_MAPPING)
|
||||||
public class RootController implements EnvironmentAware {
|
public class RootController {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(RootController.class);
|
private static final Logger LOG = LoggerFactory.getLogger(RootController.class);
|
||||||
private static final String GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET = "given action ({}) is not assigned to given target ({}).";
|
private static final String GIVEN_ACTION_IS_NOT_ASSIGNED_TO_GIVEN_TARGET = "given action ({}) is not assigned to given target ({}).";
|
||||||
@@ -99,16 +97,8 @@ public class RootController implements EnvironmentAware {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
private String requestHeader;
|
@Autowired
|
||||||
|
private HawkbitSecurityProperties securityProperties;
|
||||||
@Override
|
|
||||||
public void setEnvironment(final Environment environment) {
|
|
||||||
final RelaxedPropertyResolver relaxedPropertyResolver = new RelaxedPropertyResolver(environment,
|
|
||||||
SP_SERVER_CONFIG_PREFIX);
|
|
||||||
|
|
||||||
requestHeader = relaxedPropertyResolver.getProperty("security.rp.remote_ip_header", String.class,
|
|
||||||
"X-Forwarded-For");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all artifacts of a given software module and target.
|
* Returns all artifacts of a given software module and target.
|
||||||
@@ -155,12 +145,13 @@ public class RootController implements EnvironmentAware {
|
|||||||
LOG.debug("getControllerBase({})", targetid);
|
LOG.debug("getControllerBase({})", targetid);
|
||||||
|
|
||||||
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(targetid,
|
final Target target = controllerManagement.findOrRegisterTargetIfItDoesNotexist(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, requestHeader));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
if (target.getTargetInfo().getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
|
if (target.getTargetInfo().getUpdateStatus() == TargetUpdateStatus.UNKNOWN) {
|
||||||
LOG.debug("target with {} extsisted but was in status UNKNOWN -> REGISTERED)", targetid);
|
LOG.debug("target with {} extsisted but was in status UNKNOWN -> REGISTERED)", targetid);
|
||||||
controllerManagement.updateTargetStatus(target.getTargetInfo(), TargetUpdateStatus.REGISTERED,
|
controllerManagement.updateTargetStatus(target.getTargetInfo(), TargetUpdateStatus.REGISTERED,
|
||||||
System.currentTimeMillis(), IpUtil.getClientIpFromRequest(request, requestHeader));
|
System.currentTimeMillis(),
|
||||||
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResponseEntity<>(
|
return new ResponseEntity<>(
|
||||||
@@ -195,7 +186,7 @@ public class RootController implements EnvironmentAware {
|
|||||||
ResponseEntity<Void> result;
|
ResponseEntity<Void> result;
|
||||||
|
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, requestHeader));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
|
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
|
||||||
|
|
||||||
if (checkModule(fileName, module)) {
|
if (checkModule(fileName, module)) {
|
||||||
@@ -265,7 +256,8 @@ public class RootController implements EnvironmentAware {
|
|||||||
public ResponseEntity<Void> downloadArtifactMd5(@PathVariable final String targetid,
|
public ResponseEntity<Void> downloadArtifactMd5(@PathVariable final String targetid,
|
||||||
@PathVariable final Long softwareModuleId, @PathVariable final String fileName,
|
@PathVariable final Long softwareModuleId, @PathVariable final String fileName,
|
||||||
final HttpServletResponse response, final HttpServletRequest request) {
|
final HttpServletResponse response, final HttpServletRequest request) {
|
||||||
controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(request, requestHeader));
|
controllerManagement.updateLastTargetQuery(targetid,
|
||||||
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
|
final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId);
|
||||||
|
|
||||||
@@ -311,7 +303,7 @@ public class RootController implements EnvironmentAware {
|
|||||||
LOG.debug("getControllerBasedeploymentAction({},{})", targetid, resource);
|
LOG.debug("getControllerBasedeploymentAction({},{})", targetid, resource);
|
||||||
|
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, requestHeader));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||||
if (!action.getTarget().getId().equals(target.getId())) {
|
if (!action.getTarget().getId().equals(target.getId())) {
|
||||||
@@ -362,7 +354,7 @@ public class RootController implements EnvironmentAware {
|
|||||||
LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", targetid, actionId, feedback);
|
LOG.debug("provideBasedeploymentActionFeedback for target [{},{}]: {}", targetid, actionId, feedback);
|
||||||
|
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, requestHeader));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
if (!actionId.equals(feedback.getId())) {
|
if (!actionId.equals(feedback.getId())) {
|
||||||
LOG.warn(
|
LOG.warn(
|
||||||
@@ -435,8 +427,6 @@ public class RootController implements EnvironmentAware {
|
|||||||
LOG.debug("Controller reported intermediate status (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
LOG.debug("Controller reported intermediate status (actionid: {}, targetid: {}) as we got {} report.", actionid,
|
||||||
targetid, feedback.getStatus().getExecution());
|
targetid, feedback.getStatus().getExecution());
|
||||||
actionStatus.setStatus(Status.RUNNING);
|
actionStatus.setStatus(Status.RUNNING);
|
||||||
// MECS-400: we should not use the unstructed message list for
|
|
||||||
// the server comment on the status.
|
|
||||||
actionStatus.addMessage("Controller reported: " + feedback.getStatus().getExecution());
|
actionStatus.addMessage("Controller reported: " + feedback.getStatus().getExecution());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +459,8 @@ public class RootController implements EnvironmentAware {
|
|||||||
+ ControllerConstants.CONFIG_DATA_ACTION, method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
|
+ ControllerConstants.CONFIG_DATA_ACTION, method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public ResponseEntity<Void> putConfigData(@Valid @RequestBody final ConfigData configData,
|
public ResponseEntity<Void> putConfigData(@Valid @RequestBody final ConfigData configData,
|
||||||
@PathVariable final String targetid, final HttpServletRequest request) {
|
@PathVariable final String targetid, final HttpServletRequest request) {
|
||||||
controllerManagement.updateLastTargetQuery(targetid, IpUtil.getClientIpFromRequest(request, requestHeader));
|
controllerManagement.updateLastTargetQuery(targetid,
|
||||||
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
controllerManagement.updateControllerAttributes(targetid, configData.getData());
|
controllerManagement.updateControllerAttributes(targetid, configData.getData());
|
||||||
|
|
||||||
@@ -495,7 +486,7 @@ public class RootController implements EnvironmentAware {
|
|||||||
LOG.debug("getControllerCancelAction({})", targetid);
|
LOG.debug("getControllerCancelAction({})", targetid);
|
||||||
|
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, requestHeader));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
final Action action = findActionWithExceptionIfNotFound(actionId);
|
final Action action = findActionWithExceptionIfNotFound(actionId);
|
||||||
if (!action.getTarget().getId().equals(target.getId())) {
|
if (!action.getTarget().getId().equals(target.getId())) {
|
||||||
@@ -542,7 +533,7 @@ public class RootController implements EnvironmentAware {
|
|||||||
LOG.debug("provideCancelActionFeedback for target [{}]: {}", targetid, feedback);
|
LOG.debug("provideCancelActionFeedback for target [{}]: {}", targetid, feedback);
|
||||||
|
|
||||||
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
final Target target = controllerManagement.updateLastTargetQuery(targetid,
|
||||||
IpUtil.getClientIpFromRequest(request, requestHeader));
|
IpUtil.getClientIpFromRequest(request, securityProperties.getClients().getRemoteIpHeader()));
|
||||||
|
|
||||||
if (!actionId.equals(feedback.getId())) {
|
if (!actionId.equals(feedback.getId())) {
|
||||||
LOG.warn(
|
LOG.warn(
|
||||||
|
|||||||
@@ -23,11 +23,6 @@ import org.springframework.data.domain.Sort.Direction;
|
|||||||
/**
|
/**
|
||||||
* Utility class for for paged body generation.
|
* Utility class for for paged body generation.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class PagingUtility {
|
public final class PagingUtility {
|
||||||
/*
|
/*
|
||||||
@@ -90,8 +85,9 @@ public final class PagingUtility {
|
|||||||
if (sortParam != null) {
|
if (sortParam != null) {
|
||||||
sorting = new Sort(SortUtility.parse(ActionFields.class, sortParam));
|
sorting = new Sort(SortUtility.parse(ActionFields.class, sortParam));
|
||||||
} else {
|
} else {
|
||||||
// default sort
|
// default sort is DESC in case of action to match behavior
|
||||||
sorting = new Sort(Direction.ASC, ActionFields.ID.getFieldName());
|
// of management UI (last entry on top)
|
||||||
|
sorting = new Sort(Direction.DESC, ActionFields.ID.getFieldName());
|
||||||
}
|
}
|
||||||
return sorting;
|
return sorting;
|
||||||
}
|
}
|
||||||
@@ -101,8 +97,9 @@ public final class PagingUtility {
|
|||||||
if (sortParam != null) {
|
if (sortParam != null) {
|
||||||
sorting = new Sort(SortUtility.parse(ActionStatusFields.class, sortParam));
|
sorting = new Sort(SortUtility.parse(ActionStatusFields.class, sortParam));
|
||||||
} else {
|
} else {
|
||||||
// default sort
|
// default sort is DESC in case of action status to match behavior
|
||||||
sorting = new Sort(Direction.ASC, ActionStatusFields.ID.getFieldName());
|
// of management UI (last entry on top)
|
||||||
|
sorting = new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName());
|
||||||
}
|
}
|
||||||
return sorting;
|
return sorting;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,8 +297,8 @@ final public class TargetMapper {
|
|||||||
final ActionStatusRest result = new ActionStatusRest();
|
final ActionStatusRest result = new ActionStatusRest();
|
||||||
|
|
||||||
result.setMessages(actionStatus.getMessages());
|
result.setMessages(actionStatus.getMessages());
|
||||||
result.setReportedAt(action.getCreatedAt());
|
result.setReportedAt(actionStatus.getCreatedAt());
|
||||||
result.setStatusId(action.getId());
|
result.setStatusId(actionStatus.getId());
|
||||||
result.setType(getNameOfActionStatusType(actionStatus.getStatus()));
|
result.setType(getNameOfActionStatusType(actionStatus.getStatus()));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ public class TargetResource implements TargetRestApi {
|
|||||||
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
|
final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam);
|
||||||
final Sort sorting = PagingUtility.sanitizeActionStatusSortParam(sortParam);
|
final Sort sorting = PagingUtility.sanitizeActionStatusSortParam(sortParam);
|
||||||
|
|
||||||
final Page<ActionStatus> statusList = this.deploymentManagement.findActionStatusMessagesByActionInDescOrder(
|
final Page<ActionStatus> statusList = this.deploymentManagement.findActionStatusByAction(
|
||||||
new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting), action, true);
|
new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting), action, true);
|
||||||
|
|
||||||
return new ResponseEntity<>(
|
return new ResponseEntity<>(
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@ActiveProfiles({ "im", "test" })
|
@ActiveProfiles({ "im", "test" })
|
||||||
@Features("Component Tests - Controller RESTful API")
|
@Features("Component Tests - Direct Device Integration API")
|
||||||
@Stories("Artifact Download Resource")
|
@Stories("Artifact Download Resource")
|
||||||
public class ArtifactDownloadTest extends AbstractIntegrationTestWithMongoDB {
|
public class ArtifactDownloadTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@ActiveProfiles({ "im", "test" })
|
@ActiveProfiles({ "im", "test" })
|
||||||
@Features("Component Tests - Controller RESTful API")
|
@Features("Component Tests - Direct Device Integration API")
|
||||||
@Stories("Cancel Action Resource")
|
@Stories("Cancel Action Resource")
|
||||||
public class CancelActionTest extends AbstractIntegrationTest {
|
public class CancelActionTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@ActiveProfiles({ "im", "test" })
|
@ActiveProfiles({ "im", "test" })
|
||||||
@Features("Component Tests - Controller RESTful API")
|
@Features("Component Tests - Direct Device Integration API")
|
||||||
@Stories("Config Data Resource")
|
@Stories("Config Data Resource")
|
||||||
public class ConfigDataTest extends AbstractIntegrationTest {
|
public class ConfigDataTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@ActiveProfiles({ "im", "test" })
|
@ActiveProfiles({ "im", "test" })
|
||||||
@Features("Component Tests - Controller RESTful API")
|
@Features("Component Tests - Direct Device Integration API")
|
||||||
@Stories("Deployment Action Resource")
|
@Stories("Deployment Action Resource")
|
||||||
public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
|||||||
@@ -45,13 +45,11 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
@ActiveProfiles({ "im", "test" })
|
@ActiveProfiles({ "im", "test" })
|
||||||
@Features("Component Tests - Controller RESTful API")
|
@Features("Component Tests - Direct Device Integration API")
|
||||||
@Stories("Root Poll Resource")
|
@Stories("Root Poll Resource")
|
||||||
// TODO: fully document tests -> @Description for long text and reasonable
|
|
||||||
// method name as short text
|
|
||||||
public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
@Test()
|
@Test
|
||||||
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.")
|
@Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.")
|
||||||
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = "ROLE_CONTROLLER", autoCreateTenant = false)
|
@WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = "ROLE_CONTROLLER", autoCreateTenant = false)
|
||||||
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception {
|
||||||
@@ -73,6 +71,7 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that target poll request does not change audit data on the entity.")
|
||||||
@WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET,
|
@WithUser(principal = "knownPrincipal", authorities = { SpPermission.READ_TARGET, SpPermission.UPDATE_TARGET,
|
||||||
SpPermission.CREATE_TARGET })
|
SpPermission.CREATE_TARGET })
|
||||||
public void targetPollDoesNotModifyAuditData() throws Exception {
|
public void targetPollDoesNotModifyAuditData() throws Exception {
|
||||||
@@ -104,11 +103,13 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that server returns a not found response in case of empty controlloer ID.")
|
||||||
public void rootRsWithoutId() throws Exception {
|
public void rootRsWithoutId() throws Exception {
|
||||||
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
mvc.perform(get("/controller/v1/")).andDo(MockMvcResultPrinter.print()).andExpect(status().isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that the system creates a new target in plug and play manner, i.e. target is authenticated but does not exist yet.")
|
||||||
public void rootRsPlugAndPlay() throws Exception {
|
public void rootRsPlugAndPlay() throws Exception {
|
||||||
|
|
||||||
final long current = System.currentTimeMillis();
|
final long current = System.currentTimeMillis();
|
||||||
@@ -133,6 +134,7 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that etag check results in not modified response if provided etag by client is identical to entity in repository.")
|
||||||
public void rootRsNotModified() throws Exception {
|
public void rootRsNotModified() throws Exception {
|
||||||
final String etag = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
final String etag = mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant()))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
@@ -197,6 +199,8 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that the target state machine of a precomissioned target switches from "
|
||||||
|
+ "UNKNOWN to REGISTERED when the target polls for the first time.")
|
||||||
public void rootRsPrecommissioned() throws Exception {
|
public void rootRsPrecommissioned() throws Exception {
|
||||||
final Target target = new Target("4711");
|
final Target target = new Target("4711");
|
||||||
targetManagement.createTarget(target);
|
targetManagement.createTarget(target);
|
||||||
@@ -219,6 +223,7 @@ public class RootControllerTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that the source IP address of the polling target is correctly stored in repository")
|
||||||
public void rootRsPlugAndPlayIpAddress() throws Exception {
|
public void rootRsPlugAndPlayIpAddress() throws Exception {
|
||||||
// test
|
// test
|
||||||
final String knownControllerId1 = "0815";
|
final String knownControllerId1 = "0815";
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.Ignore;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.context.annotation.Description;
|
import org.springframework.context.annotation.Description;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
@@ -59,15 +58,8 @@ import com.jayway.jsonpath.JsonPath;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
/**
|
@Features("Component Tests - Management API")
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Features("Component Tests - Management RESTful API")
|
|
||||||
@Stories("Distribution Set Resource")
|
@Stories("Distribution Set Resource")
|
||||||
// TODO: fully document tests -> @Description for long text and reasonable
|
|
||||||
// method name as short text
|
|
||||||
public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -235,6 +227,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that multi target assignment through API is reflected by the repository.")
|
||||||
public void assignMultipleTargetsToDistributionSet() throws Exception {
|
public void assignMultipleTargetsToDistributionSet() throws Exception {
|
||||||
// prepare distribution set
|
// prepare distribution set
|
||||||
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
||||||
@@ -255,9 +248,13 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
.andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1)))
|
.andExpect(status().isOk()).andExpect(jsonPath("$.assigned", equalTo(knownTargetIds.length - 1)))
|
||||||
.andExpect(jsonPath("$.alreadyAssigned", equalTo(1)))
|
.andExpect(jsonPath("$.alreadyAssigned", equalTo(1)))
|
||||||
.andExpect(jsonPath("$.total", equalTo(knownTargetIds.length)));
|
.andExpect(jsonPath("$.total", equalTo(knownTargetIds.length)));
|
||||||
|
|
||||||
|
assertThat(targetManagement.findTargetByAssignedDistributionSet(createdDs.getId(), pageReq).getContent())
|
||||||
|
.as("Five targets in repository have DS assigned").hasSize(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that assigned targets of DS are returned as reflected by the repository.")
|
||||||
public void getAssignedTargetsOfDistributionSet() throws Exception {
|
public void getAssignedTargetsOfDistributionSet() throws Exception {
|
||||||
// prepare distribution set
|
// prepare distribution set
|
||||||
final String knownTargetId = "knownTargetId1";
|
final String knownTargetId = "knownTargetId1";
|
||||||
@@ -273,6 +270,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that assigned targets of DS are returned as persisted in the repository.")
|
||||||
public void getAssignedTargetsOfDistributionSetIsEmpty() throws Exception {
|
public void getAssignedTargetsOfDistributionSetIsEmpty() throws Exception {
|
||||||
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
||||||
final DistributionSet createdDs = createDistributionSetsAlphabetical.iterator().next();
|
final DistributionSet createdDs = createDistributionSetsAlphabetical.iterator().next();
|
||||||
@@ -283,6 +281,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that installed targets of DS are returned as persisted in the repository.")
|
||||||
public void getInstalledTargetsOfDistributionSet() throws Exception {
|
public void getInstalledTargetsOfDistributionSet() throws Exception {
|
||||||
// prepare distribution set
|
// prepare distribution set
|
||||||
final String knownTargetId = "knownTargetId1";
|
final String knownTargetId = "knownTargetId1";
|
||||||
@@ -305,46 +304,50 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that DS in repository are listed with proper paging properties.")
|
||||||
public void getDistributionSetsWithoutAddtionalRequestParameters() throws Exception {
|
public void getDistributionSetsWithoutAddtionalRequestParameters() throws Exception {
|
||||||
final int modules = 5;
|
final int sets = 5;
|
||||||
createDistributionSetsAlphabetical(modules);
|
createDistributionSetsAlphabetical(sets);
|
||||||
mvc.perform(get(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)).andDo(MockMvcResultPrinter.print())
|
mvc.perform(get(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(sets)))
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(modules)))
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(sets)))
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(modules)));
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(sets)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that DS in repository are listed with proper paging results with paging limit parameter.")
|
||||||
public void getDistributionSetsWithPagingLimitRequestParameter() throws Exception {
|
public void getDistributionSetsWithPagingLimitRequestParameter() throws Exception {
|
||||||
final int modules = 5;
|
final int sets = 5;
|
||||||
final int limitSize = 1;
|
final int limitSize = 1;
|
||||||
createDistributionSetsAlphabetical(modules);
|
createDistributionSetsAlphabetical(sets);
|
||||||
mvc.perform(get(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
|
mvc.perform(get(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(limitSize)))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(sets)))
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(limitSize)))
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)));
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(limitSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that DS in repository are listed with proper paging results with paging limit and offset parameter.")
|
||||||
public void getDistributionSetsWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
public void getDistributionSetsWithPagingLimitAndOffsetRequestParameter() throws Exception {
|
||||||
final int modules = 5;
|
final int sets = 5;
|
||||||
final int offsetParam = 2;
|
final int offsetParam = 2;
|
||||||
final int expectedSize = modules - offsetParam;
|
final int expectedSize = sets - offsetParam;
|
||||||
createDistributionSetsAlphabetical(modules);
|
createDistributionSetsAlphabetical(sets);
|
||||||
mvc.perform(get(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
|
mvc.perform(get(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING)
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, String.valueOf(offsetParam))
|
||||||
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(modules)))
|
.param(RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, String.valueOf(sets)))
|
||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk())
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(modules)))
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_TOTAL, equalTo(sets)))
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize)))
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_SIZE, equalTo(expectedSize)))
|
||||||
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize)));
|
.andExpect(jsonPath(TargetResourceTest.JSON_PATH_PAGED_LIST_CONTENT, hasSize(expectedSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
|
@Description("Ensures that multiple DS requested are listed with expected payload.")
|
||||||
public void getDistributionSets() throws Exception {
|
public void getDistributionSets() throws Exception {
|
||||||
// prepare test data
|
// prepare test data
|
||||||
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
||||||
@@ -389,6 +392,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
|
@Description("Ensures that single DS requested by ID is listed with expected payload.")
|
||||||
public void getDistributionSet() throws Exception {
|
public void getDistributionSet() throws Exception {
|
||||||
final DistributionSet set = createTestDistributionSet(softwareManagement, distributionSetManagement);
|
final DistributionSet set = createTestDistributionSet(softwareManagement, distributionSetManagement);
|
||||||
|
|
||||||
@@ -420,6 +424,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
|
@Description("Ensures that multipe DS posted to API are created in the repository.")
|
||||||
public void createDistributionSets() throws JSONException, Exception {
|
public void createDistributionSets() throws JSONException, Exception {
|
||||||
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
||||||
|
|
||||||
@@ -534,7 +539,8 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteUnassignedistributionSet() throws Exception {
|
@Description("Ensures that DS deletion request to API is reflected by the repository.")
|
||||||
|
public void deleteUnassignedistributionSet() throws Exception {
|
||||||
// prepare test data
|
// prepare test data
|
||||||
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
||||||
|
|
||||||
@@ -553,7 +559,8 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteAssignedDistributionSet() throws Exception {
|
@Description("Ensures that assigned DS deletion request to API is reflected by the repository by means of deleted flag set.")
|
||||||
|
public void deleteAssignedDistributionSet() throws Exception {
|
||||||
// prepare test data
|
// prepare test data
|
||||||
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
assertThat(distributionSetManagement.findDistributionSetsAll(pageReq, false, true)).hasSize(0);
|
||||||
|
|
||||||
@@ -574,6 +581,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that DS property update request to API is reflected by the repository.")
|
||||||
public void updateDistributionSet() throws Exception {
|
public void updateDistributionSet() throws Exception {
|
||||||
|
|
||||||
// prepare test data
|
// prepare test data
|
||||||
@@ -601,6 +609,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that the server reacts properly to invalid requests (URI, Media Type, Methods) with correct reponses.")
|
||||||
public void invalidRequestsOnDistributionSetsResource() throws Exception {
|
public void invalidRequestsOnDistributionSetsResource() throws Exception {
|
||||||
final DistributionSet set = TestDataUtil.generateDistributionSet("one", softwareManagement,
|
final DistributionSet set = TestDataUtil.generateDistributionSet("one", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
@@ -642,6 +651,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that the metadata creation through API is reflected by the repository.")
|
||||||
public void createMetadata() throws Exception {
|
public void createMetadata() throws Exception {
|
||||||
final DistributionSet testDS = TestDataUtil.generateDistributionSet("one", softwareManagement,
|
final DistributionSet testDS = TestDataUtil.generateDistributionSet("one", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
@@ -674,6 +684,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a metadata update through API is reflected by the repository.")
|
||||||
public void updateMetadata() throws Exception {
|
public void updateMetadata() throws Exception {
|
||||||
// prepare and create metadata for update
|
// prepare and create metadata for update
|
||||||
final String knownKey = "knownKey";
|
final String knownKey = "knownKey";
|
||||||
@@ -700,6 +711,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a metadata entry deletion through API is reflected by the repository.")
|
||||||
public void deleteMetadata() throws Exception {
|
public void deleteMetadata() throws Exception {
|
||||||
// prepare and create metadata for deletion
|
// prepare and create metadata for deletion
|
||||||
final String knownKey = "knownKey";
|
final String knownKey = "knownKey";
|
||||||
@@ -722,6 +734,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a metadata entry selection through API reflectes the repository content.")
|
||||||
public void getSingleMetadata() throws Exception {
|
public void getSingleMetadata() throws Exception {
|
||||||
// prepare and create metadata
|
// prepare and create metadata
|
||||||
final String knownKey = "knownKey";
|
final String knownKey = "knownKey";
|
||||||
@@ -737,6 +750,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a metadata entry paged list selection through API reflectes the repository content.")
|
||||||
public void getPagedListofMetadata() throws Exception {
|
public void getPagedListofMetadata() throws Exception {
|
||||||
|
|
||||||
final int totalMetadata = 10;
|
final int totalMetadata = 10;
|
||||||
@@ -760,6 +774,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a DS search with query parameters returns the expected result.")
|
||||||
public void searchDistributionSetRsql() throws Exception {
|
public void searchDistributionSetRsql() throws Exception {
|
||||||
final String dsSuffix = "test";
|
final String dsSuffix = "test";
|
||||||
final int amount = 10;
|
final int amount = 10;
|
||||||
@@ -776,11 +791,13 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Ignore
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a DS search with complete==true parameter returns only DS that are actually completely filled with mandatory modules.")
|
||||||
public void filterDistributionSetComplete() throws Exception {
|
public void filterDistributionSetComplete() throws Exception {
|
||||||
final int amount = 10;
|
final int amount = 10;
|
||||||
TestDataUtil.generateDistributionSets(amount, softwareManagement, distributionSetManagement);
|
TestDataUtil.generateDistributionSets(amount, softwareManagement, distributionSetManagement);
|
||||||
|
distributionSetManagement.createDistributionSet(new DistributionSet("incomplete", "2", "incomplete",
|
||||||
|
distributionSetManagement.findDistributionSetTypeByKey("ecl_os"), null));
|
||||||
|
|
||||||
final String rsqlFindLikeDs1OrDs2 = "complete==" + Boolean.TRUE;
|
final String rsqlFindLikeDs1OrDs2 = "complete==" + Boolean.TRUE;
|
||||||
|
|
||||||
@@ -790,6 +807,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a DS assigned target search with controllerId==1 parameter returns only the target with the given ID.")
|
||||||
public void searchDistributionSetAssignedTargetsRsql() throws Exception {
|
public void searchDistributionSetAssignedTargetsRsql() throws Exception {
|
||||||
// prepare distribution set
|
// prepare distribution set
|
||||||
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
final Set<DistributionSet> createDistributionSetsAlphabetical = createDistributionSetsAlphabetical(1);
|
||||||
@@ -815,6 +833,7 @@ public class DistributionSetResourceTest extends AbstractIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Description("Ensures that a DS metadata filtered query with value==knownValue1 parameter returns only the metadata entries with that value.")
|
||||||
public void searchDistributionSetMetadataRsql() throws Exception {
|
public void searchDistributionSetMetadataRsql() throws Exception {
|
||||||
final int totalMetadata = 10;
|
final int totalMetadata = 10;
|
||||||
final String knownKeyPrefix = "knownKey";
|
final String knownKeyPrefix = "knownKey";
|
||||||
|
|||||||
@@ -46,11 +46,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
/**
|
/**
|
||||||
* Test for {@link DistributionSetTypeResource}.
|
* Test for {@link DistributionSetTypeResource}.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Management RESTful API")
|
@Features("Component Tests - Management API")
|
||||||
@Stories("Distribution Set Type Resource")
|
@Stories("Distribution Set Type Resource")
|
||||||
public class DistributionSetTypeResourceTest extends AbstractIntegrationTest {
|
public class DistributionSetTypeResourceTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -30,11 +30,7 @@ import org.springframework.context.annotation.Description;
|
|||||||
import ru.yandex.qatools.allure.annotations.Features;
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
/**
|
@Features("Component Tests - Management API")
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Features("Component Tests- Download Restful API")
|
|
||||||
@Stories("Download Resource")
|
@Stories("Download Resource")
|
||||||
public class DownloadResourceTest extends AbstractIntegrationTestWithMongoDB {
|
public class DownloadResourceTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
/**
|
/**
|
||||||
* Tests for covering the {@link RolloutResource}.
|
* Tests for covering the {@link RolloutResource}.
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Management RESTful API")
|
@Features("Component Tests - Management API")
|
||||||
@Stories("Rollout Resource")
|
@Stories("Rollout Resource")
|
||||||
public class RolloutResourceTest extends AbstractIntegrationTest {
|
public class RolloutResourceTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ public class RolloutResourceTest extends AbstractIntegrationTest {
|
|||||||
.andReturn();
|
.andReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Description("TODO")
|
@Description("Ensures that the repository refuses to create rollout without a defined target filter set.")
|
||||||
public void missingTargetFilterQueryInRollout() throws Exception {
|
public void missingTargetFilterQueryInRollout() throws Exception {
|
||||||
|
|
||||||
final String targetFilterQuery = null;
|
final String targetFilterQuery = null;
|
||||||
@@ -435,7 +435,6 @@ public class RolloutResourceTest extends AbstractIntegrationTest {
|
|||||||
.andExpect(jsonPath("$content", hasSize(5))).andExpect(jsonPath("$total", equalTo(5)));
|
.andExpect(jsonPath("$content", hasSize(5))).andExpect(jsonPath("$total", equalTo(5)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Start the rollout in async mode")
|
@Description("Start the rollout in async mode")
|
||||||
public void startingRolloutSwitchesIntoRunningStateAsync() throws Exception {
|
public void startingRolloutSwitchesIntoRunningStateAsync() throws Exception {
|
||||||
@@ -528,7 +527,6 @@ public class RolloutResourceTest extends AbstractIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO copied code from sp-bic-test
|
|
||||||
protected <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
|
protected <T> T doWithTimeout(final Callable<T> callable, final SuccessCondition<T> successCondition,
|
||||||
final long timeout, final long pollInterval) throws Exception // NOPMD
|
final long timeout, final long pollInterval) throws Exception // NOPMD
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,13 +23,16 @@ import org.junit.Test;
|
|||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Description;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link SoftwareModuleResource} in case of missing MongoDB connection.
|
* Tests {@link SoftwareModuleResource} in case of missing MongoDB connection.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
@Features("Component Tests - Management API")
|
||||||
|
@Stories("Download Resource")
|
||||||
public class SMRessourceMisingMongoDbConnectionTest extends AbstractIntegrationTest {
|
public class SMRessourceMisingMongoDbConnectionTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
@@ -40,7 +43,8 @@ public class SMRessourceMisingMongoDbConnectionTest extends AbstractIntegrationT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMissingMongoDbConnection() throws Exception {
|
@Description("Ensures that the correct error code is returned in case MongoDB unavailable.")
|
||||||
|
public void missingMongoDbConnectionResultsInErrorAtUpload() throws Exception {
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
|
|||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -49,6 +50,7 @@ import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest;
|
|||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
@@ -65,10 +67,17 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
* Tests for {@link SoftwareModuleResource} {@link RestController}.
|
* Tests for {@link SoftwareModuleResource} {@link RestController}.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Management RESTful API")
|
@Features("Component Tests - Management API")
|
||||||
@Stories("Software Module Resource")
|
@Stories("Software Module Resource")
|
||||||
public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongoDB {
|
public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void assertPreparationOfRepo() {
|
||||||
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("no softwaremodule should be founded")
|
||||||
|
.hasSize(0);
|
||||||
|
assertThat(artifactRepository.findAll()).as("no artifacts should be founded").hasSize(0);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the update of software module metadata. It is verfied that only the selected fields for the update are really updated and the modification values are filled (i.e. updated by and at).")
|
@Description("Tests the update of software module metadata. It is verfied that only the selected fields for the update are really updated and the modification values are filled (i.e. updated by and at).")
|
||||||
@WithUser(principal = "smUpdateTester", allSpPermissions = true)
|
@WithUser(principal = "smUpdateTester", allSpPermissions = true)
|
||||||
@@ -81,18 +90,14 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
final String updateVendor = "newVendor1";
|
final String updateVendor = "newVendor1";
|
||||||
final String updateDescription = "newDescription1";
|
final String updateDescription = "newDescription1";
|
||||||
|
|
||||||
final SoftwareModule ah = softwareManagement
|
softwareManagement.createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, ""));
|
||||||
.createSoftwareModule(new SoftwareModule(appType, "agent-hub", "1.0.1", null, ""));
|
softwareManagement.createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, ""));
|
||||||
final SoftwareModule jvm = softwareManagement
|
softwareManagement.createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, ""));
|
||||||
.createSoftwareModule(new SoftwareModule(runtimeType, "oracle-jre", "1.7.2", null, ""));
|
|
||||||
final SoftwareModule os = softwareManagement
|
|
||||||
.createSoftwareModule(new SoftwareModule(osType, "poky", "3.0.2", null, ""));
|
|
||||||
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, knownSWName, knownSWVersion, knownSWDescription, knownSWVendor);
|
SoftwareModule sm = new SoftwareModule(osType, knownSWName, knownSWVersion, knownSWDescription, knownSWVendor);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
|
|
||||||
assertThat(sm.getName()).isEqualTo(knownSWName);
|
assertThat(sm.getName()).as("Wrong name of the software module").isEqualTo(knownSWName);
|
||||||
assertThat(sm.getName()).isEqualTo(knownSWName);
|
|
||||||
|
|
||||||
final String body = new JSONObject().put("vendor", updateVendor).put("description", updateDescription)
|
final String body = new JSONObject().put("vendor", updateVendor).put("description", updateDescription)
|
||||||
.put("name", "nameShouldNotBeChanged").toString();
|
.put("name", "nameShouldNotBeChanged").toString();
|
||||||
@@ -112,20 +117,9 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test method for
|
|
||||||
* {@link org.eclipse.hawkbit.rest.resource.SoftwareModuleResource#uploadArtifact(java.lang.Long, org.springframework.web.multipart.MultipartFile)}
|
|
||||||
* .
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
* if test fails
|
|
||||||
*/
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the uppload of an artifact binary. The upload is executed and the content checked in the repository for completenes.")
|
@Description("Tests the uppload of an artifact binary. The upload is executed and the content checked in the repository for completenes.")
|
||||||
public void uploadArtifact() throws Exception {
|
public void uploadArtifact() throws Exception {
|
||||||
// prepare repo
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||||
@@ -152,36 +146,41 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.convertArtifactResponse(mvcResult.getResponse().getContentAsString());
|
.convertArtifactResponse(mvcResult.getResponse().getContentAsString());
|
||||||
final Long artId = ((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts()
|
final Long artId = ((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts()
|
||||||
.get(0)).getId();
|
.get(0)).getId();
|
||||||
assertThat(artResult.getArtifactId()).isEqualTo(artId);
|
assertThat(artResult.getArtifactId()).as("Wrong artifact id").isEqualTo(artId);
|
||||||
assertThat(JsonPath.compile("$_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
assertThat(JsonPath.compile("$_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
|
.as("Link contains no self url")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId);
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId);
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("$_links.download.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("$_links.download.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + sm.getId() + "/artifacts/" + artId
|
.as("response contains no download url ").isEqualTo("http://localhost/rest/v1/softwaremodules/"
|
||||||
+ "/download");
|
+ sm.getId() + "/artifacts/" + artId + "/download");
|
||||||
|
|
||||||
|
assertArtifact(sm, random);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertArtifact(final SoftwareModule sm, final byte[] random) throws IOException {
|
||||||
// check result in db...
|
// check result in db...
|
||||||
// repo
|
// repo
|
||||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
assertThat(artifactRepository.findAll()).as("Wrong artifact size").hasSize(1);
|
||||||
|
|
||||||
// binary
|
// binary
|
||||||
assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random),
|
assertTrue("Wrong artifact content",
|
||||||
artifactManagement
|
IOUtils.contentEquals(new ByteArrayInputStream(random),
|
||||||
.loadLocalArtifactBinary((LocalArtifact) softwareManagement
|
artifactManagement
|
||||||
.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0))
|
.loadLocalArtifactBinary((LocalArtifact) softwareManagement
|
||||||
.getFileInputStream()));
|
.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0))
|
||||||
|
.getFileInputStream()));
|
||||||
|
|
||||||
// hashes
|
// hashes
|
||||||
assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getSha1Hash())
|
assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getSha1Hash())
|
||||||
.isEqualTo(HashGeneratorUtils.generateSHA1(random));
|
.as("Wrong sha1 hash").isEqualTo(HashGeneratorUtils.generateSHA1(random));
|
||||||
|
|
||||||
assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getMd5Hash())
|
assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getMd5Hash())
|
||||||
.isEqualTo(HashGeneratorUtils.generateMD5(random));
|
.as("Wrong md5 hash").isEqualTo(HashGeneratorUtils.generateMD5(random));
|
||||||
|
|
||||||
// metadata
|
// metadata
|
||||||
assertThat(((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0))
|
assertThat(((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0))
|
||||||
.getFilename()).isEqualTo("origFilename");
|
.getFilename()).as("wrong metadata of the filename").isEqualTo("origFilename");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -203,9 +202,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system does not accept identical artifacts uploads for the same software module. Expected response: CONFLICT")
|
@Description("Verfies that the system does not accept identical artifacts uploads for the same software module. Expected response: CONFLICT")
|
||||||
public void duplicateUploadArtifact() throws Exception {
|
public void duplicateUploadArtifact() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
|
||||||
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
|
|
||||||
@@ -228,9 +224,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
@Test
|
@Test
|
||||||
@Description("verfies that option to upload artifacts with a custom defined by metadata, i.e. not the file name of the binary itself.")
|
@Description("verfies that option to upload artifacts with a custom defined by metadata, i.e. not the file name of the binary itself.")
|
||||||
public void uploadArtifactWithCustomName() throws Exception {
|
public void uploadArtifactWithCustomName() throws Exception {
|
||||||
// prepare repo
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||||
@@ -245,22 +238,19 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isCreated())
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
|
||||||
.andExpect(jsonPath("$providedFilename", equalTo("customFilename"))).andExpect(status().isCreated());
|
.andExpect(jsonPath("$providedFilename", equalTo("customFilename"))).andExpect(status().isCreated());
|
||||||
;
|
|
||||||
|
|
||||||
// check result in db...
|
// check result in db...
|
||||||
// repo
|
// repo
|
||||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
assertThat(artifactRepository.findAll()).as("Artifact size is wring").hasSize(1);
|
||||||
|
|
||||||
// hashes
|
// hashes
|
||||||
assertThat(artifactManagement.findLocalArtifactByFilename("customFilename")).hasSize(1);
|
assertThat(artifactManagement.findLocalArtifactByFilename("customFilename")).as("Local artifact is wrong")
|
||||||
|
.hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verfies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST")
|
@Description("Verfies that the system refuses upload of an artifact where the provided hash sums do not match. Expected result: BAD REQUEST")
|
||||||
public void uploadArtifactWithHashCheck() throws Exception {
|
public void uploadArtifactWithHashCheck() throws Exception {
|
||||||
// prepare repo
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
assertThat(artifactRepository.findAll()).hasSize(0);
|
||||||
@@ -280,7 +270,8 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
|
|
||||||
// check error result
|
// check error result
|
||||||
ExceptionInfo exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString());
|
ExceptionInfo exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString());
|
||||||
assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH.getKey());
|
assertThat(exceptionInfo.getErrorCode()).as("Exception contains wrong error code")
|
||||||
|
.isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_SHA1_MATCH.getKey());
|
||||||
|
|
||||||
// wrong md5
|
// wrong md5
|
||||||
mvcResult = mvc
|
mvcResult = mvc
|
||||||
@@ -290,42 +281,20 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
|
|
||||||
// check error result
|
// check error result
|
||||||
exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString());
|
exceptionInfo = ResourceUtility.convertException(mvcResult.getResponse().getContentAsString());
|
||||||
assertThat(exceptionInfo.getErrorCode()).isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH.getKey());
|
assertThat(exceptionInfo.getErrorCode()).as("Exception contains wrong error code")
|
||||||
|
.isEqualTo(SpServerError.SP_ARTIFACT_UPLOAD_FAILED_MD5_MATCH.getKey());
|
||||||
|
|
||||||
mvc.perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
mvc.perform(fileUpload("/rest/v1/softwaremodules/{smId}/artifacts", sm.getId()).file(file)
|
||||||
.param("md5sum", md5sum).param("sha1sum", sha1sum)).andDo(MockMvcResultPrinter.print())
|
.param("md5sum", md5sum).param("sha1sum", sha1sum)).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isCreated());
|
.andExpect(status().isCreated());
|
||||||
|
|
||||||
// check result...
|
assertArtifact(sm, random);
|
||||||
// repo
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
|
||||||
|
|
||||||
// binary
|
|
||||||
assertTrue(IOUtils.contentEquals(new ByteArrayInputStream(random),
|
|
||||||
artifactManagement
|
|
||||||
.loadLocalArtifactBinary((LocalArtifact) softwareManagement
|
|
||||||
.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0))
|
|
||||||
.getFileInputStream()));
|
|
||||||
|
|
||||||
// hashes
|
|
||||||
assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getSha1Hash())
|
|
||||||
.isEqualTo(HashGeneratorUtils.generateSHA1(random));
|
|
||||||
|
|
||||||
assertThat(artifactManagement.findLocalArtifactByFilename("origFilename").get(0).getMd5Hash())
|
|
||||||
.isEqualTo(md5sum);
|
|
||||||
|
|
||||||
// metadata
|
|
||||||
assertThat(((LocalArtifact) softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts().get(0))
|
|
||||||
.getFilename()).isEqualTo("origFilename");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests binary download of an artifact including verfication that the downloaded binary is consistent and that the etag header is as expected identical to the SHA1 hash of the file.")
|
@Description("Tests binary download of an artifact including verfication that the downloaded binary is consistent and that the etag header is as expected identical to the SHA1 hash of the file.")
|
||||||
public void downloadArtifact() throws Exception {
|
public void downloadArtifact() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
|
||||||
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
|
|
||||||
@@ -350,19 +319,16 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andExpect(header().string("ETag", artifact2.getSha1Hash()))
|
.andExpect(header().string("ETag", artifact2.getSha1Hash()))
|
||||||
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)).andReturn();
|
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM)).andReturn();
|
||||||
|
|
||||||
assertTrue(Arrays.equals(result2.getResponse().getContentAsByteArray(), random));
|
assertTrue("Response has wrong response content",
|
||||||
|
Arrays.equals(result2.getResponse().getContentAsByteArray(), random));
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremodule size is wrong").hasSize(1);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(2);
|
assertThat(artifactRepository.findAll()).as("Wrong artifact repostiory").hasSize(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.")
|
@Description("Verifies the listing of one defined artifact assigned to a given software module. That includes the artifact metadata and download links.")
|
||||||
public void getArtifact() throws Exception {
|
public void getArtifact() throws Exception {
|
||||||
// check baseline
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
assertThat(artifactRepository.findAll()).hasSize(0);
|
|
||||||
|
|
||||||
// prepare data for test
|
// prepare data for test
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
@@ -548,8 +514,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
@Description("Test retrieval of all software modules the user has access to.")
|
@Description("Test retrieval of all software modules the user has access to.")
|
||||||
public void getSoftwareModules() throws Exception {
|
public void getSoftwareModules() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
|
|
||||||
SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1");
|
SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1");
|
||||||
os = softwareManagement.createSoftwareModule(os);
|
os = softwareManagement.createSoftwareModule(os);
|
||||||
|
|
||||||
@@ -612,14 +576,12 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andExpect(jsonPath("$content.[?(@.id==" + ah.getId() + ")][0]._links.self.href",
|
.andExpect(jsonPath("$content.[?(@.id==" + ah.getId() + ")][0]._links.self.href",
|
||||||
equalTo("http://localhost/rest/v1/softwaremodules/" + ah.getId())));
|
equalTo("http://localhost/rest/v1/softwaremodules/" + ah.getId())));
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremodule size is wrong").hasSize(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Test the various filter parameters, e.g. filter by name or type of the module.")
|
@Description("Test the various filter parameters, e.g. filter by name or type of the module.")
|
||||||
public void getSoftwareModulesWithFilterParameters() throws Exception {
|
public void getSoftwareModulesWithFilterParameters() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
|
|
||||||
SoftwareModule os1 = new SoftwareModule(osType, "osName1", "1.0.0", "description1", "vendor1");
|
SoftwareModule os1 = new SoftwareModule(osType, "osName1", "1.0.0", "description1", "vendor1");
|
||||||
os1 = softwareManagement.createSoftwareModule(os1);
|
os1 = softwareManagement.createSoftwareModule(os1);
|
||||||
|
|
||||||
@@ -712,8 +674,6 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
@Description("Tests GET request on /rest/v1/softwaremodules/{smId}.")
|
@Description("Tests GET request on /rest/v1/softwaremodules/{smId}.")
|
||||||
public void getSoftareModule() throws Exception {
|
public void getSoftareModule() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
|
|
||||||
SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1");
|
SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1");
|
||||||
os = softwareManagement.createSoftwareModule(os);
|
os = softwareManagement.createSoftwareModule(os);
|
||||||
|
|
||||||
@@ -771,15 +731,13 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andExpect(jsonPath("$_links.artifacts.href",
|
.andExpect(jsonPath("$_links.artifacts.href",
|
||||||
equalTo("http://localhost/rest/v1/softwaremodules/" + ah.getId() + "/artifacts")));
|
equalTo("http://localhost/rest/v1/softwaremodules/" + ah.getId() + "/artifacts")));
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremodule size is wrong").hasSize(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
@WithUser(principal = "uploadTester", allSpPermissions = true)
|
||||||
@Description("Verfies that the create request actually results in the creation of the modules in the repository.")
|
@Description("Verfies that the create request actually results in the creation of the modules in the repository.")
|
||||||
public void createSoftwareModules() throws JSONException, Exception {
|
public void createSoftwareModules() throws JSONException, Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(0);
|
|
||||||
|
|
||||||
final SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1");
|
final SoftwareModule os = new SoftwareModule(osType, "name1", "version1", "description1", "vendor1");
|
||||||
final SoftwareModule jvm = new SoftwareModule(runtimeType, "name2", "version1", "description1", "vendor1");
|
final SoftwareModule jvm = new SoftwareModule(runtimeType, "name2", "version1", "description1", "vendor1");
|
||||||
final SoftwareModule ah = new SoftwareModule(appType, "name3", "version1", "description1", "vendor1");
|
final SoftwareModule ah = new SoftwareModule(appType, "name3", "version1", "description1", "vendor1");
|
||||||
@@ -824,74 +782,75 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("[0]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
|
.as("Response contains invalid self href")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId());
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId());
|
||||||
assertThat(JsonPath.compile("[0]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString())
|
assertThat(JsonPath.compile("[0]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString())
|
||||||
.toString()).isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId() + "/artifacts");
|
.toString()).as("Response contains invalid artifacts href")
|
||||||
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + osCreated.getId() + "/artifacts");
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("[1]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
|
.as("Response contains invalid self href")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId());
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId());
|
||||||
assertThat(JsonPath.compile("[1]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString())
|
assertThat(JsonPath.compile("[1]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString())
|
||||||
.toString()).isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId() + "/artifacts");
|
.toString()).as("Response contains invalid artfacts href")
|
||||||
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + jvmCreated.getId() + "/artifacts");
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
JsonPath.compile("[2]_links.self.href").read(mvcResult.getResponse().getContentAsString()).toString())
|
||||||
|
.as("Response contains links self href")
|
||||||
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId());
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId());
|
||||||
assertThat(JsonPath.compile("[2]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString())
|
assertThat(JsonPath.compile("[2]_links.artifacts.href").read(mvcResult.getResponse().getContentAsString())
|
||||||
.toString()).isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId() + "/artifacts");
|
.toString()).as("Response contains invalid artifacts href")
|
||||||
|
.isEqualTo("http://localhost/rest/v1/softwaremodules/" + ahCreated.getId() + "/artifacts");
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Wrong softwaremodule size").hasSize(3);
|
||||||
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getName())
|
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getName())
|
||||||
.isEqualTo(os.getName());
|
.as("Softwaremoudle name is wrong").isEqualTo(os.getName());
|
||||||
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getCreatedBy())
|
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getCreatedBy())
|
||||||
.isEqualTo("uploadTester");
|
.as("Softwaremoudle created by is wrong").isEqualTo("uploadTester");
|
||||||
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getCreatedAt())
|
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, osType).getContent().get(0).getCreatedAt())
|
||||||
.isGreaterThanOrEqualTo(current);
|
.as("Softwaremoudle created at is wrong").isGreaterThanOrEqualTo(current);
|
||||||
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, runtimeType).getContent().get(0).getName())
|
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, runtimeType).getContent().get(0).getName())
|
||||||
.isEqualTo(jvm.getName());
|
.as("Softwaremoudle name is wrong").isEqualTo(jvm.getName());
|
||||||
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, appType).getContent().get(0).getName())
|
assertThat(softwareManagement.findSoftwareModulesByType(pageReq, appType).getContent().get(0).getName())
|
||||||
.isEqualTo(ah.getName());
|
.as("Softwaremoudle name is wrong").isEqualTo(ah.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies successfull deletion of software modules that are not in use, i.e. assigned to a DS.")
|
@Description("Verifies successfull deletion of software modules that are not in use, i.e. assigned to a DS.")
|
||||||
public void deleteUnassignedSoftwareModule() throws Exception {
|
public void deleteUnassignedSoftwareModule() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty();
|
|
||||||
assertThat(artifactRepository.findAll()).isEmpty();
|
|
||||||
|
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
|
|
||||||
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
|
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
|
||||||
|
|
||||||
final Artifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(),
|
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file1", false);
|
||||||
"file1", false);
|
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("Softwaremoudle size is wrong").hasSize(1);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
assertThat(artifactRepository.findAll()).as("artifact site is wrong").hasSize(1);
|
||||||
assertThat(softwareModuleRepository.findAll()).hasSize(1);
|
assertThat(softwareModuleRepository.findAll()).as("Softwaremoudle size is wrong").hasSize(1);
|
||||||
|
|
||||||
mvc.perform(delete("/rest/v1/softwaremodules/{smId}", sm.getId())).andDo(MockMvcResultPrinter.print())
|
mvc.perform(delete("/rest/v1/softwaremodules/{smId}", sm.getId())).andDo(MockMvcResultPrinter.print())
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty();
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq))
|
||||||
assertThat(softwareModuleRepository.findAll()).isEmpty();
|
.as("After delete no softwarmodule should be available").isEmpty();
|
||||||
assertThat(artifactRepository.findAll()).isEmpty();
|
assertThat(softwareModuleRepository.findAll()).as("After delete no softwarmodule should be available")
|
||||||
|
.isEmpty();
|
||||||
|
assertThat(artifactRepository.findAll()).as("After delete no artifact should be available").isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Verifies successfull deletion of software modules that are in use, i.e. assigned to a DS which should result in movinf the module to the archive.")
|
@Description("Verifies successfull deletion of software modules that are in use, i.e. assigned to a DS which should result in movinf the module to the archive.")
|
||||||
public void deleteAssignedSoftwareModule() throws Exception {
|
public void deleteAssignedSoftwareModule() throws Exception {
|
||||||
// check baseline
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty();
|
|
||||||
assertThat(artifactRepository.findAll()).isEmpty();
|
|
||||||
|
|
||||||
final DistributionSet ds1 = TestDataUtil.generateDistributionSet("a", softwareManagement,
|
final DistributionSet ds1 = TestDataUtil.generateDistributionSet("a", softwareManagement,
|
||||||
distributionSetManagement);
|
distributionSetManagement);
|
||||||
|
|
||||||
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
|
final byte random[] = RandomStringUtils.random(5 * 1024).getBytes();
|
||||||
|
|
||||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||||
ds1.findFirstModuleByType(appType).getId(), "file1", false);
|
ds1.findFirstModuleByType(appType).getId(), "file1", false);
|
||||||
|
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(3);
|
||||||
@@ -906,17 +865,17 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
|
|
||||||
// all 3 are now marked as deleted
|
// all 3 are now marked as deleted
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq).getNumber()).isEqualTo(0);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq).getNumber())
|
||||||
assertThat(softwareModuleRepository.findAll()).hasSize(3);
|
.as("After delete no softwarmodule should be available").isEqualTo(0);
|
||||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
assertThat(softwareModuleRepository.findAll()).as("After delete no softwarmodule should marked as deleted")
|
||||||
|
.hasSize(3);
|
||||||
|
assertThat(artifactRepository.findAll()).as("After delete artifact should available for marked as deleted sm's")
|
||||||
|
.hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the deletion of an artifact including verfication that the artifact is actually erased in the repository and removed from the software module.")
|
@Description("Tests the deletion of an artifact including verfication that the artifact is actually erased in the repository and removed from the software module.")
|
||||||
public void deleteArtifact() throws Exception {
|
public void deleteArtifact() throws Exception {
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).isEmpty();
|
|
||||||
assertThat(artifactRepository.findAll()).isEmpty();
|
|
||||||
|
|
||||||
// Create 1 SM
|
// Create 1 SM
|
||||||
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
SoftwareModule sm = new SoftwareModule(osType, "name 1", "version 1", null, null);
|
||||||
sm = softwareManagement.createSoftwareModule(sm);
|
sm = softwareManagement.createSoftwareModule(sm);
|
||||||
@@ -926,8 +885,7 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
// Create 2 artifacts
|
// Create 2 artifacts
|
||||||
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
final LocalArtifact artifact = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
||||||
sm.getId(), "file1", false);
|
sm.getId(), "file1", false);
|
||||||
final LocalArtifact artifact2 = artifactManagement.createLocalArtifact(new ByteArrayInputStream(random),
|
artifactManagement.createLocalArtifact(new ByteArrayInputStream(random), sm.getId(), "file2", false);
|
||||||
sm.getId(), "file2", false);
|
|
||||||
|
|
||||||
// check repo before delete
|
// check repo before delete
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1);
|
||||||
@@ -940,9 +898,12 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
.andDo(MockMvcResultPrinter.print()).andExpect(status().isOk());
|
||||||
|
|
||||||
// check that only one artifact is still alive and still assigned
|
// check that only one artifact is still alive and still assigned
|
||||||
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).hasSize(1);
|
assertThat(softwareManagement.findSoftwareModulesAll(pageReq)).as("After the sm should be marked as deleted")
|
||||||
assertThat(artifactRepository.findAll()).hasSize(1);
|
.hasSize(1);
|
||||||
assertThat(softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts()).hasSize(1);
|
assertThat(artifactRepository.findAll()).as("After delete artifact should available for marked as deleted sm's")
|
||||||
|
.hasSize(1);
|
||||||
|
assertThat(softwareManagement.findSoftwareModuleWithDetails(sm.getId()).getArtifacts())
|
||||||
|
.as("After delete artifact should available for marked as deleted sm's").hasSize(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -972,8 +933,8 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
final SoftwareModuleMetadata metaKey1 = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey1));
|
final SoftwareModuleMetadata metaKey1 = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey1));
|
||||||
final SoftwareModuleMetadata metaKey2 = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey2));
|
final SoftwareModuleMetadata metaKey2 = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey2));
|
||||||
|
|
||||||
assertThat(metaKey1.getValue()).isEqualTo(knownValue1);
|
assertThat(metaKey1.getValue()).as("Metadata key is wrong").isEqualTo(knownValue1);
|
||||||
assertThat(metaKey2.getValue()).isEqualTo(knownValue2);
|
assertThat(metaKey2.getValue()).as("Metadata key is wrong").isEqualTo(knownValue2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -997,7 +958,7 @@ public class SoftwareModuleResourceTest extends AbstractIntegrationTestWithMongo
|
|||||||
.andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(updateValue)));
|
.andExpect(jsonPath("key", equalTo(knownKey))).andExpect(jsonPath("value", equalTo(updateValue)));
|
||||||
|
|
||||||
final SoftwareModuleMetadata assertDS = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey));
|
final SoftwareModuleMetadata assertDS = softwareManagement.findOne(new SwMetadataCompositeKey(sm, knownKey));
|
||||||
assertThat(assertDS.getValue()).isEqualTo(updateValue);
|
assertThat(assertDS.getValue()).as("Metadata is wrong").isEqualTo(updateValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -43,11 +43,8 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
/**
|
/**
|
||||||
* Test for {@link SoftwareModuleTypeResource}.
|
* Test for {@link SoftwareModuleTypeResource}.
|
||||||
*
|
*
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Management RESTful API")
|
@Features("Component Tests - Management API")
|
||||||
@Stories("Software Module Type Resource")
|
@Stories("Software Module Type Resource")
|
||||||
public class SoftwareModuleTypeResourceTest extends AbstractIntegrationTest {
|
public class SoftwareModuleTypeResourceTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user