Update Spring Boot & Hateoas (#430)
* Upgrade spring boot 1.4.4 and hateoas 0.23. Removed unneded dependency, Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Avoid link change with new hateoas version. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Readded commons.io Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Update MariaDB driver to 1.5.7 Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Added missing content to docs. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix equals. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Simplify Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix equal after removal of commons collections. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -17,6 +17,8 @@
|
||||
href: "/documentation/architecture/datamodel.html"
|
||||
- title: "Target States"
|
||||
href: "/documentation/architecture/targetstate.html"
|
||||
- title: "Rollout Management"
|
||||
href: "/documentation/architecture/rollout-management.html"
|
||||
|
||||
- title: "Interfaces"
|
||||
href: ""
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
layout: documentation
|
||||
title: Rollout Management
|
||||
---
|
||||
|
||||
{% include base.html %}
|
||||
|
||||
Software update operations in large scale IoT scenarios with hundreds of thousands of devices require special handling.
|
||||
|
||||
That includes:
|
||||
- _Technical Scalability_ by means of horizontal scale of the _Rollouts_ server cluster in the cloud.
|
||||
- _Global_ artifact _content delivery_ capacities.
|
||||
- _Functional Scalability_ by means of:
|
||||
- Secure handling of large volumes of devices at rollout creation time.
|
||||
- Monitoring of the rollout progress.
|
||||
- Emergency rollout shutdown in case of problems on to many devices.
|
||||
|
||||
- Reporting capabilities for a complete understanding of the rollout progress at each point in time.
|
||||
|
||||
Eclipse _hawkBit_ sees these capabilities under the term Rollout Management.
|
||||
|
||||
The following capabilities are currently supported by the _Rollout Management_:
|
||||
- Create, update and start of rollouts.
|
||||
- Selection of targets as input for the rollout based on _target filter_ functionality.
|
||||
- Selection of a _DistributionSet_.
|
||||
- Auto-splitting of the input target list into a defined number deployment groups.
|
||||
|
||||
- Cascading start of the deployment groups based on installation status of the previous group.
|
||||
- Emergency shutdown of the rollout in case a group exceeds the defined error threshold.
|
||||
- Rollout progress monitoring for the entire rollout and the individual groups.
|
||||
|
||||
|
||||
## Cascading Deployment Group Execution
|
||||
The cascading execution of the deployment groups is based on two thresholds that can be defined by the rollout creator.
|
||||
- success condition by means of percentage of successfully installed targets in the current groups triggers.
|
||||
- error condition by means of absolute or percentage of failed installations which triggers an emergency shutdown of the entire rollout.
|
||||
|
||||
[[images/DeploymentGroups.png]]
|
||||
|
||||
## Rollout state machine
|
||||
### State Machine on Rollout
|
||||
{:width="100%" .image-center}
|
||||
|
||||
### State Machine on Rollout Deployment Group
|
||||
{:width="100%" .image-center}
|
||||
@@ -18,7 +18,7 @@ _hawkBit_ is able to run in a cluster with some constraints. This guide provides
|
||||
Event communication between nodes is based on [Spring Cloud Bus](https://cloud.spring.io/spring-cloud-bus/) and [Spring Cloud Stream](http://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/). There are different [binder implementations](http://docs.spring.io/spring-cloud-stream/docs/current/reference/htmlsingle/#_binders) available. The _hawkbit example app_ uses RabbitMQ binder. Every node gets his own queue to receive cluster events, the default payload is JSON.
|
||||
If an event is thrown locally at one node, it will be automatically delivered to all other available nodes via the Spring Cloud Bus's topic exchange:
|
||||
|
||||
{:width="100%"}
|
||||
[[images/eventing-within-cluster.png]]
|
||||
|
||||
Via the ServiceMatcher you can check whether an event happened locally at one node or on a different node.
|
||||
`serviceMatcher.isFromSelf(event)`
|
||||
@@ -49,4 +49,3 @@ In a cluster-capable environment this fact can lead to issues as it could happen
|
||||
_hawkbit_ owns the feature of guarding itself from DoS attacks, a [DoS filter](https://github.com/eclipse/hawkbit/blob/master/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/DosFilter.java). It reduces the maximum number of requests per seconds which can be configured for read and write requests.
|
||||
This mechanism is only working for every node separately, i.e. in a cluster environment the worst-case behaviour would be that the maximum number of requests per seconds will be increased to its product if every request is handled by a different node.
|
||||
The same constraint exists with the validator to check if a user tried too many logins within a defined period of time.
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -36,7 +36,7 @@ Available Management APIs resources are:
|
||||
* [Software Module Types](https://docs.bosch-iot-rollouts.com/documentation/rest-api/softwaremoduletypes-api-guide.html)
|
||||
* [Target Tag](https://docs.bosch-iot-rollouts.com/documentation/rest-api/targettag-api-guide.html)
|
||||
* [Distribution Set Tag](https://docs.bosch-iot-rollouts.com/documentation/rest-api/distributionsettag-api-guide.html)
|
||||
* [Rollouts](http://https://docs.bosch-iot-rollouts.com/documentation/developerguide/apispecifications/managementapi/rollouts.html)
|
||||
* [Rollouts](https://docs.bosch-iot-rollouts.com/documentation/rest-api/rollout-api-guide.html)
|
||||
|
||||
|
||||
## Headers
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtMetadata;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifact;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.artifact.MgmtArtifactHash;
|
||||
@@ -116,7 +117,7 @@ public final class MgmtSoftwareModuleMapper {
|
||||
response.add(linkTo(methodOn(MgmtSoftwareModuleResource.class).getMetadata(response.getModuleId(),
|
||||
Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET),
|
||||
Integer.parseInt(MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, null))
|
||||
.withRel("metadata"));
|
||||
.withRel("metadata").expand(ArrayUtils.toArray()));
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.MgmtPollStatus;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtAction;
|
||||
import org.eclipse.hawkbit.mgmt.json.model.action.MgmtActionStatus;
|
||||
@@ -65,7 +66,7 @@ public final class MgmtTargetMapper {
|
||||
response.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionHistory(response.getControllerId(), 0,
|
||||
MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE,
|
||||
ActionFields.ID.getFieldName() + ":" + SortDirection.DESC, null))
|
||||
.withRel(MgmtRestConstants.TARGET_V1_ACTIONS));
|
||||
.withRel(MgmtRestConstants.TARGET_V1_ACTIONS).expand(ArrayUtils.toArray()));
|
||||
}
|
||||
|
||||
static void addPollStatus(final Target target, final MgmtTarget targetRest) {
|
||||
|
||||
@@ -81,10 +81,6 @@
|
||||
<groupId>cz.jirutka.rsql</groupId>
|
||||
<artifactId>rsql-parser</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
|
||||
@@ -18,7 +18,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetFields;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetMetadataFields;
|
||||
@@ -69,6 +68,7 @@ import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.transaction.annotation.Isolation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
@@ -12,7 +12,6 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.AbstractDistributionSetUpdateCreate;
|
||||
@@ -21,6 +20,7 @@ import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Create/build implementation.
|
||||
|
||||
@@ -11,13 +11,13 @@ package org.eclipse.hawkbit.repository.jpa.builder;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.eclipse.hawkbit.repository.SoftwareManagement;
|
||||
import org.eclipse.hawkbit.repository.builder.AbstractDistributionSetTypeUpdateCreate;
|
||||
import org.eclipse.hawkbit.repository.builder.DistributionSetTypeCreate;
|
||||
import org.eclipse.hawkbit.repository.exception.EntityNotFoundException;
|
||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* Create/build implementation.
|
||||
|
||||
@@ -25,12 +25,12 @@ import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
/**
|
||||
* A distribution set type defines which software module types can or have to be
|
||||
|
||||
@@ -204,10 +204,6 @@
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.hawkbit.ui.artifacts.smtable.SoftwareModuleAddUpdateWindow;
|
||||
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||
@@ -33,7 +32,6 @@ import org.vaadin.hene.flexibleoptiongroup.FlexibleOptionGroupItemComponent;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.vaadin.data.Container.ItemSetChangeEvent;
|
||||
import com.vaadin.data.Container.ItemSetChangeListener;
|
||||
import com.vaadin.data.Property.ValueChangeEvent;
|
||||
@@ -240,7 +238,7 @@ public class CommonDialogWindow extends Window {
|
||||
Object value = field.getValue();
|
||||
|
||||
if (field instanceof Table) {
|
||||
value = Sets.newHashSet(((Table) field).getContainerDataSource().getItemIds());
|
||||
value = ((Table) field).getContainerDataSource().getItemIds();
|
||||
}
|
||||
orginalValues.put(field, value);
|
||||
}
|
||||
@@ -263,6 +261,9 @@ public class CommonDialogWindow extends Window {
|
||||
}
|
||||
|
||||
protected void addComponentListeners() {
|
||||
// avoid duplicate registration
|
||||
removeListeners();
|
||||
|
||||
for (final AbstractField<?> field : allComponents) {
|
||||
if (field instanceof TextChangeNotifier) {
|
||||
((TextChangeNotifier) field).addTextChangeListener(new ChangeListener(field));
|
||||
@@ -290,28 +291,13 @@ public class CommonDialogWindow extends Window {
|
||||
}
|
||||
final Object currentValue = getCurrentVaue(currentChangedComponent, newValue, field);
|
||||
|
||||
if (!isValueEquals(field, originalValue, currentValue)) {
|
||||
if (!Objects.equals(originalValue, currentValue)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isValueEquals(final AbstractField<?> field, final Object orginalValue,
|
||||
final Object currentValue) {
|
||||
if (Set.class.equals(field.getType())) {
|
||||
return CollectionUtils.isEqualCollection(CollectionUtils.emptyIfNull((Collection<?>) orginalValue),
|
||||
CollectionUtils.emptyIfNull((Collection<?>) currentValue));
|
||||
}
|
||||
|
||||
if (String.class.equals(field.getType())) {
|
||||
return Objects.equals(Strings.emptyToNull((String) orginalValue),
|
||||
Strings.emptyToNull((String) currentValue));
|
||||
}
|
||||
|
||||
return Objects.equals(orginalValue, currentValue);
|
||||
}
|
||||
|
||||
private static Object getCurrentVaue(final Component currentChangedComponent, final Object newValue,
|
||||
final AbstractField<?> field) {
|
||||
Object currentValue = field.getValue();
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.eclipse.hawkbit.repository.FilterParams;
|
||||
import org.eclipse.hawkbit.repository.OffsetBasedPageRequest;
|
||||
import org.eclipse.hawkbit.repository.TargetManagement;
|
||||
@@ -39,6 +38,7 @@ import org.eclipse.hawkbit.ui.utils.SpringContextHelper;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Slice;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.vaadin.addons.lazyquerycontainer.AbstractBeanQuery;
|
||||
import org.vaadin.addons.lazyquerycontainer.QueryDefinition;
|
||||
|
||||
@@ -211,7 +211,7 @@ public class TargetBeanQuery extends AbstractBeanQuery<ProxyTarget> {
|
||||
|
||||
private boolean isAnyFilterSelected() {
|
||||
final boolean isFilterSelected = isTagSelected() || isOverdueFilterEnabled();
|
||||
return isFilterSelected || CollectionUtils.isNotEmpty(status) || distributionId != null
|
||||
return isFilterSelected || !CollectionUtils.isEmpty(status) || distributionId != null
|
||||
|| !isNullOrEmpty(searchText);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.eclipse.hawkbit.repository.DistributionSetManagement;
|
||||
import org.eclipse.hawkbit.repository.FilterParams;
|
||||
import org.eclipse.hawkbit.repository.TagManagement;
|
||||
@@ -70,6 +69,7 @@ import org.eclipse.hawkbit.ui.utils.UIComponentIdProvider;
|
||||
import org.eclipse.hawkbit.ui.utils.UINotification;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer;
|
||||
import org.vaadin.addons.lazyquerycontainer.LazyQueryDefinition;
|
||||
|
||||
13
pom.xml
13
pom.xml
@@ -14,7 +14,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.3.RELEASE</version>
|
||||
<version>1.4.4.RELEASE</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.eclipse.hawkbit</groupId>
|
||||
@@ -101,11 +101,12 @@
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<spring.boot.version>1.4.3.RELEASE</spring.boot.version>
|
||||
<spring.boot.version>1.4.4.RELEASE</spring.boot.version>
|
||||
<snapshotDependencyAllowed>true</snapshotDependencyAllowed>
|
||||
|
||||
<!-- Spring boot version overrides (should be reviewed with every boot upgrade) - START -->
|
||||
<!-- Newer versions needed than defined in Boot -->
|
||||
<spring-hateoas.version>0.23.0.RELEASE</spring-hateoas.version>
|
||||
<!-- Older versions needed than defined in Boot -->
|
||||
<!-- Incompatible changes in 2.2 -->
|
||||
<json-path.version>2.0.0</json-path.version>
|
||||
@@ -137,14 +138,13 @@
|
||||
<gwtmockito.version>1.1.6</gwtmockito.version>
|
||||
<pl.pragmatists.version>1.0.2</pl.pragmatists.version>
|
||||
<guava.version>19.0</guava.version>
|
||||
<mariadb-java-client.version>1.5.3</mariadb-java-client.version>
|
||||
<mariadb-java-client.version>1.5.7</mariadb-java-client.version>
|
||||
<embedded-mongo.version>1.50.5</embedded-mongo.version>
|
||||
<javax.el-api.version>2.2.4</javax.el-api.version>
|
||||
<corn-cps.version>1.1.7</corn-cps.version>
|
||||
<jlorem.version>1.1</jlorem.version>
|
||||
<json-simple.version>1.1.1</json-simple.version>
|
||||
<commons-lang3.version>3.4</commons-lang3.version>
|
||||
<commons-collections4.version>4.1</commons-collections4.version>
|
||||
<json.version>20141113</json.version>
|
||||
<rsql-parser.version>2.1.0</rsql-parser.version>
|
||||
<spring.cloud.version>Camden.SR1</spring.cloud.version>
|
||||
@@ -668,11 +668,6 @@
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
|
||||
Reference in New Issue
Block a user