Create Rollout UI with Groups definition (#369)

* Rollout creation UI with groups definition

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Improved code quality

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Added a legend to the Rollouts Creation UI's PieChart

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Updated color palette for pie chart. Using RolloutGroupCreate for validation. Displaying pie chart for group editing.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Optimized ComboBoxBuilder

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Removed not necessary RPC interfaces.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Fix Rollout verification count query. Improved UI style. Added dependency management for d3.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Auto start and scheduled start of Rollouts

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Optimized RSQL Utility to avoid multiple joins on the same table.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Fixed RSQL Utility to avoid multiple joins on the same table to only work with OR nodes. Optimized validation queries for rollout group creation.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Asynchronous handling of groups validation in the create rollouts UI.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Added loading indicator to create rollout UI.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Avoid parallel validation for a user session.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Fix issues after merge of master into branch.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Improve code quality

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Refreshing the total target count after validation on the rollouts creation UI.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>

* Remove unused RolloutUpdate method. Optimization of the RolloutHelper.
Comments for RolloutGroupsValidation and RSQLUtility with explanation.

Signed-off-by: Dominik Herbst <dominik.herbst@bosch-si.com>
This commit is contained in:
Dominik Herbst
2017-01-26 09:37:20 +01:00
committed by Kai Zimmermann
parent 430bf632cf
commit 833b0795e3
45 changed files with 2864 additions and 369 deletions

View File

@@ -9,6 +9,7 @@
package org.eclipse.hawkbit.repository;
import java.util.List;
import java.util.concurrent.Future;
import javax.validation.constraints.NotNull;
@@ -27,11 +28,13 @@ import org.eclipse.hawkbit.repository.model.Rollout.RolloutStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupStatus;
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
import org.eclipse.hawkbit.repository.model.RolloutGroupsValidation;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.concurrent.ListenableFuture;
/**
* RolloutManagement to control rollouts e.g. like creating, starting, resuming
@@ -42,7 +45,7 @@ public interface RolloutManagement {
/**
* Checking running rollouts. Rollouts which are checked updating the
* {@link Rollout#setLastCheck(long)} to indicate that the current instance
* lastCheck to indicate that the current instance
* is handling the specific rollout. This code should run as system-code.
*
* <pre>
@@ -55,8 +58,8 @@ public interface RolloutManagement {
* }
* </pre>
*
* This method is attend to be called by a scheduler.
* {@link RolloutScheduler}. And must be running in an transaction so it's
* This method is intended to be called by a scheduler.
* And must be running in an transaction so it's
* splitted from the scheduler.
*
* Rollouts which are currently running are investigated, by means the
@@ -95,6 +98,17 @@ public interface RolloutManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
void checkStartingRollouts(long delayBetweenChecks);
/**
* Checking Rollouts that are currently ready for an auto start.
*
* @param delayBetweenChecks
* the time in milliseconds of the delay between the further and
* this check. This check is only applied if the last check is
* less than (lastcheck-delay).
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE)
void checkReadyRollouts(long delayBetweenChecks);
/**
* Counts all {@link Rollout}s in the repository.
*
@@ -181,6 +195,24 @@ public interface RolloutManagement {
Rollout createRollout(@NotNull RolloutCreate rollout, @NotNull List<RolloutGroupCreate> groups,
RolloutGroupConditions conditions);
/**
* Calculates how many targets are addressed by each rollout group and
* returns the validation information.
*
* @param groups
* a list of rollout groups
* @param targetFilter
* the rollout
* @param createdAt
* timestamp when the rollout was created
* @return the validation information
* @throws RolloutIllegalStateException
* thrown when no targets are targeted by the rollout
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ)
ListenableFuture<RolloutGroupsValidation> validateTargetsInGroups(List<RolloutGroupCreate> groups,
String targetFilter, Long createdAt);
/**
* Can be called on a Rollout in {@link RolloutStatus#CREATING} to
* automatically fill it with targets.
@@ -365,10 +397,6 @@ public interface RolloutManagement {
*
* @param update
* rollout to be updated
* @param name
* to update or <code>null</code>
* @param description
* to update or <code>null</code>
*
* @return Rollout updated rollout
*/

View File

@@ -25,6 +25,9 @@ public class RolloutProperties {
// used by @Scheduled annotation which needs constant
public static final String PROP_STARTING_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.rollout.startingScheduler.fixedDelay:2000}";
// used by @Scheduled annotation which needs constant
public static final String PROP_READY_SCHEDULER_DELAY_PLACEHOLDER = "${hawkbit.rollout.readyScheduler.fixedDelay:30000}";
/**
* Rollout scheduler configuration.
*/
@@ -65,6 +68,8 @@ public class RolloutProperties {
private final Scheduler startingScheduler = new Scheduler(2000L);
private final Scheduler readyScheduler = new Scheduler(30000L);
public Scheduler getScheduler() {
return scheduler;
}
@@ -76,4 +81,8 @@ public class RolloutProperties {
public Scheduler getStartingScheduler() {
return startingScheduler;
}
public Scheduler getReadyScheduler() {
return readyScheduler;
}
}

View File

@@ -108,6 +108,18 @@ public interface TargetFilterQueryManagement {
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findTargetFilterQueryByFilter(@NotNull Pageable pageable, @NotNull String rsqlFilter);
/**
* Retrieves all target filter query which have exactly the provided query.
*
* @param pageable
* pagination parameter
* @param query
* the query saved in the target filter query
* @return the page with the found {@link TargetFilterQuery}
*/
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET)
Page<TargetFilterQuery> findTargetFilterQueryByQuery(@NotNull Pageable pageable, String query);
/**
* Retrieves all target filter query which {@link TargetFilterQuery}.
*

View File

@@ -76,6 +76,13 @@ public interface RolloutCreate {
*/
RolloutCreate forcedTime(Long forcedTime);
/**
* @param startAt
* for {@link Rollout#getStartAt()}
* @return updated builder instance
*/
RolloutCreate startAt(Long startAt);
/**
* @return peek on current state of {@link Rollout} in the builder
*/

View File

@@ -8,9 +8,14 @@
*/
package org.eclipse.hawkbit.repository.builder;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Rollout;
import org.hibernate.validator.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Optional;
/**
* Builder to update an existing {@link Rollout} entry. Defines all fields that
* can be updated.
@@ -30,4 +35,33 @@ public interface RolloutUpdate {
* @return updated builder instance
*/
RolloutUpdate description(String description);
/**
* @param setId
* for {@link Rollout#getDistributionSet()}
* @return updated builder instance
*/
RolloutUpdate set(long setId);
/**
* @param actionType
* for {@link Rollout#getActionType()}
* @return updated builder instance
*/
RolloutUpdate actionType(@NotNull Action.ActionType actionType);
/**
* @param forcedTime
* for {@link Rollout#getForcedTime()}
* @return updated builder instance
*/
RolloutUpdate forcedTime(Long forcedTime);
/**
* @param startAt
* for {@link Rollout#getStartAt()}
* @return updated builder instance
*/
RolloutUpdate startAt(Long startAt);
}

View File

@@ -59,6 +59,12 @@ public interface Rollout extends NamedEntity {
*/
long getForcedTime();
/**
* @return Timestamp when the rollout should be started automatically. Can be null.
*/
Long getStartAt();
/**
* @return number of {@link Target}s in this rollout.
*/

View File

@@ -0,0 +1,65 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.repository.model;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* Represents information to validate the correct distribution of targets to
* rollout groups.
*/
public class RolloutGroupsValidation {
/**
* The total amount of targets in a {@link Rollout}
*/
private long totalTargets;
/**
* A list containing the count of targets for each {@link RolloutGroup}
*/
private List<Long> targetsPerGroup;
/**
* Instantiates a new validation result
*
* @param totalTargets
* The total amount of targets in a {@link Rollout}
* @param targetsPerGroup
* A list containing the count of targets for each
* {@link RolloutGroup}
*/
public RolloutGroupsValidation(final long totalTargets, @NotNull final List<Long> targetsPerGroup) {
this.totalTargets = totalTargets;
this.targetsPerGroup = targetsPerGroup;
}
public long getTotalTargets() {
return totalTargets;
}
public List<Long> getTargetsPerGroup() {
return targetsPerGroup;
}
/**
* @return the count of targets that are in groups
*/
public long getTargetsInGroups() {
return targetsPerGroup.stream().mapToLong(Long::longValue).sum();
}
/**
* @return whether the groups contain all targets
*/
public boolean isValid() {
return totalTargets == getTargetsInGroups();
}
}